1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 1998-2014 Licq developers <licq-dev@googlegroups.com>
4  *
5  * Licq is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Licq is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Licq; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 /* Socket routine descriptions */
21 
22 #include "config.h"
23 
24 #include <licq/socket.h>
25 
26 #include <arpa/inet.h>
27 #include <cerrno>
28 #include <cstdio>
29 #include <cstring>
30 #include <fcntl.h>
31 #include <netdb.h>
32 #include <netinet/in.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <unistd.h>
36 
37 #ifdef USE_OPENSSL
38 #include <openssl/ssl.h>
39 #include <openssl/err.h>
40 
41 SSL_CTX *gSSL_CTX;
42 SSL_CTX *gSSL_CTX_NONICQ;
43 #endif // OpenSSL
44 
45 #ifdef USE_SOCKS5
46 
47 #define SOCKS
48 #define INCLUDE_PROTOTYPES
49 extern "C" {
50 #include <socks.h>
51 }
52 #define socket_send Rsend
53 #undef send
54 #else
55 #define socket_send send
56 #endif // SOCKS5
57 
58 #ifdef SOCKS5_OPTLEN
59   #ifdef socklen_t
60     #undef socklen_t
61   #endif
62 
63   #define socklen_t SOCKS5_OPTLEN
64 #endif
65 
66 #include <licq/buffer.h>
67 #include <licq/proxy.h>
68 #include <licq/logging/log.h>
69 
70 #include "gettext.h"
71 
72 using Licq::Buffer;
73 using Licq::INetSocket;
74 using Licq::TCPSocket;
75 using Licq::UDPSocket;
76 using Licq::UserId;
77 using std::string;
78 
ip_ntoa(unsigned long in,char * buf)79 char* Licq::ip_ntoa(unsigned long in, char *buf)
80 {
81   inet_ntop(AF_INET, &in, buf, 32);
82   return buf;
83 }
84 
85 
86 //=====INetSocket===============================================================
87 
addrToString(const struct sockaddr * addr)88 string INetSocket::addrToString(const struct sockaddr* addr)
89 {
90   switch (addr->sa_family)
91   {
92     case AF_INET:
93     {
94       char buf[INET_ADDRSTRLEN];
95       inet_ntop(AF_INET, &((struct sockaddr_in*)addr)->sin_addr.s_addr, buf, sizeof(buf));
96       return buf;
97     }
98 
99     case AF_INET6:
100     {
101       char buf[INET6_ADDRSTRLEN];
102       inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr.s6_addr, buf, sizeof(buf));
103       return buf;
104     }
105 
106     default:
107       return string();
108   }
109 }
110 
addrToInt(const struct sockaddr * addr)111 uint32_t INetSocket::addrToInt(const struct sockaddr* addr)
112 {
113   if (addr->sa_family == AF_INET)
114     return ((struct sockaddr_in*)addr)->sin_addr.s_addr;
115   return 0;
116 }
117 
ipToInt(const std::string & ip)118 uint32_t INetSocket::ipToInt(const std::string& ip)
119 {
120   struct in_addr addr;
121   if (::inet_aton(ip.c_str(), &addr))
122     return addr.s_addr;
123   return 0;
124 }
125 
getAddrPort(const struct sockaddr * addr)126 uint16_t INetSocket::getAddrPort(const struct sockaddr* addr)
127 {
128   switch (addr->sa_family)
129   {
130     case AF_INET:
131       return ntohs(((struct sockaddr_in*)addr)->sin_port);
132 
133     case AF_INET6:
134       return ntohs(((struct sockaddr_in6*)addr)->sin6_port);
135 
136     default:
137       return 0;
138   }
139 }
140 
141 //-----INetSocket::Error------------------------------------------------------
Error()142 int INetSocket::Error()
143 {
144   switch (myErrorType)
145   {
146     case ErrorErrno:
147       return errno;
148     case ErrorNone:
149       return 0;
150     case ErrorInternal:
151       return -2;
152     case ErrorProxy:
153       if (myProxy != NULL)
154         return myProxy->error();
155   }
156   return 0;
157 }
158 
errorStr() const159 string INetSocket::errorStr() const
160 {
161   switch (myErrorType)
162   {
163     case ErrorErrno:
164       return strerror(errno);
165 
166     case ErrorNone:
167       return tr("No error detected");
168 
169     case ErrorProxy:
170       if (myProxy != NULL)
171         return myProxy->errorStr();
172 
173     case ErrorInternal:
174     default:
175       return tr("Internal error");
176   }
177 }
178 
179 
INetSocket(int sockType,const string & logId,const UserId & userId)180 INetSocket::INetSocket(int sockType, const string& logId, const UserId& userId)
181   : myDescriptor(-1),
182     myLogId(logId),
183     mySockType(sockType),
184     myErrorType(ErrorNone),
185     myProxy(NULL),
186     myUserId(userId)
187 {
188   memset(&myRemoteAddr, 0, sizeof(myRemoteAddrStorage));
189   memset(&myLocalAddr, 0, sizeof(myLocalAddrStorage));
190 }
191 
~INetSocket()192 INetSocket::~INetSocket()
193 {
194   CloseConnection();
195 }
196 
197 //-----INetSocket::dumpPacket---------------------------------------------------
DumpPacket(const Buffer * b,bool isReceiver)198 void INetSocket::DumpPacket(const Buffer *b, bool isReceiver)
199 {
200   if (!isReceiver)
201   {
202     b->log(Log::Debug, "Packet (%s, %lu bytes) sent:\n(%s:%d -> %s:%d)",
203            myLogId.c_str(), b->getDataSize(),
204            getLocalIpString().c_str(), getLocalPort(),
205            getRemoteIpString().c_str(), getRemotePort());
206   }
207   else
208   {
209     b->log(Log::Debug, "Packet (%s, %lu bytes) received:\n(%s:%d <- %s:%d)",
210            myLogId.c_str(), b->getDataSize(),
211            getLocalIpString().c_str(), getLocalPort(),
212            getRemoteIpString().c_str(), getRemotePort());
213   }
214 }
215 
216 
217 //-----INetSocket::ResetSocket-------------------------------------------------
ResetSocket()218 void INetSocket::ResetSocket()
219 {
220   CloseConnection();
221   memset(&myRemoteAddr, 0, sizeof(myRemoteAddrStorage));
222   memset(&myLocalAddr, 0, sizeof(myLocalAddrStorage));
223 }
224 
225 
226 /*-----INetSocket::SetLocalAddress------------------------------------------
227  * Sets the sockaddr_in structures using data from the connected socket
228  *---------------------------------------------------------------------------*/
SetLocalAddress(bool)229 bool INetSocket::SetLocalAddress(bool /* bIp */)
230 {
231   // Setup the local structure
232   socklen_t sizeofSockaddr = sizeof(myLocalAddrStorage);
233 
234   if (getsockname(myDescriptor, (struct sockaddr*)&myLocalAddr, &sizeofSockaddr) < 0)
235   {
236     myErrorType = ErrorNone;
237     return (false);
238   }
239 
240   return (true);
241 }
242 
connectTo(const string & remoteName,uint16_t remotePort,Licq::Proxy * proxy)243 bool INetSocket::connectTo(const string& remoteName, uint16_t remotePort, Licq::Proxy* proxy)
244 {
245   myRemoteName = remoteName;
246   myProxy = proxy;
247 
248   // If we're using a proxy, let the proxy class handle this
249   if (myProxy != NULL)
250   {
251     myDescriptor = myProxy->openConnection(remoteName, remotePort);
252     if (myDescriptor == -1)
253     {
254       myErrorType = ErrorProxy;
255       return(false);
256     }
257 
258     memcpy(&myRemoteAddr, myProxy->proxyAddr(), sizeof(myRemoteAddrStorage));
259     return SetLocalAddress();
260   }
261 
262   // No proxy, let's do this ourselves
263 
264   // If already connected, close the old connection first
265   if (myDescriptor != -1)
266     CloseConnection();
267 
268   // If anything happens here, the error will be in errno
269   myErrorType = ErrorErrno;
270 
271   myDescriptor = connectDirect(remoteName, remotePort, mySockType, &myRemoteAddr);
272 
273 #ifdef USE_SOCKS5
274     if (mySockType != SOCK_STREAM)
275       return true;
276 #endif
277 
278   if (myDescriptor == -1)
279     return false;
280 
281   return SetLocalAddress();
282 }
283 
connectDirect(const string & remoteName,uint16_t remotePort,uint16_t sockType,struct sockaddr * remoteAddr)284 int INetSocket::connectDirect(const string& remoteName, uint16_t remotePort, uint16_t sockType, struct sockaddr* remoteAddr)
285 {
286   struct addrinfo hints;
287   memset(&hints, 0, sizeof(hints));
288 #ifdef LICQ_DISABLE_IPV6
289   hints.ai_family = AF_INET;
290 #else
291   hints.ai_family = AF_UNSPEC;
292 #endif
293   hints.ai_socktype = sockType;
294 #ifdef AI_ADDRCONFIG
295   // AI_ADDRCONFIG = Don't return IPvX address if host has no IPvX address configured
296   hints.ai_flags = AI_ADDRCONFIG;
297 #endif
298 
299   struct addrinfo* addrs;
300   int s = getaddrinfo(remoteName.c_str(), NULL, &hints, &addrs);
301   if(s != 0)
302   {
303     gLog.warning(tr("Error when trying to resolve %s. getaddrinfo() returned %d."),
304         remoteName.c_str(), s);
305     return false;
306   }
307 
308   int sock = -1;
309 
310   // getaddrinfo() returns a list of addresses, we'll try them one by one until
311   //   we manage to make a connection. The list is already be sorted with
312   //   preferred address first.
313   struct addrinfo* ai;
314   for (ai = addrs; ai != NULL; ai = ai->ai_next)
315   {
316     memcpy(remoteAddr, ai->ai_addr, ai->ai_addrlen);
317 
318     // We didn't use getaddrinfo to lookup port so set in manually
319     if (remoteAddr->sa_family == AF_INET)
320       ((struct sockaddr_in*)remoteAddr)->sin_port = htons(remotePort);
321     else if (remoteAddr->sa_family == AF_INET6)
322       ((struct sockaddr_in6*)remoteAddr)->sin6_port = htons(remotePort);
323 
324     gLog.info(tr("Connecting to %s:%i..."),
325         addrToString(remoteAddr).c_str(), remotePort);
326 
327     // Create socket of the returned type
328     sock = socket(remoteAddr->sa_family, sockType, 0);
329     if (sock == -1)
330       continue;
331 
332 #ifdef IP_PORTRANGE
333     int i=IP_PORTRANGE_HIGH;
334     if (setsockopt(sock, IPPROTO_IP, IP_PORTRANGE, &i, sizeof(i))<0)
335     {
336       close(sock);
337       sock = -1;
338       gLog.warning(tr("Failed to set port range for socket."));
339       continue;
340     }
341 #endif
342 
343     // Try to connect, exit loop if successful
344     if (connect(sock, (struct sockaddr*)remoteAddr, ai->ai_addrlen) != -1)
345       break;
346 
347     // Failed to connect, close socket and try next
348     close(sock);
349     sock = -1;
350   }
351 
352   // Return the memory allocated by getaddrinfo
353   freeaddrinfo(addrs);
354 
355   // If we reached the end of the address list we didn't find anything that could connect
356   if (ai == NULL)
357     return -1;
358 
359   return sock;
360 }
361 
connectTo(uint32_t remoteAddr,uint16_t remotePort,Licq::Proxy * proxy)362 bool INetSocket::connectTo(uint32_t remoteAddr, uint16_t remotePort, Licq::Proxy* proxy)
363 {
364   char buf[INET_ADDRSTRLEN];
365   return connectTo(string(inet_ntop(AF_INET, &remoteAddr, buf, sizeof(buf))), remotePort, proxy);
366 }
367 
368 //-----INetSocket::StartServer--------------------------------------------------
StartServer(unsigned int _nPort)369 bool INetSocket::StartServer(unsigned int _nPort)
370 {
371   socklen_t addrlen;
372   memset(&myLocalAddr, 0, sizeof(myLocalAddrStorage));
373 
374 #ifndef LICQ_DISABLE_IPV6
375   // Try to create an IPv6 socket
376   myDescriptor = socket(AF_INET6, mySockType, 0);
377   if (myDescriptor != -1)
378   {
379     // IPv6 socket created
380 
381     // Make sure we can accept connections for IPv4 as well
382     int i = 0;
383     if (setsockopt(myDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0)
384     {
385       myErrorType = ErrorErrno;
386       ::close(myDescriptor);
387       myDescriptor = -1;
388       return false;
389     }
390 
391 #ifdef IPV6_PORTRANGE
392     i = IPV6_PORTRANGE_HIGH;
393     if (setsockopt(myDescriptor, IPPROTO_IPV6, IPV6_PORTRANGE, &i, sizeof(i)) < 0)
394     {
395       myErrorType = ErrorErrno;
396       ::close(myDescriptor);
397       myDescriptor = -1;
398       return false;
399     }
400 #endif
401 
402     addrlen = sizeof(sockaddr_in6);
403     myLocalAddr.sa_family = AF_INET6;
404     ((struct sockaddr_in6*)&myLocalAddr)->sin6_port = htons(_nPort);
405     ((struct sockaddr_in6*)&myLocalAddr)->sin6_addr = in6addr_any;
406   }
407   else
408   {
409     // Unable to create an IPv6 socket, try with IPv4 instead
410     gLog.warning(tr("Failed to start local server using IPv6 socket "
411                     "(falling back to IPv4):\n%s"), strerror(errno));
412 
413 #endif
414     myDescriptor = socket(AF_INET, mySockType, 0);
415     if (myDescriptor == -1)
416     {
417       myErrorType = ErrorErrno;
418       return (false);
419     }
420 
421 #ifdef IP_PORTRANGE
422     int i = IP_PORTRANGE_HIGH;
423     if (setsockopt(myDescriptor, IPPROTO_IP, IP_PORTRANGE, &i, sizeof(i)) < 0)
424     {
425       myErrorType = ErrorErrno;
426       ::close(myDescriptor);
427       myDescriptor = -1;
428       return false;
429     }
430 #endif
431 
432     addrlen = sizeof(sockaddr_in);
433     myLocalAddr.sa_family = AF_INET;
434     ((struct sockaddr_in*)&myLocalAddr)->sin_port = htons(_nPort);
435     ((struct sockaddr_in*)&myLocalAddr)->sin_addr.s_addr = INADDR_ANY;
436 #ifndef LICQ_DISABLE_IPV6
437   }
438 #endif
439 
440   if (::bind(myDescriptor, (struct sockaddr*)&myLocalAddr, addrlen) == -1)
441   {
442     myErrorType = ErrorErrno;
443     ::close(myDescriptor);
444     myDescriptor = -1;
445     return (false);
446   }
447 
448   if (!SetLocalAddress(false)) return (false);
449 
450   if (mySockType == SOCK_STREAM)
451   {
452     // Allow 10 unprocessed connections
453     if (listen(myDescriptor, 10) != 0)
454     {
455       myErrorType = ErrorErrno;
456       ::close(myDescriptor);
457       myDescriptor = -1;
458       return false;
459     }
460   }
461 
462   return(true);
463 }
464 
465 
466 //-----INetSocket::CloseConnection-------------------------------------------
CloseConnection()467 void INetSocket::CloseConnection()
468 {
469   if (myDescriptor != -1)
470   {
471     ::shutdown(myDescriptor, 2);
472     ::close (myDescriptor);
473     myDescriptor = -1;
474   }
475 }
476 
send(const void * buf,size_t length)477 bool INetSocket::send(const void* buf, size_t length)
478 {
479   while (length > 0)
480   {
481     ssize_t bytesSent = ::socket_send(myDescriptor, buf, length, 0);
482     if (bytesSent < 0)
483     {
484       if (errno == EINTR)
485         continue;
486       myErrorType = ErrorErrno;
487       return false;
488     }
489     length -= bytesSent;
490     buf = (char*)buf + bytesSent;
491   }
492   return true;
493 }
494 
send(const Buffer & buf)495 bool INetSocket::send(const Buffer& buf)
496 {
497   if (!send(buf.getDataStart(), buf.getDataSize()))
498     return false;
499 
500   // Print the packet
501   DumpPacket(&buf, false);
502   return true;
503 }
504 
receive(void * buf,size_t maxlength)505 ssize_t INetSocket::receive(void* buf, size_t maxlength)
506 {
507   errno = 0;
508   int f = fcntl(myDescriptor, F_GETFL);
509   fcntl(myDescriptor, F_SETFL, f | O_NONBLOCK);
510   ssize_t bytesReceived = recv(myDescriptor, buf, maxlength, 0);
511   fcntl(myDescriptor, F_SETFL, f & ~O_NONBLOCK);
512   if (bytesReceived > 0)
513     return bytesReceived;
514 
515   myErrorType = ErrorErrno;
516   if (errno == EAGAIN || errno == EWOULDBLOCK)
517     return 0;
518   return -1;
519 }
520 
receive(Buffer & buf,size_t maxlength,bool dump)521 bool INetSocket::receive(Buffer& buf, size_t maxlength, bool dump)
522 {
523   // Don't try to read more than the buffer has room for
524   if (buf.Full())
525     return true;
526   if (!buf.Empty() && maxlength > buf.remainingDataToWrite())
527     maxlength = buf.remainingDataToWrite();
528 
529   char* buffer = new char[maxlength];
530   ssize_t bytesReceived = receive(buffer, maxlength);
531   if (bytesReceived > 0)
532   {
533     if (buf.Empty())
534       buf.Create(bytesReceived);
535     buf.packRaw(buffer, bytesReceived);
536 
537     // Print the packet
538     if (dump)
539       DumpPacket(&buf, true);
540   }
541   delete[] buffer;
542 
543   return (bytesReceived >= 0);
544 }
545 
546 
547 //=====TCPSocket===============================================================
TCPSocket(const UserId & userId)548 TCPSocket::TCPSocket(const UserId& userId)
549   : INetSocket(SOCK_STREAM, "TCP", userId)
550 {
551   m_p_SSL = NULL;
552 }
553 
TCPSocket()554 TCPSocket::TCPSocket()
555   : INetSocket(SOCK_STREAM, "TCP", UserId())
556 {
557   m_p_SSL = NULL;
558 }
559 
~TCPSocket()560 TCPSocket::~TCPSocket()
561 {
562   SecureStop();
563 }
564 
565 
566 /*-----TCPSocket::ReceiveConnection--------------------------------------------
567  * Called to set up a given TCPSocket from an incoming connection on the
568  * current TCPSocket
569  *---------------------------------------------------------------------------*/
RecvConnection(TCPSocket & newSocket)570 bool TCPSocket::RecvConnection(TCPSocket &newSocket)
571 {
572   socklen_t sizeofSockaddr = sizeof(myRemoteAddrStorage);
573   bool success = false;
574 
575   // Make sure we stay under FD_SETSIZE
576   // See:
577   // * http://www.securityfocus.com/archive/1/490711
578   // * http://securityvulns.com/docs7669.html
579   // for more details
580   // This probably has no affect, since we are using multiple threads, but keep it here
581   // to be used as a sanity check.
582   int newDesc = accept(myDescriptor, (struct sockaddr*)&newSocket.myRemoteAddr, &sizeofSockaddr);
583   if (newDesc < 0)
584   {
585     // Something went wrong, probably indicates an error somewhere else
586     gLog.warning(tr("Cannot accept new connection:\n%s"), strerror(errno));
587     return false;
588   }
589   if (newDesc < static_cast<int>(FD_SETSIZE))
590   {
591     newSocket.myDescriptor = newDesc;
592     newSocket.SetLocalAddress();
593     success = true;
594   }
595   else
596   {
597     gLog.error(tr("Cannot accept new connection, too many descriptors in use."));
598     close(newDesc);
599   }
600 
601   return success;
602 }
603 
604 #ifdef USE_OPENSSL
605 #define m_pSSL ((SSL *) m_p_SSL)
606 #else
607 #define m_pSSL m_p_SSL
608 #endif
609 
610 /*-----TCPSocket::TransferConnectionFrom---------------------------------------
611  * Transfers a connection from the given socket to the current one and closes
612  * and resets the given socket
613  *---------------------------------------------------------------------------*/
TransferConnectionFrom(TCPSocket & from)614 void TCPSocket::TransferConnectionFrom(TCPSocket &from)
615 {
616   myDescriptor = from.myDescriptor;
617   myLocalAddr = from.myLocalAddr;
618   myRemoteAddr = from.myRemoteAddr;
619   myUserId = from.myUserId;
620 
621   if (from.m_p_SSL)
622   {
623     pthread_mutex_lock(&from.mutex_ssl);
624 
625     pthread_mutex_init(&mutex_ssl, NULL);
626     pthread_mutex_lock(&mutex_ssl);
627     m_p_SSL = from.m_p_SSL;
628     from.SecureStop();
629 
630     pthread_mutex_unlock(&mutex_ssl);
631   }
632   else
633     m_p_SSL = NULL;
634   from.myDescriptor = -1;
635   from.CloseConnection();
636 }
637 
638 /*-----TCPSocket::SendPacket---------------------------------------------------
639  * Sends a packet on a socket.  The socket is blocking, so we are guaranteed
640  * that the entire packet will be sent, however, it may block if the tcp
641  * buffer is full.  This should not be a problem unless we are sending a huge
642  * packet.
643  *---------------------------------------------------------------------------*/
send(const void * buf,size_t length)644 bool TCPSocket::send(const void* buf, size_t length)
645 {
646   if (m_pSSL == NULL)
647     return INetSocket::send(buf, length);
648 
649 #ifdef USE_OPENSSL
650   int i, j;
651   ERR_clear_error();
652   pthread_mutex_lock(&mutex_ssl);
653   i = SSL_write(m_pSSL, buf, length);
654   j = SSL_get_error(m_pSSL, i);
655   pthread_mutex_unlock(&mutex_ssl);
656   if (j != SSL_ERROR_NONE)
657   {
658     const char *file; int line;
659     unsigned long err;
660     switch (j)
661     {
662       case SSL_ERROR_SSL:
663         err = ERR_get_error_line(&file, &line);
664         printf("SSL_write error = %lx, %s:%i\n", err, file, line);
665         ERR_clear_error();
666         break;
667       default:
668         printf("SSL_write error %d, SSL_%d\n", i, j);
669         break;
670     }
671   }
672 
673   return true;
674 #else
675   return false;
676 #endif
677 }
678 
receive(void * buf,size_t maxlength)679 ssize_t TCPSocket::receive(void* buf, size_t maxlength)
680 {
681   // If SSL not enabled for this socket, use normal receive
682   if (m_pSSL == NULL)
683     return INetSocket::receive(buf, maxlength);
684 
685 #ifdef USE_OPENSSL
686   errno = 0;
687   pthread_mutex_lock(&mutex_ssl);
688   int nBytesReceived = SSL_read(m_pSSL, buf, maxlength);
689   int tmp = SSL_get_error(m_pSSL, nBytesReceived);
690   pthread_mutex_unlock(&mutex_ssl);
691   switch (tmp)
692   {
693     case SSL_ERROR_NONE:
694       break;
695     case SSL_ERROR_WANT_READ:
696     case SSL_ERROR_WANT_WRITE:
697     case SSL_ERROR_WANT_X509_LOOKUP:
698       return 0;
699     case SSL_ERROR_ZERO_RETURN:
700       myErrorType = ErrorErrno;
701       errno = 0;
702       return -1;
703     case SSL_ERROR_SYSCALL:
704       myErrorType = ErrorErrno;
705       return -1;
706     case SSL_ERROR_SSL:
707       myErrorType = ErrorInternal;
708       return -1;
709   }
710   if (nBytesReceived <= 0)
711   {
712     myErrorType = ErrorErrno;
713     return -1;
714   }
715 
716   return nBytesReceived;
717 #else
718   return -1;
719 #endif
720 }
721 
722 
SSL_Pending()723 bool TCPSocket::SSL_Pending()
724 {
725 #ifdef USE_OPENSSL
726   return (m_pSSL && SSL_pending(m_pSSL));
727 #else
728   return false;
729 #endif
730 }
731 
732 
733 
734 #ifdef USE_OPENSSL /*-----Start of OpenSSL code----------------------------*/
735 
SecureConnect()736 bool TCPSocket::SecureConnect()
737 {
738   pthread_mutex_init(&mutex_ssl, NULL);
739   if (myUserId.protocolId() == ICQ_PPID)
740     m_p_SSL = SSL_new(gSSL_CTX);
741   else
742     m_p_SSL = SSL_new(gSSL_CTX_NONICQ);
743 #ifdef SSL_DEBUG
744   m_pSSL->debug = 1;
745 #endif
746   SSL_set_session(m_pSSL, NULL);
747   SSL_set_fd(m_pSSL, myDescriptor);
748   int i = SSL_connect(m_pSSL);
749   int j = SSL_get_error(m_pSSL, i);
750   if (j != SSL_ERROR_NONE)
751   {
752     const char *file;
753     int line;
754     unsigned long err;
755     switch (j)
756     {
757       case SSL_ERROR_SSL:
758         err = ERR_get_error_line(&file, &line);
759         gLog.warning(tr("SSL_connect error = %lx, %s:%i"), err, file, line);
760         ERR_clear_error();
761         break;
762       default:
763         gLog.warning(tr("SSL_connect error %d, SSL_%d"), i, j);
764         break;
765     }
766     return false;
767   }
768   return true;
769 }
770 
SecureListen()771 bool TCPSocket::SecureListen()
772 {
773   pthread_mutex_init(&mutex_ssl, NULL);
774 
775   if (myUserId.protocolId() == ICQ_PPID)
776     m_p_SSL = SSL_new(gSSL_CTX);
777   else
778     m_p_SSL = SSL_new(gSSL_CTX_NONICQ);
779   SSL_set_session(m_pSSL, NULL);
780   SSL_set_fd(m_pSSL, myDescriptor);
781   int i = SSL_accept(m_pSSL);
782   int j = SSL_get_error(m_pSSL, i);
783   if (j != SSL_ERROR_NONE)
784   {
785     const char *file;
786     int line;
787     unsigned long err;
788     switch (j)
789     {
790       case SSL_ERROR_SSL:
791         err = ERR_get_error_line(&file, &line);
792         gLog.warning("SSL_accept error = %lx, %s:%i\n%s", err, file, line,
793                      ERR_error_string(err, 0));
794         ERR_clear_error();
795         break;
796       default:
797         err = ERR_get_error();
798         gLog.warning("SSL_accept error %d, SSL_%d\n%s", i, j,
799                      ERR_error_string(err, 0));
800         break;
801     }
802     return false;
803   }
804   return true;
805 }
806 
SecureStop()807 void TCPSocket::SecureStop()
808 {
809   if(m_pSSL)
810   {
811     pthread_mutex_destroy(&mutex_ssl);
812     SSL_free(m_pSSL);
813     m_p_SSL = NULL;
814   }
815 }
816 
817 #else
818 
SecureConnect()819 bool TCPSocket::SecureConnect()
820 {
821   return false;
822 }
823 
SecureListen()824 bool TCPSocket::SecureListen()
825 {
826   return false;
827 }
828 
SecureStop()829 void TCPSocket::SecureStop()
830 {
831   m_p_SSL = NULL;
832 }
833 
834 
835 #endif /*-----End of OpenSSL code------------------------------------------*/
836 
UDPSocket(const UserId & userId)837 UDPSocket::UDPSocket(const UserId& userId)
838   : INetSocket(SOCK_DGRAM, "UDP", userId)
839 {
840   // Empty
841 }
842 
~UDPSocket()843 UDPSocket::~UDPSocket()
844 {
845   // Empty
846 }
847 
848 //=====Locking==================================================================
Lock()849 void INetSocket::Lock()
850 {
851   myMutex.lock();
852 }
853 
Unlock()854 void INetSocket::Unlock()
855 {
856   myMutex.unlock();
857 }
858