From fddef325ba633158875a88c72de2eb3b999d71de Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 10 Nov 2021 13:10:40 +0000 Subject: Implement support for WebIRC gateways sending client fingerprints. --- src/modules/m_sslinfo.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index 8e3399e85..0fae5d821 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -252,6 +252,7 @@ class ModuleSSLInfo { private: CommandSSLInfo cmd; + std::string hash; bool MatchFP(ssl_cert* const cert, const std::string& fp) const { @@ -271,6 +272,7 @@ class ModuleSSLInfo { ConfigTag* tag = ServerInstance->Config->ConfValue("sslinfo"); cmd.operonlyfp = tag->getBool("operonly"); + hash = tag->getString("hash"); } Version GetVersion() CXX11_OVERRIDE @@ -436,11 +438,29 @@ class ModuleSSLInfo // Create a fake ssl_cert for the user. ssl_cert* cert = new ssl_cert; - cert->error = "WebIRC users can not specify valid certs yet"; - cert->invalid = true; - cert->revoked = true; - cert->trusted = false; - cert->unknownsigner = true; + if (!hash.empty()) + { + iter = flags->find("certfp-" + hash); + if (iter != flags->end() && !iter->second.empty()) + { + // If the gateway specifies this flag we put all trust onto them + // for having validated the client certificate. This is probably + // ill-advised but there's not much else we can do. + cert->fingerprint = iter->second; + cert->dn = "(unknown)"; + cert->invalid = false; + cert->issuer = "(unknown)"; + cert->trusted = true; + cert->unknownsigner = false; + } + } + + if (cert->fingerprint.empty()) + { + cert->error = "WebIRC gateway did not send a client fingerprint"; + cert->revoked = true; + } + cmd.sslapi.SetCertificate(user, cert); } }; -- cgit v1.3.1-10-gc9f91 From 87d3512de59189b6a1fd4ff42b64f15a1ff12724 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 10 Nov 2021 18:22:31 +0000 Subject: Allow configuring which options to trust from a WebIRC gateway. --- src/modules/m_cgiirc.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 37609bec0..8207bc11a 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -81,14 +81,21 @@ class WebIRCHost std::string fingerprint; std::string password; std::string passhash; + TokenList trustedflags; public: - WebIRCHost(const MaskList& masks, const std::string& fp, const std::string& pass, const std::string& hash) + WebIRCHost(const MaskList& masks, const std::string& fp, const std::string& pass, const std::string& hash, const std::string& flags) : hostmasks(masks) , fingerprint(fp) , password(pass) , passhash(hash) { + trustedflags.AddList(flags); + } + + bool IsFlagTrusted(const std::string& flag) const + { + return trustedflags.Contains(flag); } bool Matches(LocalUser* user, const std::string& pass, UserCertificateAPI& sslapi) const @@ -254,6 +261,9 @@ class CommandWebIRC : public SplitCommand const bool hasflags = (parameters.size() > 4); if (hasflags) { + std::string flagname; + std::string flagvalue; + // Parse the flags. irc::spacesepstream flagstream(parameters[4]); for (std::string flag; flagstream.GetToken(flag); ) @@ -262,14 +272,19 @@ class CommandWebIRC : public SplitCommand const size_t separator = flag.find('='); if (separator == std::string::npos) { - flags[flag]; - continue; + // It does not; just use the flag. + flagname = flag; + flagvalue.clear(); + } + else + { + // It does; extract the value. + flagname = flag.substr(0, separator); + flagvalue = flag.substr(separator + 1); } - // The flag has a value! - const std::string key = flag.substr(0, separator); - const std::string value = flag.substr(separator + 1); - flags[key] = value; + if (iter->IsFlagTrusted(flagname)) + flags[flagname] = flagvalue; } } @@ -379,6 +394,7 @@ class ModuleCgiIRC const std::string fingerprint = tag->getString("fingerprint"); const std::string password = tag->getString("password"); const std::string passwordhash = tag->getString("hash", "plaintext", 1); + const std::string trustedflags = tag->getString("trustedflags", "*", 1); // WebIRC blocks require a password. if (fingerprint.empty() && password.empty()) @@ -390,7 +406,7 @@ class ModuleCgiIRC tag->getTagLocation().c_str()); } - webirchosts.push_back(WebIRCHost(masks, fingerprint, password, passwordhash)); + webirchosts.push_back(WebIRCHost(masks, fingerprint, password, passwordhash, trustedflags)); } else { -- cgit v1.3.1-10-gc9f91