ZNC  trunk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Socket.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2018 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, public 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 SNIConfigureClient(CString& sHostname) override;
40 #endif
41  void SetHostToVerifySSL(const CString& sHost) {
42  m_sHostToVerifySSL = sHost;
43  }
46  m_ssTrustedFingerprints = ssFPs;
47  }
48 
49  void SetTrustAllCerts(bool bTrustAll) { m_bTrustAllCerts = bTrustAll; }
50  bool GetTrustAllCerts() const { return m_bTrustAllCerts; }
51 
52  void SetTrustPKI(bool bTrustPKI) { m_bTrustPKI = bTrustPKI; }
53  bool GetTrustPKI() const { return m_bTrustPKI; }
54 
55  void SetEncoding(const CString&);
56 
57  virtual CString GetRemoteIP() const { return Csock::GetRemoteIP(); }
58 
59  protected:
60  // All existing errno codes seem to be in range 1-300
61  enum {
62  errnoBadSSLCert = 12569,
63  };
64 
65  private:
66  CString m_sHostToVerifySSL;
67  SCString m_ssTrustedFingerprints;
68  SCString m_ssCertVerificationErrors;
69  bool m_bTrustAllCerts = false;
70  bool m_bTrustPKI = true;
71 };
72 
74 
75 class CSockManager : public TSocketManager<CZNCSock> {
76  public:
77  CSockManager();
78  virtual ~CSockManager();
79 
80  bool ListenHost(u_short iPort, const CString& sSockName,
81  const CString& sBindHost, bool bSSL = false,
82  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
83  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
84  CSListener L(iPort, sBindHost);
85 
86  L.SetSockName(sSockName);
87  L.SetIsSSL(bSSL);
88  L.SetTimeout(iTimeout);
89  L.SetMaxConns(iMaxConns);
90 
91 #ifdef HAVE_IPV6
92  switch (eAddr) {
93  case ADDR_IPV4ONLY:
95  break;
96  case ADDR_IPV6ONLY:
98  break;
99  case ADDR_ALL:
101  break;
102  }
103 #endif
104 
105  return Listen(L, pcSock);
106  }
107 
108  bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false,
109  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
110  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
111  return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock,
112  iTimeout, eAddr);
113  }
114 
115  u_short ListenRand(const CString& sSockName, const CString& sBindHost,
116  bool bSSL = false, int iMaxConns = SOMAXCONN,
117  CZNCSock* pcSock = nullptr, u_int iTimeout = 0,
118  EAddrType eAddr = ADDR_ALL) {
119  unsigned short uPort = 0;
120  CSListener L(0, sBindHost);
121 
122  L.SetSockName(sSockName);
123  L.SetIsSSL(bSSL);
124  L.SetTimeout(iTimeout);
125  L.SetMaxConns(iMaxConns);
126 
127 #ifdef HAVE_IPV6
128  switch (eAddr) {
129  case ADDR_IPV4ONLY:
131  break;
132  case ADDR_IPV6ONLY:
134  break;
135  case ADDR_ALL:
137  break;
138  }
139 #endif
140 
141  Listen(L, pcSock, &uPort);
142 
143  return uPort;
144  }
145 
146  u_short ListenAllRand(const CString& sSockName, bool bSSL = false,
147  int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr,
148  u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
149  return (ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout,
150  eAddr));
151  }
152 
153  void Connect(const CString& sHostname, u_short iPort,
154  const CString& sSockName, int iTimeout = 60, bool bSSL = false,
155  const CString& sBindHost = "", CZNCSock* pcSock = nullptr);
156 
157  unsigned int GetAnonConnectionCount(const CString& sIP) const;
158  void DelSockByAddr(Csock* pcSock) override;
159 
160  private:
161  void FinishConnect(const CString& sHostname, u_short iPort,
162  const CString& sSockName, int iTimeout, bool bSSL,
163  const CString& sBindHost, CZNCSock* pcSock);
164 
165  std::map<Csock*, bool /* deleted */> m_InFlightDnsSockets;
166 
167 #ifdef HAVE_PTHREAD
169  friend class CThreadMonitorFD;
170 #endif
171 #ifdef HAVE_THREADED_DNS
172  struct TDNSTask {
173  TDNSTask()
174  : sHostname(""),
175  iPort(0),
176  sSockName(""),
177  iTimeout(0),
178  bSSL(false),
179  sBindhost(""),
180  pcSock(nullptr),
181  bDoneTarget(false),
182  bDoneBind(false),
183  aiTarget(nullptr),
184  aiBind(nullptr) {}
185 
186  TDNSTask(const TDNSTask&) = delete;
187  TDNSTask& operator=(const TDNSTask&) = delete;
188 
189  CString sHostname;
190  u_short iPort;
191  CString sSockName;
192  int iTimeout;
193  bool bSSL;
194  CString sBindhost;
195  CZNCSock* pcSock;
196 
197  bool bDoneTarget;
198  bool bDoneBind;
199  addrinfo* aiTarget;
200  addrinfo* aiBind;
201  };
202  class CDNSJob : public CJob {
203  public:
204  CDNSJob()
205  : sHostname(""),
206  task(nullptr),
207  pManager(nullptr),
208  bBind(false),
209  iRes(0),
210  aiResult(nullptr) {}
211 
212  CDNSJob(const CDNSJob&) = delete;
213  CDNSJob& operator=(const CDNSJob&) = delete;
214 
215  CString sHostname;
216  TDNSTask* task;
217  CSockManager* pManager;
218  bool bBind;
219 
220  int iRes;
221  addrinfo* aiResult;
222 
223  void runThread() override;
224  void runMain() override;
225  };
226  void StartTDNSThread(TDNSTask* task, bool bBind);
227  void SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult);
228  static void* TDNSThread(void* argument);
229 #endif
230  protected:
231 };
232 
242 class CSocket : public CZNCSock {
243  public:
248  CSocket(CModule* pModule);
256  CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort,
257  int iTimeout = 60);
258  virtual ~CSocket();
259 
260  CSocket(const CSocket&) = delete;
261  CSocket& operator=(const CSocket&) = delete;
262 
263  using Csock::Connect;
264  using Csock::Listen;
265 
267  void ReachedMaxBuffer() override;
268  void SockError(int iErrno, const CString& sDescription) override;
269 
271  bool ConnectionFrom(const CString& sHost, unsigned short uPort) override;
272 
274  bool Connect(const CString& sHostname, unsigned short uPort,
275  bool bSSL = false, unsigned int uTimeout = 60);
277  bool Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout = 0);
278 
279  // Getters
280  CModule* GetModule() const;
281  // !Getters
282 
283 #ifndef SWIG
284  // Translation. As opposed to CCoreTranslationMixin, this one uses module.mo
285  CString t_s(const CString& sEnglish, const CString& sContext = "") const;
286  CInlineFormatMessage t_f(const CString& sEnglish,
287  const CString& sContext = "") const;
288  CInlineFormatMessage t_p(const CString& sEnglish, const CString& sEnglishes,
289  int iNum, const CString& sContext) const;
290  CDelayedTranslation t_d(const CString& sEnglish,
291  const CString& sContext = "") const;
292 #endif
293 
294  private:
295  protected:
296  CModule*
298 };
299 
304 class CIRCSocket : public CZNCSock {
305  public:
306 #ifdef HAVE_ICU
307 
317  void IcuExtToUCallback(UConverterToUnicodeArgs* toArgs,
318  const char* codeUnits, int32_t length,
319  UConverterCallbackReason reason,
320  UErrorCode* err) override;
321  void IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs,
322  const UChar* codeUnits, int32_t length,
323  UChar32 codePoint, UConverterCallbackReason reason,
324  UErrorCode* err) override;
325 #endif
326 };
327 
328 #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:115
Ease of use templated socket manager.
Definition: Csocket.h:1655
EAddrType
Definition: Socket.h:73
Definition: Csocket.h:223
bool GetTrustPKI() const
Definition: Socket.h:53
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:45
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:80
CModule * GetModule() const
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:1408
CString GetSSLPeerFingerprint() const
CS_STRING GetRemoteIP() const
CZNCSock(int timeout=60)
CString t_s(const CString &sEnglish, const CString &sContext="") const
Base IRC socket for client<->ZNC, and ZNC<->server.
Definition: Socket.h:304
CDelayedTranslation t_d(const CString &sEnglish, const CString &sContext="") const
virtual CString GetRemoteIP() const
Definition: Socket.h:57
friend class CThreadMonitorFD
Definition: Socket.h:168
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:146
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:75
void SetTrustPKI(bool bTrustPKI)
Definition: Socket.h:52
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:242
int ConvertAddress(const struct sockaddr_storage *pAddr, socklen_t iAddrLen, CString &sIP, u_short *piPort) const override
Definition: Csocket.h:225
void SockError(int iErrno, const CString &sDescription) override
Basic socket class.
Definition: Csocket.h:564
Definition: Translation.h:70
void SetAFRequire(CSSockAddr::EAFRequire iAFRequire)
sets the AF family type required
Definition: Csocket.h:1410
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 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:1406
The base class for your own ZNC modules.
Definition: Modules.h:407
Definition: Socket.h:73
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:1355
Definition: Socket.h:73
CInlineFormatMessage t_p(const CString &sEnglish, const CString &sEnglishes, int iNum, const CString &sContext) const
Definition: Socket.h:62
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:1400
virtual ~CSockManager()
Definition: Socket.h:73
unsigned int GetAnonConnectionCount(const CString &sIP) 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:49
CModule * m_pModule
pointer to the module that this sock instance belongs to
Definition: Socket.h:297
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:108
void SetEncoding(const CString &)
void SetHostToVerifySSL(const CString &sHost)
Definition: Socket.h:41
Definition: Csocket.h:227
bool SNIConfigureClient(CString &sHostname) override
bool GetTrustAllCerts() const
Definition: Socket.h:50
~CZNCSock()
Definition: Socket.h:31
CInlineFormatMessage t_f(const CString &sEnglish, const CString &sContext="") const
virtual bool Connect()
Create the connection, this is used by the socket manager, and shouldn't be called directly by the us...
Definition: ZNCString.h:673
void SetIsSSL(bool b)
set to true to enable SSL
Definition: Csocket.h:1404
virtual ~CSocket()
Definition: Translation.h:104