ZNC  trunk
Socket.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2024 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_SOCKET_H
18 #define ZNC_SOCKET_H
19 
20 #include <znc/zncconfig.h>
21 #include <znc/Csocket.h>
22 #include <znc/Threads.h>
23 #include <znc/Translation.h>
24 
25 class CModule;
26 
27 class CZNCSock : public Csock, protected CCoreTranslationMixin {
28  public:
29  CZNCSock(int timeout = 60);
30  CZNCSock(const CString& sHost, u_short port, int timeout = 60);
31  ~CZNCSock() {}
32 
33  int ConvertAddress(const struct sockaddr_storage* pAddr, socklen_t iAddrLen,
34  CString& sIP, u_short* piPort) const override;
35 #ifdef HAVE_LIBSSL
36  int VerifyPeerCertificate(int iPreVerify,
37  X509_STORE_CTX* pStoreCTX) override;
38  void SSLHandShakeFinished() override;
39  bool CheckSSLCert(X509* pCert);
40  virtual void SSLCertError(X509* pCert) {}
41  bool SNIConfigureClient(CString& sHostname) override;
42  CString GetSSLPeerFingerprint(X509* pCert = nullptr) const;
43 #else
44  CString GetSSLPeerFingerprint() const { return ""; }
45 #endif
46  void SetHostToVerifySSL(const CString& sHost) {
47  m_sHostToVerifySSL = sHost;
48  }
50  m_ssTrustedFingerprints = ssFPs;
51  }
52 
53  void SetTrustAllCerts(bool bTrustAll) { m_bTrustAllCerts = bTrustAll; }
54  bool GetTrustAllCerts() const { return m_bTrustAllCerts; }
55 
56  void SetTrustPKI(bool bTrustPKI) { m_bTrustPKI = bTrustPKI; }
57  bool GetTrustPKI() const { return m_bTrustPKI; }
58 
59  void SetEncoding(const CString&);
60 
61  virtual CString GetRemoteIP() const { return Csock::GetRemoteIP(); }
62 
63  protected:
64  // All existing errno codes seem to be in range 1-300
65  enum {
66  errnoBadSSLCert = 12569,
67  };
68 
69  private:
70  CString m_sHostToVerifySSL;
71  SCString m_ssTrustedFingerprints;
72  SCString m_ssCertVerificationErrors;
73  bool m_bTrustAllCerts = false;
74  bool m_bTrustPKI = true;
75 };
76 
78 
79 class CSockManager : public TSocketManager<CZNCSock>,
80  private CCoreTranslationMixin {
81  public:
82  CSockManager();
83  virtual ~CSockManager();
84 
85  bool ListenHost(u_short iPort, const CString& sSockName,
86  const CString& sBindHost, bool bSSL = false,
87  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
88  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
89  CSListener L(iPort, sBindHost);
90 
91  L.SetSockName(sSockName);
92  L.SetIsSSL(bSSL);
93  L.SetTimeout(iTimeout);
94  L.SetMaxConns(iMaxConns);
95 
96 #ifdef HAVE_IPV6
97  switch (eAddr) {
98  case ADDR_IPV4ONLY:
100  break;
101  case ADDR_IPV6ONLY:
103  break;
104  case ADDR_ALL:
106  break;
107  }
108 #endif
109 
110  return Listen(L, pcSock);
111  }
112 
113  bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false,
114  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
115  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
116  return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock,
117  iTimeout, eAddr);
118  }
119 
120  u_short ListenRand(const CString& sSockName, const CString& sBindHost,
121  bool bSSL = false, int iMaxConns = SOMAXCONN,
122  CZNCSock* pcSock = nullptr, u_int iTimeout = 0,
123  EAddrType eAddr = ADDR_ALL) {
124  unsigned short uPort = 0;
125  CSListener L(0, sBindHost);
126 
127  L.SetSockName(sSockName);
128  L.SetIsSSL(bSSL);
129  L.SetTimeout(iTimeout);
130  L.SetMaxConns(iMaxConns);
131 
132 #ifdef HAVE_IPV6
133  switch (eAddr) {
134  case ADDR_IPV4ONLY:
136  break;
137  case ADDR_IPV6ONLY:
139  break;
140  case ADDR_ALL:
142  break;
143  }
144 #endif
145 
146  Listen(L, pcSock, &uPort);
147 
148  return uPort;
149  }
150 
151  u_short ListenAllRand(const CString& sSockName, bool bSSL = false,
152  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
153  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
154  return (ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout,
155  eAddr));
156  }
157 
158  void Connect(const CString& sHostname, u_short iPort,
159  const CString& sSockName, int iTimeout = 60, bool bSSL = false,
160  const CString& sBindHost = "", CZNCSock* pcSock = nullptr);
161 
162  unsigned int GetAnonConnectionCount(const CString& sIP) const;
163  void DelSockByAddr(Csock* pcSock) override;
164 
165  private:
166  void FinishConnect(const CString& sHostname, u_short iPort,
167  const CString& sSockName, int iTimeout, bool bSSL,
168  const CString& sBindHost, CZNCSock* pcSock);
169 
170  std::map<Csock*, bool /* deleted */> m_InFlightDnsSockets;
171 
172 #ifdef HAVE_PTHREAD
174  friend class CThreadMonitorFD;
175 #endif
176 #ifdef HAVE_THREADED_DNS
177  struct TDNSTask {
178  TDNSTask()
179  : sHostname(""),
180  iPort(0),
181  sSockName(""),
182  iTimeout(0),
183  bSSL(false),
184  sBindhost(""),
185  pcSock(nullptr),
186  bDoneTarget(false),
187  bDoneBind(false),
188  aiTarget(nullptr),
189  aiBind(nullptr) {}
190 
191  TDNSTask(const TDNSTask&) = delete;
192  TDNSTask& operator=(const TDNSTask&) = delete;
193 
194  CString sHostname;
195  u_short iPort;
196  CString sSockName;
197  int iTimeout;
198  bool bSSL;
199  CString sBindhost;
200  CZNCSock* pcSock;
201 
202  bool bDoneTarget;
203  bool bDoneBind;
204  addrinfo* aiTarget;
205  addrinfo* aiBind;
206  };
207  class CDNSJob : public CJob {
208  public:
209  CDNSJob()
210  : sHostname(""),
211  task(nullptr),
212  pManager(nullptr),
213  bBind(false),
214  iRes(0),
215  aiResult(nullptr) {}
216 
217  CDNSJob(const CDNSJob&) = delete;
218  CDNSJob& operator=(const CDNSJob&) = delete;
219 
220  CString sHostname;
221  TDNSTask* task;
222  CSockManager* pManager;
223  bool bBind;
224 
225  int iRes;
226  addrinfo* aiResult;
227 
228  void runThread() override;
229  void runMain() override;
230  };
231  void StartTDNSThread(TDNSTask* task, bool bBind);
232  void SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult);
233  static void* TDNSThread(void* argument);
234 #endif
235  protected:
236 };
237 
247 class CSocket : public CZNCSock {
248  public:
253  CSocket(CModule* pModule);
261  CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort,
262  int iTimeout = 60);
263  virtual ~CSocket();
264 
265  CSocket(const CSocket&) = delete;
266  CSocket& operator=(const CSocket&) = delete;
267 
268  using Csock::Connect;
269  using Csock::Listen;
270 
272  void ReachedMaxBuffer() override;
273  void SockError(int iErrno, const CString& sDescription) override;
274 
276  bool ConnectionFrom(const CString& sHost, unsigned short uPort) override;
277 
279  bool Connect(const CString& sHostname, unsigned short uPort,
280  bool bSSL = false, unsigned int uTimeout = 60);
282  bool Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout = 0);
283 
284  // Getters
285  CModule* GetModule() const;
286  // !Getters
287 
288 #ifndef SWIG
289  // Translation. As opposed to CCoreTranslationMixin, this one uses module.mo
290  CString t_s(const CString& sEnglish, const CString& sContext = "") const;
291  CInlineFormatMessage t_f(const CString& sEnglish,
292  const CString& sContext = "") const;
293  CInlineFormatMessage t_p(const CString& sEnglish, const CString& sEnglishes,
294  int iNum, const CString& sContext) const;
295  CDelayedTranslation t_d(const CString& sEnglish,
296  const CString& sContext = "") const;
297 #endif
298 
299  private:
300  protected:
301  CModule*
303 };
304 
309 class CIRCSocket : public CZNCSock {
310  public:
311 #ifdef HAVE_ICU
312 
322  void IcuExtToUCallback(UConverterToUnicodeArgs* toArgs,
323  const char* codeUnits, int32_t length,
324  UConverterCallbackReason reason,
325  UErrorCode* err) override;
326  void IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs,
327  const UChar* codeUnits, int32_t length,
328  UChar32 codePoint, UConverterCallbackReason reason,
329  UErrorCode* err) override;
330 #endif
331 };
332 
333 #endif /* ZNC_SOCKET_H */
u_short ListenRand(const CString &sSockName, const CString &sBindHost, bool bSSL=false, int iMaxConns=SOMAXCONN, CZNCSock *pcSock=nullptr, u_int iTimeout=0, EAddrType eAddr=ADDR_ALL)
Definition: Socket.h:120
Ease of use templated socket manager.
Definition: Csocket.h:1654
EAddrType
Definition: Socket.h:77
Definition: Csocket.h:223
void IcuExtFromUCallback(UConverterFromUnicodeArgs *fromArgs, const UChar *codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode *err) override
void SetSSLTrustedPeerFingerprints(const SCString &ssFPs)
Definition: Socket.h:49
int VerifyPeerCertificate(int iPreVerify, X509_STORE_CTX *pStoreCTX) override
this is hooked in via SSL_set_verify, and be default it just returns 1 meaning success ...
A job is a task which should run without blocking the main thread.
Definition: Threads.h:67
bool ListenHost(u_short iPort, const CString &sSockName, const CString &sBindHost, bool bSSL=false, int iMaxConns=SOMAXCONN, CZNCSock *pcSock=nullptr, u_int iTimeout=0, EAddrType eAddr=ADDR_ALL)
Definition: Socket.h:85
void SetTimeout(uint32_t i)
sets the listen timeout. The listener class will close after timeout has been reached if not 0 ...
Definition: Csocket.h:1407
CZNCSock(int timeout=60)
CString GetSSLPeerFingerprint(X509 *pCert=nullptr) const
CModule * GetModule() const
unsigned int GetAnonConnectionCount(const CString &sIP) const
Base IRC socket for client<->ZNC, and ZNC<->server.
Definition: Socket.h:309
friend class CThreadMonitorFD
Definition: Socket.h:173
u_short ListenAllRand(const CString &sSockName, bool bSSL=false, int iMaxConns=SOMAXCONN, CZNCSock *pcSock=nullptr, u_int iTimeout=0, EAddrType eAddr=ADDR_ALL)
Definition: Socket.h:151
void Connect(const CString &sHostname, u_short iPort, const CString &sSockName, int iTimeout=60, bool bSSL=false, const CString &sBindHost="", CZNCSock *pcSock=nullptr)
Definition: Socket.h:79
void SetTrustPKI(bool bTrustPKI)
Definition: Socket.h:56
bool ConnectionFrom(const CString &sHost, unsigned short uPort) override
This limits the global connections from this IP to defeat DoS attacks, feel free to override...
std::set< CString > SCString
Definition: ZNCString.h:35
Definition: Socket.h:27
CSocket(CModule *pModule)
ctor
Base Csock implementation to be used by modules.
Definition: Socket.h:247
int ConvertAddress(const struct sockaddr_storage *pAddr, socklen_t iAddrLen, CString &sIP, u_short *piPort) const override
Definition: Csocket.h:225
virtual CString GetRemoteIP() const
Definition: Socket.h:61
void SockError(int iErrno, const CString &sDescription) override
Basic socket class.
Definition: Csocket.h:563
Definition: Translation.h:71
void SetAFRequire(CSSockAddr::EAFRequire iAFRequire)
sets the AF family type required
Definition: Csocket.h:1409
bool GetTrustAllCerts() const
Definition: Socket.h:54
void ReachedMaxBuffer() override
This defaults to closing the socket, feel free to override.
String class that is used inside ZNC.
Definition: ZNCString.h:68
void IcuExtToUCallback(UConverterToUnicodeArgs *toArgs, const char *codeUnits, int32_t length, UConverterCallbackReason reason, UErrorCode *err) override
Allow IRC control characters to appear even if protocol encoding explicitly disallows them...
bool CheckSSLCert(X509 *pCert)
bool Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout=0)
Ease of use Listen, assigned to the manager and is subsequently tracked.
void SetMaxConns(int i)
set max connections as called by accept()
Definition: Csocket.h:1405
The base class for your own ZNC modules.
Definition: Modules.h:421
Definition: Socket.h:77
virtual bool Listen(const CSListener &cListen, Csock *pcSock=NULL, uint16_t *piRandPort=NULL)
Sets up a listening socket.
options container to create a listener
Definition: Csocket.h:1354
Definition: Socket.h:77
Definition: Socket.h:66
virtual bool Listen(uint16_t iPort, int iMaxConns=SOMAXCONN, const CS_STRING &sBindHost="", uint32_t iTimeout=0, bool bDetach=false)
Listens for connections.
CSocket & operator=(const CSocket &)=delete
void SetSockName(const CS_STRING &sSockName)
sets the sock name for later reference (ie FindSockByName)
Definition: Csocket.h:1399
virtual ~CSockManager()
Definition: Socket.h:77
bool GetTrustPKI() const
Definition: Socket.h:57
CInlineFormatMessage t_p(const CString &sEnglish, const CString &sEnglishes, int iNum, const CString &sContext) const
void DelSockByAddr(Csock *pcSock) override
Delete a sock by addr its position is looked up the socket is deleted, the appropriate call backs are...
void SSLHandShakeFinished() override
called once the SSL handshake is complete, this is triggered via SSL_CB_HANDSHAKE_DONE in SSL_set_inf...
void SetTrustAllCerts(bool bTrustAll)
Definition: Socket.h:53
CModule * m_pModule
pointer to the module that this sock instance belongs to
Definition: Socket.h:302
CS_STRING GetRemoteIP() const
bool ListenAll(u_short iPort, const CString &sSockName, bool bSSL=false, int iMaxConns=SOMAXCONN, CZNCSock *pcSock=nullptr, u_int iTimeout=0, EAddrType eAddr=ADDR_ALL)
Definition: Socket.h:113
CInlineFormatMessage t_f(const CString &sEnglish, const CString &sContext="") const
void SetEncoding(const CString &)
void SetHostToVerifySSL(const CString &sHost)
Definition: Socket.h:46
Definition: Csocket.h:227
bool SNIConfigureClient(CString &sHostname) override
CString t_s(const CString &sEnglish, const CString &sContext="") const
CDelayedTranslation t_d(const CString &sEnglish, const CString &sContext="") const
~CZNCSock()
Definition: Socket.h:31
virtual void SSLCertError(X509 *pCert)
Definition: Socket.h:40
virtual bool Connect()
Create the connection, this is used by the socket manager, and shouldn&#39;t be called directly by the us...
Definition: ZNCString.h:673
void SetIsSSL(bool b)
set to true to enable SSL
Definition: Csocket.h:1403
virtual ~CSocket()
Definition: Translation.h:103