1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/*
* TLS Session Manager
* (C) 2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
#ifndef BOTAN_TLS_SESSION_MANAGER_H__
#define BOTAN_TLS_SESSION_MANAGER_H__
#include <botan/tls_session.h>
#include <mutex>
#include <chrono>
#include <map>
namespace Botan {
namespace TLS {
/**
* Session_Manager is an interface to systems which can save
* session parameters for supporting session resumption.
*
* Saving sessions is done on a best-effort basis; an implementation is
* allowed to drop sessions due to space constraints.
*
* Implementations should strive to be thread safe
*/
class BOTAN_DLL Session_Manager
{
public:
/**
* Try to load a saved session (server side)
* @param session_id the session identifier we are trying to resume
* @param session will be set to the saved session data (if found),
or not modified if not found
* @return true if session was modified
*/
virtual bool load_from_session_id(const std::vector<byte>& session_id,
Session& session) = 0;
/**
* Try to load a saved session (client side)
* @param hostname of the host we are connecting to
* @param port the port number if we know it, or 0 if unknown
* @param session will be set to the saved session data (if found),
or not modified if not found
* @return true if session was modified
*/
virtual bool load_from_host_info(const std::string& hostname, u16bit port,
Session& session) = 0;
/**
* Remove this session id from the cache, if it exists
*/
virtual void remove_entry(const std::vector<byte>& session_id) = 0;
/**
* Save a session on a best effort basis; the manager may not in
* fact be able to save the session for whatever reason; this is
* not an error. Caller cannot assume that calling save followed
* immediately by load_from_* will result in a successful lookup.
*
* @param session to save
* @param port the protocol port (if known)
*/
virtual void save(const Session& session, u16bit port = 0) = 0;
/**
* Return the allowed lifetime of a session; beyond this time,
* sessions are not resumed. Returns 0 if unknown/no explicit
* expiration policy.
*/
virtual std::chrono::seconds session_lifetime() const = 0;
virtual ~Session_Manager() {}
};
/**
* An implementation of Session_Manager that does not save sessions at
* all, preventing session resumption.
*/
class BOTAN_DLL Session_Manager_Noop : public Session_Manager
{
public:
bool load_from_session_id(const std::vector<byte>&, Session&) override
{ return false; }
bool load_from_host_info(const std::string&, u16bit, Session&) override
{ return false; }
void remove_entry(const std::vector<byte>&) override {}
void save(const Session&, u16bit) override {}
std::chrono::seconds session_lifetime() const override
{ return std::chrono::seconds(0); }
};
/**
* An implementation of Session_Manager that saves values in memory
*/
class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager
{
public:
/**
* @param max_sessions a hint on the maximum number of sessions
* to keep in memory at any one time. (If zero, don't cap)
* @param session_lifetime sessions are expired after this many
* seconds have elapsed from initial handshake.
*/
Session_Manager_In_Memory(size_t max_sessions = 1000,
std::chrono::seconds session_lifetime = std::chrono::seconds(7200)) :
m_max_sessions(max_sessions),
m_session_lifetime(session_lifetime)
{}
bool load_from_session_id(const std::vector<byte>& session_id,
Session& session) override;
bool load_from_host_info(const std::string& hostname, u16bit port,
Session& session) override;
void remove_entry(const std::vector<byte>& session_id) override;
void save(const Session& session_data, u16bit port) override;
std::chrono::seconds session_lifetime() const override
{ return m_session_lifetime; }
private:
bool load_from_session_str(const std::string& session_str,
Session& session);
std::mutex m_mutex;
size_t m_max_sessions;
std::chrono::seconds m_session_lifetime;
std::map<std::string, Session> m_sessions; // hex(session_id) -> session
std::map<std::string, std::string> m_host_sessions;
};
}
}
#endif
|