Пример #1
0
	EModRet OnNumericMessage(CNumericMessage &Message) override {
		unsigned int uCode = Message.GetCode();

		if (uCode == 375 /* RPL_MOTDSTART */
				|| uCode == 372 /* RPL_MOTD */)
			return HALT;
		if (uCode == 376 /* RPL_ENDOFMOTD */) {
			Message.SetCommand("422"); /* ERR_NOMOTD */
			Message.SetParams({Message.GetParam(0), "MOTD blocked by ZNC"});
		}
		return CONTINUE;
	}
Пример #2
0
    EModRet OnNumericMessage(CNumericMessage& msg) override {
        if (m_pTimer) {
            // Are we trying to get our primary nick and we caused this error?
            // :irc.server.net 433 mynick badnick :Nickname is already in use.
            if (msg.GetCode() == 433 && msg.GetParam(1).Equals(GetNick())) {
                return HALT;
            }
            // clang-format off
            // :leguin.freenode.net 435 mynick badnick #chan :Cannot change nickname while banned on channel
            // clang-format on
            if (msg.GetCode() == 435) {
                PutModule("Unable to obtain nick " + msg.GetParam(1) + ": " +
                          msg.GetParam(3) + ", " + msg.GetParam(2));
                Disable();
            }
            // clang-format off
            // :irc1.unrealircd.org 447 mynick :Can not change nickname while on #chan (+N)
            // clang-format on
            if (msg.GetCode() == 447) {
                PutModule("Unable to obtain nick: " + msg.GetParam(1));
                Disable();
            }
        }

        return CONTINUE;
    }
Пример #3
0
static CMessage BufferMessage(const CNumericMessage& Message) {
    CMessage Format(Message);
    Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetHostMask())));
    Format.SetParam(0, "{target}");
    unsigned uParams = Format.GetParams().size();
    for (unsigned int i = 1; i < uParams; ++i) {
        Format.SetParam(i, _NAMEDFMT(Format.GetParam(i)));
    }
    return Format;
}
Пример #4
0
TEST(MessageTest, Numeric) {
	CNumericMessage msg;
	msg.Parse(":server 123 user :foo bar");
	EXPECT_EQ("server", msg.GetNick().GetNick());
	EXPECT_EQ("123", msg.GetCommand());
	EXPECT_EQ(123u, msg.GetCode());
	EXPECT_EQ(CMessage::Type::Numeric, msg.GetType());

	EXPECT_EQ(":server 123 user :foo bar", msg.ToString());
}
Пример #5
0
    EModRet OnNumericMessage(CNumericMessage& msg) override {
        if (msg.GetCode() == 903) {
            /* SASL success! */
            if (m_bVerbose) {
                PutModule(m_Mechanisms.GetCurrent() + " mechanism succeeded.");
            }
            GetNetwork()->GetIRCSock()->ResumeCap();
            m_bAuthenticated = true;
            DEBUG("sasl: Authenticated with mechanism ["
                  << m_Mechanisms.GetCurrent() << "]");
        } else if (msg.GetCode() == 904 ||
                   msg.GetCode() == 905) {
            DEBUG("sasl: Mechanism [" << m_Mechanisms.GetCurrent()
                                      << "] failed.");
            if (m_bVerbose) {
                PutModule(m_Mechanisms.GetCurrent() + " mechanism failed.");
            }

            if (m_Mechanisms.HasNext()) {
                m_Mechanisms.IncrementIndex();
                PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent());
            } else {
                CheckRequireAuth();
                GetNetwork()->GetIRCSock()->ResumeCap();
            }
        } else if (msg.GetCode() == 906) {
            /* CAP wasn't paused? */
            DEBUG("sasl: Reached 906.");
            CheckRequireAuth();
        } else if (msg.GetCode() == 907) {
            m_bAuthenticated = true;
            GetNetwork()->GetIRCSock()->ResumeCap();
            DEBUG("sasl: Received 907 -- We are already registered");
        } else {
            return CONTINUE;
        }
        return HALT;
    }
Пример #6
0
bool CIRCSock::OnNumericMessage(CNumericMessage& Message) {
    const CString& sCmd = Message.GetCommand();
    CString sServer = Message.GetNick().GetHostMask();
    unsigned int uRaw = Message.GetCode();
    CString sNick = Message.GetParam(0);

    bool bResult = false;
    IRCSOCKMODULECALL(OnNumericMessage(Message), &bResult);
    if (bResult) return true;

    switch (uRaw) {
    case 1: {  // :irc.server.com 001 nick :Welcome to the Internet Relay
        if (m_bAuthed && sServer == "irc.znc.in") {
            // m_bAuthed == true => we already received another 001 => we
            // might be in a traffic loop
            m_pNetwork->PutStatus(
                "ZNC seems to be connected to itself, disconnecting...");
            Quit();
            return true;
        }

        m_pNetwork->SetIRCServer(sServer);
        // Now that we are connected, let nature take its course
        SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ);
        PutIRC("WHO " + sNick);

        m_bAuthed = true;
        m_pNetwork->PutStatus("Connected!");

        const vector<CClient*>& vClients = m_pNetwork->GetClients();

        for (CClient* pClient : vClients) {
            CString sClientNick = pClient->GetNick(false);

            if (!sClientNick.Equals(sNick)) {
                // If they connected with a nick that doesn't match the one
                // we got on irc, then we need to update them
                pClient->PutClient(":" + sClientNick + "!" +
                                   m_Nick.GetIdent() + "@" +
                                   m_Nick.GetHost() + " NICK :" + sNick);
            }
        }

        SetNick(sNick);

        IRCSOCKMODULECALL(OnIRCConnected(), NOTHING);

        m_pNetwork->ClearRawBuffer();
        m_pNetwork->AddRawBuffer(BufferMessage(Message));

        m_pNetwork->IRCConnected();

        break;
    }
    case 5:
        ParseISupport(Message);
        m_pNetwork->UpdateExactRawBuffer(BufferMessage(Message));
        break;
    case 10: {  // :irc.server.com 010 nick <hostname> <port> :<info>
        CString sHost = Message.GetParam(1);
        CString sPort = Message.GetParam(2);
        CString sInfo = Message.GetParam(3);
        m_pNetwork->PutStatus(
            "Server [" + m_pNetwork->GetCurrentServer()->GetString(false) +
            "] redirects us to [" + sHost + ":" + sPort +
            "] with reason [" + sInfo + "]");
        m_pNetwork->PutStatus(
            "Perhaps you want to add it as a new server.");
        // Don't send server redirects to the client
        return true;
    }
    case 2:
    case 3:
    case 4:
    case 250:  // highest connection count
    case 251:  // user count
    case 252:  // oper count
    case 254:  // channel count
    case 255:  // client count
    case 265:  // local users
    case 266:  // global users
        m_pNetwork->UpdateRawBuffer(sCmd, BufferMessage(Message));
        break;
    case 305:
        m_pNetwork->SetIRCAway(false);
        break;
    case 306:
        m_pNetwork->SetIRCAway(true);
        break;
    case 324: {  // MODE
        // :irc.server.com 324 nick #chan +nstk key
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            pChan->SetModes(Message.GetParams(2));

            // We don't SetModeKnown(true) here,
            // because a 329 will follow
            if (!pChan->IsModeKnown()) {
                // When we JOIN, we send a MODE
                // request. This makes sure the
                // reply isn't forwarded.
                return true;
            }
            if (pChan->IsDetached()) {
                return true;
            }
        }
    }
    break;
    case 329: {
        // :irc.server.com 329 nick #chan 1234567890
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            unsigned long ulDate = Message.GetParam(2).ToULong();
            pChan->SetCreationDate(ulDate);

            if (!pChan->IsModeKnown()) {
                pChan->SetModeKnown(true);
                // When we JOIN, we send a MODE
                // request. This makes sure the
                // reply isn't forwarded.
                return true;
            }
            if (pChan->IsDetached()) {
                return true;
            }
        }
    }
    break;
    case 331: {
        // :irc.server.com 331 yournick #chan :No topic is set.
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            pChan->SetTopic("");
            if (pChan->IsDetached()) {
                return true;
            }
        }

        break;
    }
    case 332: {
        // :irc.server.com 332 yournick #chan :This is a topic
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            CString sTopic = Message.GetParam(2);
            pChan->SetTopic(sTopic);
            if (pChan->IsDetached()) {
                return true;
            }
        }

        break;
    }
    case 333: {
        // :irc.server.com 333 yournick #chan setternick 1112320796
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            sNick = Message.GetParam(2);
            unsigned long ulDate = Message.GetParam(3).ToULong();

            pChan->SetTopicOwner(sNick);
            pChan->SetTopicDate(ulDate);

            if (pChan->IsDetached()) {
                return true;
            }
        }

        break;
    }
    case 352: {  // WHO
        // :irc.yourserver.com 352 yournick #chan ident theirhost.com irc.theirserver.com theirnick H :0 Real Name
        sNick = Message.GetParam(5);
        CString sChan = Message.GetParam(1);
        CString sIdent = Message.GetParam(2);
        CString sHost = Message.GetParam(3);

        if (sNick.Equals(GetNick())) {
            m_Nick.SetIdent(sIdent);
            m_Nick.SetHost(sHost);
        }

        m_pNetwork->SetIRCNick(m_Nick);
        m_pNetwork->SetIRCServer(sServer);

        const vector<CChan*>& vChans = m_pNetwork->GetChans();

        for (CChan* pChan : vChans) {
            pChan->OnWho(sNick, sIdent, sHost);
        }

        CChan* pChan = m_pNetwork->FindChan(sChan);
        if (pChan && pChan->IsDetached()) {
            return true;
        }

        break;
    }
    case 353: {  // NAMES
        // :irc.server.com 353 nick @ #chan :nick1 nick2
        // Todo: allow for non @+= server msgs
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(2));
        // If we don't know that channel, some client might have
        // requested a /names for it and we really should forward this.
        if (pChan) {
            CString sNicks = Message.GetParam(3);
            pChan->AddNicks(sNicks);
            if (pChan->IsDetached()) {
                return true;
            }
        }

        break;
    }
    case 366: {  // end of names list
        // :irc.server.com 366 nick #chan :End of /NAMES list.
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));

        if (pChan) {
            if (pChan->IsOn()) {
                // If we are the only one in the chan, set our default modes
                if (pChan->GetNickCount() == 1) {
                    CString sModes = pChan->GetDefaultModes();

                    if (sModes.empty()) {
                        sModes =
                            m_pNetwork->GetUser()->GetDefaultChanModes();
                    }

                    if (!sModes.empty()) {
                        PutIRC("MODE " + pChan->GetName() + " " + sModes);
                    }
                }
            }
            if (pChan->IsDetached()) {
                // don't put it to clients
                return true;
            }
        }

        break;
    }
    case 375:  // begin motd
    case 422:  // MOTD File is missing
        if (m_pNetwork->GetIRCServer().Equals(sServer)) {
            m_pNetwork->ClearMotdBuffer();
        }
    case 372:  // motd
    case 376:  // end motd
        if (m_pNetwork->GetIRCServer().Equals(sServer)) {
            m_pNetwork->AddMotdBuffer(BufferMessage(Message));
        }
        break;
    case 437:
        // :irc.server.net 437 * badnick :Nick/channel is temporarily unavailable
        // :irc.server.net 437 mynick badnick :Nick/channel is temporarily unavailable
        // :irc.server.net 437 mynick badnick :Cannot change nickname while banned on channel
        if (m_pNetwork->IsChan(Message.GetParam(1)) || sNick != "*") break;
    case 432:
    // :irc.server.com 432 * nick :Erroneous Nickname: Illegal chars
    case 433: {
        CString sBadNick = Message.GetParam(1);

        if (!m_bAuthed) {
            SendAltNick(sBadNick);
            return true;
        }
        break;
    }
    case 451:
        // :irc.server.com 451 CAP :You have not registered
        // Servers that don't support CAP will give us this error, don't send
        // it to the client
        if (sNick.Equals("CAP")) return true;
    case 470: {
        // :irc.unreal.net 470 mynick [Link] #chan1 has become full, so you are automatically being transferred to the linked channel #chan2
        // :mccaffrey.freenode.net 470 mynick #electronics ##electronics :Forwarding to another channel

        // freenode style numeric
        CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));
        if (!pChan) {
            // unreal style numeric
            pChan = m_pNetwork->FindChan(Message.GetParam(2));
        }
        if (pChan) {
            pChan->Disable();
            m_pNetwork->PutStatus("Channel [" + pChan->GetName() +
                                  "] is linked to "
                                  "another channel and was thus disabled.");
        }
        break;
    }
    case 670:
        // :hydra.sector5d.org 670 kylef :STARTTLS successful, go ahead with TLS handshake
        //
        // 670 is a response to `STARTTLS` telling the client to switch to
        // TLS
        if (!GetSSL()) {
            StartTLS();
            m_pNetwork->PutStatus("Switched to SSL (STARTTLS)");
        }

        return true;
    }

    return false;
}
Пример #7
0
	EModRet OnNumericMessage(CNumericMessage& msg) override { vsHooks.push_back("OnNumericMessage"); vsMessages.push_back(msg.ToString()); vNetworks.push_back(msg.GetNetwork()); vChannels.push_back(msg.GetChan()); return eAction; }