Merge branch 'insp3' into master.

This commit is contained in:
Sadie Powell 2021-02-01 18:50:31 +00:00
commit 9ef90acced
8 changed files with 108 additions and 47 deletions

2
configure vendored
View File

@ -321,7 +321,6 @@ EOW
my $question = <<"EOQ"; my $question = <<"EOQ";
Currently, InspIRCd is configured with the following paths: Currently, InspIRCd is configured with the following paths:
<|BOLD Base:|> $config{BASE_DIR}
<|BOLD Binary:|> $config{BINARY_DIR} <|BOLD Binary:|> $config{BINARY_DIR}
<|BOLD Config:|> $config{CONFIG_DIR} <|BOLD Config:|> $config{CONFIG_DIR}
<|BOLD Data:|> $config{DATA_DIR} <|BOLD Data:|> $config{DATA_DIR}
@ -454,7 +453,6 @@ push @makeargs, "-j${\(get_cpu_count() + 1)}";
print console_format <<"EOM"; print console_format <<"EOM";
<|GREEN Paths:|> <|GREEN Paths:|>
<|GREEN Base:|> $config{BASE_DIR}
<|GREEN Binary:|> $config{BINARY_DIR} <|GREEN Binary:|> $config{BINARY_DIR}
<|GREEN Config:|> $config{CONFIG_DIR} <|GREEN Config:|> $config{CONFIG_DIR}
<|GREEN Data:|> $config{DATA_DIR} <|GREEN Data:|> $config{DATA_DIR}

View File

@ -29,7 +29,7 @@
#define INSPIRCD_VERSION_BEFORE(MAJOR, MINOR) (((@VERSION_MAJOR@ << 8) | @VERSION_MINOR@) < ((MAJOR << 8) | (MINOR))) #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. */ /** 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. */ /** The default location that config files are stored in. */
#define INSPIRCD_CONFIG_PATH "@CONFIG_DIR@" #define INSPIRCD_CONFIG_PATH "@CONFIG_DIR@"

View File

@ -62,11 +62,10 @@ use constant {
}; };
my $scriptpath = "@SCRIPT_DIR@"; my $scriptpath = "@SCRIPT_DIR@";
my $basepath = "@BASE_DIR@";
my $confpath = "@CONFIG_DIR@"; my $confpath = "@CONFIG_DIR@";
my $binpath = "@BINARY_DIR@"; my $binpath = "@BINARY_DIR@";
my $runtimedir = "@RUNTIME_DIR@"; my $runtimedir = "@RUNTIME_DIR@";
my $valgrindlogpath = "$basepath/valgrindlogs"; my $valgrindlogpath = "@LOG_DIR@/valgrind";
my $executable = "inspircd"; my $executable = "inspircd";
my $version = "@VERSION_FULL@"; my $version = "@VERSION_FULL@";
my $uid = "@UID@"; my $uid = "@UID@";

View File

@ -51,7 +51,6 @@ CORELDFLAGS = -rdynamic -L.
PICLDFLAGS = -fPIC -shared -rdynamic PICLDFLAGS = -fPIC -shared -rdynamic
DESTDIR := $(if $(DESTDIR),$(DESTDIR),"@DESTDIR|@") DESTDIR := $(if $(DESTDIR),$(DESTDIR),"@DESTDIR|@")
BASE = "$(DESTDIR)@BASE_DIR@"
BINPATH = "$(DESTDIR)@BINARY_DIR@" BINPATH = "$(DESTDIR)@BINARY_DIR@"
CONPATH = "$(DESTDIR)@CONFIG_DIR@" CONPATH = "$(DESTDIR)@CONFIG_DIR@"
DATPATH = "$(DESTDIR)@DATA_DIR@" DATPATH = "$(DESTDIR)@DATA_DIR@"
@ -222,7 +221,6 @@ finishmessage: target
@echo "*************************************" @echo "*************************************"
install: target 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) $(BINPATH)
@-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(CONPATH) @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(CONPATH)
@-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(DATPATH) @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(DATPATH)
@ -262,7 +260,6 @@ endif
@echo "* INSTALL COMPLETE! *" @echo "* INSTALL COMPLETE! *"
@echo "*************************************" @echo "*************************************"
@echo 'Paths:' @echo 'Paths:'
@echo ' Base install:' $(BASE)
@echo ' Configuration:' $(CONPATH) @echo ' Configuration:' $(CONPATH)
@echo ' Binaries:' $(BINPATH) @echo ' Binaries:' $(BINPATH)
@echo ' Modules:' $(MODPATH) @echo ' Modules:' $(MODPATH)
@ -318,7 +315,6 @@ help:
@echo 'Targets:' @echo 'Targets:'
@echo ' all Complete build of InspIRCd, without installing (default)' @echo ' all Complete build of InspIRCd, without installing (default)'
@echo ' install Build and install InspIRCd to the directory chosen in ./configure' @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 ' debug Compile a debug build. Equivalent to "make D=1 all"'
@echo '' @echo ''
@echo ' INSPIRCD_TARGET=target Builds a user-specified target, such as "inspircd" or "core_dns"' @echo ' INSPIRCD_TARGET=target Builds a user-specified target, such as "inspircd" or "core_dns"'

View File

@ -32,27 +32,31 @@ CommandServList::CommandServList(Module* parent)
, invisiblemode(parent, "invisible") , invisiblemode(parent, "invisible")
{ {
allow_empty_last_param = false; allow_empty_last_param = false;
syntax = { "[<mask>]" }; syntax = { "[<mask> [<type>]]" };
} }
CmdResult CommandServList::HandleLocal(LocalUser* user, const Params& parameters) CmdResult CommandServList::HandleLocal(LocalUser* user, const Params& parameters)
{ {
const std::string& mask = parameters.empty() ? "*" : parameters[0]; const std::string& mask = parameters.empty() ? "*" : parameters[0];
const bool has_type = parameters.size() > 1;
for (auto* serviceuser : ServerInstance->Users.all_services) for (auto* serviceuser : ServerInstance->Users.all_services)
{ {
if (serviceuser->IsModeSet(invisiblemode) || !InspIRCd::Match(serviceuser->nick, mask)) if (serviceuser->IsModeSet(invisiblemode) || !InspIRCd::Match(serviceuser->nick, mask))
continue; continue;
if (has_type && (!user->IsOper() || !InspIRCd::Match(user->oper->name, parameters[2 ])))
continue;
Numeric::Numeric numeric(RPL_SERVLIST); Numeric::Numeric numeric(RPL_SERVLIST);
numeric numeric
.push(serviceuser->nick) .push(serviceuser->nick)
.push(serviceuser->server->GetName()) .push(serviceuser->server->GetName())
.push(mask) .push("*")
.push(0) .push(serviceuser->IsOper() ? serviceuser->oper->name : "*")
.push(0) .push(0)
.push(serviceuser->GetRealName()); .push(serviceuser->GetRealName());
user->WriteNumeric(numeric); 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 CmdResult::SUCCESS; return CmdResult::SUCCESS;
} }

View File

@ -519,7 +519,8 @@ InspIRCd::InspIRCd(int argc, char** argv)
if (Config->cmdline.forcedebug) 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); FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw);
Logs.AddLogTypes("*", fls, true); Logs.AddLogTypes("*", fls, true);
} }

View File

@ -144,54 +144,110 @@ class UserCertificateAPIImpl : public UserCertificateAPIBase
} }
}; };
class CommandSSLInfo : public Command class CommandSSLInfo : public SplitCommand
{ {
public: private:
UserCertificateAPIImpl sslapi; ChanModeReference sslonlymode;
CommandSSLInfo(Module* Creator) void HandleUserInternal(LocalUser* source, User* target, bool verbose)
: Command(Creator, "SSLINFO", 1)
, sslapi(Creator)
{ {
syntax = { "<nick>" };
}
CmdResult Handle(User* user, const Params& parameters) override
{
User* target = ServerInstance->Users.FindNick(parameters[0]);
if ((!target) || (target->registered != REG_ALL))
{
user->WriteNumeric(Numerics::NoSuchNick(parameters[0]));
return CmdResult::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");
return CmdResult::FAILURE;
}
ssl_cert* cert = sslapi.GetCertificate(target); ssl_cert* cert = sslapi.GetCertificate(target);
if (!cert) if (!cert)
{ {
user->WriteNotice(InspIRCd::Format("*** %s is not connected using TLS (SSL).", target->nick.c_str())); source->WriteNotice(InspIRCd::Format("*** %s is not connected using TLS (SSL).", target->nick.c_str()));
} }
else if (cert->GetError().length()) else if (cert->GetError().length())
{ {
user->WriteNotice(InspIRCd::Format("*** %s is connected using TLS (SSL) but has not specified a valid client certificate (%s).", 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())); 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 else
{ {
user->WriteNotice("*** Distinguished Name: " + cert->GetDN()); source->WriteNotice("*** Distinguished Name: " + cert->GetDN());
user->WriteNotice("*** Issuer: " + cert->GetIssuer()); source->WriteNotice("*** Issuer: " + cert->GetIssuer());
user->WriteNotice("*** Key Fingerprint: " + cert->GetFingerprint()); source->WriteNotice("*** Key Fingerprint: " + cert->GetFingerprint());
}
}
CmdResult HandleUser(LocalUser* source, const std::string& nick)
{
User* target = ServerInstance->Users.FindNick(nick);
if (!target || target->registered != REG_ALL)
{
source->WriteNumeric(Numerics::NoSuchNick(nick));
return CmdResult::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 CmdResult::FAILURE;
}
HandleUserInternal(source, target, true);
return CmdResult::SUCCESS; return CmdResult::SUCCESS;
} }
CmdResult HandleChannel(LocalUser* source, const std::string& channel)
{
Channel* chan = ServerInstance->FindChan(channel);
if (!chan)
{
source->WriteNumeric(Numerics::NoSuchChannel(channel));
return CmdResult::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 CmdResult::FAILURE;
}
if (!source->IsOper() && chan->GetPrefixValue(source) < OP_VALUE)
{
source->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, "You must be a channel operator.");
return CmdResult::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 CmdResult::SUCCESS;
}
public:
UserCertificateAPIImpl sslapi;
bool operonlyfp;
CommandSSLInfo(Module* Creator)
: SplitCommand(Creator, "SSLINFO", 1)
, sslonlymode(Creator, "sslonly")
, sslapi(Creator)
{
allow_empty_last_param = false;
syntax = { "<channel|nick>" };
}
CmdResult HandleLocal(LocalUser* user, const Params& parameters) override
{
if (ServerInstance->IsChannel(parameters[0]))
return HandleChannel(user, parameters[0]);
else
return HandleUser(user, parameters[0]);
}
}; };
class ModuleSSLInfo class ModuleSSLInfo
@ -218,14 +274,19 @@ class ModuleSSLInfo
{ {
} }
void ReadConfig(ConfigStatus& status) override
{
auto tag = ServerInstance->Config->ConfValue("sslinfo");
cmd.operonlyfp = tag->getBool("operonly");
}
void OnWhois(Whois::Context& whois) override void OnWhois(Whois::Context& whois) override
{ {
ssl_cert* cert = cmd.sslapi.GetCertificate(whois.GetTarget()); ssl_cert* cert = cmd.sslapi.GetCertificate(whois.GetTarget());
if (cert) if (cert)
{ {
whois.SendLine(RPL_WHOISSECURE, "is using a secure connection"); whois.SendLine(RPL_WHOISSECURE, "is using a secure connection");
bool operonlyfp = ServerInstance->Config->ConfValue("sslinfo")->getBool("operonly"); if ((!cmd.operonlyfp || whois.IsSelfWhois() || whois.GetSource()->IsOper()) && !cert->fingerprint.empty())
if ((!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())); whois.SendLine(RPL_WHOISCERTFP, InspIRCd::Format("has TLS (SSL) client certificate fingerprint %s", cert->fingerprint.c_str()));
} }
} }

View File

@ -102,6 +102,8 @@ typedef SSIZE_T ssize_t;
#define popen _popen #define popen _popen
#define pclose _pclose #define pclose _pclose
#define getpid _getpid #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' // 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. // Normally, this is a huge problem, but due to our new/delete remap, we can ignore it.