diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/core/db_mysql.cpp | 2 | ||||
| -rw-r--r-- | modules/core/os_restart.cpp | 2 | ||||
| -rw-r--r-- | modules/core/os_shutdown.cpp | 2 | ||||
| -rw-r--r-- | modules/extra/m_ssl.cpp | 152 | ||||
| -rw-r--r-- | modules/extra/m_xmlrpc.cpp | 37 | ||||
| -rw-r--r-- | modules/protocol/bahamut.cpp | 2 | ||||
| -rw-r--r-- | modules/protocol/inspircd-ts6.h | 2 | ||||
| -rw-r--r-- | modules/protocol/inspircd11.cpp | 2 | ||||
| -rw-r--r-- | modules/protocol/plexus.cpp | 2 | ||||
| -rw-r--r-- | modules/protocol/ratbox.cpp | 2 | ||||
| -rw-r--r-- | modules/protocol/unreal.cpp | 2 |
11 files changed, 114 insertions, 93 deletions
diff --git a/modules/core/db_mysql.cpp b/modules/core/db_mysql.cpp index 193d467da..6a5ba8900 100644 --- a/modules/core/db_mysql.cpp +++ b/modules/core/db_mysql.cpp @@ -136,7 +136,7 @@ class DBMySQL : public Module if (operserv) this->AddCommand(operserv->Bot(), &commandsqlsync); - if (uplink_server) + if (CurrentUplink) OnServerConnect(); } diff --git a/modules/core/os_restart.cpp b/modules/core/os_restart.cpp index bda2d861c..196d0a3ab 100644 --- a/modules/core/os_restart.cpp +++ b/modules/core/os_restart.cpp @@ -26,7 +26,7 @@ class CommandOSRestart : public Command { User *u = source.u; quitmsg = "RESTART command received from " + u->nick; - do_restart_services(); + quitting = save_data = restarting = true; return MOD_CONT; } diff --git a/modules/core/os_shutdown.cpp b/modules/core/os_shutdown.cpp index c67d7acb2..35f76f0c9 100644 --- a/modules/core/os_shutdown.cpp +++ b/modules/core/os_shutdown.cpp @@ -26,7 +26,7 @@ class CommandOSShutdown : public Command { User *u = source.u; quitmsg = "SHUTDOWN command received from " + u->nick; - shutting_down = true; + quitting = save_data = true; return MOD_CONT; } diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp index da6361769..30e548150 100644 --- a/modules/extra/m_ssl.cpp +++ b/modules/extra/m_ssl.cpp @@ -28,9 +28,16 @@ class MySSLService : public SSLService class SSLSocketIO : public SocketIO { + /** Check whether this socket has a pending connect() or accept() + * @return 0 if neither, -1 if connect/accept fails, -2 to wait more + */ + int CheckState(); + public: /* The SSL socket for this socket */ SSL *sslsock; + /* -1 if not, 0 if waiting, 1 if true */ + int connected, accepted; /** Constructor */ @@ -42,27 +49,27 @@ class SSLSocketIO : public SocketIO * @param sz How much to read * @return Number of bytes received */ - int Recv(Socket *s, char *buf, size_t sz) const; + int Recv(Socket *s, char *buf, size_t sz); /** Really write something to the socket * @param s The socket * @param buf What to write * @return Number of bytes written */ - int Send(Socket *s, const Anope::string &buf) const; + int Send(Socket *s, const Anope::string &buf); /** Accept a connection from a socket * @param s The socket + * @return The new socket */ - void Accept(ListenSocket *s); + ClientSocket *Accept(ListenSocket *s); /** Connect the socket * @param s THe socket * @param target IP to connect to * @param port to connect to - * @param bindip IP to bind to, if any */ - void Connect(ConnectionSocket *s, const Anope::string &target, int port, const Anope::string &bindip = ""); + void Connect(ConnectionSocket *s, const Anope::string &target, int port); /** Called when the socket is destructing */ @@ -144,41 +151,27 @@ class SSLModule : public Module ~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); } - EventReturn OnPreServerConnect(Uplink *u, int Number) + void OnPreServerConnect() { ConfigReader config; - if (config.ReadFlag("uplink", "ssl", "no", Number - 1)) + if (config.ReadFlag("uplink", "ssl", "no", CurrentUplink)) { - DNSRecord req = DNSManager::BlockingQuery(uplink_server->host, uplink_server->ipv6 ? DNS_QUERY_AAAA : DNS_QUERY_A); - - if (!req) - Log() << "Unable to connect to server " << uplink_server->host << ":" << uplink_server->port << " using SSL: Invalid hostname/IP"; - else - { - try - { - new UplinkSocket(uplink_server->ipv6); - this->service.Init(UplinkSock); - UplinkSock->Connect(req.result, uplink_server->port, Config->LocalHost); - - Log() << "Connected to server " << Number << " (" << u->host << ":" << u->port << ") with SSL"; - return EVENT_ALLOW; - } - catch (const SocketException &ex) - { - Log() << "Unable to connect with SSL to server " << Number << " (" << u->host << ":" << u->port << "), " << ex.GetReason(); - } - } - - return EVENT_STOP; + this->service.Init(UplinkSock); } - - return EVENT_CONTINUE; } }; @@ -194,39 +187,67 @@ void MySSLService::Init(Socket *s) s->IO = new SSLSocketIO(); } -SSLSocketIO::SSLSocketIO() +int SSLSocketIO::CheckState() +{ + if (this->connected == 0 || this->accepted == 0) + { + int ret; + if (this->connected == 0) + ret = SSL_connect(this->sslsock); + else if (this->accepted == 0) + ret = SSL_accept(this->sslsock); + if (ret <= 0) + { + int error = SSL_get_error(this->sslsock, ret); + + if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) + // Wait more + return -2; + return -1; + } + + if (this->connected == 0) + this->connected = 1; + else if (this->accepted == 0) + this->accepted = 1; + } + + return 0; +} + +SSLSocketIO::SSLSocketIO() : connected(-1), accepted(-1) { this->sslsock = NULL; } -int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz) const +int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz) { - int i = SSL_read(this->sslsock, buf, sz); + int i = this->CheckState(); + if (i < 0) + return i; + + i = SSL_read(this->sslsock, buf, sz); TotalRead += i; return i; } -int SSLSocketIO::Send(Socket *s, const Anope::string &buf) const +int SSLSocketIO::Send(Socket *s, const Anope::string &buf) { - int i = SSL_write(this->sslsock, buf.c_str(), buf.length()); + int i = this->CheckState(); + if (i < 0) + return i; + + i = SSL_write(this->sslsock, buf.c_str(), buf.length()); TotalWritten += i; return i; } -void SSLSocketIO::Accept(ListenSocket *s) +ClientSocket *SSLSocketIO::Accept(ListenSocket *s) { - sockaddrs conaddr; - - socklen_t size = conaddr.size(); - int newsock = accept(s->GetFD(), &conaddr.sa, &size); - -#ifndef INVALID_SOCKET -# define INVALID_SOCKET -1 -#endif - if (newsock <= 0 || newsock == INVALID_SOCKET) - throw SocketException("Unable to accept SSL socket: " + Anope::LastError()); - - ClientSocket *newsocket = s->OnAccept(newsock, conaddr); + if (s->IO == &normalSocketIO) + throw SocketException("Attempting to accept on uninitialized socket with SSL"); + + ClientSocket *newsocket = normalSocketIO.Accept(s); me->service.Init(newsocket); SSLSocketIO *IO = debug_cast<SSLSocketIO *>(newsocket->IO); @@ -236,25 +257,22 @@ void SSLSocketIO::Accept(ListenSocket *s) SSL_set_accept_state(IO->sslsock); - if (!SSL_set_fd(IO->sslsock, newsock)) + if (!SSL_set_fd(IO->sslsock, newsocket->GetFD())) throw SocketException("Unable to set SSL fd"); - 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_READ)) - throw SocketException("Unable to accept new SSL connection: " + Anope::string(ERR_error_string(ERR_get_error(), NULL))); - } + IO->accepted = 0; + if (this->CheckState() == -1) + throw SocketException("Unable to accept new SSL connection: " + Anope::string(ERR_error_string(ERR_get_error(), NULL))); + + return newsocket; } -void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &TargetHost, int Port, const Anope::string &BindHost) +void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port) { if (s->IO == &normalSocketIO) - throw SocketException("Attempting to connect uninitialized socket with SQL"); + throw SocketException("Attempting to connect uninitialized socket with SSL"); - normalSocketIO.Connect(s, TargetHost, Port, BindHost); + normalSocketIO.Connect(s, target, port); SSLSocketIO *IO = debug_cast<SSLSocketIO *>(s->IO); @@ -265,15 +283,9 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &TargetHost, 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_READ)) - throw SocketException("Unable to connect to server: " + Anope::string(ERR_error_string(ERR_get_error(), NULL))); - } + IO->connected = 0; + if (this->CheckState() == -1) + throw SocketException("Unable to connect to server: " + Anope::string(ERR_error_string(ERR_get_error(), NULL))); } void SSLSocketIO::Destroy() diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp index 8c0723c42..bba72c2f5 100644 --- a/modules/extra/m_xmlrpc.cpp +++ b/modules/extra/m_xmlrpc.cpp @@ -2,6 +2,8 @@ #include "ssl.h" #include "xmlrpc.h" +std::vector<XMLRPCListenSocket *> listen_sockets; + class MyXMLRPCClientSocket : public XMLRPCClientSocket { /* Used to skip the (optional) HTTP header, which we really don't care about */ @@ -85,7 +87,17 @@ class MyXMLRPCClientSocket : public XMLRPCClientSocket class MyXMLRPCListenSocket : public XMLRPCListenSocket { public: - MyXMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : XMLRPCListenSocket(bindip, port, ipv6, u, p, a) { } + MyXMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : XMLRPCListenSocket(bindip, port, ipv6, u, p, a) + { + listen_sockets.push_back(this); + } + + ~MyXMLRPCListenSocket() + { + std::vector<XMLRPCListenSocket *>::iterator it = std::find(listen_sockets.begin(), listen_sockets.end(), this); + if (it != listen_sockets.end()) + listen_sockets.erase(it); + } ClientSocket *OnAccept(int fd, const sockaddrs &addr) { @@ -208,7 +220,6 @@ class ModuleXMLRPC; static ModuleXMLRPC *me; class ModuleXMLRPC : public Module { - std::vector<MyXMLRPCListenSocket *> listen_sockets; service_reference<SSLService> sslref; public: @@ -229,15 +240,16 @@ class ModuleXMLRPC : public Module ~ModuleXMLRPC() { /* Clean up our sockets and our listening sockets */ - for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end; ++it) + 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 (s->Type == SOCKTYPE_CLIENT) { ClientSocket *cs = debug_cast<ClientSocket *>(s); - for (unsigned i = 0; i < this->listen_sockets.size(); ++i) - if (cs->LS == this->listen_sockets[i]) + for (unsigned i = 0; i < listen_sockets.size(); ++i) + if (cs->LS == listen_sockets[i]) { delete cs; break; @@ -245,18 +257,18 @@ class ModuleXMLRPC : public Module } } - for (unsigned i = 0; i < this->listen_sockets.size(); ++i) - delete this->listen_sockets[i]; - this->listen_sockets.clear(); + for (unsigned i = 0; i < listen_sockets.size(); ++i) + delete listen_sockets[i]; + listen_sockets.clear(); } void OnReload() { ConfigReader config; - for (unsigned i = 0; i < this->listen_sockets.size(); ++i) - delete this->listen_sockets[i]; - this->listen_sockets.clear(); + for (unsigned i = 0; i < listen_sockets.size(); ++i) + delete listen_sockets[i]; + listen_sockets.clear(); for (int i = 0; i < config.Enumerate("m_xmlrpc"); ++i) { @@ -282,10 +294,7 @@ class ModuleXMLRPC : public Module { MyXMLRPCListenSocket *xmls = new MyXMLRPCListenSocket(bindip, port, ipv6, username, password, allowed_vector); if (ssl) - { sslref->Init(xmls); - } - this->listen_sockets.push_back(xmls); } catch (const SocketException &ex) { diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 92aee74fb..29f16004e 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -232,7 +232,7 @@ class BahamutIRCdProto : public IRCDProto void SendConnect() { - bahamut_cmd_pass(uplink_server->password); + bahamut_cmd_pass(Config->Uplinks[CurrentUplink]->password); bahamut_cmd_capab(); SendServer(Me); bahamut_cmd_svinfo(); diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h index d76dc27c2..cf93865f8 100644 --- a/modules/protocol/inspircd-ts6.h +++ b/modules/protocol/inspircd-ts6.h @@ -124,7 +124,7 @@ class InspIRCdTS6Proto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(const Server *server) { - send_cmd("", "SERVER %s %s %d %s :%s", server->GetName().c_str(), uplink_server ? uplink_server->password.c_str() : "none", server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str()); + send_cmd("", "SERVER %s %s %d %s :%s", server->GetName().c_str(), Config->Uplinks[CurrentUplink]->password.c_str(), server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str()); } /* JOIN */ diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 5ab55ab07..a382d4006 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -199,7 +199,7 @@ class InspIRCdProto : public IRCDProto void SendConnect() { - inspircd_cmd_pass(uplink_server->password); + inspircd_cmd_pass(Config->Uplinks[CurrentUplink]->password); SendServer(Me); send_cmd("", "BURST"); Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index 04095e5a2..5e6c67781 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -157,7 +157,7 @@ class PlexusProto : public IRCDProto void SendConnect() { - plexus_cmd_pass(uplink_server->password); + plexus_cmd_pass(Config->Uplinks[CurrentUplink]->password); plexus_cmd_capab(); /* Make myself known to myself in the serverlist */ SendServer(Me); diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index d6cfc761f..2833c52b7 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -160,7 +160,7 @@ class RatboxProto : public IRCDProto void SendConnect() { - ratbox_cmd_pass(uplink_server->password); + ratbox_cmd_pass(Config->Uplinks[CurrentUplink]->password); ratbox_cmd_capab(); /* Make myself known to myself in the serverlist */ SendServer(Me); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index cb7a54d61..e07b97af0 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -228,7 +228,7 @@ class UnrealIRCdProto : public IRCDProto void SendConnect() { unreal_cmd_capab(); - unreal_cmd_pass(uplink_server->password); + unreal_cmd_pass(Config->Uplinks[CurrentUplink]->password); SendServer(Me); } |
