Botan
1.11.15
|
00001 /* 00002 * TLS Session Management 00003 * (C) 2011,2012 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/tls_session_manager.h> 00009 #include <botan/hex.h> 00010 #include <chrono> 00011 00012 namespace Botan { 00013 00014 namespace TLS { 00015 00016 Session_Manager_In_Memory::Session_Manager_In_Memory( 00017 RandomNumberGenerator& rng, 00018 size_t max_sessions, 00019 std::chrono::seconds session_lifetime) : 00020 m_max_sessions(max_sessions), 00021 m_session_lifetime(session_lifetime), 00022 m_rng(rng), 00023 m_session_key(m_rng, 32) 00024 {} 00025 00026 bool Session_Manager_In_Memory::load_from_session_str( 00027 const std::string& session_str, Session& session) 00028 { 00029 // assert(lock is held) 00030 00031 auto i = m_sessions.find(session_str); 00032 00033 if(i == m_sessions.end()) 00034 return false; 00035 00036 try 00037 { 00038 session = Session::decrypt(i->second, m_session_key); 00039 } 00040 catch(...) 00041 { 00042 return false; 00043 } 00044 00045 // if session has expired, remove it 00046 const auto now = std::chrono::system_clock::now(); 00047 00048 if(session.start_time() + session_lifetime() < now) 00049 { 00050 m_sessions.erase(i); 00051 return false; 00052 } 00053 00054 return true; 00055 } 00056 00057 bool Session_Manager_In_Memory::load_from_session_id( 00058 const std::vector<byte>& session_id, Session& session) 00059 { 00060 std::lock_guard<std::mutex> lock(m_mutex); 00061 00062 return load_from_session_str(hex_encode(session_id), session); 00063 } 00064 00065 bool Session_Manager_In_Memory::load_from_server_info( 00066 const Server_Information& info, Session& session) 00067 { 00068 std::lock_guard<std::mutex> lock(m_mutex); 00069 00070 auto i = m_info_sessions.find(info); 00071 00072 if(i == m_info_sessions.end()) 00073 return false; 00074 00075 if(load_from_session_str(i->second, session)) 00076 return true; 00077 00078 /* 00079 * It existed at one point but was removed from the sessions map, 00080 * remove m_info_sessions entry as well 00081 */ 00082 m_info_sessions.erase(i); 00083 00084 return false; 00085 } 00086 00087 void Session_Manager_In_Memory::remove_entry( 00088 const std::vector<byte>& session_id) 00089 { 00090 std::lock_guard<std::mutex> lock(m_mutex); 00091 00092 auto i = m_sessions.find(hex_encode(session_id)); 00093 00094 if(i != m_sessions.end()) 00095 m_sessions.erase(i); 00096 } 00097 00098 void Session_Manager_In_Memory::save(const Session& session) 00099 { 00100 std::lock_guard<std::mutex> lock(m_mutex); 00101 00102 if(m_max_sessions != 0) 00103 { 00104 /* 00105 We generate new session IDs with the first 4 bytes being a 00106 timestamp, so this actually removes the oldest sessions first. 00107 */ 00108 while(m_sessions.size() >= m_max_sessions) 00109 m_sessions.erase(m_sessions.begin()); 00110 } 00111 00112 const std::string session_id_str = hex_encode(session.session_id()); 00113 00114 m_sessions[session_id_str] = session.encrypt(m_session_key, m_rng); 00115 00116 if(session.side() == CLIENT && !session.server_info().empty()) 00117 m_info_sessions[session.server_info()] = session_id_str; 00118 } 00119 00120 } 00121 00122 }