summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/conf/modules.conf.example2
-rw-r--r--src/dns.cpp8
-rw-r--r--src/modes/cmode_b.cpp1
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp4
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp97
-rw-r--r--src/modules/m_banredirect.cpp11
-rw-r--r--src/modules/m_delaymsg.cpp19
-rw-r--r--win/inspircd_win32wrapper.cpp8
8 files changed, 144 insertions, 6 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 2af84c83b..30b8181ac 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -695,6 +695,8 @@
# from talking in the channel unless they've been joined for X seconds.
# Settable using /MODE #chan +d 30
#<module name="m_delaymsg.so">
+# Set allownotice to no to disallow NOTICEs too. Defaults to yes.
+#<delaymsg allownotice="no">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Deny channels module: Deny channels from being used by users.
diff --git a/src/dns.cpp b/src/dns.cpp
index 977f4bad0..75e5731fe 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -677,7 +677,13 @@ DNSResult DNS::GetResult()
case DNS_QUERY_AAAA:
{
- inet_ntop(AF_INET6, data.first, formatted, sizeof(formatted));
+ if (!inet_ntop(AF_INET6, data.first, formatted, sizeof(formatted)))
+ {
+ std::string ro = req->orig;
+ delete req;
+ return DNSResult(this_id | ERROR_MASK, "inet_ntop() failed", 0, ro);
+ }
+
resultstr = formatted;
/* Special case. Sending ::1 around between servers
diff --git a/src/modes/cmode_b.cpp b/src/modes/cmode_b.cpp
index 09df05100..e45f191f7 100644
--- a/src/modes/cmode_b.cpp
+++ b/src/modes/cmode_b.cpp
@@ -168,6 +168,7 @@ std::string& ModeChannelBan::DelBan(User *user, std::string& dest, Channel *chan
dest.clear();
return dest;
}
+ dest = i->data;
chan->bans.erase(i);
return dest;
}
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index 21b58f280..228ceb994 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -419,6 +419,10 @@ class ModuleSSLGnuTLS : public Module
hash = GNUTLS_DIG_MD5;
else if (hashname == "sha1")
hash = GNUTLS_DIG_SHA1;
+#ifdef INSPIRCD_GNUTLS_ENABLE_SHA256_FINGERPRINT
+ else if (hashname == "sha256")
+ hash = GNUTLS_DIG_SHA256;
+#endif
else
throw ModuleException("Unknown hash type " + hashname);
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index 01bf11678..02f44f2f1 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -51,10 +51,16 @@
/* $NoPedantic */
+class ModuleSSLOpenSSL;
+
enum issl_status { ISSL_NONE, ISSL_HANDSHAKING, ISSL_OPEN };
static bool SelfSigned = false;
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+static ModuleSSLOpenSSL* opensslmod = NULL;
+#endif
+
char* get_error()
{
return ERR_error_string(ERR_get_error(), NULL);
@@ -141,10 +147,72 @@ class ModuleSSLOpenSSL : public Module
ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "OpenSSL %s context options: %ld", ctxname.c_str(), final);
}
+#ifdef INSPIRCD_OPENSSL_ENABLE_ECDH
+ void SetupECDH(ConfigTag* tag)
+ {
+ std::string curvename = tag->getString("ecdhcurve", "prime256v1");
+ if (curvename.empty())
+ return;
+
+ int nid = OBJ_sn2nid(curvename.c_str());
+ if (nid == 0)
+ {
+ ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Unknown curve: \"%s\"", curvename.c_str());
+ return;
+ }
+
+ EC_KEY* eckey = EC_KEY_new_by_curve_name(nid);
+ if (!eckey)
+ {
+ ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Unable to create EC key object");
+ return;
+ }
+
+ ERR_clear_error();
+ if (SSL_CTX_set_tmp_ecdh(ctx, eckey) < 0)
+ {
+ ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Couldn't set ECDH parameters");
+ ERR_print_errors_cb(error_callback, this);
+ }
+
+ EC_KEY_free(eckey);
+ }
+#endif
+
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+ static void SSLInfoCallback(const SSL* ssl, int where, int rc)
+ {
+ int fd = SSL_get_fd(const_cast<SSL*>(ssl));
+ issl_session& session = opensslmod->sessions[fd];
+
+ if ((where & SSL_CB_HANDSHAKE_START) && (session.status == ISSL_OPEN))
+ {
+ // The other side is trying to renegotiate, kill the connection and change status
+ // to ISSL_NONE so CheckRenego() closes the session
+ session.status = ISSL_NONE;
+ ServerInstance->SE->Shutdown(fd, 2);
+ }
+ }
+
+ bool CheckRenego(StreamSocket* sock, issl_session* session)
+ {
+ if (session->status != ISSL_NONE)
+ return true;
+
+ ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Session %p killed, attempted to renegotiate", (void*)session->sess);
+ CloseSession(session);
+ sock->SetError("Renegotiation is not allowed");
+ return false;
+ }
+#endif
+
public:
ModuleSSLOpenSSL() : iohook(this, "ssl/openssl", SERVICE_IOHOOK)
{
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+ opensslmod = this;
+#endif
sessions = new issl_session[ServerInstance->SE->GetMaxFds()];
/* Global SSL library initialization*/
@@ -203,6 +271,20 @@ class ModuleSSLOpenSSL : public Module
ConfigTag* Conf = ServerInstance->Config->ConfValue("openssl");
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+ // Set the callback if we are not allowing renegotiations, unset it if we do
+ if (Conf->getBool("renegotiation", true))
+ {
+ SSL_CTX_set_info_callback(ctx, NULL);
+ SSL_CTX_set_info_callback(clictx, NULL);
+ }
+ else
+ {
+ SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
+ SSL_CTX_set_info_callback(clictx, SSLInfoCallback);
+ }
+#endif
+
if (Conf->getBool("showports", true))
{
sslports = Conf->getString("advertisedports");
@@ -334,6 +416,10 @@ class ModuleSSLOpenSSL : public Module
#ifndef _WIN32
fclose(dhpfile);
#endif
+
+#ifdef INSPIRCD_OPENSSL_ENABLE_ECDH
+ SetupECDH(conf);
+#endif
}
void On005Numeric(std::string &output)
@@ -497,6 +583,11 @@ class ModuleSSLOpenSSL : public Module
size_t bufsiz = ServerInstance->Config->NetBufferSize;
int ret = SSL_read(session->sess, buffer, bufsiz);
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+ if (!CheckRenego(user, session))
+ return -1;
+#endif
+
if (ret > 0)
{
recvq.append(buffer, ret);
@@ -565,6 +656,12 @@ class ModuleSSLOpenSSL : public Module
{
ERR_clear_error();
int ret = SSL_write(session->sess, buffer.data(), buffer.size());
+
+#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION
+ if (!CheckRenego(user, session))
+ return -1;
+#endif
+
if (ret == (int)buffer.length())
{
session->data_to_write = false;
diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp
index 2e2592541..1b9e361bf 100644
--- a/src/modules/m_banredirect.cpp
+++ b/src/modules/m_banredirect.cpp
@@ -75,6 +75,9 @@ class BanRedirect : public ModeWatcher
if (param.length() >= 2 && param[1] == ':')
return true;
+ if (param.find('#') == std::string::npos)
+ return true;
+
if(adding && (channel->bans.size() > static_cast<unsigned>(maxbans)))
{
source->WriteNumeric(478, "%s %s :Channel ban list for %s is full (maximum entries for this channel is %ld)", source->nick.c_str(), channel->name.c_str(), channel->name.c_str(), maxbans);
@@ -119,6 +122,14 @@ class BanRedirect : public ModeWatcher
mask[NICK].swap(mask[IDENT]);
}
+ if (!mask[NICK].empty() && mask[IDENT].empty() && mask[HOST].empty())
+ {
+ if (mask[NICK].find('.') != std::string::npos || mask[NICK].find(':') != std::string::npos)
+ {
+ mask[NICK].swap(mask[HOST]);
+ }
+ }
+
for(int i = 0; i < 3; i++)
{
if(mask[i].empty())
diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp
index cfc06866a..978ab55d2 100644
--- a/src/modules/m_delaymsg.cpp
+++ b/src/modules/m_delaymsg.cpp
@@ -52,12 +52,15 @@ class ModuleDelayMsg : public Module
{
ServerInstance->Modules->AddService(djm);
ServerInstance->Modules->AddService(djm.jointime);
- Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage};
+ Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage, I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+ OnRehash(NULL);
}
Version GetVersion();
void OnUserJoin(Membership* memb, bool sync, bool created, CUList&);
ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list);
+ ModResult OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list);
+ void OnRehash(User* user);
};
ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
@@ -144,5 +147,19 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty
return MOD_RES_PASSTHRU;
}
+ModResult ModuleDelayMsg::OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list)
+{
+ return OnUserPreMessage(user, dest, target_type, text, status, exempt_list);
+}
+
+void ModuleDelayMsg::OnRehash(User* user)
+{
+ ConfigTag* tag = ServerInstance->Config->ConfValue("delaymsg");
+ if (tag->getBool("allownotice", true))
+ ServerInstance->Modules->Detach(I_OnUserPreNotice, this);
+ else
+ ServerInstance->Modules->Attach(I_OnUserPreNotice, this);
+}
+
MODULE_INIT(ModuleDelayMsg)
diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp
index 7707dea0c..d66797f13 100644
--- a/win/inspircd_win32wrapper.cpp
+++ b/win/inspircd_win32wrapper.cpp
@@ -38,8 +38,8 @@ CoreExport const char *insp_inet_ntop(int af, const void *src, char *dst, sockle
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
memcpy(&in.sin_addr, src, sizeof(struct in_addr));
- getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
+ if (getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST) == 0)
+ return dst;
}
else if (af == AF_INET6)
{
@@ -47,8 +47,8 @@ CoreExport const char *insp_inet_ntop(int af, const void *src, char *dst, sockle
memset(&in, 0, sizeof(in));
in.sin6_family = AF_INET6;
memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
- getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
+ if (getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST) == 0)
+ return dst;
}
return NULL;
}