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";
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}
@ -454,7 +453,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}

View File

@ -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@"

View File

@ -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@";

View File

@ -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@"
@ -222,7 +221,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)
@ -262,7 +260,6 @@ endif
@echo "* INSTALL COMPLETE! *"
@echo "*************************************"
@echo 'Paths:'
@echo ' Base install:' $(BASE)
@echo ' Configuration:' $(CONPATH)
@echo ' Binaries:' $(BINPATH)
@echo ' Modules:' $(MODPATH)
@ -318,7 +315,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"'

View File

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

View File

@ -519,7 +519,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);
}

View File

@ -144,54 +144,110 @@ class UserCertificateAPIImpl : public UserCertificateAPIBase
}
};
class CommandSSLInfo : public Command
class CommandSSLInfo : public SplitCommand
{
public:
UserCertificateAPIImpl sslapi;
private:
ChanModeReference sslonlymode;
CommandSSLInfo(Module* Creator)
: Command(Creator, "SSLINFO", 1)
, sslapi(Creator)
void HandleUserInternal(LocalUser* source, User* target, bool verbose)
{
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);
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())
{
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()));
}
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
{
user->WriteNotice("*** Distinguished Name: " + cert->GetDN());
user->WriteNotice("*** Issuer: " + cert->GetIssuer());
user->WriteNotice("*** Key Fingerprint: " + cert->GetFingerprint());
source->WriteNotice("*** Distinguished Name: " + cert->GetDN());
source->WriteNotice("*** Issuer: " + cert->GetIssuer());
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;
}
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
@ -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
{
ssl_cert* cert = cmd.sslapi.GetCertificate(whois.GetTarget());
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()));
}
}

View File

@ -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.