ZNC
Versions: latest readthedocs-test
Client.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2017 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 
27 // Forward Declarations
28 class CZNC;
29 class CUser;
30 class CIRCNetwork;
31 class CIRCSock;
32 class CClient;
33 class CMessage;
34 class CChan;
35 // !Forward Declarations
36 
37 class CAuthBase {
38  public:
39  CAuthBase(const CString& sUsername, const CString& sPassword,
40  CZNCSock* pSock)
41  : m_sUsername(sUsername), m_sPassword(sPassword), m_pSock(pSock) {}
42 
43  virtual ~CAuthBase() {}
44 
45  CAuthBase(const CAuthBase&) = delete;
46  CAuthBase& operator=(const CAuthBase&) = delete;
47 
48  virtual void SetLoginInfo(const CString& sUsername,
49  const CString& sPassword, CZNCSock* pSock) {
50  m_sUsername = sUsername;
51  m_sPassword = sPassword;
52  m_pSock = pSock;
53  }
54 
55  void AcceptLogin(CUser& User);
56  void RefuseLogin(const CString& sReason);
57 
58  const CString& GetUsername() const { return m_sUsername; }
59  const CString& GetPassword() const { return m_sPassword; }
60  Csock* GetSocket() const { return m_pSock; }
61  CString GetRemoteIP() const;
62 
63  // Invalidate this CAuthBase instance which means it will no longer use
64  // m_pSock and AcceptLogin() or RefusedLogin() will have no effect.
65  virtual void Invalidate();
66 
67  protected:
68  virtual void AcceptedLogin(CUser& User) = 0;
69  virtual void RefusedLogin(const CString& sReason) = 0;
70 
71  private:
72  CString m_sUsername;
73  CString m_sPassword;
74  CZNCSock* m_pSock;
75 };
76 
77 class CClientAuth : public CAuthBase {
78  public:
79  CClientAuth(CClient* pClient, const CString& sUsername,
80  const CString& sPassword);
81  virtual ~CClientAuth() {}
82 
83  CClientAuth(const CClientAuth&) = delete;
84  CClientAuth& operator=(const CClientAuth&) = delete;
85 
86  void Invalidate() override {
87  m_pClient = nullptr;
89  }
90  void AcceptedLogin(CUser& User) override;
91  void RefusedLogin(const CString& sReason) override;
92 
93  private:
94  protected:
96 };
97 
98 class CClient : public CIRCSocket {
99  public:
101  : CIRCSocket(),
102  m_bGotPass(false),
103  m_bGotNick(false),
104  m_bGotUser(false),
105  m_bInCap(false),
106  m_bCapNotify(false),
107  m_bAwayNotify(false),
108  m_bAccountNotify(false),
109  m_bExtendedJoin(false),
110  m_bNamesx(false),
111  m_bUHNames(false),
112  m_bAway(false),
113  m_bServerTime(false),
114  m_bBatch(false),
115  m_bEchoMessage(false),
116  m_bSelfMessage(false),
117  m_bPlaybackActive(false),
118  m_pUser(nullptr),
119  m_pNetwork(nullptr),
120  m_sNick("unknown-nick"),
121  m_sPass(""),
122  m_sUser(""),
123  m_sNetwork(""),
124  m_sIdentifier(""),
125  m_spAuth(),
126  m_ssAcceptedCaps(),
127  m_ssSupportedTags(),
128  m_mCoreCaps({
129  {"multi-prefix",
130  {false, [this](bool bVal) { m_bNamesx = bVal; }}},
131  {"userhost-in-names",
132  {false, [this](bool bVal) { m_bUHNames = bVal; }}},
133  {"echo-message",
134  {false, [this](bool bVal) { m_bEchoMessage = bVal; }}},
135  {"server-time",
136  {false, [this](bool bVal) {
137  m_bServerTime = bVal;
138  SetTagSupport("time", bVal);
139  }}},
140  {"batch", {false, [this](bool bVal) {
141  m_bBatch = bVal;
142  SetTagSupport("batch", bVal);
143  }}},
144  {"cap-notify",
145  {false, [this](bool bVal) { m_bCapNotify = bVal; }}},
146  {"away-notify",
147  {true, [this](bool bVal) { m_bAwayNotify = bVal; }}},
148  {"account-notify",
149  {true, [this](bool bVal) { m_bAccountNotify = bVal; }}},
150  {"extended-join",
151  {true, [this](bool bVal) { m_bExtendedJoin = bVal; }}},
152  }) {
153  EnableReadLine();
154  // RFC says a line can have 512 chars max, but we are
155  // a little more gentle ;)
156  SetMaxBufferThreshold(1024);
157 
158  // For compatibility with older clients
159  m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"];
160  m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"];
161  m_mCoreCaps["znc.in/self-message"] = {
162  false, [this](bool bVal) { m_bSelfMessage = bVal; }};
163  }
164 
165  virtual ~CClient();
166 
167  CClient(const CClient&) = delete;
168  CClient& operator=(const CClient&) = delete;
169 
170  void SendRequiredPasswordNotice();
171  void AcceptLogin(CUser& User);
172  void RefuseLogin(const CString& sReason);
173 
174  CString GetNick(bool bAllowIRCNick = true) const;
175  CString GetNickMask() const;
176  CString GetIdentifier() const { return m_sIdentifier; }
177  bool HasCapNotify() const { return m_bCapNotify; }
178  bool HasAwayNotify() const { return m_bAwayNotify; }
179  bool HasAccountNotify() const { return m_bAccountNotify; }
180  bool HasExtendedJoin() const { return m_bExtendedJoin; }
181  bool HasNamesx() const { return m_bNamesx; }
182  bool HasUHNames() const { return m_bUHNames; }
183  bool IsAway() const { return m_bAway; }
184  bool HasServerTime() const { return m_bServerTime; }
185  bool HasBatch() const { return m_bBatch; }
186  bool HasEchoMessage() const { return m_bEchoMessage; }
187  bool HasSelfMessage() const { return m_bSelfMessage; }
188 
189  static bool IsValidIdentifier(const CString& sIdentifier);
190 
191  void UserCommand(CString& sLine);
192  void UserPortCommand(CString& sLine);
193  void StatusCTCP(const CString& sCommand);
194  void BouncedOff();
195  bool IsAttached() const { return m_pUser != nullptr; }
196 
197  bool IsPlaybackActive() const { return m_bPlaybackActive; }
198  void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; }
199 
200  void PutIRC(const CString& sLine);
210  void PutClient(const CString& sLine);
257  bool PutClient(const CMessage& Message);
258  unsigned int PutStatus(const CTable& table);
259  void PutStatus(const CString& sLine);
260  void PutStatusNotice(const CString& sLine);
261  void PutModule(const CString& sModule, const CString& sLine);
262  void PutModNotice(const CString& sModule, const CString& sLine);
263 
264  bool IsCapEnabled(const CString& sCap) const {
265  return 1 == m_ssAcceptedCaps.count(sCap);
266  }
267 
268  bool IsTagEnabled(const CString& sTag) const {
269  return 1 == m_ssSupportedTags.count(sTag);
270  }
275  void SetTagSupport(const CString& sTag, bool bState);
276 
277  void NotifyServerDependentCaps(const SCString& ssCaps);
278  void ClearServerDependentCaps();
279 
280  void ReadLine(const CString& sData) override;
281  bool SendMotd();
282  void HelpUser(const CString& sFilter = "");
283  void AuthUser();
284  void Connected() override;
285  void Timeout() override;
286  void Disconnected() override;
287  void ConnectionRefused() override;
288  void ReachedMaxBuffer() override;
289 
290  void SetNick(const CString& s);
291  void SetAway(bool bAway) { m_bAway = bAway; }
292  CUser* GetUser() const { return m_pUser; }
293  void SetNetwork(CIRCNetwork* pNetwork, bool bDisconnect = true,
294  bool bReconnect = true);
295  CIRCNetwork* GetNetwork() const { return m_pNetwork; }
296  const std::vector<CClient*>& GetClients() const;
297  const CIRCSock* GetIRCSock() const;
298  CIRCSock* GetIRCSock();
299  CString GetFullName() const;
300 
301  private:
302  void HandleCap(const CMessage& Message);
303  void RespondCap(const CString& sResponse);
304  void ParsePass(const CString& sAuthLine);
305  void ParseUser(const CString& sAuthLine);
306  void ParseIdentifier(const CString& sAuthLine);
307 
308  template <typename T>
309  void AddBuffer(const T& Message);
310  void EchoMessage(const CMessage& Message);
311 
312  std::set<CChan*> MatchChans(const CString& sPatterns) const;
313  unsigned int AttachChans(const std::set<CChan*>& sChans);
314  unsigned int DetachChans(const std::set<CChan*>& sChans);
315 
316  bool OnActionMessage(CActionMessage& Message);
317  bool OnCTCPMessage(CCTCPMessage& Message);
318  bool OnJoinMessage(CJoinMessage& Message);
319  bool OnModeMessage(CModeMessage& Message);
320  bool OnNoticeMessage(CNoticeMessage& Message);
321  bool OnPartMessage(CPartMessage& Message);
322  bool OnPingMessage(CMessage& Message);
323  bool OnPongMessage(CMessage& Message);
324  bool OnQuitMessage(CQuitMessage& Message);
325  bool OnTextMessage(CTextMessage& Message);
326  bool OnTopicMessage(CTopicMessage& Message);
327  bool OnOtherMessage(CMessage& Message);
328 
329  protected:
333  bool m_bInCap;
338  bool m_bNamesx;
340  bool m_bAway;
342  bool m_bBatch;
353  std::shared_ptr<CAuthBase> m_spAuth;
356  // The capabilities supported by the ZNC core - capability names mapped
357  // to a pair which contains a bool describing whether the capability is
358  // server-dependent, and a capability value change handler.
359  std::map<CString, std::pair<bool, std::function<void(bool bVal)>>>
361  // A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed
362  // in CAP LS and may be notified to the client with CAP NEW (cap-notify).
364 
365  friend class ClientTest;
366 };
367 
368 #endif // !ZNC_CLIENT_H
virtual void RefusedLogin(const CString &sReason)=0
void Invalidate() override
Definition: Client.h:86
bool m_bCapNotify
Definition: Client.h:334
Definition: Message.h:302
Definition: Message.h:245
CString m_sPass
Definition: Client.h:349
bool m_bServerTime
Definition: Client.h:341
Definition: User.h:37
bool IsTagEnabled(const CString &sTag) const
Definition: Client.h:268
bool HasAccountNotify() const
Definition: Client.h:179
SCString m_ssAcceptedCaps
Definition: Client.h:354
bool m_bSelfMessage
Definition: Client.h:344
std::map< CString, std::pair< bool, std::function< void(bool bVal)> > > m_mCoreCaps
Definition: Client.h:360
bool m_bGotNick
Definition: Client.h:331
CAuthBase(const CString &sUsername, const CString &sPassword, CZNCSock *pSock)
Definition: Client.h:39
bool HasBatch() const
Definition: Client.h:185
const CString & GetUsername() const
Definition: Client.h:58
CString m_sNick
Definition: Client.h:348
Definition: Client.h:77
virtual void Invalidate()
Definition: Client.h:98
Base IRC socket for client<->ZNC, and ZNC<->server.
Definition: Socket.h:304
bool IsAttached() const
Definition: Client.h:195
bool HasCapNotify() const
Definition: Client.h:177
Definition: Message.h:281
Definition: Message.h:259
bool HasSelfMessage() const
Definition: Client.h:187
void SetAway(bool bAway)
Definition: Client.h:291
bool IsAway() const
Definition: Client.h:183
bool m_bUHNames
Definition: Client.h:339
std::set< CString > SCString
Definition: ZNCString.h:35
Definition: Socket.h:27
bool HasExtendedJoin() const
Definition: Client.h:180
Definition: Message.h:228
void RefuseLogin(const CString &sReason)
bool m_bEchoMessage
Definition: Client.h:343
bool HasEchoMessage() const
Definition: Client.h:186
Definition: Message.h:288
CUser * GetUser() const
Definition: Client.h:292
Definition: znc.h:38
Definition: Message.h:217
Basic socket class.
Definition: Csocket.h:548
Definition: IRCNetwork.h:40
bool HasAwayNotify() const
Definition: Client.h:178
String class that is used inside ZNC.
Definition: ZNCString.h:68
bool m_bPlaybackActive
Definition: Client.h:345
CString m_sNetwork
Definition: Client.h:351
bool m_bAccountNotify
Definition: Client.h:336
CUser * m_pUser
Definition: Client.h:346
CString GetIdentifier() const
Definition: Client.h:176
Csock * GetSocket() const
Definition: Client.h:60
bool m_bExtendedJoin
Definition: Client.h:337
CClient()
Definition: Client.h:100
Definition: Client.h:37
virtual void SetLoginInfo(const CString &sUsername, const CString &sPassword, CZNCSock *pSock)
Definition: Client.h:48
SCString m_ssServerDependentCaps
Definition: Client.h:363
CIRCNetwork * m_pNetwork
Definition: Client.h:347
bool m_bGotPass
Definition: Client.h:330
bool IsPlaybackActive() const
Definition: Client.h:197
virtual ~CClientAuth()
Definition: Client.h:81
CIRCNetwork * GetNetwork() const
Definition: Client.h:295
Definition: Message.h:295
bool m_bAwayNotify
Definition: Client.h:335
bool m_bNamesx
Definition: Client.h:338
bool m_bInCap
Definition: Client.h:333
bool HasNamesx() const
Definition: Client.h:181
const CString & GetPassword() const
Definition: Client.h:59
virtual ~CAuthBase()
Definition: Client.h:43
CString GetRemoteIP() const
CAuthBase & operator=(const CAuthBase &)=delete
CClient * m_pClient
Definition: Client.h:95
void SetPlaybackActive(bool bActive)
Definition: Client.h:198
std::shared_ptr< CAuthBase > m_spAuth
Definition: Client.h:353
CString m_sIdentifier
Definition: Client.h:352
Definition: Message.h:238
bool m_bAway
Definition: Client.h:340
Definition: IRCSock.h:35
bool HasUHNames() const
Definition: Client.h:182
bool m_bBatch
Definition: Client.h:342
bool HasServerTime() const
Definition: Client.h:184
Definition: Chan.h:34
Generate a grid-like output from a given input.
Definition: Utils.h:141
SCString m_ssSupportedTags
Definition: Client.h:355
bool IsCapEnabled(const CString &sCap) const
Definition: Client.h:264
bool m_bGotUser
Definition: Client.h:332
CString m_sUser
Definition: Client.h:350
Here is a small explanation of how messages on IRC work, and how you can use this class to get useful...
Definition: Message.h:63
virtual void AcceptedLogin(CUser &User)=0
void AcceptLogin(CUser &User)