changed the algorithm how sessions work:

- if the IP is banned or there is no a winix function then we set a temporary session
- else
  if there is a session's cookie sent by the client then:
   - if the cookie is a correct session's cookie then we set the session from the cookie
   - or if the cookie is not a correct session's cookie (e.g. session expired) and the winix function
     requires a cookie then we set a new session
   - or if there is no cookie sent then if a winix function requires a session we create a new session

  if there was an error creating a new session or event counters reach a ban limit then a temporary session will be used





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@1115 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2018-06-20 15:00:02 +00:00
parent 35b93b1655
commit 08123fe6ac
9 changed files with 78 additions and 40 deletions

View File

@ -408,9 +408,9 @@ void App::ProcessRequestThrow()
if( !cur.request->dir_tab.empty() ) if( !cur.request->dir_tab.empty() )
{ {
functions.CheckFunctionAndSymlink(); // CHECK ME it is correct now? functions.CheckFunctionAndSymlink();
session_manager.SetSession(); session_manager.PrepareSession();
cur.session = session_manager.GetCurSession(); cur.session = session_manager.GetCurSession();
SetLocale(); SetLocale();
@ -451,6 +451,10 @@ void App::ProcessRequestThrow()
cur.request->dir_tab.push_back(root_dir); cur.request->dir_tab.push_back(root_dir);
cur.request->last_item = cur.request->dir_tab.back(); cur.request->last_item = cur.request->dir_tab.back();
} }
else
{
log << log1 << "App: oops, we do not have a root dir" << logend;
}
} }
cur.mount = system.mounts.CalcCurMount(); cur.mount = system.mounts.CalcCurMount();

View File

@ -263,7 +263,7 @@ public:
// default: 128 (value in the range <0 - 65535>) // default: 128 (value in the range <0 - 65535>)
size_t session_hijacking_treshold; size_t session_hijacking_treshold;
// after how many times a client will be banned if it did not send a session cookie // after how many times a client will be banned (or given temporary session) if it did not send a session cookie
// this can be a bot such as a Google Bot or just people connecting from a NAT and all have the same IP // this can be a bot such as a Google Bot or just people connecting from a NAT and all have the same IP
// default: 128 (value in the range <0 - 65535>) // default: 128 (value in the range <0 - 65535>)
size_t no_session_cookie_treshold; size_t no_session_cookie_treshold;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -51,12 +51,22 @@ namespace Winix
SessionManager::SessionManager() SessionManager::SessionManager()
{ {
config = nullptr;
cur = nullptr;
system = nullptr;
last_container = nullptr;
current_ip_ban = nullptr;
temporary_session.id = 0; temporary_session.id = 0;
session = &temporary_session; session = &temporary_session;
session_tab.SetTmpSession(&temporary_session); session_tab.SetTmpSession(&temporary_session);
// thread work mode // thread work mode
work_mode = 1; work_mode = 1;
// for another thread
deleted = 0;
} }
@ -182,7 +192,6 @@ SessionContainer::Iterator i = session_tab.End();
if( i != session_tab.End() ) if( i != session_tab.End() )
{ {
is_session_set = true;
session = &(*i); session = &(*i);
session->new_session = true; session->new_session = true;
session->SetTimesTo(cur->request->start_time); session->SetTimesTo(cur->request->start_time);
@ -195,15 +204,12 @@ SessionContainer::Iterator i = session_tab.End();
{ {
// there is a problem with generating a new session id // there is a problem with generating a new session id
log << log1 << "SM: cannot create a session id" << logend; log << log1 << "SM: cannot create a session id" << logend;
SetTemporarySession();
} }
} }
void SessionManager::SetTemporarySession() void SessionManager::SetTemporarySession()
{ {
is_session_set = true;
session = &temporary_session; session = &temporary_session;
session->Clear(false); session->Clear(false);
session->SetTimesTo(cur->request->start_time); session->SetTimesTo(cur->request->start_time);
@ -278,7 +284,6 @@ void SessionManager::BrokenCookieCheckBan()
{ {
log << log2 << "SM: too many incorrect encoded cookies were sent from this IP" << logend; log << log2 << "SM: too many incorrect encoded cookies were sent from this IP" << logend;
IncrementBanLevel(current_ip_ban); IncrementBanLevel(current_ip_ban);
SetTemporarySession();
} }
} }
@ -297,13 +302,12 @@ void SessionManager::IncorrectSessionCheckBan()
{ {
log << log2 << "SM: too many incorrect sessions identifiers were sent from this IP" << logend; log << log2 << "SM: too many incorrect sessions identifiers were sent from this IP" << logend;
IncrementBanLevel(current_ip_ban); IncrementBanLevel(current_ip_ban);
SetTemporarySession();
} }
} }
void SessionManager::NoSessionCookieCheckBan() bool SessionManager::ShouldNoSessionCookieGenerateTmpSession()
{ {
if( !current_ip_ban ) if( !current_ip_ban )
current_ip_ban = &AddIPToBanList(cur->request->ip, cur->request->start_time); current_ip_ban = &AddIPToBanList(cur->request->ip, cur->request->start_time);
@ -312,6 +316,7 @@ void SessionManager::NoSessionCookieCheckBan()
{ {
current_ip_ban->no_session_cookie_events += 1; current_ip_ban->no_session_cookie_events += 1;
SetFirstExpirationTime(current_ip_ban); SetFirstExpirationTime(current_ip_ban);
return false;
} }
else else
{ {
@ -320,7 +325,7 @@ void SessionManager::NoSessionCookieCheckBan()
if( config->no_session_cookie_ban_mode == 1 ) if( config->no_session_cookie_ban_mode == 1 )
IncrementBanLevel(current_ip_ban); IncrementBanLevel(current_ip_ban);
SetTemporarySession(); return true;
} }
} }
@ -379,7 +384,6 @@ bool is_session_correct;
if( is_session_correct ) if( is_session_correct )
{ {
is_session_set = true;
session = &(*s); session = &(*s);
session->new_session = false; session->new_session = false;
session->last_time = cur->request->start_time; session->last_time = cur->request->start_time;
@ -402,7 +406,6 @@ return is_session_correct;
bool SessionManager::SetSessionFromCookie(const std::wstring & cookie) bool SessionManager::SetSessionFromCookie(const std::wstring & cookie)
{ {
if( config->session_cookie_encode ) if( config->session_cookie_encode )
@ -444,8 +447,7 @@ bool SessionManager::IsIPBanned()
if( current_ip_ban->IsIPBanned() ) if( current_ip_ban->IsIPBanned() )
{ {
PT::Date date = current_ip_ban->expires; PT::Date date = current_ip_ban->expires;
log << log2 << "SM: this ip is bannned to: " << date << logend; log << log2 << "SM: this ip is bannned to: " << date << " UTC" << logend;
SetTemporarySession();
return true; return true;
} }
} }
@ -454,34 +456,62 @@ return false;
} }
void SessionManager::SetSession() /*
* preparing a new session
*
* algorithm:
* - if the IP is banned or there is no a winix function then we set a temporary session
* - else
* if there is a session's cookie sent by the client then:
* - if the cookie is a correct session's cookie then we set the session from the cookie
* - or if the cookie is not a correct session's cookie (e.g. session expired) and the winix function
* requires a cookie then we set a new session
* - or if there is no cookie sent then if a winix function requires a session we create a new session
*
* if there was an error creating a new session or event counters reach a ban limit then a temporary session will be used
* so we always have a session
*
*/
void SessionManager::PrepareSession()
{ {
is_session_set = false; session = nullptr;
if( !IsIPBanned() ) if( !IsIPBanned() && cur->request->function )
{ {
if( cur->request->function && cur->request->function->need_session ) CookieTab::iterator i = cur->request->cookie_tab.find(config->http_session_id_name);
{
CookieTab::iterator i = cur->request->cookie_tab.find(config->http_session_id_name);
if( i != cur->request->cookie_tab.end() ) if( i != cur->request->cookie_tab.end() )
{
if( !SetSessionFromCookie(i->second) )
{ {
if( !SetSessionFromCookie(i->second) ) cur->request->cookie_tab.erase(i);
cur->request->cookie_tab.erase(i);
} if( cur->request->function->need_session )
else {
{ // IP could be banned in SetSessionFromCookie() when the cookie string was incorrect
NoSessionCookieCheckBan(); if( !current_ip_ban || !current_ip_ban->IsIPBanned() )
{
CreateSession();
}
}
} }
} }
else else
{ {
SetTemporarySession(); if( cur->request->function->need_session )
{
if( !ShouldNoSessionCookieGenerateTmpSession() )
{
CreateSession();
}
}
} }
} }
if( !is_session_set ) if( !session )
CreateSession(); {
SetTemporarySession();
}
session->ip_ban = current_ip_ban; session->ip_ban = current_ip_ban;
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -70,7 +70,7 @@ public:
// can return a null pointer // can return a null pointer
Session * FindSession(long id); Session * FindSession(long id);
void SetSession(); void PrepareSession();
void DeleteSessions(); // deleting all sessions void DeleteSessions(); // deleting all sessions
bool ChangeSessionId(long old_id); bool ChangeSessionId(long old_id);
@ -116,7 +116,6 @@ private:
SessionContainer session_tab; SessionContainer session_tab;
IPBanContainer ban_tab; IPBanContainer ban_tab;
IPBan * current_ip_ban; IPBan * current_ip_ban;
bool is_session_set;
Session temporary_session; Session temporary_session;
SessionIdManager session_id_manager; SessionIdManager session_id_manager;
@ -133,7 +132,7 @@ private:
void SetFirstExpirationTime(IPBan * ip_ban); void SetFirstExpirationTime(IPBan * ip_ban);
void BrokenCookieCheckBan(); void BrokenCookieCheckBan();
void IncorrectSessionCheckBan(); void IncorrectSessionCheckBan();
void NoSessionCookieCheckBan(); bool ShouldNoSessionCookieGenerateTmpSession();
/* /*

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2016, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -45,6 +45,7 @@ namespace Fun
Cat::Cat() Cat::Cat()
{ {
fun.url = L"cat"; fun.url = L"cat";
need_session = false;
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -47,6 +47,7 @@ namespace Fun
Download::Download() Download::Download()
{ {
fun.url = L"download"; fun.url = L"download";
need_session = false;
} }

View File

@ -396,6 +396,7 @@ bool was_default_function = false;
SetDefaultFunction(); SetDefaultFunction();
} }
// callback for plugins can set a different status
if( cur->request->status != WINIX_ERR_OK || !cur->request->redirect_to.empty() ) if( cur->request->status != WINIX_ERR_OK || !cur->request->redirect_to.empty() )
return; return;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -46,6 +46,7 @@ namespace Fun
Ls::Ls() Ls::Ls()
{ {
fun.url = L"ls"; fun.url = L"ls";
need_session = false;
} }

View File

@ -6,7 +6,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -47,6 +47,7 @@ namespace Fun
Run::Run() Run::Run()
{ {
fun.url = L"run"; fun.url = L"run";
need_session = false;
} }