From 219d0fa1a64c5c2c155942ebc52543dd956519b1 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sat, 30 Jan 2021 16:29:01 +0000 Subject: [PATCH 01/10] Fix a few issues with SERVLIST. - Implement support for service type matching based on the service oper type. This isn't the same as irc2 but its close enough. - Fix erroneously sending the mask in the field. This field is for the service name mask not the service distribution mask. --- src/coremods/core_info/cmd_servlist.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/coremods/core_info/cmd_servlist.cpp b/src/coremods/core_info/cmd_servlist.cpp index f400124d2..9490f7280 100644 --- a/src/coremods/core_info/cmd_servlist.cpp +++ b/src/coremods/core_info/cmd_servlist.cpp @@ -32,28 +32,32 @@ CommandServList::CommandServList(Module* parent) , invisiblemode(parent, "invisible") { allow_empty_last_param = false; - syntax = "[]"; + syntax = "[ []]"; } CmdResult CommandServList::HandleLocal(LocalUser* user, const Params& parameters) { const std::string& mask = parameters.empty() ? "*" : parameters[0]; + const bool has_type = parameters.size() > 1; for (UserManager::ULineList::const_iterator iter = ServerInstance->Users.all_ulines.begin(); iter != ServerInstance->Users.all_ulines.end(); ++iter) { User* uline = *iter; if (uline->IsModeSet(invisiblemode) || !InspIRCd::Match(uline->nick, mask)) continue; + if (has_type && (!user->IsOper() || !InspIRCd::Match(user->oper->name, parameters[2 ]))) + continue; + Numeric::Numeric numeric(RPL_SERVLIST); numeric .push(uline->nick) .push(uline->server->GetName()) - .push(mask) - .push(0) + .push("*") + .push(user->IsOper() ? user->oper->name : "*") .push(0) .push(uline->GetRealName()); user->WriteNumeric(numeric); } - user->WriteNumeric(RPL_SERVLISTEND, mask, 0, "End of service listing"); + user->WriteNumeric(RPL_SERVLISTEND, mask, has_type ? parameters[1] : "*", "End of service listing"); return CMD_SUCCESS; } From 563c9aba9ee3b62914a0c5903882f3a825258275 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sat, 30 Jan 2021 16:46:23 +0000 Subject: [PATCH 02/10] Fix an oversight in the previous commit. --- src/coremods/core_info/cmd_servlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coremods/core_info/cmd_servlist.cpp b/src/coremods/core_info/cmd_servlist.cpp index 9490f7280..a6f4101ee 100644 --- a/src/coremods/core_info/cmd_servlist.cpp +++ b/src/coremods/core_info/cmd_servlist.cpp @@ -53,7 +53,7 @@ CmdResult CommandServList::HandleLocal(LocalUser* user, const Params& parameters .push(uline->nick) .push(uline->server->GetName()) .push("*") - .push(user->IsOper() ? user->oper->name : "*") + .push(uline->IsOper() ? uline->oper->name : "*") .push(0) .push(uline->GetRealName()); user->WriteNumeric(numeric); From 10714b0ded0ff1304034bb3c2eab9ef5fb163616 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sat, 30 Jan 2021 17:31:40 +0000 Subject: [PATCH 03/10] Fix bitshift in INSPIRCD_VERSION_SINCE. --- make/template/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/template/config.h b/make/template/config.h index 97dd15453..ec3cff94a 100644 --- a/make/template/config.h +++ b/make/template/config.h @@ -29,7 +29,7 @@ #define INSPIRCD_VERSION_BEFORE(MAJOR, MINOR) (((@VERSION_MAJOR@ << 8) | @VERSION_MINOR@) < ((MAJOR << 8) | (MINOR))) /** Determines whether this version of InspIRCd is equal to or newer than the requested version. */ -#define INSPIRCD_VERSION_SINCE(MAJOR, MINOR) (((@VERSION_MAJOR@ << 16) | @VERSION_MINOR@) >= ((MAJOR << 8) | (MINOR))) +#define INSPIRCD_VERSION_SINCE(MAJOR, MINOR) (((@VERSION_MAJOR@ << 8) | @VERSION_MINOR@) >= ((MAJOR << 8) | (MINOR))) /** The default location that config files are stored in. */ #define INSPIRCD_CONFIG_PATH "@CONFIG_DIR@" From 55a0a6ab66739fae65d123fadff1a31d96999c16 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 31 Jan 2021 14:33:53 +0000 Subject: [PATCH 04/10] Fix the base path being used for more than just the install prefix. --- configure | 2 -- make/template/inspircd | 3 +-- make/template/main.mk | 4 ---- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/configure b/configure index 5a587b808..65dce82a3 100755 --- a/configure +++ b/configure @@ -322,7 +322,6 @@ EOW my $question = <<"EOQ"; Currently, InspIRCd is configured with the following paths: -<|BOLD Base:|> $config{BASE_DIR} <|BOLD Binary:|> $config{BINARY_DIR} <|BOLD Config:|> $config{CONFIG_DIR} <|BOLD Data:|> $config{DATA_DIR} @@ -456,7 +455,6 @@ push @makeargs, "-j${\(get_cpu_count() + 1)}"; print console_format <<"EOM"; <|GREEN Paths:|> - <|GREEN Base:|> $config{BASE_DIR} <|GREEN Binary:|> $config{BINARY_DIR} <|GREEN Config:|> $config{CONFIG_DIR} <|GREEN Data:|> $config{DATA_DIR} diff --git a/make/template/inspircd b/make/template/inspircd index c50d28c7f..9bc7dd85f 100644 --- a/make/template/inspircd +++ b/make/template/inspircd @@ -62,11 +62,10 @@ use constant { }; my $scriptpath = "@SCRIPT_DIR@"; -my $basepath = "@BASE_DIR@"; my $confpath = "@CONFIG_DIR@"; my $binpath = "@BINARY_DIR@"; my $runtimedir = "@RUNTIME_DIR@"; -my $valgrindlogpath = "$basepath/valgrindlogs"; +my $valgrindlogpath = "@LOG_DIR@/valgrind"; my $executable = "inspircd"; my $version = "@VERSION_FULL@"; my $uid = "@UID@"; diff --git a/make/template/main.mk b/make/template/main.mk index 181c1f9f2..a8783aa05 100644 --- a/make/template/main.mk +++ b/make/template/main.mk @@ -51,7 +51,6 @@ CORELDFLAGS = -rdynamic -L. PICLDFLAGS = -fPIC -shared -rdynamic DESTDIR := $(if $(DESTDIR),$(DESTDIR),"@DESTDIR|@") -BASE = "$(DESTDIR)@BASE_DIR@" BINPATH = "$(DESTDIR)@BINARY_DIR@" CONPATH = "$(DESTDIR)@CONFIG_DIR@" DATPATH = "$(DESTDIR)@DATA_DIR@" @@ -212,7 +211,6 @@ finishmessage: target @echo "*************************************" install: target - @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(BASE) @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(BINPATH) @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(CONPATH) @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(DATPATH) @@ -252,7 +250,6 @@ endif @echo "* INSTALL COMPLETE! *" @echo "*************************************" @echo 'Paths:' - @echo ' Base install:' $(BASE) @echo ' Configuration:' $(CONPATH) @echo ' Binaries:' $(BINPATH) @echo ' Modules:' $(MODPATH) @@ -308,7 +305,6 @@ help: @echo 'Targets:' @echo ' all Complete build of InspIRCd, without installing (default)' @echo ' install Build and install InspIRCd to the directory chosen in ./configure' - @echo ' Currently installs to ${BASE}' @echo ' debug Compile a debug build. Equivalent to "make D=1 all"' @echo '' @echo ' INSPIRCD_TARGET=target Builds a user-specified target, such as "inspircd" or "core_dns"' From ff06be6c442359aa223aa68c43d1d8c41920fb91 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 12:59:06 +0000 Subject: [PATCH 05/10] Read once at load time. --- src/modules/m_sslinfo.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index bbbc9ba64..3ced2bc8b 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -148,6 +148,7 @@ class CommandSSLInfo : public Command { public: UserCertificateAPIImpl sslapi; + bool operonlyfp; CommandSSLInfo(Module* Creator) : Command(Creator, "SSLINFO", 1) @@ -166,7 +167,6 @@ class CommandSSLInfo : public Command return CMD_FAILURE; } - bool operonlyfp = ServerInstance->Config->ConfValue("sslinfo")->getBool("operonly"); if (operonlyfp && !user->IsOper() && target != user) { user->WriteNotice("*** You cannot view TLS (SSL) client certificate information for other users"); @@ -217,6 +217,12 @@ class ModuleSSLInfo { } + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE + { + ConfigTag* tag = ServerInstance->Config->ConfValue("sslinfo"); + cmd.operonlyfp = tag->getBool("operonly"); + } + Version GetVersion() CXX11_OVERRIDE { return Version("Adds user facing TLS (SSL) information, various TLS (SSL) configuration options, and the /SSLINFO command to look up TLS (SSL) certificate information for other users.", VF_VENDOR); @@ -228,8 +234,7 @@ class ModuleSSLInfo if (cert) { whois.SendLine(RPL_WHOISSECURE, "is using a secure connection"); - bool operonlyfp = ServerInstance->Config->ConfValue("sslinfo")->getBool("operonly"); - if ((!operonlyfp || whois.IsSelfWhois() || whois.GetSource()->IsOper()) && !cert->fingerprint.empty()) + if ((!cmd.operonlyfp || whois.IsSelfWhois() || whois.GetSource()->IsOper()) && !cert->fingerprint.empty()) whois.SendLine(RPL_WHOISCERTFP, InspIRCd::Format("has TLS (SSL) client certificate fingerprint %s", cert->fingerprint.c_str())); } } From 35530841cf4f38d0d5d0c3b399681a2eb0a43700 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 13:02:07 +0000 Subject: [PATCH 06/10] Convert SSLINFO to SplitCommand. --- src/modules/m_sslinfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index 3ced2bc8b..4623b318f 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -144,23 +144,23 @@ class UserCertificateAPIImpl : public UserCertificateAPIBase } }; -class CommandSSLInfo : public Command +class CommandSSLInfo : public SplitCommand { public: UserCertificateAPIImpl sslapi; bool operonlyfp; CommandSSLInfo(Module* Creator) - : Command(Creator, "SSLINFO", 1) + : SplitCommand(Creator, "SSLINFO", 1) , sslapi(Creator) { + allow_empty_last_param = false; syntax = ""; } - CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE + CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE { User* target = ServerInstance->FindNickOnly(parameters[0]); - if ((!target) || (target->registered != REG_ALL)) { user->WriteNumeric(Numerics::NoSuchNick(parameters[0])); From b191657921845a26128e910bfff0f21251e98ee4 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 14:11:12 +0000 Subject: [PATCH 07/10] Allow using SSLINFO on channels. --- src/modules/m_sslinfo.cpp | 87 +++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index 4623b318f..2809731be 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -146,20 +146,87 @@ class UserCertificateAPIImpl : public UserCertificateAPIBase class CommandSSLInfo : public SplitCommand { + private: + ChanModeReference sslonlymode; + + void HandleUserInternal(LocalUser* source, User* target, bool verbose) + { + ssl_cert* cert = sslapi.GetCertificate(target); + if (!cert) + { + source->WriteNotice(InspIRCd::Format("*** %s is not connected using TLS (SSL).", target->nick.c_str())); + } + else if (cert->GetError().length()) + { + source->WriteNotice(InspIRCd::Format("*** %s is connected using TLS (SSL) but has not specified a valid client certificate (%s).", + target->nick.c_str(), cert->GetError().c_str())); + } + else if (!verbose) + { + source->WriteNotice(InspIRCd::Format("*** %s is connected using TLS (SSL) with a valid client certificate (%s).", + target->nick.c_str(), cert->GetFingerprint().c_str())); + } + else + { + source->WriteNotice("*** Distinguished Name: " + cert->GetDN()); + source->WriteNotice("*** Issuer: " + cert->GetIssuer()); + source->WriteNotice("*** Key Fingerprint: " + cert->GetFingerprint()); + } + } + + CmdResult HandleChannel(LocalUser* source, const std::string& channel) + { + Channel* chan = ServerInstance->FindChan(channel); + if (!chan) + { + source->WriteNumeric(Numerics::NoSuchChannel(channel)); + return CMD_FAILURE; + } + + if (operonlyfp && !source->IsOper()) + { + source->WriteNumeric(ERR_NOPRIVILEGES, "You must be a server operator to view TLS (SSL) client certificate information for channels."); + return CMD_FAILURE; + } + + if (!source->IsOper() && chan->GetPrefixValue(source) < OP_VALUE) + { + source->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, "You must be a channel operator."); + return CMD_FAILURE; + } + + if (sslonlymode) + { + source->WriteNotice(InspIRCd::Format("*** %s %s have channel mode +%c (%s) set.", + chan->name.c_str(), chan->IsModeSet(sslonlymode) ? "does" : "does not", + sslonlymode->GetModeChar(), sslonlymode->name.c_str())); + } + + const Channel::MemberMap& userlist = chan->GetUsers(); + for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i) + HandleUserInternal(source, i->first, false); + + return CMD_SUCCESS; + } + public: UserCertificateAPIImpl sslapi; bool operonlyfp; CommandSSLInfo(Module* Creator) : SplitCommand(Creator, "SSLINFO", 1) + , sslonlymode(Creator, "sslonly") , sslapi(Creator) { allow_empty_last_param = false; - syntax = ""; + syntax = ""; } CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE { + if (ServerInstance->IsChannel(parameters[0])) + return HandleChannel(user, parameters[0]); + User* target = ServerInstance->FindNickOnly(parameters[0]); if ((!target) || (target->registered != REG_ALL)) { @@ -173,23 +240,7 @@ class CommandSSLInfo : public SplitCommand return CMD_FAILURE; } - ssl_cert* cert = sslapi.GetCertificate(target); - if (!cert) - { - user->WriteNotice(InspIRCd::Format("*** %s is not connected using TLS (SSL).", target->nick.c_str())); - } - else if (cert->GetError().length()) - { - user->WriteNotice(InspIRCd::Format("*** %s is connected using TLS (SSL) but has not specified a valid client certificate (%s).", - target->nick.c_str(), cert->GetError().c_str())); - } - else - { - user->WriteNotice("*** Distinguished Name: " + cert->GetDN()); - user->WriteNotice("*** Issuer: " + cert->GetIssuer()); - user->WriteNotice("*** Key Fingerprint: " + cert->GetFingerprint()); - } - + HandleUserInternal(user, target, true); return CMD_SUCCESS; } }; From a235e4356074f10b6946ee4019769a707f4f6e1d Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 14:13:36 +0000 Subject: [PATCH 08/10] Move SSLINFO code for users to its own function and refactor. --- src/modules/m_sslinfo.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index 2809731be..d51a691c6 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -174,6 +174,25 @@ class CommandSSLInfo : public SplitCommand } } + CmdResult HandleUser(LocalUser* source, const std::string& nick) + { + User* target = ServerInstance->FindNickOnly(nick); + if (!target || target->registered != REG_ALL) + { + source->WriteNumeric(Numerics::NoSuchNick(nick)); + return CMD_FAILURE; + } + + if (operonlyfp && !source->IsOper() && source != target) + { + source->WriteNumeric(ERR_NOPRIVILEGES, "You must be a server operator to view TLS (SSL) client certificate information for other users."); + return CMD_FAILURE; + } + + HandleUserInternal(source, target, true); + return CMD_SUCCESS; + } + CmdResult HandleChannel(LocalUser* source, const std::string& channel) { Channel* chan = ServerInstance->FindChan(channel); @@ -226,22 +245,8 @@ class CommandSSLInfo : public SplitCommand { if (ServerInstance->IsChannel(parameters[0])) return HandleChannel(user, parameters[0]); - - User* target = ServerInstance->FindNickOnly(parameters[0]); - if ((!target) || (target->registered != REG_ALL)) - { - user->WriteNumeric(Numerics::NoSuchNick(parameters[0])); - return CMD_FAILURE; - } - - if (operonlyfp && !user->IsOper() && target != user) - { - user->WriteNotice("*** You cannot view TLS (SSL) client certificate information for other users"); - return CMD_FAILURE; - } - - HandleUserInternal(user, target, true); - return CMD_SUCCESS; + else + return HandleUser(user, parameters[0]); } }; From 5b21a60a9d96827d6822c56b2dfdf08dbce5867f Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 17:00:19 +0000 Subject: [PATCH 09/10] Fix using the TR1 headers on compilers that support C++17. --- include/compat.h | 2 +- make/test/compiler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/compat.h b/include/compat.h index 47fda1e23..886805243 100644 --- a/include/compat.h +++ b/include/compat.h @@ -24,7 +24,7 @@ * Some implementations of the C++11 standard library are incomplete so we use * the implementation of the same types from C++ Technical Report 1 instead. */ -#if defined _LIBCPP_VERSION || defined _WIN32 +#if defined _LIBCPP_VERSION || defined _WIN32 || __cplusplus >= 201103L # define TR1NS std # include # include diff --git a/make/test/compiler.cpp b/make/test/compiler.cpp index 5adf83df8..524874ed6 100644 --- a/make/test/compiler.cpp +++ b/make/test/compiler.cpp @@ -19,7 +19,7 @@ #include -#if defined _LIBCPP_VERSION +#if defined _LIBCPP_VERSION || __cplusplus >= 201103L # include # include # include From aa4c7489b708eb54856871ecdf2bbde99fde92bc Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 1 Feb 2021 18:10:53 +0000 Subject: [PATCH 10/10] Duplicate the stdout file handle when used for logging. Failure to do this may result in a crash on shutdown when started in debug mode. --- src/inspircd.cpp | 3 ++- win/inspircd_win32wrapper.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/inspircd.cpp b/src/inspircd.cpp index ba7e08eff..8cbb83d6f 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -524,7 +524,8 @@ InspIRCd::InspIRCd(int argc, char** argv) if (Config->cmdline.forcedebug) { - FileWriter* fw = new FileWriter(stdout, 1); + FILE* newstdout = fdopen(dup(STDOUT_FILENO), "w"); + FileWriter* fw = new FileWriter(newstdout, 1); FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw); Logs->AddLogTypes("*", fls, true); } diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h index 7366fc336..368504d61 100644 --- a/win/inspircd_win32wrapper.h +++ b/win/inspircd_win32wrapper.h @@ -102,6 +102,8 @@ typedef SSIZE_T ssize_t; #define popen _popen #define pclose _pclose #define getpid _getpid +#define dup _dup +#define fdopen _fdopen // warning: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' // Normally, this is a huge problem, but due to our new/delete remap, we can ignore it.