diff options
-rw-r--r-- | include/socket.h | 13 | ||||
-rw-r--r-- | src/listensocket.cpp | 14 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 83 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 87 | ||||
-rw-r--r-- | src/socket.cpp | 4 |
5 files changed, 50 insertions, 151 deletions
diff --git a/include/socket.h b/include/socket.h index d3a45475d..f97630d04 100644 --- a/include/socket.h +++ b/include/socket.h @@ -139,10 +139,12 @@ class CoreExport ListenSocketBase : public EventHandler /** Socket description (shown in stats p) */ std::string desc; - /** Address socket is bound to */ + /** Raw address socket is bound to */ std::string bind_addr; /** Port socket is bound to */ int bind_port; + /** Human-readable address/port socket is bound to */ + std::string bind_desc; /** The client address if the most recently connected client. * Should only be used when accepting a new client. @@ -173,18 +175,17 @@ class CoreExport ListenSocketBase : public EventHandler } /** Get description for socket */ - const std::string& GetDescription() - { - return desc; - } + const std::string& GetDescription() { return desc; } /** Get port number for socket */ - int GetPort() { return bind_port; } + const int GetPort() { return bind_port; } /** Get IP address socket is bound to */ const std::string &GetIP() { return bind_addr; } + const std::string &GetBindDesc() { return bind_desc; } + /** Handles sockets internals crap of a connection, convenience wrapper really */ void AcceptInternal(); diff --git a/src/listensocket.cpp b/src/listensocket.cpp index 663f912e6..df252f18b 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -25,12 +25,18 @@ ListenSocketBase::ListenSocketBase(InspIRCd* Instance, int port, const std::stri { irc::sockets::sockaddrs bind_to; - bind_addr = addr; - bind_port = port; - // canonicalize address if it is defined - if (!addr.empty() && irc::sockets::aptosa(addr.c_str(), port, &bind_to)) + if (irc::sockets::aptosa(addr.c_str(), port, &bind_to)) + { irc::sockets::satoap(&bind_to, bind_addr, bind_port); + bind_desc = irc::sockets::satouser(&bind_to); + } + else + { + bind_addr = addr; + bind_port = port; + bind_desc = addr + ":" + ConvToStr(port); + } this->SetFd(irc::sockets::OpenTCPSocket(bind_addr.c_str())); if (this->GetFd() > -1) diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 7e3b62671..7c5f7ee49 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -30,17 +30,6 @@ enum issl_status { ISSL_NONE, ISSL_HANDSHAKING_READ, ISSL_HANDSHAKING_WRITE, ISSL_HANDSHAKEN, ISSL_CLOSING, ISSL_CLOSED }; -bool isin(const std::string &host, int port, const std::vector<std::string> &portlist) -{ - if (std::find(portlist.begin(), portlist.end(), "*:" + ConvToStr(port)) != portlist.end()) - return true; - - if (std::find(portlist.begin(), portlist.end(), ":" + ConvToStr(port)) != portlist.end()) - return true; - - return std::find(portlist.begin(), portlist.end(), host + ":" + ConvToStr(port)) != portlist.end(); -} - /** Represents an SSL user's extra data */ class issl_session : public classbase @@ -93,7 +82,7 @@ class CommandStartTLS : public Command class ModuleSSLGnuTLS : public Module { - std::vector<std::string> listenports; + std::set<ListenSocketBase*> listenports; issl_session* sessions; @@ -107,7 +96,6 @@ class ModuleSSLGnuTLS : public Module std::string sslports; int dh_bits; - int clientactive; bool cred_alloc; CommandStartTLS starttls; @@ -131,8 +119,8 @@ class ModuleSSLGnuTLS : public Module gnutls_certificate_set_dh_params(x509_cred, dh_params); Implementation eventlist[] = { I_On005Numeric, I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, - I_OnBufferFlushed, I_OnRequest, I_OnUnloadModule, I_OnRehash, I_OnModuleRehash, - I_OnPostConnect, I_OnEvent, I_OnHookIO }; + I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, + I_OnEvent, I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); ServerInstance->AddCommand(&starttls); @@ -143,51 +131,21 @@ class ModuleSSLGnuTLS : public Module ConfigReader Conf(ServerInstance); listenports.clear(); - clientactive = 0; sslports.clear(); - for(int index = 0; index < Conf.Enumerate("bind"); index++) + for (size_t i = 0; i < ServerInstance->ports.size(); i++) { - // For each <bind> tag - std::string x = Conf.ReadValue("bind", "type", index); - if(((x.empty()) || (x == "clients")) && (Conf.ReadValue("bind", "ssl", index) == "gnutls")) - { - // Get the port we're meant to be listening on with SSL - std::string port = Conf.ReadValue("bind", "port", index); - std::string addr = Conf.ReadValue("bind", "address", index); - - if (!addr.empty()) - { - // normalize address, important for IPv6 - int portint = 0; - irc::sockets::sockaddrs bin; - if (irc::sockets::aptosa(addr.c_str(), portint, &bin)) - irc::sockets::satoap(&bin, addr, portint); - } - - irc::portparser portrange(port, false); - long portno = -1; - while ((portno = portrange.GetToken())) - { - clientactive++; - try - { - listenports.push_back(addr + ":" + ConvToStr(portno)); + ListenSocketBase* port = ServerInstance->ports[i]; + std::string desc = port->GetDescription(); + if (desc != "gnutls") + continue; - for (size_t i = 0; i < ServerInstance->ports.size(); i++) - if ((ServerInstance->ports[i]->GetPort() == portno) && (ServerInstance->ports[i]->GetIP() == addr)) - ServerInstance->ports[i]->SetDescription("ssl"); - ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %ld", portno); + listenports.insert(port); + std::string portid = port->GetBindDesc(); - if (addr != "127.0.0.1") - sslports.append((addr.empty() ? "*" : addr)).append(":").append(ConvToStr(portno)).append(";"); - } - catch (ModuleException &e) - { - ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: FAILED to enable SSL on port %ld: %s. Maybe it's already hooked by the same port on a different IP, or you have an other SSL or similar module loaded?", portno, e.GetReason()); - } - } - } + ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %s", portid.c_str()); + if (port->GetIP() != "127.0.0.1") + sslports.append(portid).append(";"); } if (!sslports.empty()) @@ -320,19 +278,6 @@ class ModuleSSLGnuTLS : public Module } } - virtual void OnUnloadModule(Module* mod, const std::string &name) - { - if(mod == this) - { - for(unsigned int i = 0; i < listenports.size(); i++) - { - for (size_t j = 0; j < ServerInstance->ports.size(); j++) - if (listenports[i] == (ServerInstance->ports[j]->GetIP()+":"+ConvToStr(ServerInstance->ports[j]->GetPort()))) - ServerInstance->ports[j]->SetDescription("plaintext"); - } - } - } - virtual Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); @@ -348,7 +293,7 @@ class ModuleSSLGnuTLS : public Module virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb) { - if (!user->GetIOHook() && isin(lsb->GetIP(),lsb->GetPort(),listenports)) + if (!user->GetIOHook() && listenports.find(lsb) != listenports.end()) { /* Hook the user with our module */ user->AddIOHook(this); diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index fc0de61f4..a8043457b 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -40,17 +40,6 @@ enum issl_io_status { ISSL_WRITE, ISSL_READ }; static bool SelfSigned = false; -bool isin(const std::string &host, int port, const std::vector<std::string> &portlist) -{ - if (std::find(portlist.begin(), portlist.end(), "*:" + ConvToStr(port)) != portlist.end()) - return true; - - if (std::find(portlist.begin(), portlist.end(), ":" + ConvToStr(port)) != portlist.end()) - return true; - - return std::find(portlist.begin(), portlist.end(), host + ":" + ConvToStr(port)) != portlist.end(); -} - char* get_error() { return ERR_error_string(ERR_get_error(), NULL); @@ -98,7 +87,7 @@ static int OnVerify(int preverify_ok, X509_STORE_CTX *ctx) class ModuleSSLOpenSSL : public Module { - std::vector<std::string> listenports; + std::set<ListenSocketBase*> listenports; int inbufsize; issl_session* sessions; @@ -116,8 +105,6 @@ class ModuleSSLOpenSSL : public Module std::string dhfile; std::string sslports; - int clientactive; - public: InspIRCd* PublicInstance; @@ -152,14 +139,14 @@ class ModuleSSLOpenSSL : public Module OnModuleRehash(NULL,"ssl"); Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, I_On005Numeric, - I_OnBufferFlushed, I_OnRequest, I_OnUnloadModule, I_OnRehash, I_OnModuleRehash, - I_OnPostConnect, I_OnHookIO }; + I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, + I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb) { - if (!user->GetIOHook() && isin(lsb->GetIP(),lsb->GetPort(),listenports)) + if (!user->GetIOHook() && listenports.find(lsb) != listenports.end()) { /* Hook the user with our module */ user->AddIOHook(this); @@ -171,51 +158,21 @@ class ModuleSSLOpenSSL : public Module ConfigReader Conf(ServerInstance); listenports.clear(); - clientactive = 0; sslports.clear(); - for(int index = 0; index < Conf.Enumerate("bind"); index++) + for (size_t i = 0; i < ServerInstance->ports.size(); i++) { - // For each <bind> tag - std::string x = Conf.ReadValue("bind", "type", index); - if(((x.empty()) || (x == "clients")) && (Conf.ReadValue("bind", "ssl", index) == "openssl")) - { - // Get the port we're meant to be listening on with SSL - std::string port = Conf.ReadValue("bind", "port", index); - std::string addr = Conf.ReadValue("bind", "address", index); - - if (!addr.empty()) - { - // normalize address, important for IPv6 - int portint = 0; - irc::sockets::sockaddrs bin; - if (irc::sockets::aptosa(addr.c_str(), portint, &bin)) - irc::sockets::satoap(&bin, addr, portint); - } - - irc::portparser portrange(port, false); - long portno = -1; - while ((portno = portrange.GetToken())) - { - clientactive++; - try - { - listenports.push_back(addr + ":" + ConvToStr(portno)); + ListenSocketBase* port = ServerInstance->ports[i]; + std::string desc = port->GetDescription(); + if (desc != "openssl") + continue; - for (size_t i = 0; i < ServerInstance->ports.size(); i++) - if ((ServerInstance->ports[i]->GetPort() == portno) && (ServerInstance->ports[i]->GetIP() == addr)) - ServerInstance->ports[i]->SetDescription("ssl"); - ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %ld", portno); + listenports.insert(port); + std::string portid = port->GetBindDesc(); - if (addr != "127.0.0.1") - sslports.append((addr.empty() ? "*" : addr)).append(":").append(ConvToStr(portno)).append(";"); - } - catch (ModuleException &e) - { - ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: FAILED to enable SSL on port %ld: %s. Maybe it's already hooked by the same port on a different IP, or you have an other SSL or similar module loaded?", portno, e.GetReason()); - } - } - } + ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %s", portid.c_str()); + if (port->GetIP() != "127.0.0.1") + sslports.append(portid).append(";"); } if (!sslports.empty()) @@ -311,7 +268,8 @@ class ModuleSSLOpenSSL : public Module virtual void On005Numeric(std::string &output) { - output.append(" SSL=" + sslports); + if (!sslports.empty()) + output.append(" SSL=" + sslports); } virtual ~ModuleSSLOpenSSL() @@ -345,19 +303,6 @@ class ModuleSSLOpenSSL : public Module } } - virtual void OnUnloadModule(Module* mod, const std::string &name) - { - if (mod == this) - { - for(unsigned int i = 0; i < listenports.size(); i++) - { - for (size_t j = 0; j < ServerInstance->ports.size(); j++) - if (listenports[i] == (ServerInstance->ports[j]->GetIP()+":"+ConvToStr(ServerInstance->ports[j]->GetPort()))) - ServerInstance->ports[j]->SetDescription("plaintext"); - } - } - } - virtual Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); diff --git a/src/socket.cpp b/src/socket.cpp index 2eb8aeb7e..e32bda901 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -126,7 +126,7 @@ int irc::sockets::OpenTCPSocket(const char* addr, int socktype) // XXX: it would be VERY nice to genericize this so all listen stuff (server/client) could use the one function. -- w00t int InspIRCd::BindPorts(FailedPortList &failed_ports) { - char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF]; + char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF], Desc[MAXBUF]; int bound = 0; bool started_with_nothing = (ports.size() == 0); std::vector<std::pair<std::string, int> > old_ports; @@ -140,6 +140,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports) Config->ConfValue("bind", "port", count, configToken, MAXBUF); Config->ConfValue("bind", "address", count, Addr, MAXBUF); Config->ConfValue("bind", "type", count, Type, MAXBUF); + Config->ConfValue("bind", "ssl", count, Desc, MAXBUF); if (strncmp(Addr, "::ffff:", 7) == 0) this->Logs->Log("SOCKET",DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead."); @@ -176,6 +177,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports) if (ll->GetFd() > -1) { bound++; + ll->SetDescription(*Desc ? Desc : "plaintext"); ports.push_back(ll); } else |