/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#ifndef SQUID_SRC_SECURITY_SESSION_H
#define SQUID_SRC_SECURITY_SESSION_H
-// LockingPointer.h instead of TidyPointer.h for CtoCpp1()
+#include "base/HardFun.h"
+#include "comm/forward.h"
#include "security/LockingPointer.h"
+#include <memory>
+
#if USE_OPENSSL
+#include "compat/openssl.h"
#if HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
namespace Security {
+/// Creates TLS Client connection structure (aka 'session' state) and initializes TLS/SSL I/O (Comm and BIO).
+/// On errors, emits DBG_IMPORTANT with details and returns false.
+bool CreateClientSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx);
+
+class PeerOptions;
+
+/// Creates TLS Server connection structure (aka 'session' state) and initializes TLS/SSL I/O (Comm and BIO).
+/// On errors, emits DBG_IMPORTANT with details and returns false.
+bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, Security::PeerOptions &, const char *squidCtx);
+
#if USE_OPENSSL
-typedef SSL* SessionPtr;
-CtoCpp1(SSL_free, SSL *);
-typedef LockingPointer<SSL, Security::SSL_free_cpp, CRYPTO_LOCK_SSL> SessionPointer;
+typedef SSL Connection;
-typedef SSL_SESSION* SessionStatePtr;
-CtoCpp1(SSL_SESSION_free, SSL_SESSION *);
-typedef LockingPointer<SSL_SESSION, Security::SSL_SESSION_free_cpp, CRYPTO_LOCK_SSL_SESSION> SessionStatePointer;
+typedef std::shared_ptr<SSL> SessionPointer;
+
+typedef std::unique_ptr<SSL_SESSION, HardFun<void, SSL_SESSION*, &SSL_SESSION_free>> SessionStatePointer;
#elif USE_GNUTLS
-typedef gnutls_session_t SessionPtr;
-CtoCpp1(gnutls_deinit, gnutls_session_t);
-// TODO: Convert to Locking pointer.
-// Locks can be implemented attaching locks counter to gnutls_session_t
-// objects using the gnutls_session_set_ptr()/gnutls_session_get_ptr ()
-// library functions
-typedef TidyPointer<struct gnutls_session_int, Security::gnutls_deinit_cpp> SessionPointer;
-
-typedef gnutls_datum_t *SessionStatePtr;
-CtoCpp1(gnutls_free, gnutls_datum_t *);
-typedef TidyPointer<gnutls_datum_t, Security::gnutls_free_cpp> SessionStatePointer;
+typedef std::shared_ptr<struct gnutls_session_int> SessionPointer;
+
+// wrapper function to get around gnutls_free being a typedef
+inline void squid_gnutls_free(void *d) {gnutls_free(d);}
+typedef std::unique_ptr<gnutls_datum_t, HardFun<void, void*, &Security::squid_gnutls_free>> SessionStatePointer;
#else
-// use void* so we can check against NULL
-typedef void* SessionPtr;
-typedef TidyPointer<void, nullptr> SessionPointer;
-typedef TidyPointer<void, nullptr> SessionStatePointer;
+typedef std::nullptr_t Connection;
+
+typedef std::shared_ptr<void> SessionPointer;
+
+typedef std::unique_ptr<int> SessionStatePointer;
#endif
+/// send the shutdown/bye notice for an active TLS session.
+void SessionSendGoodbye(const Security::SessionPointer &);
+
/// whether the session is a resumed one
bool SessionIsResumed(const Security::SessionPointer &);
-/// Retrieve the data needed to resume this session on a later connection
-void GetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &);
+/**
+ * When the session is not a resumed session, retrieve the details needed to
+ * resume a later connection and store them in 'data'. This may result in 'data'
+ * becoming a nil Pointer if no details exist or an error occurs.
+ *
+ * When the session is already a resumed session, do nothing and leave 'data'
+ * unhanged.
+ * XXX: is this latter behaviour always correct?
+ */
+void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &data);
/// Set the data for resuming a previous session.
/// Needs to be done before using the SessionPointer for a handshake.
-void SetSessionResumeData(const Security::SessionPtr &, const Security::SessionStatePointer &);
+void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &);
+
+#if USE_OPENSSL
+// TODO: remove from public API. It is only public because of Security::ServerOptions::updateContextConfig
+/// Setup the given TLS context with callbacks used to manage the session cache
+void SetSessionCacheCallbacks(Security::ContextPointer &);
+
+/// Helper function to retrieve a (non-locked) ContextPointer from a SessionPointer
+inline Security::ContextPointer
+GetFrom(Security::SessionPointer &s)
+{
+ auto *ctx = SSL_get_SSL_CTX(s.get());
+ return Security::ContextPointer(ctx, [](SSL_CTX *) {/* nothing to unlock/free */});
+}
+
+/// \deprecated use the PeerOptions/ServerOptions API methods instead.
+/// Wraps SessionPointer value creation to reduce risk of
+/// a nasty hack in ssl/support.cc.
+Security::SessionPointer NewSessionObject(const Security::ContextPointer &);
+#endif
} // namespace Security