]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/Session.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / security / Session.cc
CommitLineData
824d4656 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
824d4656
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
5d9a65df
AJ
9/* DEBUG: section 83 TLS session management */
10
824d4656
AJ
11#include "squid.h"
12#include "anyp/PortCfg.h"
13#include "base/RunnersRegistry.h"
5d9a65df 14#include "Debug.h"
824d4656
AJ
15#include "ipc/MemMap.h"
16#include "security/Session.h"
17#include "SquidConfig.h"
18
19#define SSL_SESSION_ID_SIZE 32
20#define SSL_SESSION_MAX_SIZE 10*1024
21
5d9a65df
AJ
22bool
23Security::SessionIsResumed(const Security::SessionPointer &s)
24{
25 bool result = false;
26#if USE_OPENSSL
27 result = SSL_session_reused(s.get()) == 1;
28#elif USE_GNUTLS
29 result = gnutls_session_is_resumed(s.get()) != 0;
30#endif
31 debugs(83, 7, "session=" << (void*)s.get() << ", query? answer: " << (result ? 'T' : 'F') );
32 return result;
33}
34
35void
36Security::MaybeGetSessionResumeData(const Security::SessionPointer &s, Security::SessionStatePointer &data)
37{
38 if (!SessionIsResumed(s)) {
39#if USE_OPENSSL
40 // nil is valid for SSL_get1_session(), it cannot fail.
41 data.reset(SSL_get1_session(s.get()));
42#elif USE_GNUTLS
43 gnutls_datum_t *tmp = nullptr;
44 const auto x = gnutls_session_get_data2(s.get(), tmp);
45 if (x != GNUTLS_E_SUCCESS) {
ea574635 46 debugs(83, 3, "session=" << (void*)s.get() << " error: " << Security::ErrorString(x));
5d9a65df
AJ
47 }
48 data.reset(tmp);
49#endif
50 debugs(83, 5, "session=" << (void*)s.get() << " data=" << (void*)data.get());
51 } else {
52 debugs(83, 5, "session=" << (void*)s.get() << " data=" << (void*)data.get() << ", do nothing.");
53 }
54}
55
56void
57Security::SetSessionResumeData(const Security::SessionPointer &s, const Security::SessionStatePointer &data)
58{
59 if (data) {
60#if USE_OPENSSL
61 if (!SSL_set_session(s.get(), data.get())) {
62 const auto ssl_error = ERR_get_error();
63 debugs(83, 3, "session=" << (void*)s.get() << " data=" << (void*)data.get() <<
ea574635 64 " resume error: " << Security::ErrorString(ssl_error));
5d9a65df
AJ
65 }
66#elif USE_GNUTLS
67 const auto x = gnutls_session_set_data(s.get(), data->data, data->size);
68 if (x != GNUTLS_E_SUCCESS) {
69 debugs(83, 3, "session=" << (void*)s.get() << " data=" << (void*)data.get() <<
ea574635 70 " resume error: " << Security::ErrorString(x));
5d9a65df
AJ
71 }
72#else
73 // critical because, how did it get here?
74 debugs(83, DBG_CRITICAL, "no TLS library. session=" << (void*)s.get() << " data=" << (void*)data.get());
75#endif
76 debugs(83, 5, "session=" << (void*)s.get() << " data=" << (void*)data.get());
77 } else {
78 debugs(83, 5, "session=" << (void*)s.get() << " no resume data");
79 }
80}
81
824d4656
AJ
82static bool
83isTlsServer()
84{
85 for (AnyP::PortCfgPointer s = HttpPortList; s != nullptr; s = s->next) {
86 if (s->secure.encryptTransport)
87 return true;
88 if (s->flags.tunnelSslBumping)
89 return true;
90 }
91
92 return false;
93}
94
95void
96initializeSessionCache()
97{
98#if USE_OPENSSL
99 // Check if the MemMap keys and data are enough big to hold
100 // session ids and session data
101 assert(SSL_SESSION_ID_SIZE >= MEMMAP_SLOT_KEY_SIZE);
102 assert(SSL_SESSION_MAX_SIZE >= MEMMAP_SLOT_DATA_SIZE);
103
104 int configuredItems = ::Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot);
105 if (IamWorkerProcess() && configuredItems)
106 Ssl::SessionCache = new Ipc::MemMap(Ssl::SessionCacheName);
107 else {
108 Ssl::SessionCache = nullptr;
109 return;
110 }
111
112 for (AnyP::PortCfgPointer s = HttpPortList; s != nullptr; s = s->next) {
b23f5f9c
AJ
113 if (s->secure.staticContext)
114 Ssl::SetSessionCallbacks(s->secure.staticContext);
824d4656
AJ
115 }
116#endif
117}
118
119/// initializes shared memory segments used by MemStore
120class SharedSessionCacheRr: public Ipc::Mem::RegisteredRunner
121{
122public:
123 /* RegisteredRunner API */
124 SharedSessionCacheRr(): owner(nullptr) {}
125 virtual void useConfig();
126 virtual ~SharedSessionCacheRr();
127
128protected:
129 virtual void create();
130
131private:
132 Ipc::MemMap::Owner *owner;
133};
134
135RunnerRegistrationEntry(SharedSessionCacheRr);
136
137void
138SharedSessionCacheRr::useConfig()
139{
140#if USE_OPENSSL // while Ssl:: bits in use
141 if (Ssl::SessionCache || !isTlsServer()) //no need to configure ssl session cache.
142 return;
143
144 Ipc::Mem::RegisteredRunner::useConfig();
145 initializeSessionCache();
146#endif
147}
148
149void
150SharedSessionCacheRr::create()
151{
152 if (!isTlsServer()) //no need to configure ssl session cache.
153 return;
154
155#if USE_OPENSSL // while Ssl:: bits in use
156 if (int items = Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot))
157 owner = Ipc::MemMap::Init(Ssl::SessionCacheName, items);
158#endif
159}
160
161SharedSessionCacheRr::~SharedSessionCacheRr()
162{
163 // XXX: Enable after testing to reduce at-exit memory "leaks".
164 // delete Ssl::SessionCache;
165
166 delete owner;
167}
168