25#define SSL_SESSION_ID_SIZE 32
26#define SSL_SESSION_MAX_SIZE 10*1024
33#if USE_OPENSSL || HAVE_LIBGNUTLS
37 auto session =
fd_table[fd].ssl.get();
38 debugs(83, 5,
"started for session=" <<
static_cast<void*
>(session) <<
" FD " << fd <<
" buf.len=" << len);
43 int i = SSL_read(session, buf, len);
44 const auto savedErrno = errno;
47 debugs(83, 3,
"SSL_read(FD " << fd <<
") error(" << i <<
"): " << SSL_get_error(session, i) <<
ReportSysError(savedErrno));
52 int i = gnutls_record_recv(session, buf, len);
53 const auto savedErrno = errno;
62 debugs(83, 8,
"TLS FD " << fd <<
" session=" << (
void*)session <<
" " << i <<
" bytes");
67 if (i > 0 && SSL_pending(session) > 0) {
69 if (i > 0 && gnutls_record_check_pending(session) > 0) {
71 debugs(83, 2,
"TLS FD " << fd <<
" is pending");
72 fd_table[fd].flags.read_pending =
true;
74 fd_table[fd].flags.read_pending =
false;
82 auto session =
fd_table[fd].ssl.get();
83 debugs(83, 5,
"started for session=" <<
static_cast<void*
>(session) <<
" FD " << fd <<
" buf.len=" << len);
86 if (!SSL_is_init_finished(session)) {
87 debugs(83, 3,
"FD " << fd <<
" is not in TLS init_finished state");
96 int i = SSL_write(session, buf, len);
97 const auto savedErrno = errno;
100 debugs(83, 3,
"SSL_write(FD " << fd <<
") error(" << i <<
"): " << SSL_get_error(session, i) <<
ReportSysError(savedErrno));
105 int i = gnutls_record_send(session, buf, len);
106 const auto savedErrno = errno;
115 debugs(83, 8,
"TLS FD " << fd <<
" session=" << (
void*)session <<
" " << i <<
" bytes");
126 debugs(83, 5,
"SSL_free session=" << (void*)p);
129 debugs(83, 5,
"SSL_new session=" << (
void*)session.get());
142#if USE_OPENSSL || HAVE_LIBGNUTLS
144 const char *errAction =
"with no TLS/SSL library";
149 errCode = ERR_get_error();
150 errAction =
"failed to allocate handle";
154 gnutls_session_t tmp;
155 errCode = gnutls_init(&tmp,
static_cast<unsigned int>(type) | GNUTLS_NONBLOCK);
157 debugs(83, 5,
"gnutls_deinit session=" << (
void*)p);
161 if (errCode != GNUTLS_E_SUCCESS) {
163 errAction =
"failed to initialize session";
169 const int fd = conn->
fd;
176 errCode = gnutls_credentials_set(session.get(), GNUTLS_CRD_CERTIFICATE, ctx.get());
177 if (errCode == GNUTLS_E_SUCCESS) {
183 gnutls_transport_set_int(session.get(), fd);
184 gnutls_handshake_set_timeout(session.get(), GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
187 debugs(83, 5,
"link FD " << fd <<
" to TLS session=" << (
void*)session.get());
196 errCode = ERR_get_error();
197 errAction =
"failed to initialize I/O";
200 errAction =
"failed to assign credentials";
235 debugs(83, 5,
"session=" << (
void*)s.get());
238 SSL_shutdown(s.get());
240 gnutls_bye(s.get(), GNUTLS_SHUT_RDWR);
250 result = SSL_session_reused(s.get()) == 1;
252 result = gnutls_session_is_resumed(s.get()) != 0;
254 debugs(83, 7,
"session=" << (
void*)s.get() <<
", query? answer: " << (result ?
'T' :
'F') );
264 data.reset(SSL_get1_session(s.get()));
266 gnutls_datum_t *tmp =
nullptr;
267 const auto x = gnutls_session_get_data2(s.get(), tmp);
268 if (x != GNUTLS_E_SUCCESS) {
273 debugs(83, 5,
"session=" << (
void*)s.get() <<
" data=" << (
void*)data.get());
275 debugs(83, 5,
"session=" << (
void*)s.get() <<
" data=" << (
void*)data.get() <<
", do nothing.");
284 if (!SSL_set_session(s.get(), data.get())) {
285 const auto ssl_error = ERR_get_error();
286 debugs(83, 3,
"session=" << (
void*)s.get() <<
" data=" << (
void*)data.get() <<
290 const auto x = gnutls_session_set_data(s.get(), data->data, data->size);
291 if (x != GNUTLS_E_SUCCESS) {
292 debugs(83, 3,
"session=" << (
void*)s.get() <<
" data=" << (
void*)data.get() <<
297 debugs(83,
DBG_CRITICAL,
"no TLS library. session=" << (
void*)s.get() <<
" data=" << (
void*)data.get());
299 debugs(83, 5,
"session=" << (
void*)s.get() <<
" data=" << (
void*)data.get());
301 debugs(83, 5,
"session=" << (
void*)s.get() <<
" no resume data");
309 if (s->secure.encryptTransport)
311 if (s->flags.tunnelSslBumping)
325 debugs(83, 5,
"Request to store SSL_SESSION");
336 memset(key, 0,
sizeof(key));
337 memcpy(key,
id, idlen);
340 int lenRequired = i2d_SSL_SESSION(session,
nullptr);
342 unsigned char *p =
static_cast<unsigned char *
>(slotW->p);
343 lenRequired = i2d_SSL_SESSION(session, &p);
347 debugs(83, 5,
"wrote an SSL_SESSION entry of size " << lenRequired <<
" at pos " << pos);
358 debugs(83, 5,
"Request to remove corrupted or not valid SSL_SESSION");
372#if SQUID_USE_CONST_SSL_SESSION_CBID
373get_session_cb(SSL *,
const unsigned char *sessionID,
int len,
int *copy)
381 const unsigned int *p =
reinterpret_cast<const unsigned int *
>(sessionID);
382 debugs(83, 5,
"Request to search for SSL_SESSION of len: " <<
383 len << p[0] <<
":" << p[1]);
385 SSL_SESSION *session =
nullptr;
389 const unsigned char *ptr = slot->p;
390 session = d2i_SSL_SESSION(
nullptr, &ptr, slot->pSize);
391 debugs(83, 5,
"SSL_SESSION retrieved from cache at pos " << pos);
393 debugs(83, 5,
"SSL_SESSION in cache expired");
398 debugs(83, 5,
"Failed to retrieve SSL_SESSION from cache");
412 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL);
438 if (s->secure.staticContext)
#define MEMMAP_SLOT_KEY_SIZE
#define MEMMAP_SLOT_DATA_SIZE
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
#define DefineRunnerRegistrator(ClassName)
a MemMap basic element, holding basic shareable memory block info
A map of MemMapSlots indexed by their keys, with read/write slot locking.
void free(const sfileno fileno)
mark the slot as waiting to be freed and, if possible, free it
void closeForReading(const sfileno fileno)
close slot after reading, decrements read level
const Slot * openForReading(const cache_key *const key, sfileno &fileno)
open slot for reading, increments read level
Slot * openForWriting(const cache_key *const key, sfileno &fileno)
static Owner * Init(const char *const path, const int limit)
initialize shared memory
void closeForWriting(const sfileno fileno)
successfully finish writing the entry
void useConfig() override
a stream manipulator for printing a system call error (if any)
A combination of PeerOptions and the corresponding Context.
const ContextPointer & raw
TLS context configured using options.
PeerOptions & options
TLS context configuration.
TLS squid.conf settings for a remote server peer.
void updateSessionOptions(Security::SessionPointer &)
setup any library-specific options that can be set for the given session
initializes shared memory segments used by MemStore
void useConfig() override
void create() override
called when the runner should create a new memory segment
~SharedSessionCacheRr() override
Ipc::MemMap::Owner * owner
struct SquidConfig::@97 SSL
static void Link(SSL *ssl, BIO *bio)
Tells ssl connection to use BIO and monitor state via stateChanged()
static BIO * Create(const int fd, Security::Io::Type type)
#define debugs(SECTION, LEVEL, CONTENT)
void fd_note(int fd, const char *s)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
void SetSessionCacheCallbacks(Security::ContextPointer &)
Setup the given TLS context with callbacks used to manage the session cache.
std::shared_ptr< SSL_CTX > ContextPointer
bool CreateClientSession(FuturePeerContext &, const Comm::ConnectionPointer &, const char *squidCtx)
bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, Security::PeerOptions &, const char *squidCtx)
Security::SessionPointer NewSessionObject(const Security::ContextPointer &)
void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &)
std::shared_ptr< SSL > SessionPointer
unsigned long LibErrorCode
TLS library-reported non-validation error.
bool SessionIsResumed(const Security::SessionPointer &)
whether the session is a resumed one
void SessionSendGoodbye(const Security::SessionPointer &)
send the shutdown/bye notice for an active TLS session.
const char * ErrorString(const LibErrorCode code)
converts numeric LibErrorCode into a human-friendlier string
std::unique_ptr< SSL_SESSION, HardFun< void, SSL_SESSION *, &SSL_SESSION_free > > SessionStatePointer
void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &data)
void ForgetErrors()
clear any errors that a TLS library has accumulated in its global storage
const unsigned char * SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
static bool CreateSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &conn, Security::PeerOptions &opts, Security::Io::Type type, const char *squidCtx)
static int tls_read_method(int fd, char *buf, int len)
#define SSL_SESSION_ID_SIZE
static void initializeSessionCache()
static void remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID)
static SSL_SESSION * get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy)
static Ipc::MemMap * SessionCache
static int store_session_cb(SSL *, SSL_SESSION *session)
static int tls_write_method(int fd, const char *buf, int len)
#define SSL_SESSION_MAX_SIZE
static bool isTlsServer()
static const char * SessionCacheName
unsigned char cache_key
Store key.
#define VALGRIND_MAKE_MEM_DEFINED