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