bool VerifyResponse(const CNick& Nick, const CString& sResponse) { MCString::iterator itQueue = m_msQueue.find(Nick.GetNick().AsLower()); if (itQueue == m_msQueue.end()) { PutModule("[" + Nick.GetHostMask() + "] sent an unchallenged response. This could be due to lag."); return false; } CString sChallenge = itQueue->second; m_msQueue.erase(itQueue); for (map<CString, CAutoOpUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); it++) { if (it->second->HostMatches(Nick.GetHostMask())) { if (sResponse == CString(it->second->GetUserKey() + "::" + sChallenge).MD5()) { OpUser(Nick, *it->second); return true; } else { PutModule("WARNING! [" + Nick.GetHostMask() + "] sent a bad response. Please verify that you have their correct password."); return false; } } } PutModule("WARNING! [" + Nick.GetHostMask() + "] sent a response but did not match any defined users."); return false; }
bool ChallengeRespond(const CNick& Nick, const CString& sChallenge) { // Validate before responding - don't blindly trust everyone bool bValid = false; bool bMatchedHost = false; CAutoOpUser* pUser = NULL; for (map<CString, CAutoOpUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); it++) { pUser = it->second; // First verify that the guy who challenged us matches a user's host if (pUser->HostMatches(Nick.GetHostMask())) { const vector<CChan*>& Chans = m_pUser->GetChans(); bMatchedHost = true; // Also verify that they are opped in at least one of the user's chans for (size_t a = 0; a < Chans.size(); a++) { const CChan& Chan = *Chans[a]; CNick* pNick = Chan.FindNick(Nick.GetNick()); if (pNick) { if (pNick->HasPerm(CChan::Op) && pUser->ChannelMatches(Chan.GetName())) { bValid = true; break; } } } if (bValid) { break; } } } if (!bValid) { if (bMatchedHost) { PutModule("[" + Nick.GetHostMask() + "] sent us a challenge but they are not opped in any defined channels."); } else { PutModule("[" + Nick.GetHostMask() + "] sent us a challenge but they do not match a defined user."); } return false; } if (sChallenge.length() != AUTOOP_CHALLENGE_LENGTH) { PutModule("WARNING! [" + Nick.GetHostMask() + "] sent an invalid challenge."); return false; } CString sResponse = pUser->GetUserKey() + "::" + sChallenge; PutIRC("NOTICE " + Nick.GetNick() + " :!ZNCAO RESPONSE " + sResponse.MD5()); return false; }
bool CheckAutoVoice(const CNick& Nick, CChan& Channel) { CAutoVoiceUser *pUser = FindUserByHost(Nick.GetHostMask(), Channel.GetName()); if (!pUser) { return false; } PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); return true; }
void OnJoin(const CNick& Nick, CChan& Channel) override { // If we have ops in this chan if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) { for (const auto& it : m_msUsers) { // and the nick who joined is a valid user if (it.second->HostMatches(Nick.GetHostMask()) && it.second->ChannelMatches(Channel.GetName())) { PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); break; } } } }
virtual void OnJoin(const CNick& Nick, CChan& Channel) { // If we have ops in this chan if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) { for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) { // and the nick who joined is a valid user if (it->second->HostMatches(Nick.GetHostMask()) && it->second->ChannelMatches(Channel.GetName())) { PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); break; } } } }
bool CheckAutoOp(const CNick& Nick, CChan& Channel) { CAutoOpUser *pUser = FindUserByHost(Nick.GetHostMask(), Channel.GetName()); if (pUser) { if (pUser->GetUserKey().Equals("__NOKEY__")) { PutIRC("MODE " + Channel.GetName() + " +o " + Nick.GetNick()); } else { // then insert this nick into the queue, the timer does the rest CString sNick = Nick.GetNick().AsLower(); if (m_msQueue.find(sNick) == m_msQueue.end()) { m_msQueue[sNick] = ""; } } } return pUser; }
virtual void OnJoin(const CNick& Nick, CChan& Channel) { // If we have ops in this chan if (Channel.HasPerm(CChan::Op)) { for (map<CString, CAutoOpUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); it++) { // and the nick who joined is a valid user if (it->second->HostMatches(Nick.GetHostMask()) && it->second->ChannelMatches(Channel.GetName())) { if (it->second->GetUserKey().Equals("__NOKEY__")) { PutIRC("MODE " + Channel.GetName() + " +o " + Nick.GetNick()); } else { // then insert this nick into the queue, the timer does the rest m_msQueue[Nick.GetNick().AsLower()] = ""; } break; } } } }
void TryAttach(const CNick& Nick, CChan& Channel, CString& Message) { const CString& sChan = Channel.GetName(); const CString& sHost = Nick.GetHostMask(); const CString& sMessage = Message; VAttachIter it; if (!Channel.IsDetached()) return; // Any negated match? for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { if (it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) return; } // Now check for a positive match for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { if (!it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) { Channel.AttachUser(); return; } } }
EModRet Message(const CNick& Nick, const CString& sMessage) { // We never block /me, because it doesn't cause a reply if (sMessage.Token(0).Equals("ACTION")) return CONTINUE; if (m_tLastCTCP + m_iThresholdSecs < time(nullptr)) { m_tLastCTCP = time(nullptr); m_iNumCTCP = 0; } m_iNumCTCP++; if (m_iNumCTCP < m_iThresholdMsgs) return CONTINUE; else if (m_iNumCTCP == m_iThresholdMsgs) PutModule(t_f("Limit reached by {1}, blocking all CTCP")( Nick.GetHostMask())); // Reset the timeout so that we continue blocking messages m_tLastCTCP = time(nullptr); return HALT; }
bool IsMatch(const CNick& Nick, const CString& sType) const { return (GetType().Equals("all") || GetType().Equals(sType)) && (Nick.GetHostMask().WildCmp(m_sHostMask)); }
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { if (IsCtcpNotifier(sMessage.Token(0))) PutModule("Replying to CTCP " + sMessage.Token(0) + " by " + Nick.GetNick() + " (" + Nick.GetHostMask() + ") to " + Channel.GetName() + "."); return CONTINUE; }
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) { // if we either want to receive all ctcp messages or GetNV(ctcp) contains something, we notify the user. // CTCP ACTIONs are ignored. if (IsCtcpNotifier(sMessage.Token(0))) PutModule("Replying to CTCP " + sMessage.Token(0) + " by " + Nick.GetNick() + " (" + Nick.GetHostMask() + ")."); return CONTINUE; }
bool IsNickMatch(const CNick& Nick) const { return Nick.GetHostMask().AsLower().WildCmp(m_sHostMask.AsLower()); }