Example #1
0
File: Chan.cpp Project: BtbN/znc
CChan::CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig,
             CConfig* pConfig)
    : m_bDetached(false),
      m_bIsOn(false),
      m_bAutoClearChanBuffer(pNetwork->GetUser()->AutoClearChanBuffer()),
      m_bInConfig(bInConfig),
      m_bDisabled(false),
      m_bHasBufferCountSet(false),
      m_bHasAutoClearChanBufferSet(false),
      m_sName(sName.Token(0)),
      m_sKey(sName.Token(1)),
      m_sTopic(""),
      m_sTopicOwner(""),
      m_ulTopicDate(0),
      m_ulCreationDate(0),
      m_pNetwork(pNetwork),
      m_Nick(),
      m_uJoinTries(0),
      m_sDefaultModes(""),
      m_msNicks(),
      m_Buffer(),
      m_bModeKnown(false),
      m_mcsModes() {
    if (!m_pNetwork->IsChan(m_sName)) {
        m_sName = "#" + m_sName;
    }

    m_Nick.SetNetwork(m_pNetwork);
    m_Buffer.SetLineCount(m_pNetwork->GetUser()->GetChanBufferSize(), true);

    if (pConfig) {
        CString sValue;
        if (pConfig->FindStringEntry("buffer", sValue))
            SetBufferCount(sValue.ToUInt(), true);
        if (pConfig->FindStringEntry("autoclearchanbuffer", sValue))
            SetAutoClearChanBuffer(sValue.ToBool());
        if (pConfig->FindStringEntry("keepbuffer", sValue))
            // XXX Compatibility crap, added in 0.207
            SetAutoClearChanBuffer(!sValue.ToBool());
        if (pConfig->FindStringEntry("detached", sValue))
            SetDetached(sValue.ToBool());
        if (pConfig->FindStringEntry("disabled", sValue))
            if (sValue.ToBool()) Disable();
        if (pConfig->FindStringEntry("autocycle", sValue))
            if (sValue.Equals("true"))
                CUtils::PrintError(
                    "WARNING: AutoCycle has been removed, instead try -> "
                    "LoadModule = autocycle " +
                    sName);
        if (pConfig->FindStringEntry("key", sValue)) SetKey(sValue);
        if (pConfig->FindStringEntry("modes", sValue)) SetDefaultModes(sValue);
    }
}
Example #2
0
    void SilentCommand(const CString& sLine) {
        const CString sArg = sLine.Token(1, true);

        if (!sArg.empty()) {
            SetNV("silent", CString(sArg.ToBool()));
        }

        if (GetNV("silent").ToBool()) {
            PutModule(t_s("Module messages are disabled"));
        } else {
            PutModule(t_s("Module messages are enabled"));
        }
    }
Example #3
0
CChan::CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig, CConfig *pConfig) {
	m_sName = sName.Token(0);
	m_sKey = sName.Token(1);
	m_pNetwork = pNetwork;

	if (!m_pNetwork->IsChan(m_sName)) {
		m_sName = "#" + m_sName;
	}

	m_bInConfig = bInConfig;
	m_Nick.SetNetwork(m_pNetwork);
	m_bDetached = false;
	m_bDisabled = false;
	SetBufferCount(m_pNetwork->GetUser()->GetBufferCount(), true);
	SetAutoClearChanBuffer(m_pNetwork->GetUser()->AutoClearChanBuffer());
	Reset();

	if (pConfig) {
		CString sValue;
		if (pConfig->FindStringEntry("buffer", sValue))
			SetBufferCount(sValue.ToUInt(), true);
		if (pConfig->FindStringEntry("autoclearchanbuffer", sValue))
			SetAutoClearChanBuffer(sValue.ToBool());
		if (pConfig->FindStringEntry("keepbuffer", sValue))
			SetAutoClearChanBuffer(!sValue.ToBool()); // XXX Compatibility crap, added in 0.207
		if (pConfig->FindStringEntry("detached", sValue))
			SetDetached(sValue.ToBool());
		if (pConfig->FindStringEntry("autocycle", sValue))
			if (sValue.Equals("true"))
				CUtils::PrintError("WARNING: AutoCycle has been removed, instead try -> LoadModule = autocycle " + sName);
		if (pConfig->FindStringEntry("key", sValue))
			SetKey(sValue);
		if (pConfig->FindStringEntry("modes", sValue))
			SetDefaultModes(sValue);
	}
}
Example #4
0
File: User.cpp Project: johnfb/znc
bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
	TOption<const CString&> StringOptions[] = {
		{ "nick", &CUser::SetNick },
		{ "quitmsg", &CUser::SetQuitMsg },
		{ "altnick", &CUser::SetAltNick },
		{ "ident", &CUser::SetIdent },
		{ "realname", &CUser::SetRealName },
		{ "chanmodes", &CUser::SetDefaultChanModes },
		{ "bindhost", &CUser::SetBindHost },
		{ "vhost", &CUser::SetBindHost },
		{ "dccbindhost", &CUser::SetDCCBindHost },
		{ "dccvhost", &CUser::SetDCCBindHost },
		{ "timestampformat", &CUser::SetTimestampFormat },
		{ "skin", &CUser::SetSkinName },
	};
	size_t numStringOptions = sizeof(StringOptions) / sizeof(StringOptions[0]);
	TOption<unsigned int> UIntOptions[] = {
		{ "jointries", &CUser::SetJoinTries },
	};
	size_t numUIntOptions = sizeof(UIntOptions) / sizeof(UIntOptions[0]);
	TOption<bool> BoolOptions[] = {
		{ "keepbuffer", &CUser::SetKeepBuffer }, // XXX compatibility crap from pre-0.207
		{ "autoclearchanbuffer", &CUser::SetAutoClearChanBuffer },
		{ "multiclients", &CUser::SetMultiClients },
		{ "denyloadmod", &CUser::SetDenyLoadMod },
		{ "admin", &CUser::SetAdmin },
		{ "denysetbindhost", &CUser::SetDenySetBindHost },
		{ "denysetvhost", &CUser::SetDenySetBindHost },
		{ "appendtimestamp", &CUser::SetTimestampAppend },
		{ "prependtimestamp", &CUser::SetTimestampPrepend },
	};
	size_t numBoolOptions = sizeof(BoolOptions) / sizeof(BoolOptions[0]);

	for (size_t i = 0; i < numStringOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(StringOptions[i].name, sValue))
			(this->*StringOptions[i].pSetter)(sValue);
	}
	for (size_t i = 0; i < numUIntOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(UIntOptions[i].name, sValue))
			(this->*UIntOptions[i].pSetter)(sValue.ToUInt());
	}
	for (size_t i = 0; i < numBoolOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(BoolOptions[i].name, sValue))
			(this->*BoolOptions[i].pSetter)(sValue.ToBool());
	}

	VCString vsList;
	VCString::const_iterator vit;
	pConfig->FindStringVector("allow", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		AddAllowedHost(*vit);
	}
	pConfig->FindStringVector("ctcpreply", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		const CString& sValue = *vit;
		AddCTCPReply(sValue.Token(0), sValue.Token(1, true));
	}

	CString sValue;

	// MaxJoins has been removed
	pConfig->FindStringEntry("maxjoins", sValue);

	CString sDCCLookupValue;
	pConfig->FindStringEntry("dcclookupmethod", sDCCLookupValue);
	if (pConfig->FindStringEntry("bouncedccs", sValue))  {
		if (sValue.ToBool()) {
			CUtils::PrintAction("Loading Module [bouncedcc]");
			CString sModRet;
			bool bModRet = GetModules().LoadModule("bouncedcc", "", CModInfo::UserModule, this, NULL, sModRet);

			CUtils::PrintStatus(bModRet, sModRet);
			if (!bModRet) {
				sError = sModRet;
				return false;
			}

			if (sDCCLookupValue.Equals("Client")) {
				GetModules().FindModule("bouncedcc")->SetNV("UseClientIP", "1");
			}
		}
	}
	if (pConfig->FindStringEntry("buffer", sValue))
		SetBufferCount(sValue.ToUInt(), true);
	if (pConfig->FindStringEntry("awaysuffix", sValue)) {
		CUtils::PrintMessage("WARNING: AwaySuffix has been depricated, instead try -> LoadModule = awaynick %nick%_" + sValue);
	}
	if (pConfig->FindStringEntry("autocycle", sValue)) {
		if (sValue.Equals("true"))
			CUtils::PrintError("WARNING: AutoCycle has been removed, instead try -> LoadModule = autocycle");
	}
	if (pConfig->FindStringEntry("keepnick", sValue)) {
		if (sValue.Equals("true"))
			CUtils::PrintError("WARNING: KeepNick has been deprecated, instead try -> LoadModule = keepnick");
	}
	if (pConfig->FindStringEntry("statusprefix", sValue)) {
		if (!SetStatusPrefix(sValue)) {
			sError = "Invalid StatusPrefix [" + sValue + "] Must be 1-5 chars, no spaces.";
			CUtils::PrintError(sError);
			return false;
		}
	}
	if (pConfig->FindStringEntry("timezone", sValue)) {
		SetTimezone(sValue);
	}
	if (pConfig->FindStringEntry("timezoneoffset", sValue)) {
		if (fabs(sValue.ToDouble()) > 0.1) {
			CUtils::PrintError("WARNING: TimezoneOffset has been deprecated, now you can set your timezone by name");
		}
	}
	if (pConfig->FindStringEntry("timestamp", sValue)) {
		if (!sValue.Trim_n().Equals("true")) {
			if (sValue.Trim_n().Equals("append")) {
				SetTimestampAppend(true);
				SetTimestampPrepend(false);
			} else if (sValue.Trim_n().Equals("prepend")) {
				SetTimestampAppend(false);
				SetTimestampPrepend(true);
			} else if (sValue.Trim_n().Equals("false")) {
				SetTimestampAppend(false);
				SetTimestampPrepend(false);
			} else {
				SetTimestampFormat(sValue);
			}
		}
	}
	pConfig->FindStringEntry("pass", sValue);
	// There are different formats for this available:
	// Pass = <plain text>
	// Pass = <md5 hash> -
	// Pass = plain#<plain text>
	// Pass = <hash name>#<hash>
	// Pass = <hash name>#<salted hash>#<salt>#
	// 'Salted hash' means hash of 'password' + 'salt'
	// Possible hashes are md5 and sha256
	if (sValue.Right(1) == "-") {
		sValue.RightChomp();
		sValue.Trim();
		SetPass(sValue, CUser::HASH_MD5);
	} else {
		CString sMethod = sValue.Token(0, false, "#");
		CString sPass = sValue.Token(1, true, "#");
		if (sMethod == "md5" || sMethod == "sha256") {
			CUser::eHashType type = CUser::HASH_MD5;
			if (sMethod == "sha256")
				type = CUser::HASH_SHA256;

			CString sSalt = sPass.Token(1, false, "#");
			sPass = sPass.Token(0, false, "#");
			SetPass(sPass, type, sSalt);
		} else if (sMethod == "plain") {
			SetPass(sPass, CUser::HASH_NONE);
		} else {
			SetPass(sValue, CUser::HASH_NONE);
		}
	}
	CConfig::SubConfig subConf;
	CConfig::SubConfig::const_iterator subIt;
	pConfig->FindSubConfig("pass", subConf);
	if (!sValue.empty() && !subConf.empty()) {
		sError = "Password defined more than once";
		CUtils::PrintError(sError);
		return false;
	}
	subIt = subConf.begin();
	if (subIt != subConf.end()) {
		CConfig* pSubConf = subIt->second.m_pSubConfig;
		CString sHash;
		CString sMethod;
		CString sSalt;
		CUser::eHashType method;
		pSubConf->FindStringEntry("hash", sHash);
		pSubConf->FindStringEntry("method", sMethod);
		pSubConf->FindStringEntry("salt", sSalt);
		if (sMethod.empty() || sMethod.Equals("plain"))
			method = CUser::HASH_NONE;
		else if (sMethod.Equals("md5"))
			method = CUser::HASH_MD5;
		else if (sMethod.Equals("sha256"))
			method = CUser::HASH_SHA256;
		else {
			sError = "Invalid hash method";
			CUtils::PrintError(sError);
			return false;
		}

		SetPass(sHash, method, sSalt);
		if (!pSubConf->empty()) {
			sError = "Unhandled lines in config!";
			CUtils::PrintError(sError);

			CZNC::DumpConfig(pSubConf);
			return false;
		}
		subIt++;
	}
	if (subIt != subConf.end()) {
		sError = "Password defined more than once";
		CUtils::PrintError(sError);
		return false;
	}

	pConfig->FindSubConfig("network", subConf);
	for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) {
		const CString& sNetworkName = subIt->first;

		CIRCNetwork *pNetwork = FindNetwork(sNetworkName);

		if (!pNetwork) {
			pNetwork = new CIRCNetwork(this, sNetworkName);
		}

		if (!pNetwork->ParseConfig(subIt->second.m_pSubConfig, sError)) {
			return false;
		}
	}

	if (pConfig->FindStringVector("server", vsList, false) || pConfig->FindStringVector("chan", vsList, false) || pConfig->FindSubConfig("chan", subConf, false)) {
		CIRCNetwork *pNetwork = FindNetwork("default");
		if (!pNetwork) {
			pNetwork = AddNetwork("default");
		}

		if (pNetwork) {
			CUtils::PrintMessage("NOTICE: Found deprecated config, upgrading to a network");

			if (!pNetwork->ParseConfig(pConfig, sError, true)) {
				return false;
			}
		}
	}

	pConfig->FindStringVector("loadmodule", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		sValue = *vit;
		CString sModName = sValue.Token(0);

		// XXX Legacy crap, added in ZNC 0.089
		if (sModName == "discon_kick") {
			CUtils::PrintMessage("NOTICE: [discon_kick] was renamed, loading [disconkick] instead");
			sModName = "disconkick";
		}

		// XXX Legacy crap, added in ZNC 0.099
		if (sModName == "fixfreenode") {
			CUtils::PrintMessage("NOTICE: [fixfreenode] doesn't do anything useful anymore, ignoring it");
			continue;
		}

		CUtils::PrintAction("Loading Module [" + sModName + "]");
		CString sModRet;
		CString sArgs = sValue.Token(1, true);
		bool bModRet = true;

		CModInfo ModInfo;
		if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sModName, sModRet)) {
			sError = "Unable to find modinfo [" + sModName + "] [" + sModRet + "]";
			return false;
		}

		if (!ModInfo.SupportsType(CModInfo::UserModule) && ModInfo.SupportsType(CModInfo::NetworkModule)) {
			CUtils::PrintMessage("NOTICE: Module [" + sModName + "] is a network module, loading module for all networks in user.");

			// Do they have old NV?
			CFile fNVFile = CFile(GetUserPath() + "/moddata/" + sModName + "/.registry");

			for (vector<CIRCNetwork*>::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
				if (fNVFile.Exists()) {
					CString sNetworkModPath = (*it)->GetNetworkPath() + "/moddata/" + sModName;
					if (!CFile::Exists(sNetworkModPath)) {
						CDir::MakeDir(sNetworkModPath);
					}

					fNVFile.Copy(sNetworkModPath + "/.registry");
				}

				bModRet = (*it)->GetModules().LoadModule(sModName, sArgs, CModInfo::NetworkModule, this, *it, sModRet);
				if (!bModRet) {
					break;
				}
			}
		} else {
			bModRet = GetModules().LoadModule(sModName, sArgs, CModInfo::UserModule, this, NULL, sModRet);
		}

		CUtils::PrintStatus(bModRet, sModRet);
		if (!bModRet) {
			sError = sModRet;
			return false;
		}
		continue;
	}

	// Move ircconnectenabled to the networks
	if (pConfig->FindStringEntry("ircconnectenabled", sValue)) {
		for (vector<CIRCNetwork*>::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
			(*it)->SetIRCConnectEnabled(sValue.ToBool());
		}
	}

	return true;
}
Example #5
0
bool CIRCNetwork::ParseConfig(CConfig* pConfig, CString& sError,
                              bool bUpgrade) {
    VCString vsList;

    if (!bUpgrade) {
        TOption<const CString&> StringOptions[] = {
            {"nick", &CIRCNetwork::SetNick},
            {"altnick", &CIRCNetwork::SetAltNick},
            {"ident", &CIRCNetwork::SetIdent},
            {"realname", &CIRCNetwork::SetRealName},
            {"bindhost", &CIRCNetwork::SetBindHost},
            {"encoding", &CIRCNetwork::SetEncoding},
            {"quitmsg", &CIRCNetwork::SetQuitMsg},
        };
        TOption<bool> BoolOptions[] = {
            {"ircconnectenabled", &CIRCNetwork::SetIRCConnectEnabled},
            {"trustallcerts", &CIRCNetwork::SetTrustAllCerts},
            {"trustpki", &CIRCNetwork::SetTrustPKI},
        };
        TOption<double> DoubleOptions[] = {
            {"floodrate", &CIRCNetwork::SetFloodRate},
        };
        TOption<short unsigned int> SUIntOptions[] = {
            {"floodburst", &CIRCNetwork::SetFloodBurst},
            {"joindelay", &CIRCNetwork::SetJoinDelay},
        };

        for (const auto& Option : StringOptions) {
            CString sValue;
            if (pConfig->FindStringEntry(Option.name, sValue))
                (this->*Option.pSetter)(sValue);
        }

        for (const auto& Option : BoolOptions) {
            CString sValue;
            if (pConfig->FindStringEntry(Option.name, sValue))
                (this->*Option.pSetter)(sValue.ToBool());
        }

        for (const auto& Option : DoubleOptions) {
            double fValue;
            if (pConfig->FindDoubleEntry(Option.name, fValue))
                (this->*Option.pSetter)(fValue);
        }

        for (const auto& Option : SUIntOptions) {
            unsigned short value;
            if (pConfig->FindUShortEntry(Option.name, value))
                (this->*Option.pSetter)(value);
        }

        pConfig->FindStringVector("loadmodule", vsList);
        for (const CString& sValue : vsList) {
            CString sModName = sValue.Token(0);
            CString sNotice = "Loading network module [" + sModName + "]";

            // XXX Legacy crap, added in ZNC 0.203, modified in 0.207
            // Note that 0.203 == 0.207
            if (sModName == "away") {
                sNotice =
                    "NOTICE: [away] was renamed, loading [awaystore] instead";
                sModName = "awaystore";
            }

            // XXX Legacy crap, added in ZNC 0.207
            if (sModName == "autoaway") {
                sNotice =
                    "NOTICE: [autoaway] was renamed, loading [awaystore] "
                    "instead";
                sModName = "awaystore";
            }

            // XXX Legacy crap, added in 1.1; fakeonline module was dropped in
            // 1.0 and returned in 1.1
            if (sModName == "fakeonline") {
                sNotice =
                    "NOTICE: [fakeonline] was renamed, loading "
                    "[modules_online] instead";
                sModName = "modules_online";
            }

            CString sModRet;
            CString sArgs = sValue.Token(1, true);

            bool bModRet = LoadModule(sModName, sArgs, sNotice, sModRet);

            if (!bModRet) {
                // XXX The awaynick module was retired in 1.6 (still available
                // as external module)
                if (sModName == "awaynick") {
                    // load simple_away instead, unless it's already on the list
                    bool bFound = false;
                    for (const CString& sLoadMod : vsList) {
                        if (sLoadMod.Token(0).Equals("simple_away")) {
                            bFound = true;
                        }
                    }
                    if (!bFound) {
                        sNotice =
                            "Loading network module [simple_away] instead";
                        sModName = "simple_away";
                        // not a fatal error if simple_away is not available
                        LoadModule(sModName, sArgs, sNotice, sModRet);
                    }
                } else {
                    sError = sModRet;
                    return false;
                }
            }
        }
    }

    pConfig->FindStringVector("server", vsList);
    for (const CString& sServer : vsList) {
        CUtils::PrintAction("Adding server [" + sServer + "]");
        CUtils::PrintStatus(AddServer(sServer));
    }

    pConfig->FindStringVector("trustedserverfingerprint", vsList);
    for (const CString& sFP : vsList) {
        AddTrustedFingerprint(sFP);
    }

    pConfig->FindStringVector("chan", vsList);
    for (const CString& sChan : vsList) {
        AddChan(sChan, true);
    }

    CConfig::SubConfig subConf;
    CConfig::SubConfig::const_iterator subIt;

    pConfig->FindSubConfig("chan", subConf);
    for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) {
        const CString& sChanName = subIt->first;
        CConfig* pSubConf = subIt->second.m_pSubConfig;
        CChan* pChan = new CChan(sChanName, this, true, pSubConf);

        if (!pSubConf->empty()) {
            sError = "Unhandled lines in config for User [" +
                     m_pUser->GetUserName() + "], Network [" + GetName() +
                     "], Channel [" + sChanName + "]!";
            CUtils::PrintError(sError);

            CZNC::DumpConfig(pSubConf);
            delete pChan;
            return false;
        }

        // Save the channel name, because AddChan
        // deletes the CChannel*, if adding fails
        sError = pChan->GetName();
        if (!AddChan(pChan)) {
            sError = "Channel [" + sError + "] defined more than once";
            CUtils::PrintError(sError);
            return false;
        }
        sError.clear();
    }

    return true;
}