ZNC  trunk
Client.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2021 ZNC, see the NOTICE file for details.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ZNC_CLIENT_H
18 #define ZNC_CLIENT_H
19 
20 #include <znc/zncconfig.h>
21 #include <znc/Socket.h>
22 #include <znc/Utils.h>
23 #include <znc/Message.h>
24 #include <znc/main.h>
25 #include <memory>
26 #include <functional>
27 
28 // Forward Declarations
29 class CZNC;
30 class CUser;
31 class CIRCNetwork;
32 class CIRCSock;
33 class CClient;
34 class CMessage;
35 class CChan;
36 // !Forward Declarations
37 
39  public:
40  CAuthBase(const CString& sUsername, const CString& sPassword,
41  CZNCSock* pSock)
42  : m_sUsername(sUsername), m_sPassword(sPassword), m_pSock(pSock) {}
43 
44  virtual ~CAuthBase() {}
45 
46  CAuthBase(const CAuthBase&) = delete;
47  CAuthBase& operator=(const CAuthBase&) = delete;
48 
49  virtual void SetLoginInfo(const CString& sUsername,
50  const CString& sPassword, CZNCSock* pSock) {
51  m_sUsername = sUsername;
52  m_sPassword = sPassword;
53  m_pSock = pSock;
54  }
55 
56  void AcceptLogin(CUser& User);
57  void RefuseLogin(const CString& sReason);
58 
59  const CString& GetUsername() const { return m_sUsername; }
60  const CString& GetPassword() const { return m_sPassword; }
61  Csock* GetSocket() const { return m_pSock; }
62  CString GetRemoteIP() const;
63 
64  // Invalidate this CAuthBase instance which means it will no longer use
65  // m_pSock and AcceptLogin() or RefusedLogin() will have no effect.
66  virtual void Invalidate();
67 
68  protected:
69  virtual void AcceptedLogin(CUser& User) = 0;
70  virtual void RefusedLogin(const CString& sReason) = 0;
71 
72  private:
73  CString m_sUsername;
74  CString m_sPassword;
75  CZNCSock* m_pSock;
76 };
77 
78 class CClientAuth : public CAuthBase {
79  public:
80  CClientAuth(CClient* pClient, const CString& sUsername,
81  const CString& sPassword);
82  virtual ~CClientAuth() {}
83 
84  CClientAuth(const CClientAuth&) = delete;
85  CClientAuth& operator=(const CClientAuth&) = delete;
86 
87  void Invalidate() override {
88  m_pClient = nullptr;
90  }
91  void AcceptedLogin(CUser& User) override;
92  void RefusedLogin(const CString& sReason) override;
93 
94  private:
95  protected:
97 };
98 
99 class CClient : public CIRCSocket {
100  public:
102  : CIRCSocket(),
103  m_bGotPass(false),
104  m_bGotNick(false),
105  m_bGotUser(false),
106  m_bInCap(false),
107  m_bCapNotify(false),
108  m_bAwayNotify(false),
109  m_bAccountNotify(false),
110  m_bAccountTag(false),
111  m_bExtendedJoin(false),
112  m_bNamesx(false),
113  m_bUHNames(false),
114  m_bAway(false),
115  m_bServerTime(false),
116  m_bBatch(false),
117  m_bEchoMessage(false),
118  m_bSelfMessage(false),
119  m_bPlaybackActive(false),
120  m_pUser(nullptr),
121  m_pNetwork(nullptr),
122  m_sNick("unknown-nick"),
123  m_sPass(""),
124  m_sUser(""),
125  m_sNetwork(""),
126  m_sIdentifier(""),
127  m_spAuth(),
130  m_mCoreCaps({
131  {"multi-prefix",
132  {false, [this](bool bVal) { m_bNamesx = bVal; }}},
133  {"userhost-in-names",
134  {false, [this](bool bVal) { m_bUHNames = bVal; }}},
135  {"echo-message",
136  {false, [this](bool bVal) { m_bEchoMessage = bVal; }}},
137  {"server-time",
138  {false, [this](bool bVal) {
139  m_bServerTime = bVal;
140  SetTagSupport("time", bVal);
141  }}},
142  {"batch", {false, [this](bool bVal) {
143  m_bBatch = bVal;
144  SetTagSupport("batch", bVal);
145  }}},
146  {"cap-notify",
147  {false, [this](bool bVal) { m_bCapNotify = bVal; }}},
148  {"away-notify",
149  {true, [this](bool bVal) { m_bAwayNotify = bVal; }}},
150  {"account-notify",
151  {true, [this](bool bVal) { m_bAccountNotify = bVal; }}},
152  {"account-tag",
153  {true, [this](bool bVal) {
154  m_bAccountTag = bVal;
155  SetTagSupport("account", bVal);
156  }}},
157  {"extended-join",
158  {true, [this](bool bVal) { m_bExtendedJoin = bVal; }}},
159  }) {
160  EnableReadLine();
161  // RFC says a line can have 512 chars max, but we are
162  // a little more gentle ;)
163  SetMaxBufferThreshold(1024);
164 
165  // For compatibility with older clients
166  m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"];
167  m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"];
168  m_mCoreCaps["znc.in/self-message"] = {
169  false, [this](bool bVal) { m_bSelfMessage = bVal; }};
170  }
171 
172  virtual ~CClient();
173 
174  CClient(const CClient&) = delete;
175  CClient& operator=(const CClient&) = delete;
176 
178  void AcceptLogin(CUser& User);
179  void RefuseLogin(const CString& sReason);
180 
181  CString GetNick(bool bAllowIRCNick = true) const;
182  CString GetNickMask() const;
183  CString GetIdentifier() const { return m_sIdentifier; }
184  bool HasCapNotify() const { return m_bCapNotify; }
185  bool HasAwayNotify() const { return m_bAwayNotify; }
186  bool HasAccountNotify() const { return m_bAccountNotify; }
187  bool HasAccountTag() const { return m_bAccountTag; }
188  bool HasExtendedJoin() const { return m_bExtendedJoin; }
189  bool HasNamesx() const { return m_bNamesx; }
190  bool HasUHNames() const { return m_bUHNames; }
191  bool IsAway() const { return m_bAway; }
192  bool HasServerTime() const { return m_bServerTime; }
193  bool HasBatch() const { return m_bBatch; }
194  bool HasEchoMessage() const { return m_bEchoMessage; }
195  bool HasSelfMessage() const { return m_bSelfMessage; }
196 
197  static bool IsValidIdentifier(const CString& sIdentifier);
198 
199  void UserCommand(CString& sLine);
200  void UserPortCommand(CString& sLine);
201  void StatusCTCP(const CString& sCommand);
202  void BouncedOff();
203  bool IsAttached() const { return m_pUser != nullptr; }
204 
205  bool IsPlaybackActive() const { return m_bPlaybackActive; }
206  void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; }
207 
208  void PutIRC(const CString& sLine);
221  bool PutClientRaw(const CString& sLine);
225  void PutClient(const CString& sLine);
275  bool PutClient(const CMessage& Message);
276  unsigned int PutStatus(const CTable& table);
277  void PutStatus(const CString& sLine);
278  void PutStatusNotice(const CString& sLine);
279  void PutModule(const CString& sModule, const CString& sLine);
280  void PutModNotice(const CString& sModule, const CString& sLine);
281 
282  bool IsCapEnabled(const CString& sCap) const {
283  return 1 == m_ssAcceptedCaps.count(sCap);
284  }
285 
286  bool IsTagEnabled(const CString& sTag) const {
287  return 1 == m_ssSupportedTags.count(sTag);
288  }
294  void SetTagSupport(const CString& sTag, bool bState);
295 
296  void NotifyServerDependentCaps(const SCString& ssCaps);
298 
299  void ReadLine(const CString& sData) override;
300  bool SendMotd();
301  void HelpUser(const CString& sFilter = "");
302  void AuthUser();
303  void Connected() override;
304  void Timeout() override;
305  void Disconnected() override;
306  void ConnectionRefused() override;
307  void ReachedMaxBuffer() override;
308 
309  void SetNick(const CString& s);
310  void SetAway(bool bAway) { m_bAway = bAway; }
311  CUser* GetUser() const { return m_pUser; }
312  void SetNetwork(CIRCNetwork* pNetwork, bool bDisconnect = true,
313  bool bReconnect = true);
314  CIRCNetwork* GetNetwork() const { return m_pNetwork; }
315  const std::vector<CClient*>& GetClients() const;
316  const CIRCSock* GetIRCSock() const;
317  CIRCSock* GetIRCSock();
318  CString GetFullName() const;
319 
320  private:
321  void HandleCap(const CMessage& Message);
322  void RespondCap(const CString& sResponse);
323  void ParsePass(const CString& sAuthLine);
324  void ParseUser(const CString& sAuthLine);
325  void ParseIdentifier(const CString& sAuthLine);
326 
327  template <typename T>
328  void AddBuffer(const T& Message);
329  void EchoMessage(const CMessage& Message);
330 
331  std::set<CChan*> MatchChans(const CString& sPatterns) const;
332  unsigned int AttachChans(const std::set<CChan*>& sChans);
333  unsigned int DetachChans(const std::set<CChan*>& sChans);
334 
335  bool OnActionMessage(CActionMessage& Message);
336  bool OnCTCPMessage(CCTCPMessage& Message);
337  bool OnJoinMessage(CJoinMessage& Message);
338  bool OnModeMessage(CModeMessage& Message);
339  bool OnNoticeMessage(CNoticeMessage& Message);
340  bool OnPartMessage(CPartMessage& Message);
341  bool OnPingMessage(CMessage& Message);
342  bool OnPongMessage(CMessage& Message);
343  bool OnQuitMessage(CQuitMessage& Message);
344  bool OnTextMessage(CTextMessage& Message);
345  bool OnTopicMessage(CTopicMessage& Message);
346  bool OnOtherMessage(CMessage& Message);
347 
348  protected:
352  bool m_bInCap;
358  bool m_bNamesx;
360  bool m_bAway;
362  bool m_bBatch;
373  std::shared_ptr<CAuthBase> m_spAuth;
376  // The capabilities supported by the ZNC core - capability names mapped
377  // to a pair which contains a bool describing whether the capability is
378  // server-dependent, and a capability value change handler.
379  std::map<CString, std::pair<bool, std::function<void(bool bVal)>>>
381  // A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed
382  // in CAP LS and may be notified to the client with CAP NEW (cap-notify).
384 
385  friend class ClientTest;
386 };
387 
388 #endif // !ZNC_CLIENT_H
CClient::HasExtendedJoin
bool HasExtendedJoin() const
Definition: Client.h:188
CClient::m_bAwayNotify
bool m_bAwayNotify
Definition: Client.h:354
CClient::m_bUHNames
bool m_bUHNames
Definition: Client.h:359
CAuthBase::operator=
CAuthBase & operator=(const CAuthBase &)=delete
CClient::HasBatch
bool HasBatch() const
Definition: Client.h:193
CClient::ReachedMaxBuffer
void ReachedMaxBuffer() override
This WARNING event is called when your buffer for readline exceeds the warning threshold and triggers...
CClient::m_bAccountNotify
bool m_bAccountNotify
Definition: Client.h:355
CClientAuth::RefusedLogin
void RefusedLogin(const CString &sReason) override
CClient
Definition: Client.h:99
CClient::SendRequiredPasswordNotice
void SendRequiredPasswordNotice()
Csock
Basic socket class.
Definition: Csocket.h:564
CClient::BouncedOff
void BouncedOff()
CTopicMessage
Definition: Message.h:340
CClient::CClient
CClient()
Definition: Client.h:101
CClient::m_ssServerDependentCaps
SCString m_ssServerDependentCaps
Definition: Client.h:383
CClient::SetTagSupport
void SetTagSupport(const CString &sTag, bool bState)
Registers a tag as being supported or unsupported by the client.
CActionMessage
Definition: Message.h:242
CQuitMessage
Definition: Message.h:324
CClient::m_bGotPass
bool m_bGotPass
Definition: Client.h:349
CAuthBase::RefusedLogin
virtual void RefusedLogin(const CString &sReason)=0
CAuthBase::GetRemoteIP
CString GetRemoteIP() const
CClient::HelpUser
void HelpUser(const CString &sFilter="")
CClient::UserCommand
void UserCommand(CString &sLine)
CClient::m_bInCap
bool m_bInCap
Definition: Client.h:352
CClient::GetIdentifier
CString GetIdentifier() const
Definition: Client.h:183
CCTCPMessage
Definition: Message.h:253
CClient::HasSelfMessage
bool HasSelfMessage() const
Definition: Client.h:195
CClient::HasNamesx
bool HasNamesx() const
Definition: Client.h:189
SCString
std::set< CString > SCString
Definition: ZNCString.h:35
CClientAuth
Definition: Client.h:78
CAuthBase::AcceptedLogin
virtual void AcceptedLogin(CUser &User)=0
CClient::m_bGotUser
bool m_bGotUser
Definition: Client.h:351
CAuthBase::AcceptLogin
void AcceptLogin(CUser &User)
CClient::ClientTest
friend class ClientTest
Definition: Client.h:385
CIRCSocket
Base IRC socket for client<->ZNC, and ZNC<->server.
Definition: Socket.h:309
Csock::SetMaxBufferThreshold
void SetMaxBufferThreshold(uint32_t iThreshold)
sets the max buffered threshold when EnableReadLine() is enabled
CMessage
Here is a small explanation of how messages on IRC work, and how you can use this class to get useful...
Definition: Message.h:70
CClient::GetNick
CString GetNick(bool bAllowIRCNick=true) const
CClient::SendMotd
bool SendMotd()
CClient::m_spAuth
std::shared_ptr< CAuthBase > m_spAuth
Definition: Client.h:373
CClient::StatusCTCP
void StatusCTCP(const CString &sCommand)
CClient::PutStatus
unsigned int PutStatus(const CTable &table)
CAuthBase::GetUsername
const CString & GetUsername() const
Definition: Client.h:59
CString
String class that is used inside ZNC.
Definition: ZNCString.h:68
CClientAuth::AcceptedLogin
void AcceptedLogin(CUser &User) override
CClient::GetFullName
CString GetFullName() const
CClient::Timeout
void Timeout() override
Sock Timed out event.
CClient::m_bSelfMessage
bool m_bSelfMessage
Definition: Client.h:364
CClient::HasAwayNotify
bool HasAwayNotify() const
Definition: Client.h:185
CClient::m_sNetwork
CString m_sNetwork
Definition: Client.h:371
CClient::m_mCoreCaps
std::map< CString, std::pair< bool, std::function< void(bool bVal)> > > m_mCoreCaps
Definition: Client.h:380
CClient::m_bNamesx
bool m_bNamesx
Definition: Client.h:358
CClient::PutModule
void PutModule(const CString &sModule, const CString &sLine)
Utils.h
CClient::ClearServerDependentCaps
void ClearServerDependentCaps()
CClient::m_bBatch
bool m_bBatch
Definition: Client.h:362
CTextMessage
Definition: Message.h:333
Socket.h
CClient::AcceptLogin
void AcceptLogin(CUser &User)
CAuthBase::GetPassword
const CString & GetPassword() const
Definition: Client.h:60
CClient::NotifyServerDependentCaps
void NotifyServerDependentCaps(const SCString &ssCaps)
CClient::m_ssSupportedTags
SCString m_ssSupportedTags
Definition: Client.h:375
CChan
Definition: Chan.h:35
CClient::SetNetwork
void SetNetwork(CIRCNetwork *pNetwork, bool bDisconnect=true, bool bReconnect=true)
CClient::SetNick
void SetNick(const CString &s)
CClient::PutIRC
void PutIRC(const CString &sLine)
CClient::SetPlaybackActive
void SetPlaybackActive(bool bActive)
Definition: Client.h:206
CIRCSock
Definition: IRCSock.h:35
CClient::UserPortCommand
void UserPortCommand(CString &sLine)
CAuthBase::Invalidate
virtual void Invalidate()
CClient::m_sIdentifier
CString m_sIdentifier
Definition: Client.h:372
CClient::m_bCapNotify
bool m_bCapNotify
Definition: Client.h:353
CJoinMessage
Definition: Message.h:263
CClient::m_sPass
CString m_sPass
Definition: Client.h:369
CClient::IsPlaybackActive
bool IsPlaybackActive() const
Definition: Client.h:205
CClient::HasAccountTag
bool HasAccountTag() const
Definition: Client.h:187
CClient::m_bEchoMessage
bool m_bEchoMessage
Definition: Client.h:363
CClient::PutClient
void PutClient(const CString &sLine)
Sends a message to the client.
CClient::HasServerTime
bool HasServerTime() const
Definition: Client.h:192
CAuthBase::CAuthBase
CAuthBase(const CString &sUsername, const CString &sPassword, CZNCSock *pSock)
Definition: Client.h:40
CClient::GetNickMask
CString GetNickMask() const
CClient::HasAccountNotify
bool HasAccountNotify() const
Definition: Client.h:186
CClient::PutModNotice
void PutModNotice(const CString &sModule, const CString &sLine)
CClient::IsAttached
bool IsAttached() const
Definition: Client.h:203
CAuthBase
Definition: Client.h:38
CClient::SetAway
void SetAway(bool bAway)
Definition: Client.h:310
CAuthBase::~CAuthBase
virtual ~CAuthBase()
Definition: Client.h:44
CClient::m_bPlaybackActive
bool m_bPlaybackActive
Definition: Client.h:365
CClient::IsAway
bool IsAway() const
Definition: Client.h:191
CClient::m_sNick
CString m_sNick
Definition: Client.h:368
Csock::EnableReadLine
void EnableReadLine()
set the value of m_bEnableReadLine to true, we don't want to store a buffer for ReadLine,...
CModeMessage
Definition: Message.h:270
CClient::m_sUser
CString m_sUser
Definition: Client.h:370
CClient::Disconnected
void Disconnected() override
Disconnected event.
CClient::IsCapEnabled
bool IsCapEnabled(const CString &sCap) const
Definition: Client.h:282
CClient::PutClientRaw
bool PutClientRaw(const CString &sLine)
Sends a raw data line to the client.
CClientAuth::CClientAuth
CClientAuth(CClient *pClient, const CString &sUsername, const CString &sPassword)
CClient::ConnectionRefused
void ConnectionRefused() override
Connection Refused Event.
CClient::m_bServerTime
bool m_bServerTime
Definition: Client.h:361
CUser
Definition: User.h:38
main.h
CClientAuth::~CClientAuth
virtual ~CClientAuth()
Definition: Client.h:82
CClient::AuthUser
void AuthUser()
CClientAuth::m_pClient
CClient * m_pClient
Definition: Client.h:96
CIRCNetwork
Definition: IRCNetwork.h:40
CClient::m_bAway
bool m_bAway
Definition: Client.h:360
CAuthBase::GetSocket
Csock * GetSocket() const
Definition: Client.h:61
CClient::~CClient
virtual ~CClient()
CClient::GetNetwork
CIRCNetwork * GetNetwork() const
Definition: Client.h:314
CClient::PutStatusNotice
void PutStatusNotice(const CString &sLine)
CZNCSock
Definition: Socket.h:27
CTable
Generate a grid-like or list-like output from a given input.
Definition: Utils.h:171
CCoreTranslationMixin
Definition: Translation.h:104
CClientAuth::Invalidate
void Invalidate() override
Definition: Client.h:87
CClient::HasEchoMessage
bool HasEchoMessage() const
Definition: Client.h:194
CClient::IsTagEnabled
bool IsTagEnabled(const CString &sTag) const
Definition: Client.h:286
CNoticeMessage
Definition: Message.h:291
CClient::operator=
CClient & operator=(const CClient &)=delete
CClient::GetUser
CUser * GetUser() const
Definition: Client.h:311
CZNC
Definition: znc.h:38
CClient::Connected
void Connected() override
Connected event.
CClient::m_pUser
CUser * m_pUser
Definition: Client.h:366
CClient::HasUHNames
bool HasUHNames() const
Definition: Client.h:190
CClientAuth::operator=
CClientAuth & operator=(const CClientAuth &)=delete
CClient::m_bExtendedJoin
bool m_bExtendedJoin
Definition: Client.h:357
CClient::m_ssAcceptedCaps
SCString m_ssAcceptedCaps
Definition: Client.h:374
CClient::m_bAccountTag
bool m_bAccountTag
Definition: Client.h:356
CClient::RefuseLogin
void RefuseLogin(const CString &sReason)
CAuthBase::RefuseLogin
void RefuseLogin(const CString &sReason)
CClient::HasCapNotify
bool HasCapNotify() const
Definition: Client.h:184
CAuthBase::SetLoginInfo
virtual void SetLoginInfo(const CString &sUsername, const CString &sPassword, CZNCSock *pSock)
Definition: Client.h:49
CClient::m_bGotNick
bool m_bGotNick
Definition: Client.h:350
CClient::GetClients
const std::vector< CClient * > & GetClients() const
CPartMessage
Definition: Message.h:315
CClient::m_pNetwork
CIRCNetwork * m_pNetwork
Definition: Client.h:367
CClient::IsValidIdentifier
static bool IsValidIdentifier(const CString &sIdentifier)
CClient::ReadLine
void ReadLine(const CString &sData) override
CClient::GetIRCSock
const CIRCSock * GetIRCSock() const
Message.h