X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_sslmodes.cpp;h=fda90c3d8278c9b77cb934c6690cfec7be84cf0b;hb=HEAD;hp=dc0063d29b0bf2260548f115521ebbda7a9bbd82;hpb=124c17e14134a4999afc1a5e981ab7c75b3694b9;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_sslmodes.cpp b/src/modules/m_sslmodes.cpp index dc0063d29..fda90c3d8 100644 --- a/src/modules/m_sslmodes.cpp +++ b/src/modules/m_sslmodes.cpp @@ -1,12 +1,16 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2013 Shawn Smith - * Copyright (C) 2009 Daniel De Graaf - * Copyright (C) 2007 Robin Burchell + * Copyright (C) 2020 Matt Schatz + * Copyright (C) 2013, 2017-2020 Sadie Powell + * Copyright (C) 2013 Shawn Smith + * Copyright (C) 2012-2014 Attila Molnar + * Copyright (C) 2012 Robby + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2009 Uli Schlachter + * Copyright (C) 2008 Robin Burchell * Copyright (C) 2007 Dennis Friis - * Copyright (C) 2006 Craig Edwards - * Copyright (C) 2006 Oliver Lupton + * Copyright (C) 2006-2007, 2010 Craig Edwards * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -23,27 +27,18 @@ #include "inspircd.h" +#include "modules/ctctags.h" #include "modules/ssl.h" enum { // From UnrealIRCd. ERR_SECUREONLYCHAN = 489, + + // InspIRCd-specific. ERR_ALLMUSTSSL = 490 }; -namespace -{ - bool IsSSLUser(UserCertificateAPI& api, User* user) - { - if (!api) - return false; - - ssl_cert* cert = api->GetCertificate(user); - return (cert != NULL); - } -} - /** Handle channel mode +z */ class SSLMode : public ModeHandler @@ -67,17 +62,25 @@ class SSLMode : public ModeHandler if (IS_LOCAL(source)) { if (!API) + { + source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, "Unable to determine whether all members of the channel are connected via TLS (SSL)"); return MODEACTION_DENY; + } + unsigned long nonssl = 0; const Channel::MemberMap& userlist = channel->GetUsers(); for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i) { ssl_cert* cert = API->GetCertificate(i->first); if (!cert && !i->first->server->IsULine()) - { - source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, "all members of the channel must be connected via SSL"); - return MODEACTION_DENY; - } + nonssl++; + } + + if (nonssl) + { + source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, InspIRCd::Format("All members of the channel must be connected via TLS (SSL) (%lu/%lu are non-TLS (SSL))", + nonssl, static_cast(userlist.size()))); + return MODEACTION_DENY; } } channel->SetMode(this, true); @@ -119,31 +122,20 @@ class SSLModeUser : public ModeHandler ModeAction OnModeChange(User* user, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE { - if (adding) - { - if (!dest->IsModeSet(this)) - { - if (!IsSSLUser(API, user)) - return MODEACTION_DENY; + if (adding == dest->IsModeSet(this)) + return MODEACTION_DENY; - dest->SetMode(this, true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet(this)) - { - dest->SetMode(this, false); - return MODEACTION_ALLOW; - } - } + if (adding && IS_LOCAL(user) && (!API || !API->GetCertificate(user))) + return MODEACTION_DENY; - return MODEACTION_DENY; + dest->SetMode(this, adding); + return MODEACTION_ALLOW; } }; -class ModuleSSLModes : public Module +class ModuleSSLModes + : public Module + , public CTCTags::EventListener { private: UserCertificateAPI api; @@ -152,7 +144,8 @@ class ModuleSSLModes : public Module public: ModuleSSLModes() - : api(this) + : CTCTags::EventListener(this) + , api(this) , sslm(this, api) , sslquery(this, api) { @@ -163,18 +156,14 @@ class ModuleSSLModes : public Module if(chan && chan->IsModeSet(sslm)) { if (!api) - return MOD_RES_DENY; - - ssl_cert* cert = api->GetCertificate(user); - if (cert) { - // Let them in - return MOD_RES_PASSTHRU; + user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; unable to determine if you are a TLS (SSL) user (+z is set)"); + return MOD_RES_DENY; } - else + + if (!api->GetCertificate(user)) { - // Deny - user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; SSL users only (+z)"); + user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; TLS (SSL) users only (+z is set)"); return MOD_RES_DENY; } } @@ -182,33 +171,33 @@ class ModuleSSLModes : public Module return MOD_RES_PASSTHRU; } - ModResult OnUserPreMessage(User* user, const MessageTarget& msgtarget, MessageDetails& details) CXX11_OVERRIDE + ModResult HandleMessage(User* user, const MessageTarget& msgtarget) { if (msgtarget.type != MessageTarget::TYPE_USER) return MOD_RES_PASSTHRU; User* target = msgtarget.Get(); - /* If one or more of the parties involved is a ulined service, we wont stop it. */ + /* If one or more of the parties involved is a ulined service, we won't stop it. */ if (user->server->IsULine() || target->server->IsULine()) return MOD_RES_PASSTHRU; /* If the target is +z */ if (target->IsModeSet(sslquery)) { - if (!IsSSLUser(api, user)) + if (!api || !api->GetCertificate(user)) { /* The sending user is not on an SSL connection */ - user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You are not permitted to send private messages to this user (+z set)"); + user->WriteNumeric(Numerics::CannotSendTo(target, "messages", &sslquery)); return MOD_RES_DENY; } } /* If the user is +z */ else if (user->IsModeSet(sslquery)) { - if (!IsSSLUser(api, target)) + if (!api || !api->GetCertificate(target)) { - user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You must remove usermode 'z' before you are able to send private messages to a non-ssl user."); + user->WriteNumeric(Numerics::CannotSendTo(target, "messages", &sslquery, true)); return MOD_RES_DENY; } } @@ -216,15 +205,22 @@ class ModuleSSLModes : public Module return MOD_RES_PASSTHRU; } + ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE + { + return HandleMessage(user, target); + } + + ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) CXX11_OVERRIDE + { + return HandleMessage(user, target); + } + ModResult OnCheckBan(User *user, Channel *c, const std::string& mask) CXX11_OVERRIDE { if ((mask.length() > 2) && (mask[0] == 'z') && (mask[1] == ':')) { - if (!api) - return MOD_RES_DENY; - - ssl_cert* cert = api->GetCertificate(user); - if (cert && InspIRCd::Match(cert->GetFingerprint(), mask.substr(2))) + const std::string fp = api ? api->GetFingerprint(user) : ""; + if (!fp.empty() && InspIRCd::Match(fp, mask.substr(2))) return MOD_RES_DENY; } return MOD_RES_PASSTHRU; @@ -237,7 +233,7 @@ class ModuleSSLModes : public Module Version GetVersion() CXX11_OVERRIDE { - return Version("Provides user and channel mode +z to allow for SSL-only channels, queries and notices.", VF_VENDOR); + return Version("Adds channel mode z (sslonly) which prevents users who are not connecting using TLS (SSL) from joining the channel and user mode z (sslqueries) to prevent messages from non-TLS (SSL) users.", VF_VENDOR); } };