diff options
author | Sadie Powell <sadie@witchery.services> | 2024-01-24 12:01:50 +0000 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2024-01-24 12:22:51 +0000 |
commit | 7ac1fe58478d58e2480b6919c4abf3a82929169c (patch) | |
tree | 198ad9a6e23d4c189dce57fd95306b6b22d8c23f /modules/extra/m_ssl_openssl.cpp | |
parent | 72acef4e159df5dcdb93b3c13b2f9d2e5e4c21a9 (diff) |
Rename several modules to remove the m_ prefix.
Diffstat (limited to 'modules/extra/m_ssl_openssl.cpp')
-rw-r--r-- | modules/extra/m_ssl_openssl.cpp | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/m_ssl_openssl.cpp deleted file mode 100644 index 8d4aca9ba..000000000 --- a/modules/extra/m_ssl_openssl.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - * - * (C) 2010-2024 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -/* RequiredLibraries: ssl,crypto */ -/* RequiredWindowsLibraries: libssl,libcrypto */ - -#include "module.h" -#include "modules/ssl.h" - -#define OPENSSL_API_COMPAT 0x10100000L -#define OPENSSL_NO_DEPRECATED - -#include <openssl/bio.h> -#include <openssl/ssl.h> -#include <openssl/err.h> -#include <openssl/crypto.h> -#include <openssl/evp.h> - -static SSL_CTX *server_ctx, *client_ctx; - -class MySSLService final - : public SSLService -{ -public: - MySSLService(Module *o, const Anope::string &n); - - /** Initialize a socket to use SSL - * @param s The socket - */ - void Init(Socket *s) override; -}; - -class SSLSocketIO final - : public SocketIO -{ -public: - /* The SSL socket for this socket */ - SSL *sslsock; - - /** Constructor - */ - SSLSocketIO(); - - /** Really receive something from the buffer - * @param s The socket - * @param buf The buf to read to - * @param sz How much to read - * @return Number of bytes received - */ - int Recv(Socket *s, char *buf, size_t sz) override; - - /** Write something to the socket - * @param s The socket - * @param buf The data to write - * @param size The length of the data - */ - int Send(Socket *s, const char *buf, size_t sz) override; - - /** Accept a connection from a socket - * @param s The socket - * @return The new socket - */ - ClientSocket *Accept(ListenSocket *s) override; - - /** Finished accepting a connection from a socket - * @param s The socket - * @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error - */ - SocketFlag FinishAccept(ClientSocket *cs) override; - - /** Connect the socket - * @param s THe socket - * @param target IP to connect to - * @param port to connect to - */ - void Connect(ConnectionSocket *s, const Anope::string &target, int port) override; - - /** Called to potentially finish a pending connection - * @param s The socket - * @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error. - */ - SocketFlag FinishConnect(ConnectionSocket *s) override; - - /** Called when the socket is destructing - */ - void Destroy() override; -}; - -class SSLModule; -static SSLModule *me; -class SSLModule final - : public Module -{ - Anope::string certfile, keyfile; - -public: - MySSLService service; - - SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), service(this, "ssl") - { - me = this; - - this->SetPermanent(true); - - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, nullptr); - - client_ctx = SSL_CTX_new(TLS_client_method()); - server_ctx = SSL_CTX_new(TLS_server_method()); - - if (!client_ctx || !server_ctx) - throw ModuleException("Error initializing SSL CTX"); - - long opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_CIPHER_SERVER_PREFERENCE; - SSL_CTX_set_options(client_ctx, opts); - SSL_CTX_set_options(server_ctx, opts); - - SSL_CTX_set_mode(client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - SSL_CTX_set_mode(server_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - Anope::string context_name = "Anope"; - SSL_CTX_set_session_id_context(client_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); - SSL_CTX_set_session_id_context(server_ctx, reinterpret_cast<const unsigned char *>(context_name.c_str()), context_name.length()); - } - - ~SSLModule() - { - for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;) - { - Socket *s = it->second; - ++it; - - if (dynamic_cast<SSLSocketIO *>(s->io)) - delete s; - } - - SSL_CTX_free(client_ctx); - SSL_CTX_free(server_ctx); - } - - void OnReload(Configuration::Conf *conf) override - { - Configuration::Block *config = conf->GetModule(this); - - this->certfile = config->Get<const Anope::string>("cert", "data/fullchain.pem"); - this->keyfile = config->Get<const Anope::string>("key", "data/privkey.pem"); - - if (Anope::IsFile(this->certfile.c_str())) - { - if (!SSL_CTX_use_certificate_chain_file(client_ctx, this->certfile.c_str()) || !SSL_CTX_use_certificate_chain_file(server_ctx, this->certfile.c_str())) - throw ConfigException("Error loading certificate"); - else - Log(LOG_DEBUG) << "m_ssl_openssl: Successfully loaded certificate " << this->certfile; - } - else - Log() << "Unable to open certificate " << this->certfile; - - if (Anope::IsFile(this->keyfile.c_str())) - { - if (!SSL_CTX_use_PrivateKey_file(client_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(server_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM)) - throw ConfigException("Error loading private key"); - else - Log(LOG_DEBUG) << "m_ssl_openssl: Successfully loaded private key " << this->keyfile; - } - else - { - if (Anope::IsFile(this->certfile.c_str())) - throw ConfigException("Error loading private key " + this->keyfile + " - file not found"); - else - Log() << "Unable to open private key " << this->keyfile; - } - - // Allow disabling old versions of TLS - if (config->Get<bool>("tlsv10", "false")) - { - SSL_CTX_clear_options(client_ctx, SSL_OP_NO_TLSv1); - SSL_CTX_clear_options(server_ctx, SSL_OP_NO_TLSv1); - } - else - { - SSL_CTX_set_options(client_ctx, SSL_OP_NO_TLSv1); - SSL_CTX_set_options(server_ctx, SSL_OP_NO_TLSv1); - } - - if (config->Get<bool>("tlsv11", "true")) - { - SSL_CTX_clear_options(client_ctx, SSL_OP_NO_TLSv1_1); - SSL_CTX_clear_options(server_ctx, SSL_OP_NO_TLSv1_1); - } - else - { - SSL_CTX_set_options(client_ctx, SSL_OP_NO_TLSv1_1); - SSL_CTX_set_options(server_ctx, SSL_OP_NO_TLSv1_1); - } - - if (config->Get<bool>("tlsv12", "true")) - { - SSL_CTX_clear_options(client_ctx, SSL_OP_NO_TLSv1_2); - SSL_CTX_clear_options(server_ctx, SSL_OP_NO_TLSv1_2); - } - else - { - SSL_CTX_set_options(client_ctx, SSL_OP_NO_TLSv1_2); - SSL_CTX_set_options(server_ctx, SSL_OP_NO_TLSv1_2); - } - } - - void OnPreServerConnect() override - { - Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink); - - if (config->Get<bool>("ssl")) - { - this->service.Init(UplinkSock); - } - } -}; - -MySSLService::MySSLService(Module *o, const Anope::string &n) : SSLService(o, n) -{ -} - -void MySSLService::Init(Socket *s) -{ - if (s->io != &NormalSocketIO) - throw CoreException("Socket initializing SSL twice"); - - s->io = new SSLSocketIO(); -} - -SSLSocketIO::SSLSocketIO() -{ - this->sslsock = NULL; -} - -int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz) -{ - int i = SSL_read(this->sslsock, buf, sz); - if (i > 0) - TotalRead += i; - else if (i < 0) - { - int err = SSL_get_error(this->sslsock, i); - switch (err) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - SocketEngine::SetLastError(EAGAIN); - } - } - - return i; -} - -int SSLSocketIO::Send(Socket *s, const char *buf, size_t sz) -{ - int i = SSL_write(this->sslsock, buf, sz); - if (i > 0) - TotalWritten += i; - else if (i < 0) - { - int err = SSL_get_error(this->sslsock, i); - switch (err) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - SocketEngine::SetLastError(EAGAIN); - } - } - return i; -} - -ClientSocket *SSLSocketIO::Accept(ListenSocket *s) -{ - if (s->io == &NormalSocketIO) - throw SocketException("Attempting to accept on uninitialized socket with SSL"); - - sockaddrs conaddr; - - socklen_t size = sizeof(conaddr); - int newsock = accept(s->GetFD(), &conaddr.sa, &size); - -#ifndef INVALID_SOCKET - const int INVALID_SOCKET = -1; -#endif - - if (newsock < 0 || newsock == INVALID_SOCKET) - throw SocketException("Unable to accept connection: " + Anope::LastError()); - - ClientSocket *newsocket = s->OnAccept(newsock, conaddr); - me->service.Init(newsocket); - SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(newsocket->io); - - io->sslsock = SSL_new(server_ctx); - if (!io->sslsock) - throw SocketException("Unable to initialize SSL socket"); - - SSL_set_accept_state(io->sslsock); - - if (!SSL_set_fd(io->sslsock, newsocket->GetFD())) - throw SocketException("Unable to set SSL fd"); - - newsocket->flags[SF_ACCEPTING] = true; - this->FinishAccept(newsocket); - - return newsocket; -} - -SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs) -{ - if (cs->io == &NormalSocketIO) - throw SocketException("Attempting to finish connect uninitialized socket with SSL"); - else if (cs->flags[SF_ACCEPTED]) - return SF_ACCEPTED; - else if (!cs->flags[SF_ACCEPTING]) - throw SocketException("SSLSocketIO::FinishAccept called for a socket not accepted nor accepting?"); - - SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(cs->io); - - int ret = SSL_accept(io->sslsock); - if (ret <= 0) - { - int error = SSL_get_error(io->sslsock, ret); - if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) - { - SocketEngine::Change(cs, error == SSL_ERROR_WANT_WRITE, SF_WRITABLE); - SocketEngine::Change(cs, error == SSL_ERROR_WANT_READ, SF_READABLE); - return SF_ACCEPTING; - } - else - { - cs->OnError(ERR_error_string(ERR_get_error(), NULL)); - cs->flags[SF_DEAD] = true; - cs->flags[SF_ACCEPTING] = false; - return SF_DEAD; - } - } - else - { - cs->flags[SF_ACCEPTED] = true; - cs->flags[SF_ACCEPTING] = false; - SocketEngine::Change(cs, false, SF_WRITABLE); - SocketEngine::Change(cs, true, SF_READABLE); - cs->OnAccept(); - return SF_ACCEPTED; - } -} - -void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port) -{ - if (s->io == &NormalSocketIO) - throw SocketException("Attempting to connect uninitialized socket with SSL"); - - s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false; - - s->conaddr.pton(s->GetFamily(), target, port); - int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); - if (c == -1) - { - if (Anope::LastErrorCode() != EINPROGRESS) - { - s->OnError(Anope::LastError()); - s->flags[SF_DEAD] = true; - return; - } - else - { - SocketEngine::Change(s, true, SF_WRITABLE); - s->flags[SF_CONNECTING] = true; - return; - } - } - else - { - s->flags[SF_CONNECTING] = true; - this->FinishConnect(s); - } -} - -SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s) -{ - if (s->io == &NormalSocketIO) - throw SocketException("Attempting to finish connect uninitialized socket with SSL"); - else if (s->flags[SF_CONNECTED]) - return SF_CONNECTED; - else if (!s->flags[SF_CONNECTING]) - throw SocketException("SSLSocketIO::FinishConnect called for a socket not connected nor connecting?"); - - SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(s->io); - - if (io->sslsock == NULL) - { - io->sslsock = SSL_new(client_ctx); - if (!io->sslsock) - throw SocketException("Unable to initialize SSL socket"); - - if (!SSL_set_fd(io->sslsock, s->GetFD())) - throw SocketException("Unable to set SSL fd"); - } - - int ret = SSL_connect(io->sslsock); - if (ret <= 0) - { - int error = SSL_get_error(io->sslsock, ret); - if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) - { - SocketEngine::Change(s, error == SSL_ERROR_WANT_WRITE, SF_WRITABLE); - SocketEngine::Change(s, error == SSL_ERROR_WANT_READ, SF_READABLE); - return SF_CONNECTING; - } - else - { - s->OnError(ERR_error_string(ERR_get_error(), NULL)); - s->flags[SF_CONNECTING] = false; - s->flags[SF_DEAD] = true; - return SF_DEAD; - } - } - else - { - s->flags[SF_CONNECTING] = false; - s->flags[SF_CONNECTED] = true; - SocketEngine::Change(s, false, SF_WRITABLE); - SocketEngine::Change(s, true, SF_READABLE); - s->OnConnect(); - return SF_CONNECTED; - } -} - -void SSLSocketIO::Destroy() -{ - if (this->sslsock) - { - SSL_shutdown(this->sslsock); - SSL_free(this->sslsock); - } - - delete this; -} - -MODULE_INIT(SSLModule) |