mirror of
https://github.com/znc/znc.git
synced 2026-08-07 09:22:55 +02:00
Merge branch 'master' into unix
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2004-2016 ZNC, see the NOTICE file for details.
|
||||
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
# Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
+31
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <znc/Nick.h>
|
||||
#include <znc/ZNCString.h>
|
||||
#include <znc/Buffer.h>
|
||||
#include <znc/Translation.h>
|
||||
#include <map>
|
||||
|
||||
// Forward Declarations
|
||||
@@ -31,7 +32,7 @@ class CConfig;
|
||||
class CFile;
|
||||
// !Forward Declarations
|
||||
|
||||
class CChan {
|
||||
class CChan : private CCoreTranslationMixin {
|
||||
public:
|
||||
typedef enum {
|
||||
Voice = '+',
|
||||
@@ -75,10 +76,24 @@ class CChan {
|
||||
const CString& sHost);
|
||||
|
||||
// Modes
|
||||
/// @deprecated Use SetModes(CString, VCString)
|
||||
void SetModes(const CString& s);
|
||||
/**
|
||||
* Set the current modes for this channel
|
||||
* @param sModes The mode characters being changed
|
||||
* @param vsModeParams The parameters for the modes to be set
|
||||
*/
|
||||
void SetModes(const CString& sModes, const VCString& vsModeParams);
|
||||
/// @deprecated Use ModeChange(CString, VCString, CNick*)
|
||||
void ModeChange(const CString& sModes, const CNick* OpNick = nullptr);
|
||||
bool AddMode(unsigned char uMode, const CString& sArg);
|
||||
bool RemMode(unsigned char uMode);
|
||||
/**
|
||||
* Handle changing the modes on a channel
|
||||
* @param sModes The mode string (eg. +ovbs-pbo)
|
||||
* @param vsModeParams The parameters for the mode string
|
||||
*/
|
||||
void ModeChange(const CString& sModes,const VCString& vsModeParams, const CNick* OpNick = nullptr);
|
||||
bool AddMode(char cMode, const CString& sArg);
|
||||
bool RemMode(char cMode);
|
||||
CString GetModeString() const;
|
||||
CString GetModeArg(CString& sArgs) const;
|
||||
CString GetModeForNames() const;
|
||||
@@ -120,10 +135,14 @@ class CChan {
|
||||
// !Buffer
|
||||
|
||||
// m_Nick wrappers
|
||||
/// e.g. '@' for chanop.
|
||||
CString GetPermStr() const { return m_Nick.GetPermStr(); }
|
||||
bool HasPerm(unsigned char uPerm) const { return m_Nick.HasPerm(uPerm); }
|
||||
bool AddPerm(unsigned char uPerm) { return m_Nick.AddPerm(uPerm); }
|
||||
bool RemPerm(unsigned char uPerm) { return m_Nick.RemPerm(uPerm); }
|
||||
/// e.g. '@' for chanop.
|
||||
bool HasPerm(char cPerm) const { return m_Nick.HasPerm(cPerm); }
|
||||
/// e.g. '@' for chanop.
|
||||
bool AddPerm(char cPerm) { return m_Nick.AddPerm(cPerm); }
|
||||
/// e.g. '@' for chanop.
|
||||
bool RemPerm(char cPerm) { return m_Nick.RemPerm(cPerm); }
|
||||
// !wrappers
|
||||
|
||||
// Setters
|
||||
@@ -154,14 +173,14 @@ class CChan {
|
||||
// Getters
|
||||
CIRCNetwork* GetNetwork() const { return m_pNetwork; }
|
||||
bool IsModeKnown() const { return m_bModeKnown; }
|
||||
bool HasMode(unsigned char uMode) const;
|
||||
bool HasMode(char cMode) const;
|
||||
CString GetOptions() const;
|
||||
CString GetModeArg(unsigned char uMode) const;
|
||||
CString GetModeArg(char cMode) const;
|
||||
std::map<char, unsigned int> GetPermCounts() const;
|
||||
bool IsOn() const { return m_bIsOn; }
|
||||
const CString& GetName() const { return m_sName; }
|
||||
const std::map<unsigned char, CString>& GetModes() const {
|
||||
return m_musModes;
|
||||
const std::map<char, CString>& GetModes() const {
|
||||
return m_mcsModes;
|
||||
}
|
||||
const CString& GetKey() const { return m_sKey; }
|
||||
const CString& GetTopic() const { return m_sTopic; }
|
||||
@@ -204,7 +223,7 @@ class CChan {
|
||||
CBuffer m_Buffer;
|
||||
|
||||
bool m_bModeKnown;
|
||||
std::map<unsigned char, CString> m_musModes;
|
||||
std::map<char, CString> m_mcsModes;
|
||||
};
|
||||
|
||||
#endif // !ZNC_CHAN_H
|
||||
|
||||
+79
-84
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ class CMessage;
|
||||
class CChan;
|
||||
// !Forward Declarations
|
||||
|
||||
class CAuthBase {
|
||||
class CAuthBase : private CCoreTranslationMixin {
|
||||
public:
|
||||
CAuthBase(const CString& sUsername, const CString& sPassword,
|
||||
CZNCSock* pSock)
|
||||
@@ -98,71 +98,7 @@ class CClientAuth : public CAuthBase {
|
||||
|
||||
class CClient : public CIRCSocket {
|
||||
public:
|
||||
CClient()
|
||||
: CIRCSocket(),
|
||||
m_bGotPass(false),
|
||||
m_bGotNick(false),
|
||||
m_bGotUser(false),
|
||||
m_bInCap(false),
|
||||
m_bCapNotify(false),
|
||||
m_bAwayNotify(false),
|
||||
m_bAccountNotify(false),
|
||||
m_bExtendedJoin(false),
|
||||
m_bNamesx(false),
|
||||
m_bUHNames(false),
|
||||
m_bAway(false),
|
||||
m_bServerTime(false),
|
||||
m_bBatch(false),
|
||||
m_bEchoMessage(false),
|
||||
m_bSelfMessage(false),
|
||||
m_bPlaybackActive(false),
|
||||
m_pUser(nullptr),
|
||||
m_pNetwork(nullptr),
|
||||
m_sNick("unknown-nick"),
|
||||
m_sPass(""),
|
||||
m_sUser(""),
|
||||
m_sNetwork(""),
|
||||
m_sIdentifier(""),
|
||||
m_spAuth(),
|
||||
m_ssAcceptedCaps(),
|
||||
m_ssSupportedTags(),
|
||||
m_mCoreCaps({
|
||||
{"multi-prefix",
|
||||
{false, [this](bool bVal) { m_bNamesx = bVal; }}},
|
||||
{"userhost-in-names",
|
||||
{false, [this](bool bVal) { m_bUHNames = bVal; }}},
|
||||
{"echo-message",
|
||||
{false, [this](bool bVal) { m_bEchoMessage = bVal; }}},
|
||||
{"server-time",
|
||||
{false, [this](bool bVal) {
|
||||
m_bServerTime = bVal;
|
||||
SetTagSupport("time", bVal);
|
||||
}}},
|
||||
{"batch", {false, [this](bool bVal) {
|
||||
m_bBatch = bVal;
|
||||
SetTagSupport("batch", bVal);
|
||||
}}},
|
||||
{"cap-notify",
|
||||
{false, [this](bool bVal) { m_bCapNotify = bVal; }}},
|
||||
{"away-notify",
|
||||
{true, [this](bool bVal) { m_bAwayNotify = bVal; }}},
|
||||
{"account-notify",
|
||||
{true, [this](bool bVal) { m_bAccountNotify = bVal; }}},
|
||||
{"extended-join",
|
||||
{true, [this](bool bVal) { m_bExtendedJoin = bVal; }}},
|
||||
}) {
|
||||
EnableReadLine();
|
||||
// RFC says a line can have 512 chars max, but we are
|
||||
// a little more gentle ;)
|
||||
SetMaxBufferThreshold(1024);
|
||||
|
||||
// For compatibility with older clients
|
||||
m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"];
|
||||
m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"];
|
||||
m_mCoreCaps["znc.in/self-message"] = {
|
||||
false, [this](bool bVal) { m_bSelfMessage = bVal; }};
|
||||
}
|
||||
|
||||
CClient();
|
||||
virtual ~CClient();
|
||||
|
||||
CClient(const CClient&) = delete;
|
||||
@@ -175,12 +111,15 @@ class CClient : public CIRCSocket {
|
||||
CString GetNick(bool bAllowIRCNick = true) const;
|
||||
CString GetNickMask() const;
|
||||
CString GetIdentifier() const { return m_sIdentifier; }
|
||||
unsigned short int CapVersion() const { return m_uCapVersion; }
|
||||
bool HasCap302() const { return CapVersion() >= 302; }
|
||||
bool HasCapNotify() const { return m_bCapNotify; }
|
||||
bool HasAwayNotify() const { return m_bAwayNotify; }
|
||||
bool HasAccountNotify() const { return m_bAccountNotify; }
|
||||
bool HasExtendedJoin() const { return m_bExtendedJoin; }
|
||||
bool HasNamesx() const { return m_bNamesx; }
|
||||
bool HasUHNames() const { return m_bUHNames; }
|
||||
bool HasChgHost() const { return m_bChgHost; }
|
||||
bool IsAway() const { return m_bAway; }
|
||||
bool HasServerTime() const { return m_bServerTime; }
|
||||
bool HasBatch() const { return m_bBatch; }
|
||||
@@ -199,14 +138,23 @@ class CClient : public CIRCSocket {
|
||||
void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; }
|
||||
|
||||
void PutIRC(const CString& sLine);
|
||||
// Strips prefix and potentially tags before sending to server.
|
||||
void PutIRCStripping(CMessage Message);
|
||||
/** Sends a raw data line to the client.
|
||||
* @param sLine The line to be sent.
|
||||
*
|
||||
* The line is first passed \e unmodified to the \ref CModule::OnSendToClient()
|
||||
* module hook. If no module halts the process, the line is then sent to the client.
|
||||
* The line is first passed \e unmodified to the \ref
|
||||
* CModule::OnSendToClient() module hook. If no module halts the process,
|
||||
* the line is then sent to the client.
|
||||
*
|
||||
* These lines appear in the debug output in the following syntax:
|
||||
* \code [time] (user/network) ZNC -> CLI [line] \endcode
|
||||
*
|
||||
* Prefer \l PutClient() instead.
|
||||
*/
|
||||
bool PutClientRaw(const CString& sLine);
|
||||
/** Sends a message to the client.
|
||||
* See \l PutClient(const CMessage&) for details.
|
||||
*/
|
||||
void PutClient(const CString& sLine);
|
||||
/** Sends a message to the client.
|
||||
@@ -245,14 +193,17 @@ class CClient : public CIRCSocket {
|
||||
* ----------- | ----------
|
||||
* \c time | \l CClient::HasServerTime() (<a href="http://ircv3.net/specs/extensions/server-time-3.2.html">server-time</a>)
|
||||
* \c batch | \l CClient::HasBatch() (<a href="http://ircv3.net/specs/extensions/batch-3.2.html">batch</a>)
|
||||
*
|
||||
* Additional tags can be added via \l CClient::SetTagSupport().
|
||||
*
|
||||
* @warning Bypassing the filter may cause troubles to some older IRC clients.
|
||||
* @warning Bypassing the filter may cause troubles to some older IRC
|
||||
* clients.
|
||||
*
|
||||
* It is possible to bypass the filter by converting a message to a string
|
||||
* using \l CMessage::ToString(), and passing the resulting raw line to the
|
||||
* \l CClient::PutClient(const CString& sLine) overload:
|
||||
* \l CClient::PutClientRaw(const CString& sLine):
|
||||
* \code
|
||||
* pClient->PutClient(Message.ToString());
|
||||
* pClient->PutClientRaw(Message.ToString());
|
||||
* \endcode
|
||||
*/
|
||||
bool PutClient(const CMessage& Message);
|
||||
@@ -269,14 +220,16 @@ class CClient : public CIRCSocket {
|
||||
bool IsTagEnabled(const CString& sTag) const {
|
||||
return 1 == m_ssSupportedTags.count(sTag);
|
||||
}
|
||||
/** Registers a tag as being supported or unsupported by a client.
|
||||
/** Registers a tag as being supported or unsupported by the client.
|
||||
* This doesn't affect tags which the client sends.
|
||||
* @param sTag The tag to register.
|
||||
* @param bState Whether the client supports the tag.
|
||||
*/
|
||||
void SetTagSupport(const CString& sTag, bool bState);
|
||||
|
||||
void NotifyServerDependentCaps(const SCString& ssCaps);
|
||||
void ClearServerDependentCaps();
|
||||
/** Notifies client about one specific cap which server has just notified us about.
|
||||
*/
|
||||
void NotifyServerDependentCap(const CString& sCap, bool bValue, const CString& sValue);
|
||||
|
||||
void ReadLine(const CString& sData) override;
|
||||
bool SendMotd();
|
||||
@@ -299,11 +252,33 @@ class CClient : public CIRCSocket {
|
||||
CIRCSock* GetIRCSock();
|
||||
CString GetFullName() const;
|
||||
|
||||
/** Sends AUTHENTIATE message to client.
|
||||
* It encodes it to Base64 and splits to multiple IRC messages if necessary.
|
||||
*/
|
||||
void SendSASLChallenge(CString sMessage);
|
||||
void RefuseSASLLogin(const CString& sReason);
|
||||
void AcceptSASLLogin(CUser& User);
|
||||
/** Start potentially asynchronous process of checking the credentials.
|
||||
* When finished, will send the success/failure SASL numerics to the
|
||||
* client. This is mostly useful for SASL PLAIN.
|
||||
* sAuthorizationId is internally passed through ParseUser() to extract
|
||||
* network and client id.
|
||||
* Currently sUser should match the username from
|
||||
* sAuthorizationId: either in full, or just the username part; but in a
|
||||
* future version we may add an ability to actually login as a different
|
||||
* user, but with your password.
|
||||
*/
|
||||
void StartSASLPasswordCheck(const CString& sUser, const CString& sPassword,
|
||||
const CString& sAuthorizationId);
|
||||
/** Gathers username, client id, network name, if present. Returns username
|
||||
* cleaned from client id and network name.
|
||||
*/
|
||||
CString ParseUser(const CString& sAuthLine);
|
||||
|
||||
private:
|
||||
void HandleCap(const CMessage& Message);
|
||||
void RespondCap(const CString& sResponse);
|
||||
void ParsePass(const CString& sAuthLine);
|
||||
void ParseUser(const CString& sAuthLine);
|
||||
void ParseIdentifier(const CString& sAuthLine);
|
||||
|
||||
template <typename T>
|
||||
@@ -315,6 +290,15 @@ class CClient : public CIRCSocket {
|
||||
unsigned int DetachChans(const std::set<CChan*>& sChans);
|
||||
|
||||
bool OnActionMessage(CActionMessage& Message);
|
||||
void OnAuthenticateMessage(const CAuthenticateMessage& Message);
|
||||
void AbortSASL(const CString& sFullIRCLine);
|
||||
bool IsDuringSASL() const { return !m_sSASLMechanism.empty(); }
|
||||
|
||||
/**
|
||||
* Returns set of all available SASL mechanisms.
|
||||
*/
|
||||
SCString EnumerateSASLMechanisms() const;
|
||||
|
||||
bool OnCTCPMessage(CCTCPMessage& Message);
|
||||
bool OnJoinMessage(CJoinMessage& Message);
|
||||
bool OnModeMessage(CModeMessage& Message);
|
||||
@@ -323,6 +307,7 @@ class CClient : public CIRCSocket {
|
||||
bool OnPingMessage(CMessage& Message);
|
||||
bool OnPongMessage(CMessage& Message);
|
||||
bool OnQuitMessage(CQuitMessage& Message);
|
||||
bool OnTagMessage(CTargetMessage& Message);
|
||||
bool OnTextMessage(CTextMessage& Message);
|
||||
bool OnTopicMessage(CTopicMessage& Message);
|
||||
bool OnOtherMessage(CMessage& Message);
|
||||
@@ -331,6 +316,7 @@ class CClient : public CIRCSocket {
|
||||
bool m_bGotPass;
|
||||
bool m_bGotNick;
|
||||
bool m_bGotUser;
|
||||
unsigned short int m_uCapVersion;
|
||||
bool m_bInCap;
|
||||
bool m_bCapNotify;
|
||||
bool m_bAwayNotify;
|
||||
@@ -338,32 +324,41 @@ class CClient : public CIRCSocket {
|
||||
bool m_bExtendedJoin;
|
||||
bool m_bNamesx;
|
||||
bool m_bUHNames;
|
||||
bool m_bChgHost;
|
||||
bool m_bAway;
|
||||
bool m_bServerTime;
|
||||
bool m_bBatch;
|
||||
bool m_bEchoMessage;
|
||||
bool m_bSelfMessage;
|
||||
bool m_bMessageTagCap;
|
||||
bool m_bSASLCap;
|
||||
bool m_bPlaybackActive;
|
||||
CUser* m_pUser;
|
||||
CIRCNetwork* m_pNetwork;
|
||||
CString m_sNick;
|
||||
CString m_sPass;
|
||||
// User who didn't necessarily login yet, or might not even exist.
|
||||
CString m_sUser;
|
||||
CString m_sNetwork;
|
||||
CString m_sIdentifier;
|
||||
CString m_sSASLBuffer;
|
||||
// Set while the exchange is in progress
|
||||
CString m_sSASLMechanism;
|
||||
// Username who successfully logged in using SASL. This is not a CUser*
|
||||
// because between the 903 and CAP END the user could have been deleted.
|
||||
CString m_sSASLUser;
|
||||
std::shared_ptr<CAuthBase> m_spAuth;
|
||||
SCString m_ssAcceptedCaps;
|
||||
SCString m_ssSupportedTags;
|
||||
// The capabilities supported by the ZNC core - capability names mapped
|
||||
// to a pair which contains a bool describing whether the capability is
|
||||
// server-dependent, and a capability value change handler.
|
||||
std::map<CString, std::pair<bool, std::function<void(bool bVal)>>>
|
||||
m_mCoreCaps;
|
||||
// A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed
|
||||
// in CAP LS and may be notified to the client with CAP NEW (cap-notify).
|
||||
SCString m_ssServerDependentCaps;
|
||||
SCString m_ssPreviouslyFailedSASLMechanisms;
|
||||
// The capabilities supported by the ZNC core - capability names mapped to
|
||||
// change handler. Note: this lists caps which don't require support on IRC
|
||||
// server.
|
||||
static const std::map<CString, std::function<void(CClient*, bool bVal)>>&
|
||||
CoreCaps();
|
||||
|
||||
friend class ClientTest;
|
||||
friend class CCoreCaps;
|
||||
};
|
||||
|
||||
#endif // !ZNC_CLIENT_H
|
||||
|
||||
+16
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,10 +35,11 @@ struct CConfigEntry {
|
||||
|
||||
class CConfig {
|
||||
public:
|
||||
CConfig() : m_ConfigEntries(), m_SubConfigs() {}
|
||||
CConfig() : m_ConfigEntries(), m_SubConfigs(), m_SubConfigNameSets() {}
|
||||
|
||||
typedef std::map<CString, VCString> EntryMap;
|
||||
typedef std::map<CString, CConfigEntry> SubConfig;
|
||||
typedef std::pair<CString, CConfigEntry> SubConfigEntry;
|
||||
typedef std::vector<SubConfigEntry> SubConfig;
|
||||
typedef std::map<CString, SubConfig> SubConfigMap;
|
||||
|
||||
typedef EntryMap::const_iterator EntryMapIterator;
|
||||
@@ -62,14 +63,13 @@ class CConfig {
|
||||
|
||||
bool AddSubConfig(const CString& sTag, const CString& sName,
|
||||
CConfig Config) {
|
||||
SubConfig& conf = m_SubConfigs[sTag];
|
||||
SubConfig::const_iterator it = conf.find(sName);
|
||||
auto& nameset = m_SubConfigNameSets[sTag];
|
||||
|
||||
if (it != conf.end()) {
|
||||
return false;
|
||||
}
|
||||
if (nameset.find(sName) != nameset.end()) return false;
|
||||
|
||||
nameset.insert(sName);
|
||||
m_SubConfigs[sTag].emplace_back(sName, Config);
|
||||
|
||||
conf[sName] = Config;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,9 +142,9 @@ class CConfig {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FindSubConfig(const CString& sName, SubConfig& Config,
|
||||
bool FindSubConfig(const CString& sTag, SubConfig& Config,
|
||||
bool bErase = true) {
|
||||
SubConfigMap::iterator it = m_SubConfigs.find(sName);
|
||||
auto it = m_SubConfigs.find(sTag);
|
||||
if (it == m_SubConfigs.end()) {
|
||||
Config.clear();
|
||||
return false;
|
||||
@@ -153,6 +153,7 @@ class CConfig {
|
||||
|
||||
if (bErase) {
|
||||
m_SubConfigs.erase(it);
|
||||
m_SubConfigNameSets.erase(sTag);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -166,8 +167,12 @@ class CConfig {
|
||||
void Write(CFile& file, unsigned int iIndentation = 0);
|
||||
|
||||
private:
|
||||
typedef SCString SubConfigNameSet;
|
||||
typedef std::map<CString, SubConfigNameSet> SubConfigNameSetMap;
|
||||
|
||||
EntryMap m_ConfigEntries;
|
||||
SubConfigMap m_SubConfigs;
|
||||
SubConfigNameSetMap m_SubConfigNameSets;
|
||||
};
|
||||
|
||||
#endif // !ZNC_CONFIG_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ class CIRCNetworkPingTimer;
|
||||
class CIRCNetworkJoinTimer;
|
||||
class CMessage;
|
||||
|
||||
class CIRCNetwork {
|
||||
class CIRCNetwork : private CCoreTranslationMixin {
|
||||
public:
|
||||
static bool IsValidNetwork(const CString& sNetwork);
|
||||
|
||||
@@ -93,6 +93,9 @@ class CIRCNetwork {
|
||||
bool AddChan(CChan* pChan);
|
||||
bool AddChan(const CString& sName, bool bInConfig);
|
||||
bool DelChan(const CString& sName);
|
||||
bool MoveChan(const CString& sChan, unsigned int index, CString& sError);
|
||||
bool SwapChans(const CString& sChan1, const CString& sChan2,
|
||||
CString& sError);
|
||||
void JoinChans();
|
||||
void JoinChans(std::set<CChan*>& sChans);
|
||||
|
||||
@@ -153,8 +156,11 @@ class CIRCNetwork {
|
||||
void IRCConnected();
|
||||
void IRCDisconnected();
|
||||
void CheckIRCConnect();
|
||||
void NotifyClientsAboutServerDependentCap(const CString& sCap, bool bValue);
|
||||
bool IsServerCapAccepted(const CString& sCap) const;
|
||||
|
||||
bool PutIRC(const CString& sLine);
|
||||
bool PutIRC(const CMessage& Message);
|
||||
|
||||
// Buffers
|
||||
void AddRawBuffer(const CMessage& Format, const CString& sText = "") {
|
||||
|
||||
+73
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,8 +56,49 @@ class CIRCSock : public CIRCSocket {
|
||||
void SockError(int iErrno, const CString& sDescription) override;
|
||||
void Timeout() override;
|
||||
void ReachedMaxBuffer() override;
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
void SSLCertError(X509* pCert) override;
|
||||
#endif
|
||||
/** Sends a raw data line to the server.
|
||||
* @param sLine The line to be sent.
|
||||
*
|
||||
* The line is first passed \e unmodified to the \ref
|
||||
* CModule::OnSendToIRC() module hook. If no module halts the process,
|
||||
* the line is then sent to the server.
|
||||
*
|
||||
* Prefer \l PutIRC() instead.
|
||||
*/
|
||||
void PutIRCRaw(const CString& sLine);
|
||||
/** Sends a message to the server.
|
||||
* See \l PutIRC(const CMessage&) for details.
|
||||
*/
|
||||
void PutIRC(const CString& sLine);
|
||||
/** Sends a message to the server.
|
||||
* @param Message The message to be sent.
|
||||
* @note Only known and compatible messages and tags are sent.
|
||||
*
|
||||
* This method can delay the delivery of the message to honor protection
|
||||
* from flood.
|
||||
*
|
||||
* This method ensures that only tags, that were negotiated with CAP REQ
|
||||
* and CAP ACK, are sent. Not all IRC server are capable of handling all
|
||||
* messages and tags. Thus, in order to stay compatible with a variety of
|
||||
* IRC servers, ZNC has to filter out messages and tags that the server
|
||||
* has not explicitly acknowleged.
|
||||
*
|
||||
* Additional tags can be added via \l CIRCSock::SetTagSupport().
|
||||
*
|
||||
* @warning Bypassing the filter may cause troubles to some older IRC
|
||||
* servers.
|
||||
*
|
||||
* It is possible to bypass the filter by converting a message to a string
|
||||
* using \l CMessage::ToString(), and passing the resulting raw line to the
|
||||
* \l CIRCSock::PutIRCRaw(const CString& sLine):
|
||||
* \code
|
||||
* pServer->PutIRCRaw(Message.ToString());
|
||||
* \endcode
|
||||
*/
|
||||
void PutIRC(const CMessage& Message);
|
||||
void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only
|
||||
void ResetChans();
|
||||
void Quit(const CString& sQuitMsg = "");
|
||||
@@ -71,6 +112,16 @@ class CIRCSock : public CIRCSocket {
|
||||
* should be resumed again.
|
||||
*/
|
||||
void ResumeCap();
|
||||
|
||||
bool IsTagEnabled(const CString& sTag) const {
|
||||
return 1 == m_ssSupportedTags.count(sTag);
|
||||
}
|
||||
/** Registers a tag as being supported or unsupported by the server.
|
||||
* This doesn't affect tags which the server sends.
|
||||
* @param sTag The tag to register.
|
||||
* @param bState Whether the client supports the tag.
|
||||
*/
|
||||
void SetTagSupport(const CString& sTag, bool bState);
|
||||
|
||||
// Setters
|
||||
void SetPass(const CString& s) { m_sPass = s; }
|
||||
@@ -78,10 +129,11 @@ class CIRCSock : public CIRCSocket {
|
||||
|
||||
// Getters
|
||||
unsigned int GetMaxNickLen() const { return m_uMaxNickLen; }
|
||||
EChanModeArgs GetModeType(unsigned char uMode) const;
|
||||
unsigned char GetPermFromMode(unsigned char uMode) const;
|
||||
const std::map<unsigned char, EChanModeArgs>& GetChanModes() const {
|
||||
return m_mueChanModes;
|
||||
EChanModeArgs GetModeType(char cMode) const;
|
||||
char GetPermFromMode(char cMode) const;
|
||||
char GetModeFromPerm(char cPerm) const;
|
||||
const std::map<char, EChanModeArgs>& GetChanModes() const {
|
||||
return m_mceChanModes;
|
||||
}
|
||||
bool IsPermChar(const char c) const {
|
||||
return (c != '\0' && GetPerms().find(c) != CString::npos);
|
||||
@@ -101,15 +153,16 @@ class CIRCSock : public CIRCSocket {
|
||||
bool HasAccountNotify() const { return m_bAccountNotify; }
|
||||
bool HasExtendedJoin() const { return m_bExtendedJoin; }
|
||||
bool HasServerTime() const { return m_bServerTime; }
|
||||
const std::set<unsigned char>& GetUserModes() const {
|
||||
return m_scUserModes;
|
||||
}
|
||||
bool HasMessageTagCap() const { return m_bMessageTagCap; }
|
||||
const std::set<char>& GetUserModes() const { return m_scUserModes; }
|
||||
// This is true if we are past raw 001
|
||||
bool IsAuthed() const { return m_bAuthed; }
|
||||
const SCString& GetAcceptedCaps() const { return m_ssAcceptedCaps; }
|
||||
bool IsCapAccepted(const CString& sCap) {
|
||||
return 1 == m_ssAcceptedCaps.count(sCap);
|
||||
}
|
||||
CString GetCapLsValue(const CString& sKey,
|
||||
const CString& sDefault = "") const;
|
||||
const MCString& GetISupport() const { return m_mISupport; }
|
||||
CString GetISupport(const CString& sKey,
|
||||
const CString& sDefault = "") const;
|
||||
@@ -124,6 +177,7 @@ class CIRCSock : public CIRCSocket {
|
||||
bool OnActionMessage(CActionMessage& Message);
|
||||
bool OnAwayMessage(CMessage& Message);
|
||||
bool OnCapabilityMessage(CMessage& Message);
|
||||
bool OnChgHostMessage(CChgHostMessage& Message);
|
||||
bool OnCTCPMessage(CCTCPMessage& Message);
|
||||
bool OnErrorMessage(CMessage& Message);
|
||||
bool OnInviteMessage(CMessage& Message);
|
||||
@@ -137,10 +191,11 @@ class CIRCSock : public CIRCSocket {
|
||||
bool OnPingMessage(CMessage& Message);
|
||||
bool OnPongMessage(CMessage& Message);
|
||||
bool OnQuitMessage(CQuitMessage& Message);
|
||||
bool OnTagMessage(CTargetMessage& Message);
|
||||
bool OnTextMessage(CTextMessage& Message);
|
||||
bool OnTopicMessage(CTopicMessage& Message);
|
||||
bool OnWallopsMessage(CMessage& Message);
|
||||
bool OnServerCapAvailable(const CString& sCap);
|
||||
bool OnServerCapAvailable(const CString& sCap, const CString& sValue);
|
||||
// !Message Handlers
|
||||
|
||||
void SetNick(const CString& sNick);
|
||||
@@ -158,10 +213,11 @@ class CIRCSock : public CIRCSocket {
|
||||
bool m_bAccountNotify;
|
||||
bool m_bExtendedJoin;
|
||||
bool m_bServerTime;
|
||||
bool m_bMessageTagCap;
|
||||
CString m_sPerms;
|
||||
CString m_sPermModes;
|
||||
std::set<unsigned char> m_scUserModes;
|
||||
std::map<unsigned char, EChanModeArgs> m_mueChanModes;
|
||||
std::set<char> m_scUserModes;
|
||||
std::map<char, EChanModeArgs> m_mceChanModes;
|
||||
CIRCNetwork* m_pNetwork;
|
||||
CNick m_Nick;
|
||||
CString m_sPass;
|
||||
@@ -170,18 +226,22 @@ class CIRCSock : public CIRCSocket {
|
||||
unsigned int m_uCapPaused;
|
||||
SCString m_ssAcceptedCaps;
|
||||
SCString m_ssPendingCaps;
|
||||
MCString m_msCapLsValues;
|
||||
time_t m_lastCTCP;
|
||||
unsigned int m_uNumCTCP;
|
||||
static const time_t m_uCTCPFloodTime;
|
||||
static const unsigned int m_uCTCPFloodCount;
|
||||
MCString m_mISupport;
|
||||
std::deque<CString> m_vsSendQueue;
|
||||
std::deque<CMessage> m_vSendQueue;
|
||||
short int m_iSendsAllowed;
|
||||
unsigned short int m_uFloodBurst;
|
||||
double m_fFloodRate;
|
||||
bool m_bFloodProtection;
|
||||
SCString m_ssSupportedTags;
|
||||
VCString m_vsSSLError;
|
||||
|
||||
friend class CIRCFloodTimer;
|
||||
friend class CCoreCaps;
|
||||
};
|
||||
|
||||
#endif // !ZNC_IRCSOCK_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
+67
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,17 +17,10 @@
|
||||
#ifndef ZNC_MESSAGE_H
|
||||
#define ZNC_MESSAGE_H
|
||||
|
||||
// Remove this after Feb 2016 when Debian 7 is EOL
|
||||
#if __cpp_ref_qualifiers >= 200710
|
||||
#define ZNC_LVREFQUAL &
|
||||
#elif defined(__clang__)
|
||||
#define ZNC_LVREFQUAL &
|
||||
#elif __GNUC__ > 4 || \
|
||||
__GNUC__ == 4 && (__GNUC_MINOR__ > 8 || \
|
||||
__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ >= 1)
|
||||
#define ZNC_LVREFQUAL &
|
||||
#ifdef SWIG
|
||||
#define ZNC_MSG_DEPRECATED(msg)
|
||||
#else
|
||||
#define ZNC_LVREFQUAL
|
||||
#define ZNC_MSG_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#endif
|
||||
|
||||
#include <znc/zncconfig.h>
|
||||
@@ -55,7 +48,8 @@ class CIRCNetwork;
|
||||
* - `nick` is the sender, which can be obtained with GetNick()
|
||||
* - `cmd` is command, which is obtained via GetCommand()
|
||||
* - `0`, `1`, ... are parameters, available via GetParam(n), which removes the
|
||||
* leading colon (:). If you don't want to remove the colon, use GetParams().
|
||||
* leading colon (:). If you don't want to remove the colon, use
|
||||
* GetParamsColon().
|
||||
*
|
||||
* For certain events, like a PRIVMSG, convienience commands like GetChan() and
|
||||
* GetNick() are available, this is not true for all CMessage extensions.
|
||||
@@ -71,8 +65,10 @@ class CMessage {
|
||||
Unknown,
|
||||
Account,
|
||||
Action,
|
||||
Authenticate,
|
||||
Away,
|
||||
Capability,
|
||||
ChgHost,
|
||||
CTCP,
|
||||
Error,
|
||||
Invite,
|
||||
@@ -86,6 +82,7 @@ class CMessage {
|
||||
Ping,
|
||||
Pong,
|
||||
Quit,
|
||||
TagMsg,
|
||||
Text,
|
||||
Topic,
|
||||
Wallops,
|
||||
@@ -114,8 +111,27 @@ class CMessage {
|
||||
void SetCommand(const CString& sCommand);
|
||||
|
||||
const VCString& GetParams() const { return m_vsParams; }
|
||||
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const;
|
||||
|
||||
/**
|
||||
* Get a subset of the message parameters
|
||||
*
|
||||
* This allows accessing a vector of a specific range of parameters,
|
||||
* allowing easy inline use, such as `pChan->SetModes(Message.GetParam(2), Message.GetParamsSplit(3));`
|
||||
*
|
||||
* @param uIdx The index of the first parameter to retrieve
|
||||
* @param uLen How many parameters to retrieve
|
||||
* @return A VCString containing the retrieved parameters
|
||||
*/
|
||||
VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen = -1) const;
|
||||
void SetParams(const VCString& vsParams);
|
||||
void SetParams(VCString&& vsParams);
|
||||
|
||||
/// @deprecated use GetParamsColon() instead.
|
||||
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const
|
||||
ZNC_MSG_DEPRECATED("Use GetParamsColon() instead") {
|
||||
return GetParamsColon(uIdx, uLen);
|
||||
}
|
||||
CString GetParamsColon(unsigned int uIdx, unsigned int uLen = -1) const;
|
||||
|
||||
CString GetParam(unsigned int uIdx) const;
|
||||
void SetParam(unsigned int uIdx, const CString& sParam);
|
||||
@@ -124,6 +140,7 @@ class CMessage {
|
||||
void SetTime(const timeval& ts) { m_time = ts; }
|
||||
|
||||
const MCString& GetTags() const { return m_mssTags; }
|
||||
MCString& GetTags() { return m_mssTags; }
|
||||
void SetTags(const MCString& mssTags) { m_mssTags = mssTags; }
|
||||
|
||||
CString GetTag(const CString& sKey) const;
|
||||
@@ -136,12 +153,12 @@ class CMessage {
|
||||
};
|
||||
|
||||
CString ToString(unsigned int uFlags = IncludeAll) const;
|
||||
void Parse(CString sMessage);
|
||||
void Parse(const CString& sMessage);
|
||||
|
||||
// Implicit and explicit conversion to a subclass reference.
|
||||
#ifndef SWIG
|
||||
template <typename M>
|
||||
M& As() ZNC_LVREFQUAL {
|
||||
M& As() & {
|
||||
static_assert(std::is_base_of<CMessage, M>{},
|
||||
"Must be subclass of CMessage");
|
||||
static_assert(sizeof(M) == sizeof(CMessage),
|
||||
@@ -150,7 +167,7 @@ class CMessage {
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
const M& As() const ZNC_LVREFQUAL {
|
||||
const M& As() const& {
|
||||
static_assert(std::is_base_of<CMessage, M>{},
|
||||
"Must be subclass of CMessage");
|
||||
static_assert(sizeof(M) == sizeof(CMessage),
|
||||
@@ -160,12 +177,12 @@ class CMessage {
|
||||
|
||||
template <typename M, typename = typename std::enable_if<
|
||||
std::is_base_of<CMessage, M>{}>::type>
|
||||
operator M&() ZNC_LVREFQUAL {
|
||||
operator M&() & {
|
||||
return As<M>();
|
||||
}
|
||||
template <typename M, typename = typename std::enable_if<
|
||||
std::is_base_of<CMessage, M>{}>::type>
|
||||
operator const M&() const ZNC_LVREFQUAL {
|
||||
operator const M&() const& {
|
||||
return As<M>();
|
||||
}
|
||||
// REGISTER_ZNC_MESSAGE allows SWIG to instantiate correct .As<> calls.
|
||||
@@ -225,6 +242,13 @@ class CActionMessage : public CTargetMessage {
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CActionMessage);
|
||||
|
||||
class CAuthenticateMessage : public CMessage {
|
||||
public:
|
||||
CString GetText() const { return GetParam(0); }
|
||||
void SetText(const CString& sText) { SetParam(0, sText); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CAuthenticateMessage);
|
||||
|
||||
class CCTCPMessage : public CTargetMessage {
|
||||
public:
|
||||
bool IsReply() const { return GetCommand().Equals("NOTICE"); }
|
||||
@@ -244,7 +268,14 @@ REGISTER_ZNC_MESSAGE(CJoinMessage);
|
||||
|
||||
class CModeMessage : public CTargetMessage {
|
||||
public:
|
||||
CString GetModes() const { return GetParams(1).TrimPrefix_n(":"); }
|
||||
/// @deprecated Use GetModeList() and GetModeParams()
|
||||
CString GetModes() const { return GetParamsColon(1).TrimPrefix_n(":"); }
|
||||
|
||||
CString GetModeList() const { return GetParam(1); };
|
||||
|
||||
VCString GetModeParams() const { return GetParamsSplit(2); };
|
||||
|
||||
bool HasModes() const { return !GetModeList().empty(); };
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CModeMessage);
|
||||
|
||||
@@ -275,6 +306,8 @@ class CKickMessage : public CTargetMessage {
|
||||
void SetKickedNick(const CString& sNick) { SetParam(1, sNick); }
|
||||
CString GetReason() const { return GetParam(2); }
|
||||
void SetReason(const CString& sReason) { SetParam(2, sReason); }
|
||||
CString GetText() const { return GetReason(); }
|
||||
void SetText(const CString& sText) { SetReason(sText); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CKickMessage);
|
||||
|
||||
@@ -282,6 +315,8 @@ class CPartMessage : public CTargetMessage {
|
||||
public:
|
||||
CString GetReason() const { return GetParam(1); }
|
||||
void SetReason(const CString& sReason) { SetParam(1, sReason); }
|
||||
CString GetText() const { return GetReason(); }
|
||||
void SetText(const CString& sText) { SetReason(sText); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CPartMessage);
|
||||
|
||||
@@ -289,6 +324,8 @@ class CQuitMessage : public CMessage {
|
||||
public:
|
||||
CString GetReason() const { return GetParam(0); }
|
||||
void SetReason(const CString& sReason) { SetParam(0, sReason); }
|
||||
CString GetText() const { return GetReason(); }
|
||||
void SetText(const CString& sText) { SetReason(sText); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CQuitMessage);
|
||||
|
||||
@@ -303,7 +340,18 @@ class CTopicMessage : public CTargetMessage {
|
||||
public:
|
||||
CString GetTopic() const { return GetParam(1); }
|
||||
void SetTopic(const CString& sTopic) { SetParam(1, sTopic); }
|
||||
CString GetText() const { return GetTopic(); }
|
||||
void SetText(const CString& sText) { SetTopic(sText); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CTopicMessage);
|
||||
|
||||
class CChgHostMessage : public CMessage {
|
||||
public:
|
||||
CString GetNewIdent() const { return GetParam(0); }
|
||||
void SetNewIdent(const CString& sIdent) { SetParam(0, sIdent); }
|
||||
CString GetNewHost() const { return GetParam(1); }
|
||||
void SetNewHost(const CString& sHost) { SetParam(1, sHost); }
|
||||
};
|
||||
REGISTER_ZNC_MESSAGE(CChgHostMessage);
|
||||
|
||||
#endif // !ZNC_MESSAGE_H
|
||||
|
||||
+170
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <znc/main.h>
|
||||
#include <znc/Translation.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <sys/time.h>
|
||||
@@ -166,6 +167,19 @@ class CFPTimer;
|
||||
class CSockManager;
|
||||
// !Forward Declarations
|
||||
|
||||
class CCapability {
|
||||
public:
|
||||
virtual ~CCapability() = default;
|
||||
virtual void OnServerChangedSupport(CIRCNetwork* pNetwork, bool bState) {}
|
||||
virtual void OnClientChangedSupport(CClient* pClient, bool bState) {}
|
||||
|
||||
CModule* GetModule() { return m_pModule; }
|
||||
void SetModule(CModule* p) { m_pModule = p; }
|
||||
|
||||
protected:
|
||||
CModule* m_pModule = nullptr;
|
||||
};
|
||||
|
||||
class CTimer : public CCron {
|
||||
public:
|
||||
CTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles,
|
||||
@@ -335,7 +349,7 @@ CModule* TModLoad(ModHandle p, CUser* pUser, CIRCNetwork* pNetwork,
|
||||
}
|
||||
|
||||
/** A helper class for handling commands in modules. */
|
||||
class CModCommand {
|
||||
class CModCommand : private CCoreTranslationMixin {
|
||||
public:
|
||||
/// Type for the callback function that handles the actual command.
|
||||
typedef void (CModule::*ModCmdFunc)(const CString& sLine);
|
||||
@@ -575,16 +589,21 @@ class CModule {
|
||||
* @param pOpNick The nick who sent the mode change, or nullptr if set by server.
|
||||
* @param Nick The nick whose channel mode changes.
|
||||
* @param Channel The channel on which the user mode is changed.
|
||||
* @param uMode The mode character that is changed, e.g. '@' for op.
|
||||
* @param cMode The mode character that is changed, e.g. '@' for op.
|
||||
* @param bAdded True if the mode is added, else false.
|
||||
* @param bNoChange true if this mode change doesn't change anything
|
||||
* because the nick already had this permission.
|
||||
* @see CIRCSock::GetModeType() for converting uMode into a mode (e.g.
|
||||
* 'o' for op).
|
||||
*/
|
||||
virtual void OnChanPermission3(const CNick* pOpNick, const CNick& Nick,
|
||||
CChan& Channel, char cMode,
|
||||
bool bAdded, bool bNoChange);
|
||||
/// @deprecated. Use OnChanPermission3.
|
||||
virtual void OnChanPermission2(const CNick* pOpNick, const CNick& Nick,
|
||||
CChan& Channel, unsigned char uMode,
|
||||
bool bAdded, bool bNoChange);
|
||||
/// @deprecated. Use OnChanPermission3.
|
||||
virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick,
|
||||
CChan& Channel, unsigned char uMode,
|
||||
bool bAdded, bool bNoChange);
|
||||
@@ -800,7 +819,6 @@ class CModule {
|
||||
|
||||
/** This module hook is called when a client sends a raw traffic line to ZNC.
|
||||
* @param sLine The raw traffic line sent.
|
||||
* @note The line does not include message tags. Use OnUserRawMessage() to access them.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnUserRaw(CString& sLine);
|
||||
@@ -994,13 +1012,28 @@ class CModule {
|
||||
virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
|
||||
|
||||
/** Called for every CAP received via CAP LS from server.
|
||||
* If you need to also advertise the cap to clients, use
|
||||
* AddServerDependentCapability() instead.
|
||||
* @param sCap capability supported by server.
|
||||
* @return true if your module supports this CAP and
|
||||
* needs to turn it on with CAP REQ.
|
||||
*/
|
||||
virtual bool OnServerCapAvailable(const CString& sCap);
|
||||
/** Called for every CAP received via CAP LS from server.
|
||||
* By default just calls OnServerCapAvailable() without sValue, so
|
||||
* overriding one of the two is enough.
|
||||
* If you need to also advertise the cap to clients, use
|
||||
* AddServerDependentCapability() instead.
|
||||
* @param sCap capability name supported by server.
|
||||
* @param sValue value.
|
||||
* @return true if your module supports this CAP and
|
||||
* needs to turn it on with CAP REQ.
|
||||
*/
|
||||
virtual bool OnServerCap302Available(const CString& sCap, const CString& sValue);
|
||||
/** Called for every CAP accepted or rejected by server
|
||||
* (with CAP ACK or CAP NAK after our CAP REQ).
|
||||
* If you need to also advertise the cap to clients, use
|
||||
* AddServerDependentCapability() instead.
|
||||
* @param sCap capability accepted/rejected by server.
|
||||
* @param bSuccess true if capability was accepted, false if rejected.
|
||||
*/
|
||||
@@ -1046,14 +1079,39 @@ class CModule {
|
||||
/// @deprecated Use OnSendToIRCMessage() instead.
|
||||
virtual EModRet OnSendToIRC(CString& sLine);
|
||||
|
||||
/** This module hook is called when a user sends a TAGMSG message.
|
||||
* @since 1.10.0
|
||||
* @param Message The message which was sent.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnUserTagMessage(CTargetMessage& Message);
|
||||
/** Called when we receive a channel TAGMSG message <em>from IRC</em>.
|
||||
* @since 1.10.0
|
||||
* @param Message The channel message.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnChanTagMessage(CTargetMessage& Message);
|
||||
/** Called when we receive a private TAGMSG message <em>from IRC</em>.
|
||||
* @since 1.10.0
|
||||
* @param Message The message.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnPrivTagMessage(CTargetMessage& Message);
|
||||
|
||||
ModHandle GetDLL() { return m_pDLL; }
|
||||
|
||||
/** This function sends a given raw IRC line to the IRC server, if we
|
||||
/** This function sends a given IRC line to the IRC server, if we
|
||||
* are connected to one. Else this line is discarded.
|
||||
* @param sLine The line which should be sent.
|
||||
* @return true if the line was queued for sending.
|
||||
*/
|
||||
virtual bool PutIRC(const CString& sLine);
|
||||
/** This function sends a given IRC message to the IRC server, if we
|
||||
* are connected to one. Else this message is discarded.
|
||||
* @param Message The message which should be sent.
|
||||
* @return true if the message was queued for sending.
|
||||
*/
|
||||
virtual bool PutIRC(const CMessage& Message);
|
||||
/** This function sends a given raw IRC line to a client.
|
||||
* If we are in a module hook which is called for a specific client,
|
||||
* only that client will get the line, else all connected clients will
|
||||
@@ -1273,8 +1331,32 @@ class CModule {
|
||||
virtual EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine);
|
||||
virtual EModRet OnUnknownUserRawMessage(CMessage& Message);
|
||||
|
||||
/** Called after login, and also during JumpNetwork. */
|
||||
virtual void OnClientAttached();
|
||||
/** Called upon disconnect, and also during JumpNetwork. */
|
||||
virtual void OnClientDetached();
|
||||
|
||||
#ifndef SWIG
|
||||
/** Simple API to support client capabilities which depend on server to support that capability.
|
||||
* It is built on top of other CAP related API, but removes boilerplate,
|
||||
* and handles some tricky cases related to cap-notify and JumpNetwork. To
|
||||
* use, create a subclass of CCapability, and pass to this function; it
|
||||
* will automatically set the module pointer, then call the callbacks to
|
||||
* notify you when server and client accepted support of the capability, or
|
||||
* stopped supporting it. Note that it's not a strict toggle: e.g.
|
||||
* sometimes client will disable the cap even when it was already disabled
|
||||
* for that client.
|
||||
* For perl and python modules, this function accepts 3 parameters:
|
||||
* name, server callback, client callback; signatures of the callbacks are
|
||||
* the same as of the virtual functions you'd implement in C++.
|
||||
*/
|
||||
void AddServerDependentCapability(const CString& sName, std::unique_ptr<CCapability> pCap);
|
||||
#endif
|
||||
|
||||
/** Called when a client told us CAP LS. Use ssCaps.insert("cap-name")
|
||||
* for announcing capabilities which your module supports.
|
||||
* If you need to adverite the cap to clients only when it's also supported
|
||||
* by the server, use AddServerDependentCapability() instead.
|
||||
* @param pClient The client which requested the list.
|
||||
* @param ssCaps set of caps which will be sent to client.
|
||||
*/
|
||||
@@ -1288,6 +1370,8 @@ class CModule {
|
||||
virtual bool IsClientCapSupported(CClient* pClient, const CString& sCap,
|
||||
bool bState);
|
||||
/** Called when we actually need to turn a capability on or off for a client.
|
||||
* If you need to adverite the cap to clients only when it's also supported
|
||||
* by the server, use AddServerDependentCapability() instead.
|
||||
* If implementing a custom capability, make sure to call
|
||||
* pClient->SetTagSupport("tag-name", bState) for each tag that the
|
||||
* capability provides.
|
||||
@@ -1299,6 +1383,47 @@ class CModule {
|
||||
virtual void OnClientCapRequest(CClient* pClient, const CString& sCap,
|
||||
bool bState);
|
||||
|
||||
/** Called when a client requests SASL authentication. Use ssMechanisms.insert("MECHANISM")
|
||||
* for announcing SASL mechanisms which your module supports.
|
||||
* @param ssMechanisms The set of supported SASL mechanisms to append to.
|
||||
* @since 1.10.0
|
||||
*/
|
||||
virtual void OnClientGetSASLMechanisms(SCString& ssMechanisms);
|
||||
/** Called when a client has selected a SASL mechanism for SASL authentication.
|
||||
* If implementing a SASL authentication mechanism, set sResponse to
|
||||
* specify an initial challenge message to send to the client. Otherwise, an
|
||||
* empty response will be sent. To avoid sending any immediate response,
|
||||
* return HALT; in that case the module should schedule calling
|
||||
* GetClient()->SendSASLChallenge() with the initial response: in IRC SASL,
|
||||
* server always responds first.
|
||||
* @param sMechanism The SASL mechanism selected by the client.
|
||||
* @param sResponse The optional value of an initial SASL challenge message
|
||||
* to send to the client.
|
||||
* @since 1.10.0
|
||||
*/
|
||||
virtual EModRet OnClientSASLServerInitialChallenge(
|
||||
const CString& sMechanism, CString& sResponse);
|
||||
/** Called when a client is sending us a SASL message after the mechanism was selected.
|
||||
* If implementing a SASL authentication mechanism, check the passed
|
||||
* credentials, then either request more data by sending a challenge in
|
||||
* GetClient()->SendSASLChallenge(), or reject authentication by calling
|
||||
* GetClient()->RefuseSASLLogin(), or accept it by calling
|
||||
* GetClient()->AcceptSASLLogin().
|
||||
* At some point before accepting the login, you should call
|
||||
* GetClient()->ParseUser(authz-id) to let it know the network name to
|
||||
* attach to and the client id.
|
||||
* @param sMechanism The SASL mechanism selected by the client.
|
||||
* @param sMessage The SASL opaque value/credentials sent by the client,
|
||||
* after debase64ing and concatenating if it was split.
|
||||
* @since 1.10.0
|
||||
*/
|
||||
virtual EModRet OnClientSASLAuthenticate(const CString& sMechanism,
|
||||
const CString& sMessage);
|
||||
/** Called when a client sent '*' to abort SASL, or aborted it for another reason.
|
||||
* @since 1.10.0
|
||||
*/
|
||||
virtual void OnClientSASLAborted();
|
||||
|
||||
/** Called when a module is going to be loaded.
|
||||
* @param sModName name of the module.
|
||||
* @param eType wanted type of the module (user/global).
|
||||
@@ -1349,6 +1474,26 @@ class CModule {
|
||||
const CString& sContext = "") const;
|
||||
#endif
|
||||
|
||||
// Default implementations of several callbacks to make
|
||||
// AddServerDependentCapability work in modpython/modperl.
|
||||
// Don't worry about existence of these functions.
|
||||
bool InternalServerDependentCapsOnServerCap302Available(
|
||||
const CString& sCap, const CString& sValue);
|
||||
void InternalServerDependentCapsOnServerCapResult(const CString& sCap,
|
||||
bool bSuccess);
|
||||
void InternalServerDependentCapsOnClientCapLs(CClient* pClient,
|
||||
SCString& ssCaps);
|
||||
bool InternalServerDependentCapsIsClientCapSupported(CClient* pClient,
|
||||
const CString& sCap,
|
||||
bool bState);
|
||||
void InternalServerDependentCapsOnClientCapRequest(CClient* pClient,
|
||||
const CString& sCap,
|
||||
bool bState);
|
||||
void InternalServerDependentCapsOnClientAttached();
|
||||
void InternalServerDependentCapsOnClientDetached();
|
||||
void InternalServerDependentCapsOnIRCConnected();
|
||||
void InternalServerDependentCapsOnIRCDisconnected();
|
||||
|
||||
protected:
|
||||
CModInfo::EModuleType m_eType;
|
||||
CString m_sDescription;
|
||||
@@ -1368,6 +1513,7 @@ class CModule {
|
||||
CString m_sArgs;
|
||||
CString m_sModPath;
|
||||
CTranslationDomainRefHolder m_Translation;
|
||||
std::map<CString, std::unique_ptr<CCapability>> m_mServerDependentCaps;
|
||||
|
||||
private:
|
||||
MCString
|
||||
@@ -1376,7 +1522,7 @@ class CModule {
|
||||
std::map<CString, CModCommand> m_mCommands;
|
||||
};
|
||||
|
||||
class CModules : public std::vector<CModule*> {
|
||||
class CModules : public std::vector<CModule*>, private CCoreTranslationMixin {
|
||||
public:
|
||||
CModules();
|
||||
~CModules();
|
||||
@@ -1404,6 +1550,9 @@ class CModules : public std::vector<CModule*> {
|
||||
CString& sRealName);
|
||||
bool OnBroadcast(CString& sMessage);
|
||||
|
||||
bool OnChanPermission3(const CNick* pOpNick, const CNick& Nick,
|
||||
CChan& Channel, char cMode, bool bAdded,
|
||||
bool bNoChange);
|
||||
bool OnChanPermission2(const CNick* pOpNick, const CNick& Nick,
|
||||
CChan& Channel, unsigned char uMode, bool bAdded,
|
||||
bool bNoChange);
|
||||
@@ -1498,6 +1647,9 @@ class CModules : public std::vector<CModule*> {
|
||||
bool OnUserTopicRequest(CString& sChannel);
|
||||
bool OnUserQuit(CString& sMessage);
|
||||
bool OnUserQuitMessage(CQuitMessage& Message);
|
||||
bool OnUserTagMessage(CTargetMessage& Message);
|
||||
bool OnChanTagMessage(CTargetMessage& Message);
|
||||
bool OnPrivTagMessage(CTargetMessage& Message);
|
||||
|
||||
bool OnCTCPReply(CNick& Nick, CString& sMessage);
|
||||
bool OnCTCPReplyMessage(CCTCPMessage& Message);
|
||||
@@ -1528,8 +1680,10 @@ class CModules : public std::vector<CModule*> {
|
||||
bool OnSendToClientMessage(CMessage& Message);
|
||||
bool OnSendToIRC(CString& sLine);
|
||||
bool OnSendToIRCMessage(CMessage& Message);
|
||||
bool OnClientAttached();
|
||||
bool OnClientDetached();
|
||||
|
||||
bool OnServerCapAvailable(const CString& sCap);
|
||||
bool OnServerCapAvailable(const CString& sCap, const CString& sValue);
|
||||
bool OnServerCapResult(const CString& sCap, bool bSuccess);
|
||||
|
||||
CModule* FindModule(const CString& sModule) const;
|
||||
@@ -1574,6 +1728,14 @@ class CModules : public std::vector<CModule*> {
|
||||
bool IsClientCapSupported(CClient* pClient, const CString& sCap,
|
||||
bool bState);
|
||||
bool OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState);
|
||||
|
||||
bool OnClientGetSASLMechanisms(SCString& ssMechanisms);
|
||||
bool OnClientSASLAborted();
|
||||
bool OnClientSASLServerInitialChallenge(const CString& sMechanism,
|
||||
CString& sResponse);
|
||||
bool OnClientSASLAuthenticate(const CString& sMechanism,
|
||||
const CString& sBuffer);
|
||||
|
||||
bool OnModuleLoading(const CString& sModName, const CString& sArgs,
|
||||
CModInfo::EModuleType eType, bool& bSuccess,
|
||||
CString& sRetMsg);
|
||||
@@ -1587,6 +1749,7 @@ class CModules : public std::vector<CModule*> {
|
||||
private:
|
||||
static ModHandle OpenModule(const CString& sModule, const CString& sModPath,
|
||||
CModInfo& Info, CString& sRetMsg);
|
||||
static bool ValidateModuleName(const CString& sModule, CString& sRetMsg);
|
||||
|
||||
protected:
|
||||
CUser* m_pUser;
|
||||
|
||||
+10
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,14 +47,19 @@ class CNick {
|
||||
void SetNick(const CString& s);
|
||||
void SetIdent(const CString& s);
|
||||
void SetHost(const CString& s);
|
||||
bool AddPerm(unsigned char uPerm);
|
||||
bool RemPerm(unsigned char uPerm);
|
||||
/// e.g. '@' for chanop.
|
||||
bool AddPerm(char cPerm);
|
||||
/// e.g. '@' for chanop.
|
||||
bool RemPerm(char cPerm);
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
/// e.g. '@' for chanop.
|
||||
CString GetPermStr() const;
|
||||
unsigned char GetPermChar() const;
|
||||
bool HasPerm(unsigned char uPerm) const;
|
||||
/// e.g. '@' for chanop.
|
||||
char GetPermChar() const;
|
||||
/// e.g. '@' for chanop.
|
||||
bool HasPerm(char cPerm) const;
|
||||
const CString& GetNick() const;
|
||||
const CString& GetIdent() const;
|
||||
const CString& GetHost() const;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
class CModule;
|
||||
|
||||
class CZNCSock : public Csock, public CCoreTranslationMixin {
|
||||
class CZNCSock : public Csock, protected CCoreTranslationMixin {
|
||||
public:
|
||||
CZNCSock(int timeout = 60);
|
||||
CZNCSock(const CString& sHost, u_short port, int timeout = 60);
|
||||
@@ -36,12 +36,16 @@ class CZNCSock : public Csock, public CCoreTranslationMixin {
|
||||
int VerifyPeerCertificate(int iPreVerify,
|
||||
X509_STORE_CTX* pStoreCTX) override;
|
||||
void SSLHandShakeFinished() override;
|
||||
bool CheckSSLCert(X509* pCert);
|
||||
virtual void SSLCertError(X509* pCert) {}
|
||||
bool SNIConfigureClient(CString& sHostname) override;
|
||||
CString GetSSLPeerFingerprint(X509* pCert = nullptr) const;
|
||||
#else
|
||||
CString GetSSLPeerFingerprint() const { return ""; }
|
||||
#endif
|
||||
void SetHostToVerifySSL(const CString& sHost) {
|
||||
m_sHostToVerifySSL = sHost;
|
||||
}
|
||||
CString GetSSLPeerFingerprint() const;
|
||||
void SetSSLTrustedPeerFingerprints(const SCString& ssFPs) {
|
||||
m_ssTrustedFingerprints = ssFPs;
|
||||
}
|
||||
@@ -72,7 +76,8 @@ class CZNCSock : public Csock, public CCoreTranslationMixin {
|
||||
|
||||
enum EAddrType { ADDR_IPV4ONLY, ADDR_IPV6ONLY, ADDR_ALL };
|
||||
|
||||
class CSockManager : public TSocketManager<CZNCSock> {
|
||||
class CSockManager : public TSocketManager<CZNCSock>,
|
||||
private CCoreTranslationMixin {
|
||||
public:
|
||||
CSockManager();
|
||||
virtual ~CSockManager();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <znc/ZNCString.h>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
struct CTranslationInfo {
|
||||
static std::map<CString, CTranslationInfo> GetTranslations();
|
||||
@@ -83,20 +84,18 @@ class CDelayedTranslation {
|
||||
|
||||
class COptionalTranslation {
|
||||
public:
|
||||
COptionalTranslation(const CString& sText)
|
||||
: m_bTranslating(false), m_sText(sText) {}
|
||||
COptionalTranslation(const CString& sText) : m_text(sText) {}
|
||||
COptionalTranslation(const char* s) : COptionalTranslation(CString(s)) {}
|
||||
COptionalTranslation(const CDelayedTranslation& dTranslation)
|
||||
: m_bTranslating(true), m_dTranslation(dTranslation) {}
|
||||
COptionalTranslation(const CDelayedTranslation& dTranslation) : m_text(dTranslation) {}
|
||||
CString Resolve() const {
|
||||
return m_bTranslating ? m_dTranslation.Resolve() : m_sText;
|
||||
if (m_text.index() == 0) {
|
||||
return std::get<0>(m_text);
|
||||
}
|
||||
return std::get<1>(m_text).Resolve();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bTranslating;
|
||||
// TODO switch to std::variant<CString, CDelayedTranslation> after C++17
|
||||
CString m_sText;
|
||||
CDelayedTranslation m_dTranslation;
|
||||
std::variant<CString, CDelayedTranslation> m_text;
|
||||
};
|
||||
|
||||
// Used by everything except modules.
|
||||
|
||||
+47
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <znc/Utils.h>
|
||||
#include <znc/Buffer.h>
|
||||
#include <znc/Nick.h>
|
||||
#include <znc/Translation.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
@@ -34,9 +35,9 @@ class CIRCSock;
|
||||
class CUserTimer;
|
||||
class CServer;
|
||||
|
||||
class CUser {
|
||||
class CUser : private CCoreTranslationMixin {
|
||||
public:
|
||||
CUser(const CString& sUserName);
|
||||
CUser(const CString& sUsername);
|
||||
~CUser();
|
||||
|
||||
CUser(const CUser&) = delete;
|
||||
@@ -44,31 +45,38 @@ class CUser {
|
||||
|
||||
bool ParseConfig(CConfig* Config, CString& sError);
|
||||
|
||||
// TODO refactor this
|
||||
enum eHashType {
|
||||
HASH_NONE,
|
||||
HASH_MD5,
|
||||
HASH_SHA256,
|
||||
HASH_ARGON2ID,
|
||||
|
||||
HASH_DEFAULT = HASH_SHA256
|
||||
// This should be kept in sync with CUtils::SaltedHash
|
||||
#if ZNC_HAVE_ARGON
|
||||
HASH_DEFAULT = HASH_ARGON2ID,
|
||||
#else
|
||||
HASH_DEFAULT = HASH_SHA256,
|
||||
#endif
|
||||
};
|
||||
|
||||
// If you change the default hash here and in HASH_DEFAULT,
|
||||
// don't forget CUtils::sDefaultHash!
|
||||
// TODO refactor this
|
||||
static CString SaltedHash(const CString& sPass, const CString& sSalt) {
|
||||
return CUtils::SaltedSHA256Hash(sPass, sSalt);
|
||||
return CUtils::SaltedHash(sPass, sSalt);
|
||||
}
|
||||
|
||||
CConfig ToConfig() const;
|
||||
bool CheckPass(const CString& sPass) const;
|
||||
/** Checks password, may upgrade the hash method. */
|
||||
bool CheckPass(const CString& sPass);
|
||||
bool AddAllowedHost(const CString& sHostMask);
|
||||
bool RemAllowedHost(const CString& sHostMask);
|
||||
void ClearAllowedHosts();
|
||||
bool IsHostAllowed(const CString& sHost) const;
|
||||
bool IsValid(CString& sErrMsg, bool bSkipPass = false) const;
|
||||
static bool IsValidUserName(const CString& sUserName);
|
||||
static CString MakeCleanUserName(const CString& sUserName);
|
||||
static bool IsValidUsername(const CString& sUsername);
|
||||
/** @deprecated Use IsValidUsername() instead. */
|
||||
static bool IsValidUserName(const CString& sUsername);
|
||||
static CString MakeCleanUsername(const CString& sUsername);
|
||||
/** @deprecated Use MakeCleanUsername() instead. */
|
||||
static CString MakeCleanUserName(const CString& sUsername);
|
||||
|
||||
// Modules
|
||||
CModules& GetModules() { return *m_pModules; }
|
||||
@@ -88,7 +96,10 @@ class CUser {
|
||||
bool PutUser(const CString& sLine, CClient* pClient = nullptr,
|
||||
CClient* pSkipClient = nullptr);
|
||||
bool PutAllUser(const CString& sLine, CClient* pClient = nullptr,
|
||||
CClient* pSkipClient = nullptr);
|
||||
CClient* pSkipClient = nullptr)
|
||||
ZNC_MSG_DEPRECATED("Use PutUser() instead") {
|
||||
return PutUser(sLine, pClient, pSkipClient);
|
||||
}
|
||||
bool PutStatus(const CString& sLine, CClient* pClient = nullptr,
|
||||
CClient* pSkipClient = nullptr);
|
||||
bool PutStatusNotice(const CString& sLine, CClient* pClient = nullptr,
|
||||
@@ -110,6 +121,7 @@ class CUser {
|
||||
|
||||
CString AddTimestamp(const CString& sStr) const;
|
||||
CString AddTimestamp(time_t tm, const CString& sStr) const;
|
||||
CString AddTimestamp(timeval tv, const CString& sStr) const;
|
||||
|
||||
void CloneNetworks(const CUser& User);
|
||||
bool Clone(const CUser& User, CString& sErrorRet,
|
||||
@@ -131,6 +143,11 @@ class CUser {
|
||||
void SetDenyLoadMod(bool b);
|
||||
void SetAdmin(bool b);
|
||||
void SetDenySetBindHost(bool b);
|
||||
void SetDenySetIdent(bool b);
|
||||
void SetDenySetNetwork(bool b);
|
||||
void SetDenySetRealName(bool b);
|
||||
void SetDenySetQuitMsg(bool b);
|
||||
void SetDenySetCTCPReplies(bool b);
|
||||
bool SetStatusPrefix(const CString& s);
|
||||
void SetDefaultChanModes(const CString& s);
|
||||
void SetClientEncoding(const CString& s);
|
||||
@@ -149,6 +166,7 @@ class CUser {
|
||||
void SetTimestampFormat(const CString& s) { m_sTimestampFormat = s; }
|
||||
void SetTimestampAppend(bool b) { m_bAppendTimestamp = b; }
|
||||
void SetTimestampPrepend(bool b) { m_bPrependTimestamp = b; }
|
||||
void SetAuthOnlyViaModule(bool b) { m_bAuthOnlyViaModule = b; }
|
||||
void SetTimezone(const CString& s) { m_sTimezone = s; }
|
||||
void SetJoinTries(unsigned int i) { m_uMaxJoinTries = i; }
|
||||
void SetMaxJoins(unsigned int i) { m_uMaxJoins = i; }
|
||||
@@ -161,7 +179,9 @@ class CUser {
|
||||
// Getters
|
||||
const std::vector<CClient*>& GetUserClients() const { return m_vClients; }
|
||||
std::vector<CClient*> GetAllClients() const;
|
||||
/** @deprecated Use GetUsername() instead. */
|
||||
const CString& GetUserName() const;
|
||||
const CString& GetUsername() const;
|
||||
const CString& GetCleanUserName() const;
|
||||
const CString& GetNick(bool bAllowDefault = true) const;
|
||||
const CString& GetAltNick(bool bAllowDefault = true) const;
|
||||
@@ -183,7 +203,13 @@ class CUser {
|
||||
bool DenyLoadMod() const;
|
||||
bool IsAdmin() const;
|
||||
bool DenySetBindHost() const;
|
||||
bool DenySetIdent() const;
|
||||
bool DenySetNetwork() const;
|
||||
bool DenySetRealName() const;
|
||||
bool DenySetQuitMsg() const;
|
||||
bool DenySetCTCPReplies() const;
|
||||
bool MultiClients() const;
|
||||
bool AuthOnlyViaModule() const;
|
||||
const CString& GetStatusPrefix() const;
|
||||
const CString& GetDefaultChanModes() const;
|
||||
/** How long must an IRC connection be idle before ZNC sends a ping */
|
||||
@@ -216,8 +242,8 @@ class CUser {
|
||||
// !Getters
|
||||
|
||||
protected:
|
||||
const CString m_sUserName;
|
||||
const CString m_sCleanUserName;
|
||||
const CString m_sUsername;
|
||||
const CString m_sCleanUsername;
|
||||
CString m_sNick;
|
||||
CString m_sAltNick;
|
||||
CString m_sIdent;
|
||||
@@ -244,11 +270,17 @@ class CUser {
|
||||
bool m_bDenyLoadMod;
|
||||
bool m_bAdmin;
|
||||
bool m_bDenySetBindHost;
|
||||
bool m_bDenySetIdent;
|
||||
bool m_bDenySetNetwork;
|
||||
bool m_bDenySetRealName;
|
||||
bool m_bDenySetQuitMsg;
|
||||
bool m_bDenySetCTCPReplies;
|
||||
bool m_bAutoClearChanBuffer;
|
||||
bool m_bAutoClearQueryBuffer;
|
||||
bool m_bBeingDeleted;
|
||||
bool m_bAppendTimestamp;
|
||||
bool m_bPrependTimestamp;
|
||||
bool m_bAuthOnlyViaModule;
|
||||
|
||||
CUserTimer* m_pUserTimer;
|
||||
|
||||
|
||||
+51
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,6 +44,7 @@ class CUtils {
|
||||
|
||||
static CString GetIP(unsigned long addr);
|
||||
static unsigned long GetLongIP(const CString& sIP);
|
||||
static CString GetHostName();
|
||||
|
||||
static void PrintError(const CString& sMessage);
|
||||
static void PrintMessage(const CString& sMessage, bool bStrong = false);
|
||||
@@ -51,15 +52,16 @@ class CUtils {
|
||||
static void PrintAction(const CString& sMessage);
|
||||
static void PrintStatus(bool bSuccess, const CString& sMessage = "");
|
||||
|
||||
#ifndef SWIGPERL
|
||||
// TODO refactor this
|
||||
static const CString sDefaultHash;
|
||||
#endif
|
||||
/** Asks password from stdin, with confirmation.
|
||||
*
|
||||
* @returns Piece of znc.conf with <Pass> block
|
||||
* */
|
||||
static CString AskSaltedHashPassForConfig();
|
||||
|
||||
static CString GetSaltedHashPass(CString& sSalt);
|
||||
static CString GetSalt();
|
||||
static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt);
|
||||
static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt);
|
||||
static CString SaltedHash(const CString& sPass, const CString& sSalt);
|
||||
static CString GetPass(const CString& sPrompt);
|
||||
static bool GetInput(const CString& sPrompt, CString& sRet,
|
||||
const CString& sDefault = "",
|
||||
@@ -73,12 +75,27 @@ class CUtils {
|
||||
static timeval GetTime();
|
||||
static unsigned long long GetMillTime();
|
||||
#ifdef HAVE_LIBSSL
|
||||
static void GenerateCert(FILE* pOut, const CString& sHost = "");
|
||||
static void GenerateCert(FILE* pOut);
|
||||
#endif /* HAVE_LIBSSL */
|
||||
|
||||
static CString CTime(time_t t, const CString& sTZ);
|
||||
static CString FormatTime(time_t t, const CString& sFormat,
|
||||
const CString& sTZ);
|
||||
/** Supports an additional format specifier for formatting sub-second values:
|
||||
*
|
||||
* - %f - sub-second fraction
|
||||
* - %3f - millisecond (default, if no width is specified)
|
||||
* - %6f - microsecond
|
||||
*
|
||||
* However, note that timeval only supports microsecond precision
|
||||
* (thus, formatting with higher-than-microsecond precision will
|
||||
* always result in trailing zeroes), and IRC server-time is specified
|
||||
* in millisecond precision (thus formatting received timestamps with
|
||||
* higher-than-millisecond precision will always result in trailing
|
||||
* zeroes).
|
||||
*/
|
||||
static CString FormatTime(const timeval& tv, const CString& sFormat,
|
||||
const CString& sTZ);
|
||||
static CString FormatServerTime(const timeval& tv);
|
||||
static timeval ParseServerTime(const CString& sTime);
|
||||
static SCString GetTimezones();
|
||||
@@ -113,7 +130,7 @@ class CException {
|
||||
};
|
||||
|
||||
|
||||
/** Generate a grid-like output from a given input.
|
||||
/** Generate a grid-like or list-like output from a given input.
|
||||
*
|
||||
* @code
|
||||
* CTable table;
|
||||
@@ -137,9 +154,25 @@ class CException {
|
||||
+-------+-------+
|
||||
| hello | world |
|
||||
+-------+-------+@endverbatim
|
||||
*
|
||||
* If the table has at most two columns, one can switch to ListStyle output
|
||||
* like so:
|
||||
* @code
|
||||
* CTable table;
|
||||
* table.AddColumn("a");
|
||||
* table.AddColumn("b");
|
||||
* table.SetStyle(CTable::ListStyle);
|
||||
* // ...
|
||||
* @endcode
|
||||
*
|
||||
* This will yield the following (Note that the header is omitted; asterisks
|
||||
* denote bold text):
|
||||
* @verbatim
|
||||
*hello*: world@endverbatim
|
||||
*/
|
||||
class CTable : protected std::vector<std::vector<CString>> {
|
||||
public:
|
||||
enum EStyle { GridStyle, ListStyle };
|
||||
CTable() {}
|
||||
virtual ~CTable() {}
|
||||
|
||||
@@ -147,10 +180,18 @@ class CTable : protected std::vector<std::vector<CString>> {
|
||||
* Please note that you should add all columns before starting to fill
|
||||
* the table!
|
||||
* @param sName The name of the column.
|
||||
* @return false if a column by that name already existed.
|
||||
* @return false if a column by that name already existed or the current
|
||||
* style does not allow this many columns.
|
||||
*/
|
||||
bool AddColumn(const CString& sName);
|
||||
|
||||
/** Selects the output style of the table.
|
||||
* Select between different styles for printing. Default is GridStyle.
|
||||
* @param eNewStyle Table style type.
|
||||
* @return false if the style cannot be applied (usually too many columns).
|
||||
*/
|
||||
bool SetStyle(EStyle eNewStyle);
|
||||
|
||||
/** Adds a new row to the table.
|
||||
* After calling this you can fill the row with content.
|
||||
* @return The index of this row
|
||||
@@ -198,6 +239,7 @@ class CTable : protected std::vector<std::vector<CString>> {
|
||||
std::vector<CString> m_vsHeaders;
|
||||
// Used to cache the width of a column
|
||||
std::map<CString, CString::size_type> m_msuWidths;
|
||||
EStyle eStyle = GridStyle;
|
||||
};
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -697,4 +697,11 @@ class CInlineFormatMessage {
|
||||
CString m_sFormat;
|
||||
};
|
||||
|
||||
// For gtest
|
||||
#ifdef GTEST_FAIL
|
||||
inline void PrintTo(const CString& s, std::ostream* os) {
|
||||
*os << '"' << s.Escape_n(CString::EDEBUG) << '"';
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !ZNCSTRING_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
+9
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,19 +16,9 @@ limitations under the License.
|
||||
#ifndef ZNC_VERSION_H
|
||||
#define ZNC_VERSION_H
|
||||
|
||||
#ifndef BUILD_WITH_CMAKE
|
||||
// The following defines are for #if comparison (preprocessor only likes ints)
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 7
|
||||
#define VERSION_PATCH -1
|
||||
// This one is for display purpose and to check ABI compatibility of modules
|
||||
#define VERSION_STR "1.7.x"
|
||||
#endif
|
||||
|
||||
// Don't use this one
|
||||
#define VERSION (VERSION_MAJOR + VERSION_MINOR / 10.0)
|
||||
|
||||
// autoconf: You can add -DVERSION_EXTRA="stuff" to your CXXFLAGS!
|
||||
// CMake: You can add -DVERSION_EXTRA=stuff to cmake!
|
||||
#ifndef VERSION_EXTRA
|
||||
#define VERSION_EXTRA ""
|
||||
@@ -67,9 +57,16 @@ extern const char* ZNC_VERSION_EXTRA;
|
||||
#define ZNC_VERSION_TEXT_I18N "no"
|
||||
#endif
|
||||
|
||||
// This is only here because HASH_DEFAULT has different value
|
||||
#ifdef ZNC_HAVE_ARGON
|
||||
#define ZNC_VERSION_TEXT_ARGON "yes"
|
||||
#else
|
||||
#define ZNC_VERSION_TEXT_ARGON "no"
|
||||
#endif
|
||||
|
||||
#define ZNC_COMPILE_OPTIONS_STRING \
|
||||
"IPv6: " ZNC_VERSION_TEXT_IPV6 ", SSL: " ZNC_VERSION_TEXT_SSL \
|
||||
", DNS: " ZNC_VERSION_TEXT_DNS ", charset: " ZNC_VERSION_TEXT_ICU \
|
||||
", i18n: " ZNC_VERSION_TEXT_I18N
|
||||
", i18n: " ZNC_VERSION_TEXT_I18N ", Argon2: " ZNC_VERSION_TEXT_ARGON
|
||||
|
||||
#endif // !ZNC_VERSION_H
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ class CConfigWriteTimer;
|
||||
class CConfig;
|
||||
class CFile;
|
||||
|
||||
class CZNC {
|
||||
class CZNC : private CCoreTranslationMixin {
|
||||
public:
|
||||
CZNC();
|
||||
~CZNC();
|
||||
@@ -123,6 +123,7 @@ class CZNC {
|
||||
}
|
||||
void SetProtectWebSessions(bool b) { m_bProtectWebSessions = b; }
|
||||
void SetHideVersion(bool b) { m_bHideVersion = b; }
|
||||
void SetAuthOnlyViaModule(bool b) { m_bAuthOnlyViaModule = b; }
|
||||
void SetConnectDelay(unsigned int i);
|
||||
void SetSSLCiphers(const CString& sCiphers) { m_sSSLCiphers = sCiphers; }
|
||||
bool SetSSLProtocols(const CString& sProtocols);
|
||||
@@ -166,6 +167,7 @@ class CZNC {
|
||||
unsigned int GetConnectDelay() const { return m_uiConnectDelay; }
|
||||
bool GetProtectWebSessions() const { return m_bProtectWebSessions; }
|
||||
bool GetHideVersion() const { return m_bHideVersion; }
|
||||
bool GetAuthOnlyViaModule() const { return m_bAuthOnlyViaModule; }
|
||||
CString GetSSLCiphers() const { return m_sSSLCiphers; }
|
||||
CString GetSSLProtocols() const { return m_sSSLProtocols; }
|
||||
Csock::EDisableProtocol GetDisabledSSLProtocols() const {
|
||||
@@ -261,6 +263,8 @@ class CZNC {
|
||||
static void DumpConfig(const CConfig* Config);
|
||||
|
||||
private:
|
||||
static CString FormatBindError();
|
||||
|
||||
CFile* InitPidFile();
|
||||
|
||||
bool ReadConfig(CConfig& config, CString& sError);
|
||||
@@ -315,6 +319,7 @@ class CZNC {
|
||||
TCacheMap<CString> m_sConnectThrottle;
|
||||
bool m_bProtectWebSessions;
|
||||
bool m_bHideVersion;
|
||||
bool m_bAuthOnlyViaModule;
|
||||
CTranslationDomainRefHolder m_Translation;
|
||||
unsigned int m_uiConfigWriteDelay;
|
||||
CConfigWriteTimer* m_pConfigTimer;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
|
||||
* Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,9 +31,11 @@
|
||||
#define HAVE_PTHREAD 1
|
||||
#cmakedefine HAVE_THREADED_DNS 1
|
||||
#cmakedefine HAVE_LIBSSL 1
|
||||
#cmakedefine HAVE_SSL_SESSION_get0_cipher 1
|
||||
#cmakedefine HAVE_IPV6 1
|
||||
#cmakedefine HAVE_ZLIB 1
|
||||
#cmakedefine HAVE_I18N 1
|
||||
#cmakedefine ZNC_HAVE_ARGON 1
|
||||
#cmakedefine CSOCK_USE_POLL 1
|
||||
|
||||
#cmakedefine HAVE_GETOPT_LONG 1
|
||||
@@ -41,6 +43,8 @@
|
||||
#cmakedefine HAVE_TCSETATTR 1
|
||||
#cmakedefine HAVE_GETPASSPHRASE 1
|
||||
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||
#cmakedefine ZNC_HAVE_GETHOSTNAME 1
|
||||
#cmakedefine ZNC_HAVE_UNAME 1
|
||||
|
||||
#cmakedefine HAVE_ICU 1
|
||||
#define U_USING_ICU_NAMESPACE 1
|
||||
|
||||
Reference in New Issue
Block a user