bool CUser::UpdateModule(const CString &sModule) { const map<CString,CUser*>& Users = CZNC::Get().GetUserMap(); map<CString,CUser*>::const_iterator it; map<CUser*, CString> Affected; map<CUser*, CString>::iterator it2; bool error = false; for (it = Users.begin(); it != Users.end(); ++it) { CModule *pMod = it->second->GetModules().FindModule(sModule); if (pMod) { Affected[it->second] = pMod->GetArgs(); it->second->GetModules().UnloadModule(pMod->GetModName()); } } CString sErr; for (it2 = Affected.begin(); it2 != Affected.end(); ++it2) { if (!it2->first->GetModules().LoadModule(sModule, it2->second, it2->first, sErr)) { error = true; DEBUG("Failed to reload [" << sModule << "] for [" << it2->first->GetUserName() << "]: " << sErr); } } return !error; }
CString GetModArgs(CUser* pUser, const CString& sModName, bool bGlobal = false) { if (!bGlobal && !pUser) { return ""; } CModules& Modules = (bGlobal) ? CZNC::Get().GetModules() : pUser->GetModules(); for (unsigned int a = 0; a < Modules.size(); a++) { CModule* pModule = Modules[a]; if (pModule->GetModName() == sModName) { return pModule->GetArgs(); } } return ""; }
void CIRCNetwork::Clone(const CIRCNetwork& Network) { m_sName = Network.GetName(); SetNick(Network.GetNick()); SetAltNick(Network.GetAltNick()); SetIdent(Network.GetIdent()); SetRealName(Network.GetRealName()); // Servers const vector<CServer*>& vServers = Network.GetServers(); CString sServer; CServer* pCurServ = GetCurrentServer(); if (pCurServ) { sServer = pCurServ->GetName(); } DelServers(); unsigned int a; for (a = 0; a < vServers.size(); a++) { CServer* pServer = vServers[a]; AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), pServer->IsSSL()); } m_uServerIdx = 0; for (a = 0; a < m_vServers.size(); a++) { if (sServer.Equals(m_vServers[a]->GetName())) { m_uServerIdx = a + 1; break; } } if (m_uServerIdx == 0) { m_uServerIdx = m_vServers.size(); CIRCSock* pSock = GetIRCSock(); if (pSock) { PutStatus("Jumping servers because this server is no longer in the list"); pSock->Quit(); } } // !Servers // Chans const vector<CChan*>& vChans = Network.GetChans(); for (a = 0; a < vChans.size(); a++) { CChan* pNewChan = vChans[a]; CChan* pChan = FindChan(pNewChan->GetName()); if (pChan) { pChan->SetInConfig(pNewChan->InConfig()); } else { AddChan(pNewChan->GetName(), pNewChan->InConfig()); } } for (a = 0; a < m_vChans.size(); a++) { CChan* pChan = m_vChans[a]; CChan* pNewChan = Network.FindChan(pChan->GetName()); if (!pNewChan) { pChan->SetInConfig(false); } else { pChan->Clone(*pNewChan); } } // !Chans // Modules set<CString> ssUnloadMods; CModules& vCurMods = GetModules(); const CModules& vNewMods = Network.GetModules(); for (a = 0; a < vNewMods.size(); a++) { CString sModRet; CModule* pNewMod = vNewMods[a]; CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); if (!pCurMod) { vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), CModInfo::NetworkModule, m_pUser, this, sModRet); } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), m_pUser, this, sModRet); } } for (a = 0; a < vCurMods.size(); a++) { CModule* pCurMod = vCurMods[a]; CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); if (!pNewMod) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (set<CString>::iterator it = ssUnloadMods.begin(); it != ssUnloadMods.end(); ++it) { vCurMods.UnloadModule(*it); } // !Modules SetIRCConnectEnabled(Network.GetIRCConnectEnabled()); }
CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CString& sPageRet) { // Check that their session really belongs to their IP address. IP-based // authentication is bad, but here it's just an extra layer that makes // stealing cookies harder to pull off. // // When their IP is wrong, we give them an invalid cookie. This makes // sure that they will get a new cookie on their next request. if (CZNC::Get().GetProtectWebSessions() && GetSession()->GetIP() != GetRemoteIP()) { DEBUG("Expected IP: " << GetSession()->GetIP()); DEBUG("Remote IP: " << GetRemoteIP()); SendCookie("SessionId", "WRONG_IP_FOR_SESSION"); PrintErrorPage(403, "Access denied", "This session does not belong to your IP."); return PAGE_DONE; } // Check that they really POSTed from one our forms by checking if they // know the "secret" CSRF check value. Don't do this for login since // CSRF against the login form makes no sense and the login form does a // cookies-enabled check which would break otherwise. if (IsPost() && GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") { DEBUG("Expected _CSRF_Check: " << GetCSRFCheck()); DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check")); PrintErrorPage(403, "Access denied", "POST requests need to send " "a secret token to prevent cross-site request forgery attacks."); return PAGE_DONE; } SendCookie("SessionId", GetSession()->GetId()); if (GetSession()->IsLoggedIn()) { m_sUser = GetSession()->GetUser()->GetUserName(); m_bLoggedIn = true; } // Handle the static pages that don't require a login if (sURI == "/") { if(!m_bLoggedIn && GetParam("cookie_check", false).ToBool() && GetRequestCookie("SessionId").empty()) { GetSession()->AddError("Your browser does not have cookies enabled for this site!"); } return PrintTemplate("index", sPageRet); } else if (sURI == "/favicon.ico") { return PrintStaticFile("/pub/favicon.ico", sPageRet); } else if (sURI == "/robots.txt") { return PrintStaticFile("/pub/robots.txt", sPageRet); } else if (sURI == "/logout") { GetSession()->SetUser(NULL); SetLoggedIn(false); Redirect("/"); // We already sent a reply return PAGE_DONE; } else if (sURI == "/login") { if (GetParam("submitted").ToBool()) { m_sUser = GetParam("user"); m_sPass = GetParam("pass"); m_bLoggedIn = OnLogin(m_sUser, m_sPass); // AcceptedLogin()/RefusedLogin() will call Redirect() return PAGE_DEFERRED; } Redirect("/"); // the login form is here return PAGE_DONE; } else if (sURI.Left(5) == "/pub/") { return PrintStaticFile(sURI, sPageRet); } else if (sURI.Left(11) == "/skinfiles/") { CString sSkinName = sURI.substr(11); CString::size_type uPathStart = sSkinName.find("/"); if (uPathStart != CString::npos) { CString sFilePath = sSkinName.substr(uPathStart + 1); sSkinName.erase(uPathStart); m_Template.ClearPaths(); m_Template.AppendPath(GetSkinPath(sSkinName) + "pub"); if (PrintFile(m_Template.ExpandFile(sFilePath))) { return PAGE_DONE; } else { return PAGE_NOTFOUND; } } return PAGE_NOTFOUND; } else if (sURI.Left(6) == "/mods/" || sURI.Left(10) == "/modfiles/") { // Make sure modules are treated as directories if (sURI.Right(1) != "/" && sURI.find(".") == CString::npos && sURI.TrimLeft_n("/mods/").TrimLeft_n("/").find("/") == CString::npos) { Redirect(sURI + "/"); return PAGE_DONE; } // The URI looks like: // /mods/[type]/([network]/)?[module][/page][?arg1=val1&arg2=val2...] m_sPath = GetPath().TrimLeft_n("/"); m_sPath.TrimPrefix("mods/"); m_sPath.TrimPrefix("modfiles/"); CString sType = m_sPath.Token(0, false, "/"); m_sPath = m_sPath.Token(1, true, "/"); CModInfo::EModuleType eModType; if (sType.Equals("global")) { eModType = CModInfo::GlobalModule; } else if (sType.Equals("user")) { eModType = CModInfo::UserModule; } else if (sType.Equals("network")) { eModType = CModInfo::NetworkModule; } else { PrintErrorPage(403, "Forbidden", "Unknown module type [" + sType + "]"); return PAGE_DONE; } if ((eModType != CModInfo::GlobalModule) && !ForceLogin()) { // Make sure we have a valid user return PAGE_DONE; } CIRCNetwork *pNetwork = NULL; if (eModType == CModInfo::NetworkModule) { CString sNetwork = m_sPath.Token(0, false, "/"); m_sPath = m_sPath.Token(1, true, "/"); pNetwork = GetSession()->GetUser()->FindNetwork(sNetwork); if (!pNetwork) { PrintErrorPage(404, "Not Found", "Network [" + sNetwork + "] not found."); return PAGE_DONE; } } m_sModName = m_sPath.Token(0, false, "/"); m_sPage = m_sPath.Token(1, true, "/"); if (m_sPage.empty()) { m_sPage = "index"; } DEBUG("Path [" + m_sPath + "], Module [" + m_sModName + "], Page [" + m_sPage + "]"); CModule *pModule = NULL; switch (eModType) { case CModInfo::GlobalModule: pModule = CZNC::Get().GetModules().FindModule(m_sModName); break; case CModInfo::UserModule: pModule = GetSession()->GetUser()->GetModules().FindModule(m_sModName); break; case CModInfo::NetworkModule: pModule = pNetwork->GetModules().FindModule(m_sModName); break; } if (!pModule) return PAGE_NOTFOUND; m_Template["ModPath"] = pModule->GetWebPath(); m_Template["ModFilesPath"] = pModule->GetWebFilesPath(); if (pModule->WebRequiresLogin() && !ForceLogin()) { return PAGE_PRINT; } else if (pModule->WebRequiresAdmin() && !GetSession()->IsAdmin()) { PrintErrorPage(403, "Forbidden", "You need to be an admin to access this module"); return PAGE_DONE; } else if (pModule->GetType() != CModInfo::GlobalModule && pModule->GetUser() != GetSession()->GetUser()) { PrintErrorPage(403, "Forbidden", "You must login as " + pModule->GetUser()->GetUserName() + " in order to view this page"); return PAGE_DONE; } else if (pModule->OnWebPreRequest(*this, m_sPage)) { return PAGE_DEFERRED; } VWebSubPages& vSubPages = pModule->GetSubPages(); for (unsigned int a = 0; a < vSubPages.size(); a++) { TWebSubPage& SubPage = vSubPages[a]; bool bActive = (m_sModName == pModule->GetModName() && m_sPage == SubPage->GetName()); if (bActive && SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { PrintErrorPage(403, "Forbidden", "You need to be an admin to access this page"); return PAGE_DONE; } } if (pModule && pModule->GetType() != CModInfo::GlobalModule && (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { AddModLoop("UserModLoop", *pModule); } if (sURI.Left(10) == "/modfiles/") { m_Template.AppendPath(GetSkinPath(GetSkinName()) + "/mods/" + m_sModName + "/files/"); m_Template.AppendPath(pModule->GetModDataDir() + "/files/"); if (PrintFile(m_Template.ExpandFile(m_sPage.TrimLeft_n("/")))) { return PAGE_PRINT; } else { return PAGE_NOTFOUND; } } else { SetPaths(pModule, true); /* if a module returns false from OnWebRequest, it does not want the template to be printed, usually because it did a redirect. */ if (pModule->OnWebRequest(*this, m_sPage, m_Template)) { // If they already sent a reply, let's assume // they did what they wanted to do. if (SentHeader()) { return PAGE_DONE; } return PrintTemplate(m_sPage, sPageRet, pModule); } if (!SentHeader()) { PrintErrorPage(404, "Not Implemented", "The requested module does not acknowledge web requests"); } return PAGE_DONE; } } else { CString sPage(sURI.Trim_n("/")); if (sPage.length() < 32) { for (unsigned int a = 0; a < sPage.length(); a++) { unsigned char c = sPage[a]; if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') { return PAGE_NOTFOUND; } } return PrintTemplate(sPage, sPageRet); } } return PAGE_NOTFOUND; }
bool CWebSock::AddModLoop(const CString& sLoopName, CModule& Module, CTemplate *pTemplate) { if (!pTemplate) { pTemplate = &m_Template; } CString sTitle(Module.GetWebMenuTitle()); if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && !Module.WebRequiresAdmin())) && (GetSession()->IsAdmin() || !Module.WebRequiresAdmin())) { CTemplate& Row = pTemplate->AddRow(sLoopName); Row["ModName"] = Module.GetModName(); Row["ModPath"] = Module.GetWebPath(); Row["Title"] = sTitle; if (m_sModName == Module.GetModName()) { Row["Active"] = "true"; } if (Module.GetUser()) { Row["Username"] = Module.GetUser()->GetUserName(); } VWebSubPages& vSubPages = Module.GetSubPages(); for (unsigned int a = 0; a < vSubPages.size(); a++) { TWebSubPage& SubPage = vSubPages[a]; // bActive is whether or not the current url matches this subpage (params will be checked below) bool bActive = (m_sModName == Module.GetModName() && m_sPage == SubPage->GetName()); if (SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { continue; // Don't add admin-only subpages to requests from non-admin users } CTemplate& SubRow = Row.AddRow("SubPageLoop"); SubRow["ModName"] = Module.GetModName(); SubRow["ModPath"] = Module.GetWebPath(); SubRow["PageName"] = SubPage->GetName(); SubRow["Title"] = SubPage->GetTitle().empty() ? SubPage->GetName() : SubPage->GetTitle(); CString& sParams = SubRow["Params"]; const VPair& vParams = SubPage->GetParams(); for (size_t b = 0; b < vParams.size(); b++) { pair<CString, CString> ssNV = vParams[b]; if (!sParams.empty()) { sParams += "&"; } if (!ssNV.first.empty()) { if (!ssNV.second.empty()) { sParams += ssNV.first.Escape_n(CString::EURL); sParams += "="; sParams += ssNV.second.Escape_n(CString::EURL); } if (bActive && GetParam(ssNV.first, false) != ssNV.second) { bActive = false; } } } if (bActive) { SubRow["Active"] = "true"; } } return true; } return false; }
bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { unsigned int a = 0; sErrorRet.clear(); if (!User.IsValid(sErrorRet, true)) { return false; } // user names can only specified for the constructor, changing it later // on breaks too much stuff (e.g. lots of paths depend on the user name) if (GetUserName() != User.GetUserName()) { DEBUG("Ignoring username in CUser::Clone(), old username [" << GetUserName() << "]; New username [" << User.GetUserName() << "]"); } if (!User.GetPass().empty()) { SetPass(User.GetPass(), User.GetPassHashType(), User.GetPassSalt()); } SetNick(User.GetNick(false)); SetAltNick(User.GetAltNick(false)); SetIdent(User.GetIdent(false)); SetRealName(User.GetRealName()); SetStatusPrefix(User.GetStatusPrefix()); SetBindHost(User.GetBindHost()); SetDCCBindHost(User.GetDCCBindHost()); SetQuitMsg(User.GetQuitMsg()); SetSkinName(User.GetSkinName()); SetLanguage(User.GetLanguage()); SetDefaultChanModes(User.GetDefaultChanModes()); SetBufferCount(User.GetBufferCount(), true); SetJoinTries(User.JoinTries()); SetMaxJoins(User.MaxJoins()); // Allowed Hosts m_ssAllowedHosts.clear(); const set<CString>& ssHosts = User.GetAllowedHosts(); for (set<CString>::const_iterator it = ssHosts.begin(); it != ssHosts.end(); ++it) { AddAllowedHost(*it); } for (a = 0; a < m_vClients.size(); a++) { CClient* pSock = m_vClients[a]; if (!IsHostAllowed(pSock->GetRemoteIP())) { pSock->PutStatusNotice("You are being disconnected because your IP is no longer allowed to connect to this user"); pSock->Close(); } } // !Allowed Hosts // Networks const vector<CIRCNetwork*>& vNetworks = User.GetNetworks(); for (a = 0; a < vNetworks.size(); a++) { new CIRCNetwork(this, vNetworks[a], bCloneChans); } // !Networks // CTCP Replies m_mssCTCPReplies.clear(); const MCString& msReplies = User.GetCTCPReplies(); for (MCString::const_iterator it = msReplies.begin(); it != msReplies.end(); ++it) { AddCTCPReply(it->first, it->second); } // !CTCP Replies // Flags SetIRCConnectEnabled(User.GetIRCConnectEnabled()); SetKeepBuffer(User.KeepBuffer()); SetMultiClients(User.MultiClients()); SetDenyLoadMod(User.DenyLoadMod()); SetAdmin(User.IsAdmin()); SetDenySetBindHost(User.DenySetBindHost()); SetTimestampAppend(User.GetTimestampAppend()); SetTimestampPrepend(User.GetTimestampPrepend()); SetTimestampFormat(User.GetTimestampFormat()); SetTimezoneOffset(User.GetTimezoneOffset()); // !Flags // Modules set<CString> ssUnloadMods; CModules& vCurMods = GetModules(); const CModules& vNewMods = User.GetModules(); for (a = 0; a < vNewMods.size(); a++) { CString sModRet; CModule* pNewMod = vNewMods[a]; CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); if (!pCurMod) { vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), CModInfo::UserModule, this, NULL, sModRet); } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), this, NULL, sModRet); } } for (a = 0; a < vCurMods.size(); a++) { CModule* pCurMod = vCurMods[a]; CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); if (!pNewMod) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (set<CString>::iterator it = ssUnloadMods.begin(); it != ssUnloadMods.end(); ++it) { vCurMods.UnloadModule(*it); } // !Modules return true; }
CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CString& sPageRet) { if (CZNC::Get().GetProtectWebSessions() && GetSession()->GetIP() != GetRemoteIP()) { DEBUG("Expected IP: " << GetSession()->GetIP()); DEBUG("Remote IP: " << GetRemoteIP()); PrintErrorPage(403, "Access denied", "This session does not belong to your IP."); return PAGE_DONE; } // Check that they really POSTed from one our forms by checking if they // know the "secret" CSRF check value. Don't do this for login since // CSRF against the login form makes no sense and the login form does a // cookies-enabled check which would break otherwise. if (IsPost() && GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") { DEBUG("Expected _CSRF_Check: " << GetCSRFCheck()); DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check")); PrintErrorPage(403, "Access denied", "POST requests need to send " "a secret token to prevent cross-site request forgery attacks."); return PAGE_DONE; } SendCookie("SessionId", GetSession()->GetId()); if (GetSession()->IsLoggedIn()) { m_sUser = GetSession()->GetUser()->GetUserName(); m_bLoggedIn = true; } // Handle the static pages that don't require a login if (sURI == "/") { if(!m_bLoggedIn && GetParam("cookie_check", false).ToBool() && GetRequestCookie("SessionId").empty()) { GetSession()->AddError("Your browser does not have cookies enabled for this site!"); } return PrintTemplate("index", sPageRet); } else if (sURI == "/favicon.ico") { return PrintStaticFile("/pub/favicon.ico", sPageRet); } else if (sURI == "/robots.txt") { return PrintStaticFile("/pub/robots.txt", sPageRet); } else if (sURI == "/logout") { GetSession()->SetUser(NULL); SetLoggedIn(false); Redirect("/"); // We already sent a reply return PAGE_DONE; } else if (sURI == "/login") { if (GetParam("submitted").ToBool()) { m_sUser = GetParam("user"); m_sPass = GetParam("pass"); m_bLoggedIn = OnLogin(m_sUser, m_sPass); // AcceptedLogin()/RefusedLogin() will call Redirect() return PAGE_DEFERRED; } Redirect("/"); // the login form is here return PAGE_DONE; } else if (sURI.Left(5) == "/pub/") { return PrintStaticFile(sURI, sPageRet); } else if (sURI.Left(11) == "/skinfiles/") { CString sSkinName = sURI.substr(11); CString::size_type uPathStart = sSkinName.find("/"); if (uPathStart != CString::npos) { CString sFilePath = sSkinName.substr(uPathStart + 1); sSkinName.erase(uPathStart); m_Template.ClearPaths(); m_Template.AppendPath(GetSkinPath(sSkinName) + "pub"); if (PrintFile(m_Template.ExpandFile(sFilePath))) { return PAGE_DONE; } else { return PAGE_NOTFOUND; } } return PAGE_NOTFOUND; } else if (sURI.Left(6) == "/mods/" || sURI.Left(10) == "/modfiles/") { ParsePath(); // Make sure modules are treated as directories if (sURI.Right(1) != "/" && sURI.find(".") == CString::npos && sURI.TrimLeft_n("/mods/").TrimLeft_n("/").find("/") == CString::npos) { Redirect(sURI + "/"); return PAGE_DONE; } CModule *pModule = CZNC::Get().GetModules().FindModule(m_sModName); if (!pModule) { // Check if GetSession()->GetUser() is NULL and display // an error in that case if (!ForceLogin()) return PAGE_DONE; pModule = GetSession()->GetUser()->GetModules().FindModule(m_sModName); } if (!pModule) { return PAGE_NOTFOUND; } else if (pModule->WebRequiresLogin() && !ForceLogin()) { return PAGE_PRINT; } else if (pModule->WebRequiresAdmin() && !GetSession()->IsAdmin()) { PrintErrorPage(403, "Forbidden", "You need to be an admin to access this module"); return PAGE_DONE; } else if (!pModule->IsGlobal() && pModule->GetUser() != GetSession()->GetUser()) { PrintErrorPage(403, "Forbidden", "You must login as " + pModule->GetUser()->GetUserName() + " in order to view this page"); return PAGE_DONE; } else if (pModule->OnWebPreRequest(*this, m_sPage)) { return PAGE_DEFERRED; } VWebSubPages& vSubPages = pModule->GetSubPages(); for (unsigned int a = 0; a < vSubPages.size(); a++) { TWebSubPage& SubPage = vSubPages[a]; bool bActive = (m_sModName == pModule->GetModName() && m_sPage == SubPage->GetName()); if (bActive && SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { PrintErrorPage(403, "Forbidden", "You need to be an admin to access this page"); return PAGE_DONE; } } if (pModule && !pModule->IsGlobal() && (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { AddModLoop("UserModLoop", *pModule); } if (sURI.Left(10) == "/modfiles/") { m_Template.AppendPath(GetSkinPath(GetSkinName()) + "/mods/" + m_sModName + "/files/"); m_Template.AppendPath(pModule->GetModDataDir() + "/files/"); if (PrintFile(m_Template.ExpandFile(m_sPage.TrimLeft_n("/")))) { return PAGE_PRINT; } else { return PAGE_NOTFOUND; } } else { SetPaths(pModule, true); /* if a module returns false from OnWebRequest, it does not want the template to be printed, usually because it did a redirect. */ if (pModule->OnWebRequest(*this, m_sPage, m_Template)) { // If they already sent a reply, let's assume // they did what they wanted to do. if (SentHeader()) { return PAGE_DONE; } return PrintTemplate(m_sPage, sPageRet, pModule); } if (!SentHeader()) { PrintErrorPage(404, "Not Implemented", "The requested module does not acknowledge web requests"); } return PAGE_DONE; } } else { CString sPage(sURI.Trim_n("/")); if (sPage.length() < 32) { for (unsigned int a = 0; a < sPage.length(); a++) { unsigned char c = sPage[a]; if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') { return PAGE_NOTFOUND; } } return PrintTemplate(sPage, sPageRet); } } return PAGE_NOTFOUND; }
bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { unsigned int a = 0; sErrorRet.clear(); if (!User.IsValid(sErrorRet, true)) { return false; } // user names can only specified for the constructor, changing it later // on breaks too much stuff (e.g. lots of paths depend on the user name) if (GetUserName() != User.GetUserName()) { DEBUG("Ignoring username in CUser::Clone(), old username [" << GetUserName() << "]; New username [" << User.GetUserName() << "]"); } if (!User.GetPass().empty()) { SetPass(User.GetPass(), User.GetPassHashType(), User.GetPassSalt()); } SetNick(User.GetNick(false)); SetAltNick(User.GetAltNick(false)); SetIdent(User.GetIdent(false)); SetRealName(User.GetRealName()); SetStatusPrefix(User.GetStatusPrefix()); SetBindHost(User.GetBindHost()); SetDCCBindHost(User.GetDCCBindHost()); SetQuitMsg(User.GetQuitMsg()); SetSkinName(User.GetSkinName()); SetDefaultChanModes(User.GetDefaultChanModes()); SetBufferCount(User.GetBufferCount(), true); SetJoinTries(User.JoinTries()); SetMaxJoins(User.MaxJoins()); // Allowed Hosts m_ssAllowedHosts.clear(); const set<CString>& ssHosts = User.GetAllowedHosts(); for (set<CString>::const_iterator it = ssHosts.begin(); it != ssHosts.end(); ++it) { AddAllowedHost(*it); } for (a = 0; a < m_vClients.size(); a++) { CClient* pSock = m_vClients[a]; if (!IsHostAllowed(pSock->GetRemoteIP())) { pSock->PutStatusNotice("You are being disconnected because your IP is no longer allowed to connect to this user"); pSock->Close(); } } // !Allowed Hosts // Servers const vector<CServer*>& vServers = User.GetServers(); CString sServer; CServer* pCurServ = GetCurrentServer(); if (pCurServ) { sServer = pCurServ->GetName(); } DelServers(); for (a = 0; a < vServers.size(); a++) { CServer* pServer = vServers[a]; AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), pServer->IsSSL()); } m_uServerIdx = 0; for (a = 0; a < m_vServers.size(); a++) { if (sServer.Equals(m_vServers[a]->GetName())) { m_uServerIdx = a + 1; break; } } if (m_uServerIdx == 0) { m_uServerIdx = m_vServers.size(); CIRCSock* pSock = GetIRCSock(); if (pSock) { PutStatus("Jumping servers because this server is no longer in the list"); pSock->Quit(); } } // !Servers // Chans const vector<CChan*>& vChans = User.GetChans(); for (a = 0; a < vChans.size(); a++) { CChan* pNewChan = vChans[a]; CChan* pChan = FindChan(pNewChan->GetName()); if (pChan) { pChan->SetInConfig(pNewChan->InConfig()); } else { AddChan(pNewChan->GetName(), pNewChan->InConfig()); } } for (a = 0; a < m_vChans.size(); a++) { CChan* pChan = m_vChans[a]; CChan* pNewChan = User.FindChan(pChan->GetName()); if (!pNewChan) { pChan->SetInConfig(false); } else { if (bCloneChans) pChan->Clone(*pNewChan); } } // !Chans // CTCP Replies m_mssCTCPReplies.clear(); const MCString& msReplies = User.GetCTCPReplies(); for (MCString::const_iterator it = msReplies.begin(); it != msReplies.end(); ++it) { AddCTCPReply(it->first, it->second); } // !CTCP Replies // Flags SetIRCConnectEnabled(User.GetIRCConnectEnabled()); SetKeepBuffer(User.KeepBuffer()); SetMultiClients(User.MultiClients()); SetBounceDCCs(User.BounceDCCs()); SetUseClientIP(User.UseClientIP()); SetDenyLoadMod(User.DenyLoadMod()); SetAdmin(User.IsAdmin()); SetDenySetBindHost(User.DenySetBindHost()); SetTimestampAppend(User.GetTimestampAppend()); SetTimestampPrepend(User.GetTimestampPrepend()); SetTimestampFormat(User.GetTimestampFormat()); SetTimezoneOffset(User.GetTimezoneOffset()); // !Flags // Modules set<CString> ssUnloadMods; CModules& vCurMods = GetModules(); const CModules& vNewMods = User.GetModules(); for (a = 0; a < vNewMods.size(); a++) { CString sModRet; CModule* pNewMod = vNewMods[a]; CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); if (!pCurMod) { vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), this, sModRet); } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), this, sModRet); } } for (a = 0; a < vCurMods.size(); a++) { CModule* pCurMod = vCurMods[a]; CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); if (!pNewMod) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (set<CString>::iterator it = ssUnloadMods.begin(); it != ssUnloadMods.end(); ++it) { vCurMods.UnloadModule(*it); } // !Modules return true; }
bool CWebSock::AddModLoop(const CString& sLoopName, CModule& Module, CTemplate *pTemplate) { if (!pTemplate) { pTemplate = &m_Template; } CString sTitle(Module.GetWebMenuTitle()); if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && !Module.WebRequiresAdmin())) && (GetSession()->IsAdmin() || !Module.WebRequiresAdmin())) { CTemplate& Row = pTemplate->AddRow(sLoopName); bool bActiveModule = false; Row["ModName"] = Module.GetModName(); Row["ModPath"] = Module.GetWebPath(); Row["Title"] = sTitle; if (m_sModName == Module.GetModName()) { CString sModuleType = GetPath().Token(1, false, "/"); if (sModuleType == "global" && Module.GetType() == CModInfo::GlobalModule) { bActiveModule = true; } else if (sModuleType == "user" && Module.GetType() == CModInfo::UserModule) { bActiveModule = true; } else if (sModuleType == "network" && Module.GetType() == CModInfo::NetworkModule) { CIRCNetwork *Network = Module.GetNetwork(); if (Network) { CString sNetworkName = GetPath().Token(2, false, "/"); if (sNetworkName == Network->GetName()) { bActiveModule = true; } } else { bActiveModule = true; } } } if (bActiveModule) { Row["Active"] = "true"; } if (Module.GetUser()) { Row["Username"] = Module.GetUser()->GetUserName(); } VWebSubPages& vSubPages = Module.GetSubPages(); for (TWebSubPage& SubPage : vSubPages) { // bActive is whether or not the current url matches this subpage (params will be checked below) bool bActive = (m_sModName == Module.GetModName() && m_sPage == SubPage->GetName() && bActiveModule); if (SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { continue; // Don't add admin-only subpages to requests from non-admin users } CTemplate& SubRow = Row.AddRow("SubPageLoop"); SubRow["ModName"] = Module.GetModName(); SubRow["ModPath"] = Module.GetWebPath(); SubRow["PageName"] = SubPage->GetName(); SubRow["Title"] = SubPage->GetTitle().empty() ? SubPage->GetName() : SubPage->GetTitle(); CString& sParams = SubRow["Params"]; const VPair& vParams = SubPage->GetParams(); for (const pair<CString, CString>& ssNV : vParams) { if (!sParams.empty()) { sParams += "&"; } if (!ssNV.first.empty()) { if (!ssNV.second.empty()) { sParams += ssNV.first.Escape_n(CString::EURL); sParams += "="; sParams += ssNV.second.Escape_n(CString::EURL); } if (bActive && GetParam(ssNV.first, false) != ssNV.second) { bActive = false; } } } if (bActive) { SubRow["Active"] = "true"; } } return true; } return false; }