From 04330da0d2e5d119f5f5ce182f4e22ae17c80d22 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 14 Jun 2021 10:08:02 +0100 Subject: Clean up VerifyCertificate in the ssl_gnutls module. --- src/modules/extra/m_ssl_gnutls.cpp | 62 ++++++++++++++------------------------ 1 file changed, 23 insertions(+), 39 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 1b9291079..670ff79b1 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -793,26 +793,14 @@ class GnuTLSIOHook : public SSLIOHook void VerifyCertificate() { - unsigned int certstatus; - const gnutls_datum_t* cert_list; - int ret; - unsigned int cert_list_size; - gnutls_x509_crt_t cert; - char str[512]; - unsigned char digest[512]; - size_t digest_size = sizeof(digest); - size_t name_size = sizeof(str); ssl_cert* certinfo = new ssl_cert; this->certificate = certinfo; - /* This verification function uses the trusted CAs in the credentials - * structure. So you must have installed one or more CA certificates. - */ - ret = gnutls_certificate_verify_peers2(this->sess, &certstatus); - + unsigned int certstatus; + int ret = gnutls_certificate_verify_peers2(this->sess, &certstatus); if (ret < 0) { - certinfo->error = std::string(gnutls_strerror(ret)); + certinfo->error = gnutls_strerror(ret); return; } @@ -821,16 +809,13 @@ class GnuTLSIOHook : public SSLIOHook certinfo->revoked = (certstatus & GNUTLS_CERT_REVOKED); certinfo->trusted = !(certstatus & GNUTLS_CERT_SIGNER_NOT_CA); - /* Up to here the process is the same for X.509 certificates and - * OpenPGP keys. From now on X.509 certificates are assumed. This can - * be easily extended to work with openpgp keys as well. - */ if (gnutls_certificate_type_get(this->sess) != GNUTLS_CRT_X509) { certinfo->error = "No X509 keys sent"; return; } + gnutls_x509_crt_t cert; ret = gnutls_x509_crt_init(&cert); if (ret < 0) { @@ -838,18 +823,17 @@ class GnuTLSIOHook : public SSLIOHook return; } - cert_list_size = 0; - cert_list = gnutls_certificate_get_peers(this->sess, &cert_list_size); + char buffer[512]; + size_t buffer_size = sizeof(buffer); + + unsigned int cert_list_size = 0; + const gnutls_datum_t* cert_list = gnutls_certificate_get_peers(this->sess, &cert_list_size); if (cert_list == NULL) { certinfo->error = "No certificate was found"; goto info_done_dealloc; } - /* This is not a real world example, since we only check the first - * certificate in the given chain. - */ - ret = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); if (ret < 0) { @@ -857,31 +841,31 @@ class GnuTLSIOHook : public SSLIOHook goto info_done_dealloc; } - if (gnutls_x509_crt_get_dn(cert, str, &name_size) == 0) + if (gnutls_x509_crt_get_dn(cert, buffer, &buffer_size) == 0) { - std::string& dn = certinfo->dn; - dn = str; - // Make sure there are no chars in the string that we consider invalid - if (dn.find_first_of("\r\n") != std::string::npos) - dn.clear(); + // Make sure there are no chars in the string that we consider invalid. + certinfo->dn = buffer; + if (certinfo->dn.find_first_of("\r\n") != std::string::npos) + certinfo->dn.clear(); } - name_size = sizeof(str); - if (gnutls_x509_crt_get_issuer_dn(cert, str, &name_size) == 0) + buffer_size = sizeof(buffer); + if (gnutls_x509_crt_get_issuer_dn(cert, buffer, &buffer_size) == 0) { - std::string& issuer = certinfo->issuer; - issuer = str; - if (issuer.find_first_of("\r\n") != std::string::npos) - issuer.clear(); + // Make sure there are no chars in the string that we consider invalid. + certinfo->issuer = buffer; + if (certinfo->issuer.find_first_of("\r\n") != std::string::npos) + certinfo->issuer.clear(); } - if ((ret = gnutls_x509_crt_get_fingerprint(cert, GetProfile().GetHash(), digest, &digest_size)) < 0) + buffer_size = sizeof(buffer); + if ((ret = gnutls_x509_crt_get_fingerprint(cert, GetProfile().GetHash(), buffer, &buffer_size)) < 0) { certinfo->error = gnutls_strerror(ret); } else { - certinfo->fingerprint = BinToHex(digest, digest_size); + certinfo->fingerprint = BinToHex(buffer, buffer_size); } /* Beware here we do not check for errors. -- cgit v1.3.1-10-gc9f91 From d0c458f5c3e0d33e62c3a05b3624468e868eb03c Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Thu, 17 Jun 2021 17:01:39 +0100 Subject: Fix joinflood applying the bootwait timeout to rehashes. --- src/modules/m_joinflood.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_joinflood.cpp b/src/modules/m_joinflood.cpp index 3241020bf..a196c5731 100644 --- a/src/modules/m_joinflood.cpp +++ b/src/modules/m_joinflood.cpp @@ -153,14 +153,15 @@ class ModuleJoinFlood { } - void ReadConfig(ConfigStatus&) CXX11_OVERRIDE + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { ConfigTag* tag = ServerInstance->Config->ConfValue("joinflood"); duration = tag->getDuration("duration", 60, 10, 600); bootwait = tag->getDuration("bootwait", 30); splitwait = tag->getDuration("splitwait", 30); - ignoreuntil = ServerInstance->startup_time + bootwait; + if (status.initial) + ignoreuntil = ServerInstance->startup_time + bootwait; } void OnServerSplit(const Server* server, bool error) CXX11_OVERRIDE -- cgit v1.3.1-10-gc9f91 From 3b5425e6e0776daf0632f4e86057486b60794e2c Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 18 Jun 2021 11:18:06 +0100 Subject: Fix joinflood overwriting the bootwait timer on split. --- src/modules/m_joinflood.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_joinflood.cpp b/src/modules/m_joinflood.cpp index a196c5731..05f9f0f0e 100644 --- a/src/modules/m_joinflood.cpp +++ b/src/modules/m_joinflood.cpp @@ -167,7 +167,7 @@ class ModuleJoinFlood void OnServerSplit(const Server* server, bool error) CXX11_OVERRIDE { if (splitwait) - ignoreuntil = ServerInstance->Time() + splitwait; + ignoreuntil = std::max(ignoreuntil, ServerInstance->Time() + splitwait); } ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE -- cgit v1.3.1-10-gc9f91 From a509f47b7d7c485dfafe2f8fe90d3dc2297b6027 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 18 Jun 2021 11:18:56 +0100 Subject: Add the bootwait and splitwait options to connectban. --- docs/conf/modules.conf.example | 38 ++++++++++++++++++++++++++++---------- src/modules/m_connectban.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 13 deletions(-) (limited to 'src/modules') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 87648a88f..837d51e6a 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -687,16 +687,34 @@ # (configurable) duration, and their count resets to 0. # # -# ipv4cidr and ipv6cidr allow you to turn the comparison from -# individual IP addresses (32 and 128 bits) into CIDR masks, to allow -# for throttling over whole ISPs/blocks of IPs, which may be needed to -# prevent attacks. -# -# This allows for 10 connections in an hour with a 10 minute ban if -# that is exceeded. -# +# threshold - The number of connections which are allowed before a user +# is connectbnaned. Defaults to 10. +# +# banmessage - The message to give users when Z-lining them for connecting +# too much. +# +# duration - The time period to ban users who connect to much for. Defaults +# to 10 minutes. +# +# ipv4cidr - The IPv4 CIDR mask (1-32) to treat connecting users as coming +# from the same host. Defaults to 32. +# +# ipv6cidr - The IPv6 CIDR mask (1-128) to treat connecting users as coming +# from the same host. Defaults to 128. +# +# bootwait - The time period to wait after starting up before enforcing +# connection bans. Defaults to 2 minutes. +# +# splitwait - The time period to wait after a netsplit before enforcing +# connection bans. Defaults to 2 minutes. +# +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Connection throttle module. diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index aa94adc2e..53aef6ca8 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -26,18 +26,25 @@ #include "inspircd.h" #include "xline.h" +#include "modules/server.h" #include "modules/webirc.h" -class ModuleConnectBan +class ModuleConnectBan CXX11_FINAL : public Module + , public ServerProtocol::LinkEventListener , public WebIRC::EventListener { + private: typedef std::map ConnectMap; + ConnectMap connects; unsigned int threshold; unsigned int banduration; unsigned int ipv4_cidr; unsigned int ipv6_cidr; + unsigned long bootwait; + unsigned long splitwait; + time_t ignoreuntil; std::string banmessage; unsigned char GetRange(LocalUser* user) @@ -72,8 +79,13 @@ class ModuleConnectBan } public: + // Stop GCC warnings about the deprecated OnServerSplit event. + using ServerProtocol::LinkEventListener::OnServerSplit; + ModuleConnectBan() - : WebIRC::EventListener(this) + : ServerProtocol::LinkEventListener(this) + , WebIRC::EventListener(this) + , ignoreuntil(0) { } @@ -95,8 +107,13 @@ class ModuleConnectBan ipv4_cidr = tag->getUInt("ipv4cidr", 32, 1, 32); ipv6_cidr = tag->getUInt("ipv6cidr", 128, 1, 128); threshold = tag->getUInt("threshold", 10, 1); + bootwait = tag->getDuration("bootwait", 60*2); + splitwait = tag->getDuration("splitwait", 60*2); banduration = tag->getDuration("duration", 10*60, 1); banmessage = tag->getString("banmessage", "Your IP range has been attempting to connect too many times in too short a duration. Wait a while, and you will be able to connect."); + + if (status.initial) + ignoreuntil = std::max(ignoreuntil, ServerInstance->Time() + splitwait); } void OnWebIRCAuth(LocalUser* user, const WebIRC::FlagMap* flags) CXX11_OVERRIDE @@ -113,9 +130,15 @@ class ModuleConnectBan iter->second--; } + void OnServerSplit(const Server* server, bool error) CXX11_OVERRIDE + { + if (splitwait) + ignoreuntil = ServerInstance->Time() + splitwait; + } + void OnSetUserIP(LocalUser* u) CXX11_OVERRIDE { - if (IsExempt(u)) + if (IsExempt(u) || ignoreuntil > ServerInstance->Time()) return; irc::sockets::cidr_mask mask(u->client_sa, GetRange(u)); -- cgit v1.3.1-10-gc9f91 From 0bbfafb9d072c8ea4f5437289213d1ae8fe94a2b Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 18 Jun 2021 13:35:01 +0100 Subject: Fix some inverted ignoreuntil values in the connectban module. --- src/modules/m_connectban.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index 53aef6ca8..d8741a141 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -113,7 +113,7 @@ class ModuleConnectBan CXX11_FINAL banmessage = tag->getString("banmessage", "Your IP range has been attempting to connect too many times in too short a duration. Wait a while, and you will be able to connect."); if (status.initial) - ignoreuntil = std::max(ignoreuntil, ServerInstance->Time() + splitwait); + ignoreuntil = ServerInstance->Time() + bootwait; } void OnWebIRCAuth(LocalUser* user, const WebIRC::FlagMap* flags) CXX11_OVERRIDE @@ -133,7 +133,7 @@ class ModuleConnectBan CXX11_FINAL void OnServerSplit(const Server* server, bool error) CXX11_OVERRIDE { if (splitwait) - ignoreuntil = ServerInstance->Time() + splitwait; + ignoreuntil = std::max(ignoreuntil, ServerInstance->Time() + splitwait); } void OnSetUserIP(LocalUser* u) CXX11_OVERRIDE -- cgit v1.3.1-10-gc9f91