Exemple #1
0
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;
}
Exemple #2
0
	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 "";
	}
Exemple #3
0
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());
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}