diff --git a/winixd/core/app.cpp b/winixd/core/app.cpp index 1658d68..22fbbc0 100644 --- a/winixd/core/app.cpp +++ b/winixd/core/app.cpp @@ -408,9 +408,9 @@ void App::ProcessRequestThrow() 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(); SetLocale(); @@ -451,6 +451,10 @@ void App::ProcessRequestThrow() cur.request->dir_tab.push_back(root_dir); 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(); diff --git a/winixd/core/config.h b/winixd/core/config.h index 64a7dc0..15a8a03 100644 --- a/winixd/core/config.h +++ b/winixd/core/config.h @@ -263,7 +263,7 @@ public: // default: 128 (value in the range <0 - 65535>) 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 // default: 128 (value in the range <0 - 65535>) size_t no_session_cookie_treshold; diff --git a/winixd/core/sessionmanager.cpp b/winixd/core/sessionmanager.cpp index 896b1f2..a081fc8 100644 --- a/winixd/core/sessionmanager.cpp +++ b/winixd/core/sessionmanager.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2014, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,12 +51,22 @@ namespace Winix SessionManager::SessionManager() { + config = nullptr; + cur = nullptr; + system = nullptr; + last_container = nullptr; + + current_ip_ban = nullptr; + temporary_session.id = 0; session = &temporary_session; session_tab.SetTmpSession(&temporary_session); // thread work mode work_mode = 1; + + // for another thread + deleted = 0; } @@ -182,7 +192,6 @@ SessionContainer::Iterator i = session_tab.End(); if( i != session_tab.End() ) { - is_session_set = true; session = &(*i); session->new_session = true; 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 log << log1 << "SM: cannot create a session id" << logend; - SetTemporarySession(); } } void SessionManager::SetTemporarySession() { - is_session_set = true; - session = &temporary_session; session->Clear(false); 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; 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; IncrementBanLevel(current_ip_ban); - SetTemporarySession(); } } -void SessionManager::NoSessionCookieCheckBan() +bool SessionManager::ShouldNoSessionCookieGenerateTmpSession() { if( !current_ip_ban ) 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; SetFirstExpirationTime(current_ip_ban); + return false; } else { @@ -320,7 +325,7 @@ void SessionManager::NoSessionCookieCheckBan() if( config->no_session_cookie_ban_mode == 1 ) IncrementBanLevel(current_ip_ban); - SetTemporarySession(); + return true; } } @@ -379,7 +384,6 @@ bool is_session_correct; if( is_session_correct ) { - is_session_set = true; session = &(*s); session->new_session = false; session->last_time = cur->request->start_time; @@ -402,7 +406,6 @@ return is_session_correct; - bool SessionManager::SetSessionFromCookie(const std::wstring & cookie) { if( config->session_cookie_encode ) @@ -444,8 +447,7 @@ bool SessionManager::IsIPBanned() if( current_ip_ban->IsIPBanned() ) { PT::Date date = current_ip_ban->expires; - log << log2 << "SM: this ip is bannned to: " << date << logend; - SetTemporarySession(); + log << log2 << "SM: this ip is bannned to: " << date << " UTC" << logend; 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); - } - else - { - NoSessionCookieCheckBan(); + cur->request->cookie_tab.erase(i); + + if( cur->request->function->need_session ) + { + // IP could be banned in SetSessionFromCookie() when the cookie string was incorrect + if( !current_ip_ban || !current_ip_ban->IsIPBanned() ) + { + CreateSession(); + } + } } } else { - SetTemporarySession(); + if( cur->request->function->need_session ) + { + if( !ShouldNoSessionCookieGenerateTmpSession() ) + { + CreateSession(); + } + } } } - if( !is_session_set ) - CreateSession(); + if( !session ) + { + SetTemporarySession(); + } session->ip_ban = current_ip_ban; } diff --git a/winixd/core/sessionmanager.h b/winixd/core/sessionmanager.h index 1257969..b677666 100644 --- a/winixd/core/sessionmanager.h +++ b/winixd/core/sessionmanager.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2014, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,7 +70,7 @@ public: // can return a null pointer Session * FindSession(long id); - void SetSession(); + void PrepareSession(); void DeleteSessions(); // deleting all sessions bool ChangeSessionId(long old_id); @@ -116,7 +116,6 @@ private: SessionContainer session_tab; IPBanContainer ban_tab; IPBan * current_ip_ban; - bool is_session_set; Session temporary_session; SessionIdManager session_id_manager; @@ -133,7 +132,7 @@ private: void SetFirstExpirationTime(IPBan * ip_ban); void BrokenCookieCheckBan(); void IncorrectSessionCheckBan(); - void NoSessionCookieCheckBan(); + bool ShouldNoSessionCookieGenerateTmpSession(); /* diff --git a/winixd/functions/cat.cpp b/winixd/functions/cat.cpp index 4b168d9..3b021fe 100644 --- a/winixd/functions/cat.cpp +++ b/winixd/functions/cat.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2016, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ namespace Fun Cat::Cat() { fun.url = L"cat"; + need_session = false; } diff --git a/winixd/functions/download.cpp b/winixd/functions/download.cpp index de77869..735ac65 100644 --- a/winixd/functions/download.cpp +++ b/winixd/functions/download.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2014, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ namespace Fun Download::Download() { fun.url = L"download"; + need_session = false; } diff --git a/winixd/functions/functions.cpp b/winixd/functions/functions.cpp index 25fd7a6..21403ab 100644 --- a/winixd/functions/functions.cpp +++ b/winixd/functions/functions.cpp @@ -396,6 +396,7 @@ bool was_default_function = false; SetDefaultFunction(); } + // callback for plugins can set a different status if( cur->request->status != WINIX_ERR_OK || !cur->request->redirect_to.empty() ) return; diff --git a/winixd/functions/ls.cpp b/winixd/functions/ls.cpp index e869ddb..500525b 100644 --- a/winixd/functions/ls.cpp +++ b/winixd/functions/ls.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008-2014, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ namespace Fun Ls::Ls() { fun.url = L"ls"; + need_session = false; } diff --git a/winixd/functions/run.cpp b/winixd/functions/run.cpp index b04d21a..280ad49 100644 --- a/winixd/functions/run.cpp +++ b/winixd/functions/run.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (c) 2008-2014, Tomasz Sowa + * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ namespace Fun Run::Run() { fun.url = L"run"; + need_session = false; }