Botan  1.11.15
src/lib/tls/tls_session_manager_memory.cpp
Go to the documentation of this file.
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 }