示例#1
0
文件: crypt.cpp 项目: jpnurmi/znc
	EModRet OnUserNotice(CString& sTarget, CString& sMessage) override {
		sTarget.TrimPrefix(NickPrefix());

		if (sMessage.TrimPrefix("``")) {
			return CONTINUE;
		}

		MCString::iterator it = FindNV(sTarget.AsLower());

		if (it != EndNV()) {
			CChan* pChan = GetNetwork()->FindChan(sTarget);
			CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask();
			if (pChan) {
				if (!pChan->AutoClearChanBuffer())
					pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + " NOTICE " + _NAMEDFMT(sTarget) + " :{text}", sMessage);
				GetUser()->PutUser(":" + NickPrefix() + sNickMask + " NOTICE " + sTarget + " :" + sMessage, NULL, GetClient());
			}

			CString sMsg = MakeIvec() + sMessage;
			sMsg.Encrypt(it->second);
			sMsg.Base64Encode();
			sMsg = "+OK *" + sMsg;

			PutIRC("NOTICE " + sTarget + " :" + sMsg);
			return HALTCORE;
		}

		return CONTINUE;
	}
示例#2
0
	virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
		VCString vsChans;
		sArgs.Split(" ", vsChans, false);

		for (VCString::const_iterator it = vsChans.begin(); it != vsChans.end(); ++it) {
			CString sAdd = *it;
			bool bNegated = sAdd.TrimPrefix("!");
			CString sChan = sAdd.Token(0);
			CString sHost = sAdd.Token(1, true);

			if (!Add(bNegated, sChan, sHost)) {
				PutModule("Unable to add [" + *it + "]");
			}
		}

		// Load our saved settings, ignore errors
		MCString::iterator it;
		for (it = BeginNV(); it != EndNV(); ++it) {
			CString sAdd = it->first;
			bool bNegated = sAdd.TrimPrefix("!");
			CString sChan = sAdd.Token(0);
			CString sHost = sAdd.Token(1, true);

			Add(bNegated, sChan, sHost);
		}

		return true;
	}
示例#3
0
文件: Message.cpp 项目: BtbN/znc
void CMessage::Parse(CString sMessage) {
    // <tags>
    m_mssTags.clear();
    if (sMessage.StartsWith("@")) {
        VCString vsTags;
        sMessage.Token(0).TrimPrefix_n("@").Split(";", vsTags, false);
        for (const CString& sTag : vsTags) {
            CString sKey = sTag.Token(0, false, "=", true);
            CString sValue = sTag.Token(1, true, "=", true);
            m_mssTags[sKey] =
                sValue.Escape(CString::EMSGTAG, CString::CString::EASCII);
        }
        sMessage = sMessage.Token(1, true);
    }

    //  <message>  ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
    //  <prefix>   ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
    //  <command>  ::= <letter> { <letter> } | <number> <number> <number>
    //  <SPACE>    ::= ' ' { ' ' }
    //  <params>   ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
    //  <middle>   ::= <Any *non-empty* sequence of octets not including SPACE
    //                 or NUL or CR or LF, the first of which may not be ':'>
    //  <trailing> ::= <Any, possibly *empty*, sequence of octets not including
    //                   NUL or CR or LF>

    // <prefix>
    if (sMessage.TrimPrefix(":")) {
        m_Nick.Parse(sMessage.Token(0));
        sMessage = sMessage.Token(1, true);
    }

    // <command>
    m_sCommand = sMessage.Token(0);
    sMessage = sMessage.Token(1, true);

    // <params>
    m_bColon = false;
    m_vsParams.clear();
    while (!sMessage.empty()) {
        m_bColon = sMessage.TrimPrefix(":");
        if (m_bColon) {
            m_vsParams.push_back(sMessage);
            sMessage.clear();
        } else {
            m_vsParams.push_back(sMessage.Token(0));
            sMessage = sMessage.Token(1, true);
        }
    }

    InitType();
}
示例#4
0
int CZNCSock::ConvertAddress(const struct sockaddr_storage* pAddr,
                             socklen_t iAddrLen, CString& sIP,
                             u_short* piPort) const {
    int ret = Csock::ConvertAddress(pAddr, iAddrLen, sIP, piPort);
    if (ret == 0) sIP.TrimPrefix("::ffff:");
    return ret;
}
示例#5
0
文件: Client.cpp 项目: evilnet/znc
bool CClient::OnOtherMessage(CMessage& Message) {
    const CString& sCommand = Message.GetCommand();

    if (sCommand.Equals("ZNC")) {
        CString sTarget = Message.GetParam(0);
        CString sModCommand;

        if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
            sModCommand = Message.GetParams(1);
        } else {
            sTarget = "status";
            sModCommand = Message.GetParams(0);
        }

        if (sTarget.Equals("status")) {
            if (sModCommand.empty())
                PutStatus("Hello. How may I help you?");
            else
                UserCommand(sModCommand);
        } else {
            if (sModCommand.empty())
                CALLMOD(sTarget, this, m_pUser, m_pNetwork,
                        PutModule("Hello. How may I help you?"))
            else
                CALLMOD(sTarget, this, m_pUser, m_pNetwork,
                        OnModCommand(sModCommand))
        }
        return true;
    } else if (sCommand.Equals("ATTACH")) {
示例#6
0
文件: crypt.cpp 项目: jpnurmi/znc
	EModRet OnUserTopic(CString& sTarget, CString& sMessage) override {
		sTarget.TrimPrefix(NickPrefix());

		if (sMessage.TrimPrefix("``")) {
			return CONTINUE;
		}

		MCString::iterator it = FindNV(sTarget.AsLower());

		if (it != EndNV()) {
			sMessage = MakeIvec() + sMessage;
			sMessage.Encrypt(it->second);
			sMessage.Base64Encode();
			sMessage = "+OK *" + sMessage;
		}

		return CONTINUE;
	}
示例#7
0
文件: crypt.cpp 项目: ConorOG/znc
	virtual void OnModCommand(const CString& sCommand) {
		CString sCmd = sCommand.Token(0);

		if (sCmd.Equals("DELKEY")) {
			CString sTarget = sCommand.Token(1);

			if (!sTarget.empty()) {
				if (DelNV(sTarget.AsLower())) {
					PutModule("Target [" + sTarget + "] deleted");
				} else {
					PutModule("Target [" + sTarget + "] not found");
				}
			} else {
				PutModule("Usage DelKey <#chan|Nick>");
			}
		} else if (sCmd.Equals("SETKEY")) {
			CString sTarget = sCommand.Token(1);
			CString sKey = sCommand.Token(2, true);

			// Strip "cbc:" from beginning of string incase someone pastes directly from mircryption
			sKey.TrimPrefix("cbc:");

			if (!sKey.empty()) {
				SetNV(sTarget.AsLower(), sKey);
				PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + "]");
			} else {
				PutModule("Usage: SetKey <#chan|Nick> <Key>");
			}
		} else if (sCmd.Equals("LISTKEYS")) {
			if (BeginNV() == EndNV()) {
				PutModule("You have no encryption keys set.");
			} else {
				CTable Table;
				Table.AddColumn("Target");
				Table.AddColumn("Key");

				for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) {
					Table.AddRow();
					Table.SetCell("Target", it->first);
					Table.SetCell("Key", it->second);
				}

				MCString::iterator it = FindNV(NICK_PREFIX_KEY);
				if (it == EndNV()) {
					Table.AddRow();
					Table.SetCell("Target", NICK_PREFIX_KEY);
					Table.SetCell("Key", NickPrefix());
				}

				PutModule(Table);
			}
		} else if (sCmd.Equals("HELP")) {
			PutModule("Try: SetKey, DelKey, ListKeys");
		} else {
			PutModule("Unknown command, try 'Help'");
		}
	}
示例#8
0
	virtual EModRet OnUserRaw(CString& sLine)
	{
		CString sCmd = sLine.Token(0).AsUpper();

		if (!m_pNetwork->GetIRCSock())
			return CONTINUE;

		if (sCmd.Equals("MODE")) {
			// Check if this is a mode request that needs to be handled

			// If there are arguments to a mode change,
			// we must not route it.
			if (!sLine.Token(3, true).empty())
				return CONTINUE;

			// Grab the mode change parameter
			CString sMode = sLine.Token(2);

			// If this is a channel mode request, znc core replies to it
			if (sMode.empty())
				return CONTINUE;

			// Check if this is a mode change or a specific
			// mode request (the later needs to be routed).
			sMode.TrimPrefix("+");
			if (sMode.length() != 1)
				return CONTINUE;

			// Now just check if it's one of the supported modes
			switch (sMode[0]) {
			case 'I':
			case 'b':
			case 'e':
				break;
			default:
				return CONTINUE;
			}

			// Ok, this looks like we should route it.
			// Fall through to the next loop
		}

		for (size_t i = 0; vRouteReplies[i].szRequest != NULL; i++) {
			if (vRouteReplies[i].szRequest == sCmd) {
				struct queued_req req = {
					sLine, vRouteReplies[i].vReplies
				};
				m_vsPending[m_pClient].push_back(req);
				SendRequest();

				return HALTCORE;
			}
		}

		return CONTINUE;
	}
示例#9
0
	void HandleDel(const CString& sLine) {
		CString sMsg  = sLine.Token(1, true);
		bool bNegated = sMsg.TrimPrefix("!");
		CString sChan = sMsg.Token(0);
		CString sHost = sMsg.Token(1);

		if (Del(bNegated, sChan, sHost)) {
			PutModule("Removed " + sChan + " from list");
		} else {
			PutModule("Usage: Del [!]<#chan> <host>");
		}
	}
示例#10
0
文件: savebuff.cpp 项目: Hasimir/znc
	EBufferType DecryptBuffer(const CString& sPath, CString& sBuffer, CString& sName)
	{
		CString sContent;
		sBuffer = "";

		CFile File(sPath);

		if (sPath.empty() || !File.Open() || !File.ReadFile(sContent))
			 return EmptyBuffer;

		File.Close();

		if (!sContent.empty())
		{
			CBlowfish c(m_sPassword, BF_DECRYPT);
			sBuffer = c.Crypt(sContent);

			if (sBuffer.TrimPrefix(LEGACY_VERIFICATION_TOKEN))
			{
				sName = FindLegacyBufferName(sPath);
				return ChanBuffer;
			}
			else if (sBuffer.TrimPrefix(CHAN_VERIFICATION_TOKEN))
			{
				sName = sBuffer.FirstLine();
				if (sBuffer.TrimLeft(sName + "\n"))
					return ChanBuffer;
			}
			else if (sBuffer.TrimPrefix(QUERY_VERIFICATION_TOKEN))
			{
				sName = sBuffer.FirstLine();
				if (sBuffer.TrimLeft(sName + "\n"))
					return QueryBuffer;
			}

			PutModule("Unable to decode Encrypted file [" + sPath + "]");
			return InvalidBuffer;
		}
		return EmptyBuffer;
	}
示例#11
0
文件: crypt.cpp 项目: jpnurmi/znc
	void FilterIncoming(const CString& sTarget, CNick& Nick, CString& sMessage) {
		if (sMessage.TrimPrefix("+OK *")) {
			MCString::iterator it = FindNV(sTarget.AsLower());

			if (it != EndNV()) {
				sMessage.Base64Decode();
				sMessage.Decrypt(it->second);
				sMessage.LeftChomp(8);
				sMessage = sMessage.c_str();
				Nick.SetNick(NickPrefix() + Nick.GetNick());
			}
		}

	}
示例#12
0
文件: crypt.cpp 项目: jpnurmi/znc
	void OnSetKeyCommand(const CString& sCommand) {
		CString sTarget = sCommand.Token(1);
		CString sKey = sCommand.Token(2, true);

		// Strip "cbc:" from beginning of string incase someone pastes directly from mircryption
		sKey.TrimPrefix("cbc:");

		if (!sKey.empty()) {
			SetNV(sTarget.AsLower(), sKey);
			PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + "]");
		} else {
			PutModule("Usage: SetKey <#chan|Nick> <Key>");
		}
	}
示例#13
0
文件: Message.cpp 项目: BtbN/znc
void CMessage::InitType() {
    if (m_sCommand.length() == 3 && isdigit(m_sCommand[0]) &&
        isdigit(m_sCommand[1]) && isdigit(m_sCommand[2])) {
        m_eType = Type::Numeric;
    } else if (m_sCommand.Equals("PRIVMSG")) {
        CString sParam = GetParam(1);
        if (sParam.TrimPrefix("\001") && sParam.EndsWith("\001")) {
            if (sParam.StartsWith("ACTION ")) {
                m_eType = Type::Action;
            } else {
                m_eType = Type::CTCP;
            }
        } else {
            m_eType = Type::Text;
        }
    } else if (m_sCommand.Equals("NOTICE")) {
        CString sParam = GetParam(1);
        if (sParam.StartsWith("\001") && sParam.EndsWith("\001")) {
            m_eType = Type::CTCP;
        } else {
            m_eType = Type::Notice;
        }
    } else {
        std::map<CString, Type> mTypes = {
            {"ACCOUNT", Type::Account},
            {"AWAY", Type::Away},
            {"CAP", Type::Capability},
            {"ERROR", Type::Error},
            {"INVITE", Type::Invite},
            {"JOIN", Type::Join},
            {"KICK", Type::Kick},
            {"MODE", Type::Mode},
            {"NICK", Type::Nick},
            {"PART", Type::Part},
            {"PING", Type::Ping},
            {"PONG", Type::Pong},
            {"QUIT", Type::Quit},
            {"TOPIC", Type::Topic},
            {"WALLOPS", Type::Wallops},
        };
        auto it = mTypes.find(m_sCommand.AsUpper());
        if (it != mTypes.end()) {
            m_eType = it->second;
        } else {
            m_eType = Type::Unknown;
        }
    }
}
示例#14
0
文件: crypt.cpp 项目: jpnurmi/znc
	EModRet OnRaw(CString& sLine) override {
		if (!sLine.Token(1).Equals("332")) {
			return CONTINUE;
		}

		CChan* pChan = GetNetwork()->FindChan(sLine.Token(3));
		if (pChan) {
			CNick* Nick = pChan->FindNick(sLine.Token(2));
			CString sTopic = sLine.Token(4, true);
			sTopic.TrimPrefix(":");

			FilterIncoming(pChan->GetName(), *Nick, sTopic);
			sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic;

		}

		return CONTINUE;
}
示例#15
0
	void HandleAdd(const CString& sLine) {
		CString sMsg = sLine.Token(1, true);
		bool bHelp = false;
		bool bNegated = sMsg.TrimPrefix("!");
		CString sChan = sMsg.Token(0);
		CString sHost = sMsg.Token(1);

		if (sChan.empty()) {
			bHelp = true;
		} else if (Add(bNegated, sChan, sHost)) {
			PutModule("Added to list");
		} else {
			PutModule(sLine.Token(1, true) + " is already added");
			bHelp = true;
		}
		if (bHelp) {
			PutModule("Usage: Add [!]<#chan> <host>");
			PutModule("Wildcards are allowed");
		}
	}
示例#16
0
bool CIRCNetwork::AddServer(const CString& sName) {
    if (sName.empty()) {
        return false;
    }

    bool bSSL = false;
    CString sLine = sName;
    sLine.Trim();

    CString sHost = sLine.Token(0);
    CString sPort = sLine.Token(1);

    if (sPort.TrimPrefix("+")) {
        bSSL = true;
    }

    unsigned short uPort = sPort.ToUShort();
    CString sPass = sLine.Token(2, true);

    return AddServer(sHost, uPort, sPass, bSSL);
}
示例#17
0
文件: Client.cpp 项目: evilnet/znc
void CClient::HandleCap(const CMessage& Message) {
    CString sSubCmd = Message.GetParam(0);

    if (sSubCmd.Equals("LS")) {
        SCString ssOfferCaps;
        for (const auto& it : m_mCoreCaps) {
            bool bServerDependent = std::get<0>(it.second);
            if (!bServerDependent ||
                m_ssServerDependentCaps.count(it.first) > 0)
                ssOfferCaps.insert(it.first);
        }
        GLOBALMODULECALL(OnClientCapLs(this, ssOfferCaps), NOTHING);
        CString sRes =
            CString(" ").Join(ssOfferCaps.begin(), ssOfferCaps.end());
        RespondCap("LS :" + sRes);
        m_bInCap = true;
        if (Message.GetParam(1).ToInt() >= 302) {
            m_bCapNotify = true;
        }
    } else if (sSubCmd.Equals("END")) {
        m_bInCap = false;
        if (!IsAttached()) {
            if (!m_pUser && m_bGotUser && !m_bGotPass) {
                SendRequiredPasswordNotice();
            } else {
                AuthUser();
            }
        }
    } else if (sSubCmd.Equals("REQ")) {
        VCString vsTokens;
        Message.GetParam(1).Split(" ", vsTokens, false);

        for (const CString& sToken : vsTokens) {
            bool bVal = true;
            CString sCap = sToken;
            if (sCap.TrimPrefix("-")) bVal = false;

            bool bAccepted = false;
            const auto& it = m_mCoreCaps.find(sCap);
            if (m_mCoreCaps.end() != it) {
                bool bServerDependent = std::get<0>(it->second);
                bAccepted = !bServerDependent ||
                            m_ssServerDependentCaps.count(sCap) > 0;
            }
            GLOBALMODULECALL(IsClientCapSupported(this, sCap, bVal),
                             &bAccepted);

            if (!bAccepted) {
                // Some unsupported capability is requested
                RespondCap("NAK :" + Message.GetParam(1));
                return;
            }
        }

        // All is fine, we support what was requested
        for (const CString& sToken : vsTokens) {
            bool bVal = true;
            CString sCap = sToken;
            if (sCap.TrimPrefix("-")) bVal = false;

            auto handler_it = m_mCoreCaps.find(sCap);
            if (m_mCoreCaps.end() != handler_it) {
                const auto& handler = std::get<1>(handler_it->second);
                handler(bVal);
            }
            GLOBALMODULECALL(OnClientCapRequest(this, sCap, bVal), NOTHING);

            if (bVal) {
                m_ssAcceptedCaps.insert(sCap);
            } else {
                m_ssAcceptedCaps.erase(sCap);
            }
        }

        RespondCap("ACK :" + Message.GetParam(1));
    } else if (sSubCmd.Equals("LIST")) {
        CString sList =
            CString(" ").Join(m_ssAcceptedCaps.begin(), m_ssAcceptedCaps.end());
        RespondCap("LIST :" + sList);
    } else {
        PutClient(":irc.znc.in 410 " + GetNick() + " " + sSubCmd +
                  " :Invalid CAP subcommand");
    }
}
示例#18
0
文件: Client.cpp 项目: nbchicong/znc
void CClient::ReadLine(const CString& sData) {
    CString sLine = sData;

    sLine.TrimRight("\n\r");

    DEBUG("(" << GetFullName() << ") CLI -> ZNC [" << sLine << "]");

    if (sLine.Left(1) == "@") {
        // TODO support message-tags properly
        sLine = sLine.Token(1, true);
    }

    bool bReturn = false;
    if (IsAttached()) {
        NETWORKMODULECALL(OnUserRaw(sLine), m_pUser, m_pNetwork, this, &bReturn);
    } else {
        GLOBALMODULECALL(OnUnknownUserRaw(this, sLine), &bReturn);
    }
    if (bReturn) return;

    CString sCommand = sLine.Token(0);
    if (sCommand.Left(1) == ":") {
        // Evil client! Sending a nickmask prefix on client's command
        // is bad, bad, bad, bad, bad, bad, bad, bad, BAD, B A D!
        sLine = sLine.Token(1, true);
        sCommand = sLine.Token(0);
    }

    if (!IsAttached()) { // The following commands happen before authentication with ZNC
        if (sCommand.Equals("PASS")) {
            m_bGotPass = true;

            CString sAuthLine = sLine.Token(1, true).TrimPrefix_n();

            // [user[/network]:]password
            if (sAuthLine.find(":") == CString::npos) {
                m_sPass = sAuthLine;
                sAuthLine = "";
            } else {
                m_sPass = sAuthLine.Token(1, true, ":");
                sAuthLine = sAuthLine.Token(0, false, ":");
            }

            if (!sAuthLine.empty()) {
                m_sUser = sAuthLine.Token(0, false, "/");
                m_sNetwork = sAuthLine.Token(1, true, "/");
            }

            AuthUser();
            return;  // Don't forward this msg.  ZNC has already registered us.
        } else if (sCommand.Equals("NICK")) {
            CString sNick = sLine.Token(1).TrimPrefix_n();

            m_sNick = sNick;
            m_bGotNick = true;

            AuthUser();
            return;  // Don't forward this msg.  ZNC will handle nick changes until auth is complete
        } else if (sCommand.Equals("USER")) {
            // user[/network]
            CString sAuthLine = sLine.Token(1);

            if (m_sUser.empty() && !sAuthLine.empty()) {
                m_sUser = sAuthLine.Token(0, false, "/");
                m_sNetwork = sAuthLine.Token(1, true, "/");
            }

            m_bGotUser = true;
            if (m_bGotPass) {
                AuthUser();
            } else if (!m_bInCap) {
                SendRequiredPasswordNotice();
            }

            return;  // Don't forward this msg.  ZNC has already registered us.
        }
    }

    if (sCommand.Equals("CAP")) {
        HandleCap(sLine);

        // Don't let the client talk to the server directly about CAP,
        // we don't want anything enabled that ZNC does not support.
        return;
    }

    if (!m_pUser) {
        // Only CAP, NICK, USER and PASS are allowed before login
        return;
    }

    if (sCommand.Equals("ZNC")) {
        CString sTarget = sLine.Token(1);
        CString sModCommand;

        if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
            sModCommand = sLine.Token(2, true);
        } else {
            sTarget  = "status";
            sModCommand = sLine.Token(1, true);
        }

        if (sTarget.Equals("status")) {
            if (sModCommand.empty())
                PutStatus("Hello. How may I help you?");
            else
                UserCommand(sModCommand);
        } else {
            if (sModCommand.empty())
                CALLMOD(sTarget, this, m_pUser, m_pNetwork, PutModule("Hello. How may I help you?"))
                else
                    CALLMOD(sTarget, this, m_pUser, m_pNetwork, OnModCommand(sModCommand))
                }
        return;
    } else if (sCommand.Equals("PING")) {
示例#19
0
文件: Socket.cpp 项目: luser/znc
CS_STRING CZNCSock::ConvertAddress(void *addr, bool ipv6) {
	CString sRet = Csock::ConvertAddress(addr, ipv6);
	sRet.TrimPrefix("::ffff:");
	return sRet;
}