void CChan::ModeChange(const CString& sModes, const CString& sOpNick) { CString sModeArg = sModes.Token(0); CString sArgs = sModes.Token(1, true); bool bAdd = true; #ifdef _MODULES CNick* pOpNick = FindNick(sOpNick); if (pOpNick) { MODULECALL(OnRawMode(*pOpNick, *this, sModeArg, sArgs), m_pUser, NULL, ); } #endif for (unsigned int a = 0; a < sModeArg.size(); a++) { const unsigned char& uMode = sModeArg[a]; if (uMode == '+') { bAdd = true; } else if (uMode == '-') { bAdd = false; } else if (m_pUser->GetIRCSock()->IsPermMode(uMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { unsigned char uPerm = m_pUser->GetIRCSock()->GetPermFromMode(uMode); if (uPerm) { if (bAdd) { pNick->AddPerm(uPerm); if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { AddPerm(uPerm); } } else { pNick->RemPerm(uPerm); if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { RemPerm(uPerm); } } #ifdef _MODULES bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); if (uMode && pOpNick) { MODULECALL(OnChanPermission(*pOpNick, *pNick, *this, uMode, bAdd, bNoChange), m_pUser, NULL, ); if (uMode == CChan::M_Op) { if (bAdd) { MODULECALL(OnOp(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } else { MODULECALL(OnDeop(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } } else if (uMode == CChan::M_Voice) { if (bAdd) { MODULECALL(OnVoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } else { MODULECALL(OnDevoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } } }
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; }
void OpUser(const CNick& Nick, const CAutoOpUser& User) { const vector<CChan*>& Chans = m_pUser->GetChans(); for (size_t a = 0; a < Chans.size(); a++) { const CChan& Chan = *Chans[a]; if (Chan.HasPerm(CChan::Op) && User.ChannelMatches(Chan.GetName())) { CNick* pNick = Chan.FindNick(Nick.GetNick()); if (pNick && !pNick->HasPerm(CChan::Op)) { PutIRC("MODE " + Chan.GetName() + " +o " + Nick.GetNick()); } } } }
void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { CString sModeArg = sModes.Token(0); CString sArgs = sModes.Token(1, true); bool bAdd = true; /* Try to find a CNick* from this channel so that pOpNick->HasPerm() * works as expected. */ if (pOpNick) { CNick* OpNick = FindNick(pOpNick->GetNick()); /* If nothing was found, use the original pOpNick, else use the * CNick* from FindNick() */ if (OpNick) pOpNick = OpNick; } if (pOpNick) { NETWORKMODULECALL(OnRawMode(*pOpNick, *this, sModeArg, sArgs), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } for (unsigned int a = 0; a < sModeArg.size(); a++) { const unsigned char& uMode = sModeArg[a]; if (uMode == '+') { bAdd = true; } else if (uMode == '-') { bAdd = false; } else if (m_pNetwork->GetIRCSock()->IsPermMode(uMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { unsigned char uPerm = m_pNetwork->GetIRCSock()->GetPermFromMode(uMode); if (uPerm) { if (bAdd) { pNick->AddPerm(uPerm); if (pNick->GetNick().Equals(m_pNetwork->GetCurNick())) { AddPerm(uPerm); } } else { pNick->RemPerm(uPerm); if (pNick->GetNick().Equals(m_pNetwork->GetCurNick())) { RemPerm(uPerm); } } bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); if (uMode && pOpNick) { NETWORKMODULECALL(OnChanPermission(*pOpNick, *pNick, *this, uMode, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); if (uMode == CChan::M_Op) { if (bAdd) { NETWORKMODULECALL(OnOp(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } else { NETWORKMODULECALL(OnDeop(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } } else if (uMode == CChan::M_Voice) { if (bAdd) { NETWORKMODULECALL(OnVoice(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } else { NETWORKMODULECALL(OnDevoice(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } } } } } } else { bool bList = false; CString sArg; switch (m_pNetwork->GetIRCSock()->GetModeType(uMode)) { case CIRCSock::ListArg: bList = true; sArg = GetModeArg(sArgs); break; case CIRCSock::HasArg: sArg = GetModeArg(sArgs); break; case CIRCSock::NoArg: break; case CIRCSock::ArgWhenSet: if (bAdd) { sArg = GetModeArg(sArgs); } break; } bool bNoChange; if (bList) { bNoChange = false; } else if (bAdd) { bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; } else { bNoChange = !HasMode(uMode); } NETWORKMODULECALL(OnMode(*pOpNick, *this, uMode, sArg, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); if (!bList) { (bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); } } } }
void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { CString sModeArg = sModes.Token(0); CString sArgs = sModes.Token(1, true); bool bAdd = true; /* Try to find a CNick* from this channel so that pOpNick->HasPerm() * works as expected. */ if (pOpNick) { CNick* OpNick = FindNick(pOpNick->GetNick()); /* If nothing was found, use the original pOpNick, else use the * CNick* from FindNick() */ if (OpNick) pOpNick = OpNick; } NETWORKMODULECALL(OnRawMode2(pOpNick, *this, sModeArg, sArgs), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); for (unsigned int a = 0; a < sModeArg.size(); a++) { const char& cMode = sModeArg[a]; if (cMode == '+') { bAdd = true; } else if (cMode == '-') { bAdd = false; } else if (m_pNetwork->GetIRCSock()->IsPermMode(cMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { char cPerm = m_pNetwork->GetIRCSock()->GetPermFromMode(cMode); if (cPerm) { bool bNoChange = (pNick->HasPerm(cPerm) == bAdd); if (bAdd) { pNick->AddPerm(cPerm); if (pNick->NickEquals(m_pNetwork->GetCurNick())) { AddPerm(cPerm); } } else { pNick->RemPerm(cPerm); if (pNick->NickEquals(m_pNetwork->GetCurNick())) { RemPerm(cPerm); } } NETWORKMODULECALL(OnChanPermission3(pOpNick, *pNick, *this, cMode, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); if (cMode == CChan::M_Op) { if (bAdd) { NETWORKMODULECALL( OnOp2(pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); } else { NETWORKMODULECALL( OnDeop2(pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); } } else if (cMode == CChan::M_Voice) { if (bAdd) { NETWORKMODULECALL( OnVoice2(pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); } else { NETWORKMODULECALL( OnDevoice2(pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); } } } } } else { bool bList = false; CString sArg; switch (m_pNetwork->GetIRCSock()->GetModeType(cMode)) { case CIRCSock::ListArg: bList = true; sArg = GetModeArg(sArgs); break; case CIRCSock::HasArg: sArg = GetModeArg(sArgs); break; case CIRCSock::NoArg: break; case CIRCSock::ArgWhenSet: if (bAdd) { sArg = GetModeArg(sArgs); } break; } bool bNoChange; if (bList) { bNoChange = false; } else if (bAdd) { bNoChange = HasMode(cMode) && GetModeArg(cMode) == sArg; } else { bNoChange = !HasMode(cMode); } NETWORKMODULECALL( OnMode2(pOpNick, *this, cMode, sArg, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); if (!bList) { (bAdd) ? AddMode(cMode, sArg) : RemMode(cMode); } // This is called when we join (ZNC requests the channel modes // on join) *and* when someone changes the channel keys. // We ignore channel key "*" because of some broken nets. if (cMode == M_Key && !bNoChange && bAdd && sArg != "*") { SetKey(sArg); } } } }