]> jfr.im git - irc/evilnet/znc.git/commitdiff
Merge evilnet patches into master/tag 'znc-1.6.5'
authorMrLenin <redacted>
Sat, 25 Mar 2017 23:44:25 +0000 (19:44 -0400)
committerMrLenin <redacted>
Sat, 25 Mar 2017 23:44:25 +0000 (19:44 -0400)
Updated internal server name from "irc.znc.in" to "znc.afternet.org"

15 files changed:
include/znc/IRCSock.h
include/znc/MD5.h
modules/cyrusauth.cpp
modules/missingmotd.cpp
modules/modules_online.cpp
modules/partyline.cpp
modules/sasl.cpp
modules/webadmin.cpp
src/Client.cpp
src/ClientCommand.cpp
src/IRCNetwork.cpp
src/IRCSock.cpp
src/Listener.cpp
src/MD5.cpp
src/User.cpp

index d9af1b0187626fafa89c7446ab14ca0f053609be..c0c3c85bde29fd9572a4b9d246cda6c6841640b9 100644 (file)
@@ -63,6 +63,7 @@ public:
        virtual void SockError(int iErrno, const CString& sDescription);
        virtual void Timeout();
        virtual void ReachedMaxBuffer();
+       void Register();
 
        void PutIRC(const CString& sLine);
        void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only
index f2cde0eeb0433d34326d19e705c4e4050bc160fc..d9eddc4185dd9fe51ab87de7a5f7da844ba87c4d 100644 (file)
@@ -26,6 +26,7 @@ md5_context;
 class CMD5 {
 protected:
        char m_szMD5[33];
+       unsigned char* m_pszMD5;
 
 public:
        CMD5();
@@ -44,6 +45,7 @@ public:
        }
 
        char* MakeHash(const char* szText, uint32 nTextLen);
+       unsigned char* GetHash();
 
 protected:
        void md5_starts( md5_context *ctx ) const;
index cba01a0b8984cd8c5b2b9c8dcbd86b55f8ae673a..8dc025fc95fd56bf3171236f52a28d3edcf2eaf9 100644 (file)
  */
 
 #include <znc/znc.h>
+#include <znc/IRCNetwork.h>
 #include <znc/User.h>
+#include <znc/MD5.h>
 
 #include <sasl/sasl.h>
+#include <sstream>
 
 class CSASLAuthMod : public CModule {
 public:
        MODCONSTRUCTOR(CSASLAuthMod) {
                m_Cache.SetTTL(60000/*ms*/);
-
+               m_bWebIrcEnabled = false;
                m_cbs[0].id = SASL_CB_GETOPT;
                m_cbs[0].proc = reinterpret_cast<int(*)()>(CSASLAuthMod::getopt);
                m_cbs[0].context = this;
@@ -44,6 +47,48 @@ public:
                AddCommand("CloneUser",        static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::CloneUserCommand),
                        "[username]");
                AddCommand("DisableCloneUser", static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::DisableCloneUserCommand));
+               AddCommand("SetImpersonateAccount",         static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetImpersonateAccount),
+                       "username password", "Set the username and password for the SASL Impersonaton Account");
+               AddCommand("SetWebIrc",        static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetWebIrc),
+                       "username password", "Set the username and password for WebIRC");
+               AddCommand("SetWebIrcHost",        static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetWebIrcHost),
+                       "hostname", "Set the hostname used for WebIRC");
+               AddCommand("SetUserSalt",      static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetUserSalt),
+                       "salt", "Set the salt used when hashing usernames");
+               AddCommand("SetNetworkName",        static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetNetworkName),
+                       "network", "Set the network name used for newly created accounts");
+               AddCommand("SetServer",        static_cast<CModCommand::ModCmdFunc>(&CSASLAuthMod::SetServer),
+                       "server port ssl", "Set the server and port used for newly created accounts");
+       }
+       void SetServer(const CString& sLine) {
+               SetNV("server", sLine.Token(1));
+               SetNV("port", sLine.Token(2));
+               SetNV("ssl", sLine.Token(3));
+               PutModule("Server and port used for newly created accounts has been set to [" + GetNV("server") + ":" + (GetNV("ssl").ToBool() ? "+" + GetNV("port") : GetNV("port")) + "]");
+       }
+       void SetNetworkName(const CString& sLine) {
+               SetNV("networkname", sLine.Token(1));
+               PutModule("Network name used for newly created accounts has been set to [" + GetNV("networkname") + "]");
+       }
+       void SetImpersonateAccount(const CString& sLine) {
+               SetNV("impersonationusername", sLine.Token(1));
+               SetNV("impersonationpassword", sLine.Token(2));
+               PutModule("SASL Impersonaton Account Username has been set to [" + GetNV("impersonationusername") + "]");
+               PutModule("SASL Impersonaton Account Password has been set to [" + GetNV("impersonationpassword") + "]");
+       }
+       void SetWebIrc(const CString& sLine) {
+               SetNV("webircusername", sLine.Token(1));
+               SetNV("webircpassword", sLine.Token(2));
+               PutModule("WebIRC Username has been set to [" + GetNV("webircusername") + "]");
+               PutModule("WebIRC Password has been set to [" + GetNV("webircpassword") + "]");
+       }
+       void SetWebIrcHost(const CString& sLine) {
+               SetNV("webirchost", sLine);
+               PutModule("WebIRC hostname has been set to [" + GetNV("webirchost") + "]");
+       }
+       void SetUserSalt(const CString& sLine) {
+               SetNV("usersalt", sLine.Token(1));
+               PutModule("User salt has been set to [" + GetNV("usersalt") + "]");
        }
 
        virtual ~CSASLAuthMod() {
@@ -67,8 +112,14 @@ public:
                        if (it->Equals("saslauthd") || it->Equals("auxprop")) {
                                m_sMethod += *it + " ";
                        } else {
-                               CUtils::PrintError("Ignoring invalid SASL pwcheck method: " + *it);
-                               sMessage = "Ignored invalid SASL pwcheck method";
+                               if (it->Equals("webirc")) {
+                                       m_bWebIrcEnabled = true;
+                               } else if (it->Equals("impersonation")) {
+                                       m_bSaslImpersonateEnabled = true;
+                               } else {
+                                   CUtils::PrintError("Ignoring invalid SASL pwcheck method: " + *it);
+                                   sMessage = "Ignored invalid SASL pwcheck method";
+                           }
                        }
                }
 
@@ -90,7 +141,7 @@ public:
        virtual EModRet OnLoginAttempt(std::shared_ptr<CAuthBase> Auth) override {
                const CString& sUsername = Auth->GetUsername();
                const CString& sPassword = Auth->GetPassword();
-               CUser *pUser(CZNC::Get().FindUser(sUsername));
+               CUser *pUser(CZNC::Get().FindUser(sUsername.AsLower()));
                sasl_conn_t *sasl_conn(NULL);
                bool bSuccess = false;
 
@@ -103,7 +154,7 @@ public:
                        bSuccess = true;
                        DEBUG("saslauth: Found [" + sUsername + "] in cache");
                } else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, m_cbs, 0, &sasl_conn) == SASL_OK &&
-                               sasl_checkpass(sasl_conn, sUsername.c_str(), sUsername.size(), sPassword.c_str(), sPassword.size()) == SASL_OK) {
+                               sasl_checkpass(sasl_conn, sUsername.AsLower().c_str(), sUsername.AsLower().size(), sPassword.c_str(), sPassword.size()) == SASL_OK) {
                        m_Cache.AddItem(sCacheKey);
 
                        DEBUG("saslauth: Successful SASL authentication [" + sUsername + "]");
@@ -116,7 +167,7 @@ public:
                if (bSuccess) {
                        if (!pUser) {
                                CString sErr;
-                               pUser = new CUser(sUsername);
+                               pUser = new CUser(sUsername.AsLower());
 
                                if (ShouldCloneUser()) {
                                        CUser *pBaseUser = CZNC::Get().FindUser(CloneUser());
@@ -134,6 +185,14 @@ public:
                                        }
                                }
 
+                               pUser->SetNick(sUsername);
+                               pUser->SetAltNick(sUsername + "_");
+                               pUser->SetIdent(sUsername);
+                               pUser->SetRealName(sUsername);
+                               CString sAddNetworkError;
+                               CIRCNetwork* pNetwork = pUser->AddNetwork(GetNV("networkname"), sAddNetworkError);
+                               if (pNetwork) {
+                                       pNetwork->AddServer(GetNV("server"), GetNV("port").ToUShort(), "", GetNV("ssl").ToBool());
                                if (pUser) {
                                        // "::" is an invalid MD5 hash, so user won't be able to login by usual method
                                        pUser->SetPass("::", CUser::HASH_MD5, "::");
@@ -144,6 +203,24 @@ public:
                                        delete pUser;
                                        pUser = NULL;
                                }
+                                       if (m_bSaslImpersonateEnabled) {
+                                               CString sModRet;
+                                               if (pNetwork->GetModules().LoadModule("sasl", "", CModInfo::NetworkModule, pUser, pNetwork, sModRet))
+                                               {
+                                                       CModule* pModule = pNetwork->GetModules().FindModule("sasl");
+                                                       if (pModule) {
+                                                               pModule->SetNV("saslimpersonation", "yes");
+                                                               pModule->SetNV("impersonationuser", sUsername);
+                                                               pModule->SetNV("username", GetNV("impersonationusername"));
+                                                               pModule->SetNV("password", GetNV("impersonationpassword"));
+                                                               pModule->SetNV("require_auth", "yes");
+                                                               pModule->SetNV("mechanisms", "PLAIN");
+                                                       }
+                                               }
+                                               else DEBUG("saslauth: Failure loading sasl module for created user [" << sUsername << "] ");
+                                       }
+                               }
+                               else DEBUG("saslauth: Failure adding network for created user [" << sUsername << "]: " << sAddNetworkError);
                        }
 
                        if (pUser) {
@@ -151,7 +228,29 @@ public:
                                return HALT;
                        }
                }
+               return CONTINUE;
+       }
 
+       virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick,
+                                                                         CString& sIdent, CString& sRealName)
+       {
+               if (m_bWebIrcEnabled) {
+                       CUser* pUser = CModule::GetUser();
+                       CIRCNetwork* pNetwork = CModule::GetNetwork();
+                       if (pUser != NULL && !(pNetwork->GetName().CaseCmp(GetNV("networkname")))) {
+                               if (!(pUser->GetUserName().StrCmp("MrLenin")))
+                                       return CONTINUE;
+                               std::ostringstream sWebIrcMsg;
+                               CString sUsername = pUser->GetUserName();
+                               CMD5 md5(sUsername + GetNV("usersalt"));
+                               uint8* hashBytes = downsample(md5.GetHash());
+                               unsigned int hashInts[3] = { hashBytes[0], hashBytes[1], hashBytes[2] };
+                               sWebIrcMsg << "WEBIRC " << GetNV("webircpassword") << " " << GetNV("webircusername") << " " << sUsername <<
+                                       GetNV("webirchost") << " 255." << hashInts[0] << "." << hashInts[1] << "." << hashInts[2];
+                               CModule::PutIRC(sWebIrcMsg.str());
+                               delete[] hashBytes;
+                       }
+               }
                return CONTINUE;
        }
 
@@ -207,6 +306,8 @@ protected:
 
        sasl_callback_t m_cbs[2];
        CString m_sMethod;
+       bool m_bWebIrcEnabled;
+       bool m_bSaslImpersonateEnabled;
 
        static int getopt(void *context, const char *plugin_name,
                        const char *option, const char **result, unsigned *len) {
@@ -217,12 +318,26 @@ protected:
 
                return SASL_CONTINUE;
        }
+
+       /** Downsamples a 128bit result to 32bits (md5 -> unsigned int).
+        * @param[in] i 128bit result to downsample.
+        * @return downsampled result.
+
+        */
+       static inline uint8* downsample(unsigned char *i)
+       {
+               uint8* r = new uint8[3];
+               r[0] = i[0] ^ i[1] ^ i[2] ^ i[3] ^ i[4];
+               r[1] = i[5] ^ i[6] ^ i[7] ^ i[8] ^ i[9];
+               r[2] = i[10] ^ i[11] ^ i[12] ^ i[13] ^ i[14] ^ i[15];
+               return r;
+       }
 };
 
 template<> void TModInfo<CSASLAuthMod>(CModInfo& Info) {
        Info.SetWikiPage("cyrusauth");
        Info.SetHasArgs(true);
-       Info.SetArgsHelpText("This global module takes up to two arguments - the methods of authentication - auxprop and saslauthd");
+       Info.SetArgsHelpText("This global module takes up to four arguments - the methods of authentication - auxprop and saslauthd - and optionally, if WebIRC host spoofing and/or SASL Impersonation is to be enabled - webirc and impersonation");
 }
 
 GLOBALMODULEDEFS(CSASLAuthMod, "Allow users to authenticate via SASL password verification method")
index 67a4dba3236499354d23c55f11df0b09d59b6141..35c5f069d3be55aad4fea1e57d64c66e2fa469cf 100644 (file)
@@ -21,7 +21,7 @@ public:
        MODCONSTRUCTOR(CMissingMotd) {}
 
        virtual void OnClientLogin() override {
-               PutUser(":irc.znc.in 422 :MOTD File is missing");
+               PutUser(":znc.afternet.org 422 :MOTD File is missing");
        }
 };
 
index 97133213bb8ef095eef5365f538503f3e2c79dc8..c7b12686882cea6fe0f756d933794bc613bb72f8 100644 (file)
@@ -58,7 +58,7 @@ public:
                        if (!GetNetwork()->GetIRCSock()) {
                                // if we are not connected to any IRC server, send
                                // an empty or module-nick filled response.
-                               PutUser(":irc.znc.in 303 " + GetClient()->GetNick() + " :" + sBNCNicks);
+                               PutUser(":znc.afternet.org 303 " + GetClient()->GetNick() + " :" + sBNCNicks);
                        } else {
                                // We let the server handle this request and then act on
                                // the 303 response from the IRC server.
index 106d46fde51dae3857d320f881500998ccf1985f..1a7f41f7bcd819f9955caaa04357b08b88c20d37 100644 (file)
@@ -159,7 +159,7 @@ public:
                        if (sAction == "topic") {
                                pChannel = FindChannel(sKey);
                                if (pChannel && !(it->second).empty()) {
-                                       PutChan(pChannel->GetNicks(), ":irc.znc.in TOPIC " + pChannel->GetName() + " :" + it->second);
+                                       PutChan(pChannel->GetNicks(), ":znc.afternet.org TOPIC " + pChannel->GetName() + " :" + it->second);
                                        pChannel->SetTopic(it->second);
                                }
                        }
@@ -290,19 +290,19 @@ public:
                                                pChannel->SetTopic(sTopic);
                                                SaveTopic(pChannel);
                                        } else {
-                                               pUser->PutUser(":irc.znc.in 482 " +  pClient->GetNick() + " " + sChannel + " :You're not channel operator");
+                                               pUser->PutUser(":znc.afternet.org 482 " +  pClient->GetNick() + " " + sChannel + " :You're not channel operator");
                                        }
                                } else {
                                        sTopic = pChannel->GetTopic();
 
                                        if (sTopic.empty()) {
-                                               pUser->PutUser(":irc.znc.in 331 " + pClient->GetNick() + " " + sChannel + " :No topic is set.");
+                                               pUser->PutUser(":znc.afternet.org 331 " + pClient->GetNick() + " " + sChannel + " :No topic is set.");
                                        } else {
-                                               pUser->PutUser(":irc.znc.in 332 " + pClient->GetNick() + " " + sChannel + " :" + sTopic);
+                                               pUser->PutUser(":znc.afternet.org 332 " + pClient->GetNick() + " " + sChannel + " :" + sTopic);
                                        }
                                }
                        } else {
-                               pUser->PutUser(":irc.znc.in 442 " + pClient->GetNick() + " " + sChannel + " :You're not on that channel");
+                               pUser->PutUser(":znc.afternet.org 442 " + pClient->GetNick() + " " + sChannel + " :You're not on that channel");
                        }
                        return HALT;
                }
@@ -517,13 +517,13 @@ public:
 
        const CString GetIRCServer(CIRCNetwork *pNetwork) {
                if (!pNetwork) {
-                       return "irc.znc.in";
+                       return "znc.afternet.org";
                }
 
                const CString& sServer = pNetwork->GetIRCServer();
                if (!sServer.empty())
                        return sServer;
-               return "irc.znc.in";
+               return "znc.afternet.org";
        }
 
        bool PutChan(const CString& sChan, const CString& sLine, bool bIncludeCurUser = true, bool bIncludeClient = true, CUser* pUser = NULL, CClient* pClient = NULL) {
index 582774be64dbee62e9651afc492c5f040221b9a4..21dc9f6f066ab0305118d74fd94c73c0cddfc628 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <znc/IRCNetwork.h>
 #include <znc/IRCSock.h>
+#include <znc/User.h>
 
 static const struct {
        const char *szName;
@@ -102,42 +103,52 @@ public:
        }
 
        void Set(const CString& sLine) {
-               SetNV("username", sLine.Token(1));
-               SetNV("password", sLine.Token(2));
+               if (!SaslImpersonation()) {
+                   SetNV("username", sLine.Token(1));
+                   SetNV("password", sLine.Token(2));
 
-               PutModule("Username has been set to [" + GetNV("username") + "]");
-               PutModule("Password has been set to [" + GetNV("password") + "]");
+                   PutModule("Username has been set to [" + GetNV("username") + "]");
+                   PutModule("Password has been set to [" + GetNV("password") + "]");
+           }
        }
-
+       
+       bool SaslImpersonation() const {
+               return GetNV("saslimpersonation").ToBool();
+       }
+       
        void SetMechanismCommand(const CString& sLine) {
-               CString sMechanisms = sLine.Token(1, true).AsUpper();
+               if (!SaslImpersonation()) {
+                   CString sMechanisms = sLine.Token(1, true).AsUpper();
 
-               if (!sMechanisms.empty()) {
-                       VCString vsMechanisms;
-                       sMechanisms.Split(" ", vsMechanisms);
+                   if (!sMechanisms.empty()) {
+                           VCString vsMechanisms;
+                           sMechanisms.Split(" ", vsMechanisms);
 
-                       for (VCString::const_iterator it = vsMechanisms.begin(); it != vsMechanisms.end(); ++it) {
-                               if (!SupportsMechanism(*it)) {
-                                       PutModule("Unsupported mechanism: " + *it);
-                                       return;
-                               }
-                       }
+                           for (VCString::const_iterator it = vsMechanisms.begin(); it != vsMechanisms.end(); ++it) {
+                                   if (!SupportsMechanism(*it)) {
+                                       PutModule("Unsupported mechanism: " + *it);
+                                           return;
+                                   }
+                           }
 
-                       SetNV(NV_MECHANISMS, sMechanisms);
-               }
+                           SetNV(NV_MECHANISMS, sMechanisms);
+                   }
 
-               PutModule("Current mechanisms set: " + GetMechanismsString());
+                   PutModule("Current mechanisms set: " + GetMechanismsString());
+           }
        }
 
        void RequireAuthCommand(const CString& sLine) {
-               if (!sLine.Token(1).empty()) {
-                       SetNV(NV_REQUIRE_AUTH, sLine.Token(1));
-               }
-
-               if (GetNV(NV_REQUIRE_AUTH).ToBool()) {
-                       PutModule("We require SASL negotiation to connect");
-               } else {
-                       PutModule("We will connect even if SASL fails");
+               if (!SaslImpersonation()) {
+                   if (!sLine.Token(1).empty()) {
+                           SetNV(NV_REQUIRE_AUTH, sLine.Token(1));
+                   }
+
+                   if (GetNV(NV_REQUIRE_AUTH).ToBool()) {
+                           PutModule("We require SASL negotiation to connect");
+                   } else {
+                           PutModule("We will connect even if SASL fails");
+                   }
                }
        }
 
@@ -181,7 +192,7 @@ public:
 
        void Authenticate(const CString& sLine) {
                if (m_Mechanisms.GetCurrent().Equals("PLAIN") && sLine.Equals("+")) {
-                       CString sAuthLine = GetNV("username") + '\0' + GetNV("username")  + '\0' + GetNV("password");
+                       CString sAuthLine = (SaslImpersonation() ? GetNV("impersonationuser") : GetNV("username")) + '\0' + GetNV("username")  + '\0' + GetNV("password");
                        sAuthLine.Base64Encode();
                        PutIRC("AUTHENTICATE " + sAuthLine);
                } else {
index 64ab6735a23c27129e2143dcfa6e535af7c00ea6..f93a397e4cafc6d4fbf7a28f9aae6703d42da4ad 100644 (file)
@@ -466,6 +466,9 @@ public:
                        return NetworkPage(WebSock, Tmpl, pNetwork->GetUser(), pNetwork);
 
                } else if (sPageName == "delnetwork") {
+                       if (!spSession->IsAdmin()) {
+                               return false;
+                       }
                        CString sUser = WebSock.GetParam("user");
                        if (sUser.empty() && !WebSock.IsPost()) {
                                sUser = WebSock.GetParam("user", false);
@@ -473,11 +476,6 @@ public:
 
                        CUser* pUser = CZNC::Get().FindUser(sUser);
 
-                       // Admin||Self Check
-                       if (!spSession->IsAdmin() && (!spSession->GetUser() || spSession->GetUser() != pUser)) {
-                               return false;
-                       }
-
                        return DelNetwork(WebSock, pUser, Tmpl);
                } else if (sPageName == "editchan") {
                        CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock);
@@ -860,10 +858,12 @@ public:
 
                                breadNet["Text"] = "Edit Network [" + pNetwork->GetName() + "]";
 
-                               const vector<CServer*>& vServers = pNetwork->GetServers();
-                               for (unsigned int a = 0; a < vServers.size(); a++) {
-                                       CTemplate& l = Tmpl.AddRow("ServerLoop");
-                                       l["Server"] = vServers[a]->GetString();
+                               if (spSession->IsAdmin()) {
+                                   const vector<CServer*>& vServers = pNetwork->GetServers();
+                                   for (unsigned int a = 0; a < vServers.size(); a++) {
+                                           CTemplate& l = Tmpl.AddRow("ServerLoop");
+                                           l["Server"] = vServers[a]->GetString();
+                                   }
                                }
 
                                const vector<CChan*>& Channels = pNetwork->GetChans();
@@ -1034,10 +1034,14 @@ public:
 
                VCString vsArgs;
 
-               pNetwork->DelServers();
-               WebSock.GetRawParam("servers").Split("\n", vsArgs);
-               for (unsigned int a = 0; a < vsArgs.size(); a++) {
-                       pNetwork->AddServer(vsArgs[a].Trim_n());
+               if (spSession->IsAdmin()) {
+                       WebSock.GetRawParam("servers").Split("\n", vsArgs);
+                       if (vsArgs.size()) {
+                       pNetwork->DelServers();
+                       for (unsigned int a = 0; a < vsArgs.size(); a++) {
+                               pNetwork->AddServer(vsArgs[a].Trim_n());
+                       }
+                       }
                }
 
                WebSock.GetRawParam("fingerprints").Split("\n", vsArgs);
@@ -1099,9 +1103,27 @@ public:
                        }
                }
 
+               CString sModUnloadError;
+               CModule* pModule;
+               
                for (set<CString>::iterator it2 = ssUnloadMods.begin(); it2 != ssUnloadMods.end(); ++it2) {
+                       if (!it2->CaseCmp("sasl")) {
+                               pModule = pNetwork->GetModules().FindModule("sasl");
+                               
+                               if (pModule) {
+                                       if (pModule->GetNV("saslimpersonation").ToBool()) {
+                                               sModUnloadError = "Unable to unload module [sasl] SaslImpersonation enabled.";
+                                               continue;
+                                       }
+                               }
+                       }
                        pNetwork->GetModules().UnloadModule(*it2);
                }
+               
+               if (!sModUnloadError.empty()) {
+                       DEBUG(sModUnloadError);
+                       WebSock.GetSession()->AddError(sModUnloadError);
+               }
 
                CTemplate TmplMod;
                TmplMod["Username"] = pUser->GetUserName();
index 6846ba8e6dfbfe57db33bd5527ceb9dc57cd7701..448c988486d4e1d5d29a603567c98bd82a4a6eb0 100644 (file)
@@ -85,13 +85,13 @@ CClient::~CClient() {
 }
 
 void CClient::SendRequiredPasswordNotice() {
-       PutClient(":irc.znc.in 464 " + GetNick() + " :Password required");
-       PutClient(":irc.znc.in NOTICE AUTH :*** "
+       PutClient(":znc.afternet.org 464 " + GetNick() + " :Password required");
+       PutClient(":znc.afternet.org NOTICE AUTH :*** "
                          "You need to send your password. "
                          "Configure your client to send a server password.");
-       PutClient(":irc.znc.in NOTICE AUTH :*** "
-                         "To connect now, you can use /quote PASS <username>:<password>, "
-                         "or /quote PASS <username>/<network>:<password> to connect to a specific network.");
+       PutClient(":znc.afternet.org NOTICE AUTH :*** "
+                         "To connect now, you can use /quote PASS /<username>/<password>, "
+                         "or /quote PASS <network>/<username>/<password> to connect to a specific network.");
 }
 
 void CClient::ReadLine(const CString& sData) {
@@ -197,9 +197,9 @@ void CClient::ReadLine(const CString& sData) {
                // All PONGs are generated by ZNC. We will still forward this to
                // the ircd, but all PONGs from irc will be blocked.
                if (sLine.length() >= 5)
-                       PutClient(":irc.znc.in PONG irc.znc.in " + sLine.substr(5));
+                       PutClient(":znc.afternet.org PONG znc.afternet.org " + sLine.substr(5));
                else
-                       PutClient(":irc.znc.in PONG irc.znc.in");
+                       PutClient(":znc.afternet.org PONG znc.afternet.org");
        } else if (sCommand.Equals("PONG")) {
                // Block PONGs, we already responded to the pings
                return;
@@ -688,7 +688,7 @@ void CAuthBase::RefuseLogin(const CString& sReason) {
 
 void CClient::RefuseLogin(const CString& sReason) {
        PutStatus("Bad username and/or password.");
-       PutClient(":irc.znc.in 464 " + GetNick() + " :" + sReason);
+       PutClient(":znc.afternet.org 464 " + GetNick() + " :" + sReason);
        Close(Csock::CLT_AFTERWRITE);
 }
 
@@ -856,7 +856,7 @@ CString CClient::GetNickMask() const {
 
        CString sHost = m_pNetwork ? m_pNetwork->GetBindHost() : m_pUser->GetBindHost();
        if (sHost.empty()) {
-               sHost = "irc.znc.in";
+               sHost = "znc.afternet.org";
        }
 
        return GetNick() + "!" + (m_pNetwork ? m_pNetwork->GetIdent() : m_pUser->GetIdent()) + "@" + sHost;
@@ -883,7 +883,7 @@ bool CClient::IsValidIdentifier(const CString& sIdentifier) {
 
 void CClient::RespondCap(const CString& sResponse)
 {
-       PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse);
+       PutClient(":znc.afternet.org CAP " + GetNick() + " " + sResponse);
 }
 
 void CClient::HandleCap(const CString& sLine)
@@ -1000,34 +1000,39 @@ void CClient::HandleCap(const CString& sLine)
                }
                RespondCap("ACK :" + sList.TrimSuffix_n(" "));
        } else {
-               PutClient(":irc.znc.in 410 " + GetNick() + " " + sSubCmd + " :Invalid CAP subcommand");
+               PutClient(":znc.afternet.org 410 " + GetNick() + " " + sSubCmd + " :Invalid CAP subcommand");
        }
 }
 
 void CClient::ParsePass(const CString& sAuthLine) {
-       // [user[@identifier][/network]:]password
+       // [network[/user[@identifier]/]]password
 
-       const size_t uColon = sAuthLine.find(":");
-       if (uColon != CString::npos) {
-               m_sPass = sAuthLine.substr(uColon + 1);
-
-               ParseUser(sAuthLine.substr(0, uColon));
+       const size_t uSlash = sAuthLine.find("/");
+       if (uSlash != CString::npos) {
+               VCString vsAuthLine;
+               sAuthLine.Split("/", vsAuthLine, false);
+               switch (vsAuthLine.size()) {
+               case 2:
+                       ParseUser(vsAuthLine[0]);
+                       m_sPass = vsAuthLine[1];
+                       break;
+               case 3:
+                       m_sNetwork = vsAuthLine[0];
+                       ParseUser(vsAuthLine[1]);
+                       m_sPass = vsAuthLine[2];
+                       break;
+               default:
+                       m_sPass = sAuthLine;
+               }
        } else {
                m_sPass = sAuthLine;
        }
 }
 
 void CClient::ParseUser(const CString& sAuthLine) {
-       // user[@identifier][/network]
-
-       const size_t uSlash = sAuthLine.rfind("/");
-       if (uSlash != CString::npos) {
-               m_sNetwork = sAuthLine.substr(uSlash + 1);
-
-               ParseIdentifier(sAuthLine.substr(0, uSlash));
-       } else {
+       // user[@identifier]
                ParseIdentifier(sAuthLine);
-       }
 }
 
 void CClient::ParseIdentifier(const CString& sAuthLine) {
index b74b0ac6d56136719d0827057cb49c9dee228591..d99fe643288957f0dd73798a982594ebce06ef07 100644 (file)
@@ -533,6 +533,10 @@ void CClient::UserCommand(CString& sLine) {
                        PutStatus(sNetworkAddError);
                }
        } else if (sCommand.Equals("DELNETWORK")) {
+        if (!m_pUser->IsAdmin()) {
+                       PutStatus("Administrative access required to remove a Network. Ask an admin to remove the network for you.");
+                       return;
+               }
                CString sNetwork = sLine.Token(1);
 
                if (sNetwork.empty()) {
@@ -691,6 +695,10 @@ void CClient::UserCommand(CString& sLine) {
                        PutStatus("You don't have a network named " + sNetwork);
                }
        } else if (sCommand.Equals("ADDSERVER")) {
+               if (!m_pUser->IsAdmin()) {
+                       PutStatus("Administrative access required to add a Server. Ask an admin to add the server for you.");
+                       return;
+               }
                CString sServer = sLine.Token(1);
 
                if (!m_pNetwork) {
@@ -710,6 +718,10 @@ void CClient::UserCommand(CString& sLine) {
                        PutStatus("Perhaps the server is already added or openssl is disabled?");
                }
        } else if (sCommand.Equals("REMSERVER") || sCommand.Equals("DELSERVER")) {
+        if (!m_pUser->IsAdmin()) {
+                       PutStatus("Administrative access required to remove a Server. Ask an admin to remove the server for you.");
+                       return;
+               }
                if (!m_pNetwork) {
                        PutStatus("You must be connected with a network to use this command");
                        return;
@@ -1080,6 +1092,7 @@ void CClient::UserCommand(CString& sLine) {
                }
 
                CString sModRet;
+               CModule* pModule;
 
                switch (eType) {
                case CModInfo::GlobalModule:
@@ -1089,6 +1102,15 @@ void CClient::UserCommand(CString& sLine) {
                        m_pUser->GetModules().UnloadModule(sMod, sModRet);
                        break;
                case CModInfo::NetworkModule:
+                       if (!sMod.CaseCmp("sasl")) {
+                               pModule = m_pNetwork->GetModules().FindModule("sasl");
+                               if (pModule) {
+                                       if (pModule->GetNV("saslimpersonation").ToBool()) {
+                                               PutStatus("Unable to unload module [sasl] SaslImpersonation enabled.");
+                                               return;
+                                       }
+                               }
+                       }
                        m_pNetwork->GetModules().UnloadModule(sMod, sModRet);
                        break;
                default:
@@ -1150,6 +1172,7 @@ void CClient::UserCommand(CString& sLine) {
                }
 
                CString sModRet;
+               CModule* pModule;
 
                switch (eType) {
                case CModInfo::GlobalModule:
@@ -1159,6 +1182,16 @@ void CClient::UserCommand(CString& sLine) {
                        m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, NULL, sModRet);
                        break;
                case CModInfo::NetworkModule:
+                       if (!sMod.CaseCmp("sasl")) {
+                               pModule = m_pNetwork->GetModules().FindModule("sasl");
+                               
+                               if (pModule) {
+                                       if (pModule->GetNV("saslimpersonation").ToBool()) {
+                                               PutStatus("Unable to reload module [sasl] SaslImpersonation enabled.");
+                                               return;
+                                       }
+                               }
+                       }
                        m_pNetwork->GetModules().ReloadModule(sMod, sArgs, m_pUser, m_pNetwork, sModRet);
                        break;
                default:
@@ -1628,19 +1661,16 @@ void CClient::HelpUser(const CString& sFilter) {
        if (!m_pUser->IsAdmin()) {
                AddCommandHelp(Table, "ListClients", "", "List all clients connected to your ZNC user", sFilter);
        }
-       AddCommandHelp(Table, "ListServers", "", "List all servers of current IRC network", sFilter);
-
-       AddCommandHelp(Table, "AddNetwork", "<name>", "Add a network to your user", sFilter);
-       AddCommandHelp(Table, "DelNetwork", "<name>", "Delete a network from your user", sFilter);
-       AddCommandHelp(Table, "ListNetworks", "", "List all networks", sFilter);
        if (m_pUser->IsAdmin()) {
+           AddCommandHelp(Table, "ListServers", "", "List all servers of current IRC network", sFilter);
+           AddCommandHelp(Table, "AddNetwork", "<name>", "Add a network to your user", sFilter);
+           AddCommandHelp(Table, "DelNetwork", "<name>", "Delete a network from your user", sFilter);
+           AddCommandHelp(Table, "ListNetworks", "", "List all networks", sFilter);
                AddCommandHelp(Table, "MoveNetwork", "<old user> <old network> <new user> [new network]", "Move an IRC network from one user to another", sFilter);
+           AddCommandHelp(Table, "JumpNetwork", "<network>", "Jump to another network (Alternatively, you can connect to ZNC several times, using `user/network` as username)", sFilter);
+           AddCommandHelp(Table, "AddServer", "<host> [[+]port] [pass]", "Add a server to the list of alternate/backup servers of current IRC network.", sFilter);
+           AddCommandHelp(Table, "DelServer", "<host> [port] [pass]", "Remove a server from the list of alternate/backup servers of current IRC network", sFilter);
        }
-       AddCommandHelp(Table, "JumpNetwork", "<network>", "Jump to another network (Alternatively, you can connect to ZNC several times, using `user/network` as username)", sFilter);
-
-       AddCommandHelp(Table, "AddServer", "<host> [[+]port] [pass]", "Add a server to the list of alternate/backup servers of current IRC network.", sFilter);
-       AddCommandHelp(Table, "DelServer", "<host> [port] [pass]", "Remove a server from the list of alternate/backup servers of current IRC network", sFilter);
-
        AddCommandHelp(Table, "AddTrustedServerFingerprint", "<fi:ng:er>", "Add a trusted server SSL certificate fingerprint (SHA-256) to current IRC network.", sFilter);
        AddCommandHelp(Table, "DelTrustedServerFingerprint", "<fi:ng:er>", "Delete a trusted server SSL certificate from current IRC network.", sFilter);
        AddCommandHelp(Table, "ListTrustedServerFingerprints", "", "List all trusted server SSL certificates of current IRC network.", sFilter);
index 4513e674dfea9aaa8cacecf68202484dedcbc4b7..53e3b267908c45e7dd1800527dafb8eb3c648c45 100644 (file)
@@ -595,7 +595,7 @@ void CIRCNetwork::ClientConnected(CClient *pClient) {
        pClient->SetPlaybackActive(true);
 
        if (m_RawBuffer.IsEmpty()) {
-               pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + " :- Welcome to ZNC -");
+               pClient->PutClient(":znc.afternet.org 001 " + pClient->GetNick() + " :- Welcome to ZNC -");
        } else {
                const CString& sClientNick = pClient->GetNick(false);
                MCString msParams;
@@ -640,7 +640,7 @@ void CIRCNetwork::ClientConnected(CClient *pClient) {
        if (m_bIRCAway) {
                // If they want to know their away reason they'll have to whois
                // themselves. At least we can tell them their away status...
-               pClient->PutClient(":irc.znc.in 306 " + GetIRCNick().GetNick() + " :You have been marked as being away");
+               pClient->PutClient(":znc.afternet.org 306 " + GetIRCNick().GetNick() + " :You have been marked as being away");
        }
 
        const vector<CChan*>& vChans = GetChans();
index 500f8df68ea0c82fd82d629de48be14a1b810a2f..04fc05c524ffeabe5f72ae8f2202cd25ba8944b1 100644 (file)
@@ -167,7 +167,7 @@ void CIRCSock::ReadLine(const CString& sData) {
 
                switch (uRaw) {
                        case 1: { // :irc.server.com 001 nick :Welcome to the Internet Relay Network nick
-                               if (m_bAuthed && sServer == "irc.znc.in") {
+                               if (m_bAuthed && sServer == "znc.afternet.org") {
                                        // m_bAuthed == true => we already received another 001 => we might be in a traffic loop
                                        m_pNetwork->PutStatus("ZNC seems to be connected to itself, disconnecting...");
                                        Quit();
@@ -844,6 +844,7 @@ void CIRCSock::SendNextCap() {
                if (m_ssPendingCaps.empty()) {
                        // We already got all needed ACK/NAK replies.
                        PutIRC("CAP END");
+                       Register();
                } else {
                        CString sCap = *m_ssPendingCaps.begin();
                        m_ssPendingCaps.erase(m_ssPendingCaps.begin());
@@ -1091,7 +1092,12 @@ void CIRCSock::SetNick(const CString& sNick) {
 
 void CIRCSock::Connected() {
        DEBUG(GetSockName() << " == Connected()");
+       PutIRC("CAP LS");
+}
 
+void CIRCSock::Register() {
+       DEBUG(GetSockName() << " == Register()");
+       
        CString sPass = m_sPass;
        CString sNick = m_pNetwork->GetNick();
        CString sIdent = m_pNetwork->GetIdent();
@@ -1101,12 +1107,9 @@ void CIRCSock::Connected() {
        IRCSOCKMODULECALL(OnIRCRegistration(sPass, sNick, sIdent, sRealName), &bReturn);
        if (bReturn) return;
 
-       PutIRC("CAP LS");
-
-       if (!sPass.empty()) {
+       if (!sPass.empty())
                PutIRC("PASS " + sPass);
-       }
-
+       
        PutIRC("NICK " + sNick);
        PutIRC("USER " + sIdent + " \"" + sIdent + "\" \"" + sIdent + "\" :" + sRealName);
 
index 4fc9eddb074ad817e77537c6db3bd688a70e3f7f..b6366d984afe3814aa0f356de58192ee548ca9d7 100644 (file)
@@ -66,7 +66,7 @@ Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) {
        if (CZNC::Get().AllowConnectionFrom(sHost)) {
                GLOBALMODULECALL(OnClientConnect(pClient, sHost, uPort), NOTHING);
        } else {
-               pClient->Write(":irc.znc.in 464 unknown-nick :Too many anonymous connections from your IP\r\n");
+               pClient->Write(":znc.afternet.org 464 unknown-nick :Too many anonymous connections from your IP\r\n");
                pClient->Close(Csock::CLT_AFTERWRITE);
                GLOBALMODULECALL(OnFailedLogin("", sHost), NOTHING);
        }
index a3e1c414aa9e9307414d5f8f50c36c2be84111e2..488c17399437a43b62da34e32938ee858b236682 100644 (file)
@@ -35,7 +35,16 @@ CMD5::CMD5(const char* szText, uint32 nTextLen) {
        MakeHash(szText, nTextLen);
 }
 
-CMD5::~CMD5() {}
+CMD5::~CMD5()
+{
+    if (m_pszMD5 != NULL)
+        delete[] m_pszMD5;
+}
+
+unsigned char* CMD5::GetHash()
+{
+    return m_pszMD5;
+}
 
 #define GET_UINT32(n,b,i) {                 \
        (n) = ((uint32) (b)[(i)    ]      )     \
@@ -258,6 +267,12 @@ char* CMD5::MakeHash(const char* szText, uint32 nTextLen) {
                        md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
                        md5sum[6], md5sum[7], md5sum[8], md5sum[9], md5sum[10], md5sum[11],
                        md5sum[12], md5sum[13], md5sum[14], md5sum[15]);
+            
+    m_pszMD5 = new unsigned char[16];
+    m_pszMD5[0] = md5sum[0]; m_pszMD5[1] = md5sum[1]; m_pszMD5[2] = md5sum[2]; m_pszMD5[3] = md5sum[3]; 
+    m_pszMD5[4] = md5sum[4]; m_pszMD5[5] = md5sum[5]; m_pszMD5[6] = md5sum[6]; m_pszMD5[7] = md5sum[7]; 
+    m_pszMD5[8] = md5sum[8]; m_pszMD5[9] = md5sum[9]; m_pszMD5[10] = md5sum[10]; m_pszMD5[11] = md5sum[11]; 
+    m_pszMD5[12] = md5sum[12]; m_pszMD5[13] = md5sum[13]; m_pszMD5[14] = md5sum[14]; m_pszMD5[15] = md5sum[15]; 
 
        return m_szMD5;
 }
index 723e34b39e0e90bb045558d9c8a9e2e7f77f58dc..684f5f12ca809d43f5b9bb6936b2bcbe0c1a2d67 100644 (file)
@@ -604,7 +604,7 @@ void CUser::UserConnected(CClient* pClient) {
                BounceAllClients();
        }
 
-       pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + " :- Welcome to ZNC -");
+       pClient->PutClient(":znc.afternet.org 001 " + pClient->GetNick() + " :- Welcome to ZNC -");
 
        m_vClients.push_back(pClient);
 }