"Fossies" - the Fresh Open Source Software Archive 
Member "neon-0.31.2/src/ne_socket.c" (20 Jun 2020, 53996 Bytes) of package /linux/www/neon-0.31.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ne_socket.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.31.1_vs_0.31.2.
1 /*
2 Socket handling routines
3 Copyright (C) 1998-2011, Joe Orton <joe@manyfish.co.uk>
4 Copyright (C) 2004 Aleix Conchillo Flaque <aleix@member.fsf.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA
20 */
21
22 /*
23 portions were originally under GPL in Mutt, http://www.mutt.org/
24 Relicensed under LGPL for neon, http://www.webdav.org/neon/
25 */
26
27 #include "config.h"
28
29 #include <sys/types.h>
30 #ifdef HAVE_SYS_UIO_H
31 #include <sys/uio.h> /* writev(2) */
32 #endif
33 #ifdef HAVE_SYS_TIME_H
34 #include <sys/time.h>
35 #endif
36 #include <sys/stat.h>
37 #ifdef HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
39 #endif
40
41 #ifdef NE_USE_POLL
42 #include <sys/poll.h>
43 #elif defined(HAVE_SYS_SELECT_H)
44 #include <sys/select.h>
45 #endif
46
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
49 #endif
50 #ifdef HAVE_NETINET_TCP_H
51 #include <netinet/tcp.h>
52 #endif
53 #ifdef HAVE_ARPA_INET_H
54 #include <arpa/inet.h>
55 #endif
56 #ifdef HAVE_NETDB_H
57 #include <netdb.h>
58 #endif
59
60 #ifdef WIN32
61 #include <winsock2.h>
62 #include <stddef.h>
63 #ifdef USE_GETADDRINFO
64 #include <ws2tcpip.h>
65 #include <wspiapi.h>
66 #endif
67 #endif
68
69 #if defined(HAVE_OPENSSL) && defined(HAVE_LIMITS_H)
70 #include <limits.h> /* for INT_MAX */
71 #endif
72 #ifdef HAVE_STRING_H
73 #include <string.h>
74 #endif
75 #ifdef HAVE_STRINGS_H
76 #include <strings.h>
77 #endif
78 #ifdef HAVE_UNISTD_H
79 #include <unistd.h>
80 #endif
81 #ifdef HAVE_SIGNAL_H
82 #include <signal.h>
83 #endif
84 #ifdef HAVE_ERRNO_H
85 #include <errno.h>
86 #endif
87 #ifdef HAVE_STDLIB_H
88 #include <stdlib.h>
89 #endif
90 #ifdef HAVE_FCNTL_H
91 #include <fcntl.h>
92 #endif
93
94 #ifdef HAVE_SOCKS_H
95 #include <socks.h>
96 #endif
97
98 #ifdef HAVE_OPENSSL
99 #include <openssl/ssl.h>
100 #include <openssl/err.h>
101 #include <openssl/pkcs12.h> /* for PKCS12_PBE_add */
102 #include <openssl/rand.h>
103 #include <openssl/opensslv.h> /* for OPENSSL_VERSION_NUMBER */
104 #endif
105
106 #ifdef HAVE_GNUTLS
107 #include <gnutls/gnutls.h>
108 #endif
109
110 #define NE_INET_ADDR_DEFINED
111 /* A slightly ugly hack: change the ne_inet_addr definition to be the
112 * real address type used. The API only exposes ne_inet_addr as a
113 * pointer to an opaque object, so this should be well-defined
114 * behaviour. It avoids the hassle of a real wrapper ne_inet_addr
115 * structure, or losing type-safety by using void *. */
116 #ifdef USE_GETADDRINFO
117 typedef struct addrinfo ne_inet_addr;
118 #else
119 typedef struct in_addr ne_inet_addr;
120 #endif
121
122 #include "ne_privssl.h" /* MUST come after ne_inet_addr is defined */
123
124 /* To avoid doing AAAA queries unless absolutely necessary, either use
125 * AI_ADDRCONFIG where available, or a run-time check for working IPv6
126 * support; the latter is only known to work on Linux. */
127 #if defined(USE_GETADDRINFO) && !defined(USE_GAI_ADDRCONFIG) && defined(__linux__)
128 #define USE_CHECK_IPV6
129 #endif
130
131 /* "Be Conservative In What You Build". */
132 #if defined(HAVE_FCNTL) && defined(O_NONBLOCK) && defined(F_SETFL) \
133 && defined(HAVE_GETSOCKOPT) && defined(SO_ERROR) \
134 && defined(HAVE_SOCKLEN_T) && defined(SOL_SOCKET) \
135 && defined(EINPROGRESS)
136 #define USE_NONBLOCKING_CONNECT
137 #endif
138
139 #include "ne_internal.h"
140 #include "ne_utils.h"
141 #include "ne_string.h"
142 #include "ne_socket.h"
143 #include "ne_alloc.h"
144 #include "ne_sspi.h"
145
146 #if defined(__BEOS__) && !defined(BONE_VERSION)
147 /* pre-BONE */
148 #define ne_close(s) closesocket(s)
149 #define ne_errno errno
150 #elif defined(WIN32)
151 #define ne_close(s) closesocket(s)
152 #define ne_errno WSAGetLastError()
153 #else /* really Unix! */
154 #define ne_close(s) close(s)
155 #define ne_errno errno
156 #endif
157
158 #ifdef WIN32
159 #define NE_ISRESET(e) ((e) == WSAECONNABORTED || (e) == WSAETIMEDOUT || \
160 (e) == WSAECONNRESET || (e) == WSAENETRESET)
161 #define NE_ISCLOSED(e) ((e) == WSAESHUTDOWN || (e) == WSAENOTCONN)
162 #define NE_ISINTR(e) (0)
163 #define NE_ISINPROGRESS(e) ((e) == WSAEWOULDBLOCK) /* says MSDN */
164 #else /* Unix */
165 /* Also treat ECONNABORTED and ENOTCONN as "connection reset" errors;
166 * both can be returned by Winsock-based sockets layers e.g. CygWin */
167 #ifndef ECONNABORTED
168 #define ECONNABORTED ECONNRESET
169 #endif
170 #ifndef ENOTCONN
171 #define ENOTCONN ECONNRESET
172 #endif
173 #define NE_ISRESET(e) ((e) == ECONNRESET || (e) == ECONNABORTED || (e) == ENOTCONN)
174 #define NE_ISCLOSED(e) ((e) == EPIPE)
175 #define NE_ISINTR(e) ((e) == EINTR)
176 #define NE_ISINPROGRESS(e) ((e) == EINPROGRESS)
177 #endif
178
179 /* Socket read timeout */
180 #define SOCKET_READ_TIMEOUT 120
181
182 /* Internal read retry value */
183 #define NE_SOCK_RETRY (-6)
184
185 /* Critical I/O functions on a socket: useful abstraction for easily
186 * handling SSL I/O alongside raw socket I/O. */
187 struct iofns {
188 /* Read up to 'len' bytes into 'buf' from socket. Return <0 on
189 * error or EOF, or >0; number of bytes read. */
190 ssize_t (*sread)(ne_socket *s, char *buf, size_t len);
191 /* Write up to 'len' bytes from 'buf' to socket. Return number of
192 * bytes written on success, or <0 on error. */
193 ssize_t (*swrite)(ne_socket *s, const char *buf, size_t len);
194 /* Wait up to 'n' seconds for socket to become readable. Returns
195 * 0 when readable, otherwise NE_SOCK_TIMEOUT or NE_SOCK_ERROR. */
196 int (*readable)(ne_socket *s, int n);
197 /* Write up to 'count' blocks described by 'vector' to socket.
198 * Return number of bytes written on success, or <0 on error. */
199 ssize_t (*swritev)(ne_socket *s, const struct ne_iovec *vector,
200 int count);
201 };
202
203 static const ne_inet_addr dummy_laddr;
204
205 struct ne_socket_s {
206 int fd;
207 unsigned int lport;
208 const ne_inet_addr *laddr;
209
210 void *progress_ud;
211 int rdtimeout, cotimeout; /* timeouts */
212 const struct iofns *ops;
213 #ifdef NE_HAVE_SSL
214 ne_ssl_socket ssl;
215 #endif
216 /* The read buffer: ->buffer stores byte which have been read; as
217 * these are consumed and passed back to the caller, bufpos
218 * advances through ->buffer. ->bufavail gives the number of
219 * bytes which remain to be consumed in ->buffer (from ->bufpos),
220 * and is hence always <= RDBUFSIZ. */
221 char *bufpos;
222 size_t bufavail;
223 #define RDBUFSIZ 4096
224 char buffer[RDBUFSIZ];
225 /* Error string. */
226 char error[192];
227 };
228
229 /* ne_sock_addr represents an Internet address. */
230 struct ne_sock_addr_s {
231 #ifdef USE_GETADDRINFO
232 struct addrinfo *result, *cursor;
233 #else
234 struct in_addr *addrs;
235 size_t cursor, count;
236 char *name;
237 #endif
238 int errnum;
239 };
240
241 /* set_error: set socket error string to 'str'. */
242 #define set_error(s, str) ne_strnzcpy((s)->error, (str), sizeof (s)->error)
243
244 /* set_strerror: set socket error to system error string for 'errnum' */
245 #ifdef WIN32
246 /* Print system error message to given buffer. */
247 static void print_error(int errnum, char *buffer, size_t buflen)
248 {
249 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
250 | FORMAT_MESSAGE_IGNORE_INSERTS,
251 NULL, (DWORD) errnum, 0,
252 buffer, buflen, NULL) == 0)
253 ne_snprintf(buffer, buflen, "Socket error %d", errnum);
254 }
255 #define set_strerror(s, e) print_error((e), (s)->error, sizeof (s)->error)
256 #else /* not WIN32 */
257 #define set_strerror(s, e) ne_strerror((e), (s)->error, sizeof (s)->error)
258 #endif
259
260 #ifdef HAVE_OPENSSL
261 /* Seed the SSL PRNG, if necessary; returns non-zero on failure. */
262 static int seed_ssl_prng(void)
263 {
264 /* Check whether the PRNG has already been seeded. */
265 if (RAND_status() == 1)
266 return 0;
267
268 #if defined(EGD_PATH)
269 NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from " EGD_PATH "...\n");
270 if (RAND_egd(EGD_PATH) != -1)
271 return 0;
272 #elif defined(ENABLE_EGD)
273 {
274 static const char *paths[] = { "/var/run/egd-pool", "/dev/egd-pool",
275 "/etc/egd-pool", "/etc/entropy" };
276 size_t n;
277 for (n = 0; n < sizeof(paths) / sizeof(char *); n++) {
278 NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from %s...\n", paths[n]);
279 if (RAND_egd(paths[n]) != -1)
280 return 0;
281 }
282 }
283 #endif /* EGD_PATH */
284
285 NE_DEBUG(NE_DBG_SOCKET, "No entropy source found; could not seed PRNG.\n");
286 return -1;
287 }
288 #endif /* HAVE_OPENSSL */
289
290 #ifdef USE_CHECK_IPV6
291 static int ipv6_disabled = 0;
292
293 /* On Linux kernels, IPv6 is typically built as a loadable module, and
294 * socket(AF_INET6, ...) will fail if this module is not loaded, so
295 * the slow AAAA lookups can be avoided for this common case. */
296 static void init_ipv6(void)
297 {
298 int fd = socket(AF_INET6, SOCK_STREAM, 0);
299
300 if (fd < 0)
301 ipv6_disabled = 1;
302 else
303 close(fd);
304 }
305 #elif defined(AF_INET6)
306 #define ipv6_disabled (0)
307 #else
308 #define ipv6_disabled (1)
309 #endif
310
311 /* If init_state is N where > 0, ne_sock_init has been called N times;
312 * if == 0, library is not initialized; if < 0, library initialization
313 * has failed. */
314 static int init_state = 0;
315
316 int ne_sock_init(void)
317 {
318 #ifdef WIN32
319 WORD wVersionRequested;
320 WSADATA wsaData;
321 int err;
322 #endif
323
324 if (init_state > 0) {
325 init_state++;
326 return 0;
327 }
328 else if (init_state < 0) {
329 return -1;
330 }
331
332 #ifdef WIN32
333 wVersionRequested = MAKEWORD(2, 2);
334
335 err = WSAStartup(wVersionRequested, &wsaData);
336 if (err != 0) {
337 return init_state = -1;
338 }
339 #ifdef HAVE_SSPI
340 if (ne_sspi_init() < 0) {
341 return init_state = -1;
342 }
343 #endif
344 #endif
345
346 #ifdef NE_HAVE_SOCKS
347 SOCKSinit("neon");
348 #endif
349
350 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
351 (void) signal(SIGPIPE, SIG_IGN);
352 #endif
353
354 #ifdef USE_CHECK_IPV6
355 init_ipv6();
356 #endif
357
358 #ifdef NE_HAVE_SSL
359 if (ne__ssl_init()) {
360 return init_state = -1;
361 }
362 #endif
363
364 init_state = 1;
365 return 0;
366 }
367
368 void ne_sock_exit(void)
369 {
370 if (init_state > 0 && --init_state == 0) {
371 #ifdef WIN32
372 WSACleanup();
373 #endif
374 #ifdef NE_HAVE_SSL
375 ne__ssl_exit();
376 #endif
377
378 #ifdef HAVE_SSPI
379 ne_sspi_deinit();
380 #endif
381 }
382 }
383
384 /* Await readability (rdwr = 0) or writability (rdwr != 0) for socket
385 * fd for secs seconds. Returns <0 on error, zero on timeout, >0 if
386 * data is available. */
387 static int raw_poll(int fdno, int rdwr, int secs)
388 {
389 int ret;
390 #ifdef NE_USE_POLL
391 struct pollfd fds;
392 int timeout = secs > 0 ? secs * 1000 : -1;
393
394 fds.fd = fdno;
395 fds.events = rdwr == 0 ? POLLIN : POLLOUT;
396 fds.revents = 0;
397
398 do {
399 ret = poll(&fds, 1, timeout);
400 } while (ret < 0 && NE_ISINTR(ne_errno));
401 #else
402 fd_set rdfds, wrfds, exfds;
403 struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL);
404
405 /* Init the fd set */
406 FD_ZERO(&rdfds);
407 FD_ZERO(&wrfds);
408 FD_ZERO(&exfds);
409
410 /* Note that (amazingly) the FD_SET macro does not expand
411 * correctly on Netware if not inside a compound statement
412 * block. */
413 if (rdwr == 0) {
414 FD_SET(fdno, &rdfds);
415 } else {
416 FD_SET(fdno, &wrfds);
417 }
418 FD_SET(fdno, &exfds);
419
420 if (tvp) {
421 tvp->tv_sec = secs;
422 tvp->tv_usec = 0;
423 }
424 do {
425 ret = select(fdno + 1, &rdfds, &wrfds, &exfds, tvp);
426 } while (ret < 0 && NE_ISINTR(ne_errno));
427 #endif
428 return ret;
429 }
430
431 int ne_sock_block(ne_socket *sock, int n)
432 {
433 if (sock->bufavail)
434 return 0;
435 return sock->ops->readable(sock, n);
436 }
437
438 /* Cast address object AD to type 'sockaddr_TY' */
439 #define SACAST(ty, ad) ((struct sockaddr_##ty *)(ad))
440
441 ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t buflen)
442 {
443 ssize_t bytes;
444
445 #if 0
446 NE_DEBUG(NE_DBG_SOCKET, "buf: at %d, %d avail [%s]\n",
447 sock->bufpos - sock->buffer, sock->bufavail, sock->bufpos);
448 #endif
449
450 if (sock->bufavail > 0) {
451 /* Deliver buffered data. */
452 if (buflen > sock->bufavail)
453 buflen = sock->bufavail;
454 memcpy(buffer, sock->bufpos, buflen);
455 sock->bufpos += buflen;
456 sock->bufavail -= buflen;
457 return buflen;
458 } else if (buflen >= sizeof sock->buffer) {
459 /* No need for read buffer. */
460 return sock->ops->sread(sock, buffer, buflen);
461 } else {
462 /* Fill read buffer. */
463 bytes = sock->ops->sread(sock, sock->buffer, sizeof sock->buffer);
464 if (bytes <= 0)
465 return bytes;
466
467 if (buflen > (size_t)bytes)
468 buflen = bytes;
469 memcpy(buffer, sock->buffer, buflen);
470 sock->bufpos = sock->buffer + buflen;
471 sock->bufavail = bytes - buflen;
472 return buflen;
473 }
474 }
475
476 ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t buflen)
477 {
478 ssize_t bytes;
479
480 if (sock->bufavail) {
481 /* just return buffered data. */
482 bytes = sock->bufavail;
483 } else {
484 /* fill the buffer. */
485 bytes = sock->ops->sread(sock, sock->buffer, sizeof sock->buffer);
486 if (bytes <= 0)
487 return bytes;
488
489 sock->bufpos = sock->buffer;
490 sock->bufavail = bytes;
491 }
492
493 if (buflen > (size_t)bytes)
494 buflen = bytes;
495
496 memcpy(buffer, sock->bufpos, buflen);
497
498 return buflen;
499 }
500
501 /* Await data on raw fd in socket. */
502 static int readable_raw(ne_socket *sock, int secs)
503 {
504 int ret = raw_poll(sock->fd, 0, secs);
505
506 if (ret < 0) {
507 set_strerror(sock, ne_errno);
508 return NE_SOCK_ERROR;
509 }
510 return (ret == 0) ? NE_SOCK_TIMEOUT : 0;
511 }
512
513 static ssize_t read_raw(ne_socket *sock, char *buffer, size_t len)
514 {
515 ssize_t ret;
516
517 ret = readable_raw(sock, sock->rdtimeout);
518 if (ret) return ret;
519
520 do {
521 ret = recv(sock->fd, buffer, len, 0);
522 } while (ret == -1 && NE_ISINTR(ne_errno));
523
524 if (ret == 0) {
525 set_error(sock, _("Connection closed"));
526 ret = NE_SOCK_CLOSED;
527 } else if (ret < 0) {
528 int errnum = ne_errno;
529 ret = NE_ISRESET(errnum) ? NE_SOCK_RESET : NE_SOCK_ERROR;
530 set_strerror(sock, errnum);
531 }
532
533 return ret;
534 }
535
536 #define MAP_ERR(e) (NE_ISCLOSED(e) ? NE_SOCK_CLOSED : \
537 (NE_ISRESET(e) ? NE_SOCK_RESET : NE_SOCK_ERROR))
538
539 static ssize_t write_raw(ne_socket *sock, const char *data, size_t length)
540 {
541 ssize_t ret;
542
543 #ifdef __QNX__
544 /* Test failures seen on QNX over loopback, if passing large
545 * buffer lengths to send(). */
546 if (length > 8192) length = 8192;
547 #endif
548
549 do {
550 ret = send(sock->fd, data, length, 0);
551 } while (ret == -1 && NE_ISINTR(ne_errno));
552
553 if (ret < 0) {
554 int errnum = ne_errno;
555 set_strerror(sock, errnum);
556 return MAP_ERR(errnum);
557 }
558 return ret;
559 }
560
561 static ssize_t writev_raw(ne_socket *sock, const struct ne_iovec *vector, int count)
562 {
563 ssize_t ret;
564 #ifdef WIN32
565 LPWSABUF wasvector = (LPWSABUF)ne_malloc(count * sizeof(WSABUF));
566 DWORD total;
567 int i;
568
569 for (i = 0; i < count; i++){
570 wasvector[i].buf = vector[i].base;
571 wasvector[i].len = vector[i].len;
572 }
573
574 ret = WSASend(sock->fd, wasvector, count, &total, 0, NULL, NULL);
575 if (ret == 0)
576 ret = total;
577
578 ne_free(wasvector);
579 #else
580 const struct iovec *vec = (const struct iovec *) vector;
581
582 do {
583 ret = writev(sock->fd, vec, count);
584 } while (ret == -1 && NE_ISINTR(ne_errno));
585 #endif
586
587 if (ret < 0) {
588 int errnum = ne_errno;
589 set_strerror(sock, errnum);
590 return MAP_ERR(errnum);
591 }
592
593 return ret;
594 }
595
596 #ifdef NE_HAVE_SSL
597 static ssize_t writev_dummy(ne_socket *sock, const struct ne_iovec *vector, int count)
598 {
599 return sock->ops->swrite(sock, vector[0].base, vector[0].len);
600 }
601 #endif
602
603 static const struct iofns iofns_raw = { read_raw, write_raw, readable_raw, writev_raw };
604
605 #ifdef HAVE_OPENSSL
606 static int error_ossl(ne_socket *sock, int sret);
607 #endif
608
609 #ifdef HAVE_OPENSSL
610 /* OpenSSL I/O function implementations. */
611 static int readable_ossl(ne_socket *sock, int secs)
612 {
613 #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L
614 /* Sufficient for TLSv1.2 and earlier. */
615 if (SSL_pending(sock->ssl))
616 return 0;
617 return readable_raw(sock, secs);
618 #else
619 /* TLSv1.3 sends a lot more handshake data so the presence of data
620 * on the socket - i.e. poll() returning 1, is an insufficient
621 * test for app-data readability. */
622 char pending;
623 int ret;
624 size_t bytes;
625
626 /* Loop while no app data is pending, each time attempting a one
627 * byte peek, and retrying the poll if that fails due to absence
628 * of app data. */
629 while (!SSL_pending(sock->ssl)) {
630 ret = readable_raw(sock, secs);
631 if (ret == NE_SOCK_TIMEOUT) {
632 return ret;
633 }
634
635 ret = SSL_peek_ex(sock->ssl, &pending, 1, &bytes);
636 if (ret) {
637 /* App data definitely available. */
638 break;
639 }
640 else {
641 /* If this gave SSL_ERROR_WANT_READ, loop and probably
642 * block again, else some other error happened. */
643 ret = error_ossl(sock, ret);
644 if (ret != NE_SOCK_RETRY)
645 return ret;
646 }
647 }
648
649 return 0;
650 #endif /* OPENSSL_VERSION_NUMBER < 1.1.1 */
651 }
652
653 /* SSL error handling, according to SSL_get_error(3). */
654 static int error_ossl(ne_socket *sock, int sret)
655 {
656 int errnum = SSL_get_error(sock->ssl, sret);
657 unsigned long err;
658
659 if (errnum == SSL_ERROR_ZERO_RETURN) {
660 set_error(sock, _("Connection closed"));
661 return NE_SOCK_CLOSED;
662 }
663 else if (errnum == SSL_ERROR_WANT_READ) {
664 set_error(sock, _("Retry operation"));
665 return NE_SOCK_RETRY;
666 }
667
668 /* for all other errors, look at the OpenSSL error stack */
669 err = ERR_get_error();
670 if (err == 0) {
671 /* Empty error stack, presume this is a system call error: */
672 if (sret == 0) {
673 /* EOF without close_notify, possible truncation */
674 set_error(sock, _("Secure connection truncated"));
675 return NE_SOCK_TRUNC;
676 } else {
677 /* Other socket error. */
678 errnum = ne_errno;
679 set_strerror(sock, errnum);
680 return MAP_ERR(errnum);
681 }
682 }
683
684 if (ERR_reason_error_string(err)) {
685 ne_snprintf(sock->error, sizeof sock->error,
686 _("SSL error: %s"), ERR_reason_error_string(err));
687 } else {
688 ne_snprintf(sock->error, sizeof sock->error,
689 _("SSL error code %d/%d/%lu"), sret, errnum, err);
690 }
691
692 /* make sure the error stack is now empty. */
693 ERR_clear_error();
694 return NE_SOCK_ERROR;
695 }
696
697 /* Work around OpenSSL's use of 'int' rather than 'size_t', to prevent
698 * accidentally passing a negative number, etc. */
699 #define CAST2INT(n) (((n) > INT_MAX) ? INT_MAX : (n))
700
701 static ssize_t read_ossl(ne_socket *sock, char *buffer, size_t len)
702 {
703 int ret;
704
705 do {
706 ret = readable_ossl(sock, sock->rdtimeout);
707 if (ret) return ret;
708
709 ret = SSL_read(sock->ssl, buffer, CAST2INT(len));
710 if (ret <= 0)
711 ret = error_ossl(sock, ret);
712 } while (ret == NE_SOCK_RETRY);
713
714 return ret;
715 }
716
717 static ssize_t write_ossl(ne_socket *sock, const char *data, size_t len)
718 {
719 int ret, ilen = CAST2INT(len);
720 ret = SSL_write(sock->ssl, data, ilen);
721 /* ssl.h says SSL_MODE_ENABLE_PARTIAL_WRITE must be enabled to
722 * have SSL_write return < length... so, SSL_write should never
723 * return < length. */
724 if (ret != ilen)
725 return error_ossl(sock, ret);
726 return ret;
727 }
728
729 static const struct iofns iofns_ssl = {
730 read_ossl,
731 write_ossl,
732 readable_ossl,
733 writev_dummy
734 };
735
736 #elif defined(HAVE_GNUTLS)
737
738 /* Return zero if an alert value can be ignored. */
739 static int check_alert(ne_socket *sock, ssize_t ret)
740 {
741 const char *alert;
742
743 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED) {
744 alert = gnutls_alert_get_name(gnutls_alert_get(sock->ssl));
745 NE_DEBUG(NE_DBG_SOCKET, "TLS warning alert: %s\n", alert);
746 return 0;
747 } else if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
748 alert = gnutls_alert_get_name(gnutls_alert_get(sock->ssl));
749 NE_DEBUG(NE_DBG_SOCKET, "TLS fatal alert: %s\n", alert);
750 return -1;
751 }
752 return ret;
753 }
754
755 static int readable_gnutls(ne_socket *sock, int secs)
756 {
757 if (gnutls_record_check_pending(sock->ssl)) {
758 return 0;
759 }
760 return readable_raw(sock, secs);
761 }
762
763 static ssize_t error_gnutls(ne_socket *sock, ssize_t sret)
764 {
765 ssize_t ret;
766
767 switch (sret) {
768 case 0:
769 ret = NE_SOCK_CLOSED;
770 set_error(sock, _("Connection closed"));
771 break;
772 case GNUTLS_E_FATAL_ALERT_RECEIVED:
773 ret = NE_SOCK_ERROR;
774 ne_snprintf(sock->error, sizeof sock->error,
775 _("SSL alert received: %s"),
776 gnutls_alert_get_name(gnutls_alert_get(sock->ssl)));
777 break;
778 #if GNUTLS_VERSION_MAJOR > 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR >= 99)
779 case GNUTLS_E_PREMATURE_TERMINATION:
780 #else
781 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
782 #endif
783 ret = NE_SOCK_TRUNC;
784 set_error(sock, _("Secure connection truncated"));
785 break;
786 case GNUTLS_E_PUSH_ERROR:
787 ret = NE_SOCK_RESET;
788 set_error(sock, ("SSL socket write failed"));
789 break;
790 case GNUTLS_E_PULL_ERROR:
791 ret = NE_SOCK_RESET;
792 set_error(sock, _("SSL socket read failed"));
793 break;
794 default:
795 ret = NE_SOCK_ERROR;
796 ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"),
797 gnutls_strerror(sret));
798 }
799 return ret;
800 }
801
802 #define RETRY_GNUTLS(sock, ret) ((ret < 0) \
803 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN \
804 || check_alert(sock, ret) == 0))
805
806 static ssize_t read_gnutls(ne_socket *sock, char *buffer, size_t len)
807 {
808 ssize_t ret;
809 unsigned reneg = 1; /* number of allowed rehandshakes */
810
811 ret = readable_gnutls(sock, sock->rdtimeout);
812 if (ret) return ret;
813
814 do {
815 do {
816 ret = gnutls_record_recv(sock->ssl, buffer, len);
817 } while (RETRY_GNUTLS(sock, ret));
818
819 } while (ret == GNUTLS_E_REHANDSHAKE && reneg--
820 && (ret = gnutls_handshake(sock->ssl)) == GNUTLS_E_SUCCESS);
821
822 if (ret <= 0)
823 ret = error_gnutls(sock, ret);
824
825 return ret;
826 }
827
828 static ssize_t write_gnutls(ne_socket *sock, const char *data, size_t len)
829 {
830 ssize_t ret;
831
832 do {
833 ret = gnutls_record_send(sock->ssl, data, len);
834 } while (RETRY_GNUTLS(sock, ret));
835
836 if (ret < 0)
837 return error_gnutls(sock, ret);
838
839 return ret;
840 }
841
842 static const struct iofns iofns_ssl = {
843 read_gnutls,
844 write_gnutls,
845 readable_gnutls,
846 writev_dummy
847 };
848
849 #endif
850
851 int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t len)
852 {
853 ssize_t ret;
854
855 do {
856 ret = sock->ops->swrite(sock, data, len);
857 if (ret > 0) {
858 data += ret;
859 len -= ret;
860 }
861 } while (ret > 0 && len > 0);
862
863 return ret < 0 ? ret : 0;
864 }
865
866 int ne_sock_fullwritev(ne_socket *sock, const struct ne_iovec *vector, int count)
867 {
868 ssize_t ret;
869
870 do {
871 ret = sock->ops->swritev(sock, vector, count);
872 if (ret > 0) {
873 while (count && (size_t)ret >= vector[0].len) {
874 ret -= vector[0].len;
875 count--;
876 vector++;
877 }
878
879 if (ret && count) {
880 /* Partial buffer sent; send the rest. */
881 ret = ne_sock_fullwrite(sock, (char *)vector[0].base + ret,
882 vector[0].len - ret);
883 count--;
884 vector++;
885 }
886 }
887 } while (count && ret >= 0);
888
889 return ret < 0 ? ret : 0;
890 }
891
892 ssize_t ne_sock_readline(ne_socket *sock, char *buf, size_t buflen)
893 {
894 char *lf;
895 size_t len;
896
897 if ((lf = memchr(sock->bufpos, '\n', sock->bufavail)) == NULL
898 && sock->bufavail < RDBUFSIZ) {
899 /* The buffered data does not contain a complete line: move it
900 * to the beginning of the buffer. */
901 if (sock->bufavail)
902 memmove(sock->buffer, sock->bufpos, sock->bufavail);
903 sock->bufpos = sock->buffer;
904
905 /* Loop filling the buffer whilst no newline is found in the data
906 * buffered so far, and there is still buffer space available */
907 do {
908 /* Read more data onto end of buffer. */
909 ssize_t ret = sock->ops->sread(sock, sock->buffer + sock->bufavail,
910 RDBUFSIZ - sock->bufavail);
911 if (ret < 0) return ret;
912 sock->bufavail += ret;
913 } while ((lf = memchr(sock->buffer, '\n', sock->bufavail)) == NULL
914 && sock->bufavail < RDBUFSIZ);
915 }
916
917 if (lf)
918 len = lf - sock->bufpos + 1;
919 else
920 len = buflen; /* fall into "line too long" error... */
921
922 if ((len + 1) > buflen) {
923 set_error(sock, _("Line too long"));
924 return NE_SOCK_ERROR;
925 }
926
927 memcpy(buf, sock->bufpos, len);
928 buf[len] = '\0';
929 /* consume the line from buffer: */
930 sock->bufavail -= len;
931 sock->bufpos += len;
932 return len;
933 }
934
935 ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t buflen)
936 {
937 ssize_t len;
938
939 while (buflen > 0) {
940 len = ne_sock_read(sock, buffer, buflen);
941 if (len < 0) return len;
942 buflen -= len;
943 buffer += len;
944 }
945
946 return 0;
947 }
948
949 #ifndef INADDR_NONE
950 #define INADDR_NONE ((in_addr_t) -1)
951 #endif
952
953 #if !defined(USE_GETADDRINFO) && !defined(WIN32) && !HAVE_DECL_H_ERRNO
954 /* Ancient versions of netdb.h don't export h_errno. */
955 extern int h_errno;
956 #endif
957
958 /* This implementation does not attempt to support IPv6 using
959 * gethostbyname2 et al. */
960 ne_sock_addr *ne_addr_resolve(const char *hostname, int flags)
961 {
962 ne_sock_addr *addr = ne_calloc(sizeof *addr);
963 #ifdef USE_GETADDRINFO
964 struct addrinfo hints = {0};
965 char *pnt;
966
967 hints.ai_socktype = SOCK_STREAM;
968
969 if (flags & NE_ADDR_CANON) {
970 hints.ai_flags = AI_CANONNAME;
971 }
972
973 #ifdef AF_INET6
974 if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) {
975 char *hn = ne_strdup(hostname + 1);
976 hn[pnt - hostname - 1] = '\0';
977 #ifdef AI_NUMERICHOST /* added in the RFC2553 API */
978 hints.ai_flags |= AI_NUMERICHOST;
979 #endif
980 hints.ai_family = AF_INET6;
981 addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result);
982 ne_free(hn);
983 } else
984 #endif /* AF_INET6 */
985 {
986 #ifdef USE_GAI_ADDRCONFIG /* added in the RFC3493 API */
987 hints.ai_flags |= AI_ADDRCONFIG;
988 hints.ai_family = AF_UNSPEC;
989 addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
990 #else
991 hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC;
992 addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
993 #endif
994 }
995 #else /* Use gethostbyname() */
996 in_addr_t laddr;
997 struct hostent *hp;
998
999 laddr = inet_addr(hostname);
1000 if (laddr == INADDR_NONE) {
1001 hp = gethostbyname(hostname);
1002 if (hp == NULL) {
1003 #ifdef WIN32
1004 addr->errnum = WSAGetLastError();
1005 #else
1006 addr->errnum = h_errno;
1007 #endif
1008 } else if (hp->h_length != sizeof(struct in_addr)) {
1009 /* fail gracefully if somebody set RES_USE_INET6 */
1010 addr->errnum = NO_RECOVERY;
1011 } else {
1012 size_t n;
1013 /* count addresses */
1014 for (n = 0; hp->h_addr_list[n] != NULL; n++)
1015 /* noop */;
1016
1017 addr->count = n;
1018 addr->addrs = ne_malloc(n * sizeof *addr->addrs);
1019
1020 for (n = 0; n < addr->count; n++)
1021 memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length);
1022
1023 if (hp->h_name && hp->h_name[0])
1024 addr->name = ne_strdup(hp->h_name);
1025 }
1026 } else {
1027 addr->addrs = ne_malloc(sizeof *addr->addrs);
1028 addr->count = 1;
1029 memcpy(addr->addrs, &laddr, sizeof *addr->addrs);
1030 }
1031 #endif
1032 return addr;
1033 }
1034
1035 int ne_addr_result(const ne_sock_addr *addr)
1036 {
1037 return addr->errnum;
1038 }
1039
1040 const char *ne_addr_canonical(const ne_sock_addr *addr)
1041 {
1042 #ifdef USE_GETADDRINFO
1043 return addr->result ? addr->result->ai_canonname : NULL;
1044 #else
1045 return addr->name;
1046 #endif
1047 }
1048
1049 const ne_inet_addr *ne_addr_first(ne_sock_addr *addr)
1050 {
1051 #ifdef USE_GETADDRINFO
1052 addr->cursor = addr->result->ai_next;
1053 return addr->result;
1054 #else
1055 addr->cursor = 0;
1056 return &addr->addrs[0];
1057 #endif
1058 }
1059
1060 const ne_inet_addr *ne_addr_next(ne_sock_addr *addr)
1061 {
1062 #ifdef USE_GETADDRINFO
1063 struct addrinfo *ret = addr->cursor;
1064 if (addr->cursor) addr->cursor = addr->cursor->ai_next;
1065 #else
1066 struct in_addr *ret;
1067 if (++addr->cursor < addr->count)
1068 ret = &addr->addrs[addr->cursor];
1069 else
1070 ret = NULL;
1071 #endif
1072 return ret;
1073 }
1074
1075 char *ne_addr_error(const ne_sock_addr *addr, char *buf, size_t bufsiz)
1076 {
1077 #ifdef WIN32
1078 print_error(addr->errnum, buf, bufsiz);
1079 #else
1080 const char *err;
1081 #ifdef USE_GETADDRINFO
1082 /* override horrible generic "Name or service not known" error. */
1083 if (addr->errnum == EAI_NONAME)
1084 err = _("Host not found");
1085 else
1086 err = gai_strerror(addr->errnum);
1087 #elif defined(HAVE_HSTRERROR)
1088 err = hstrerror(addr->errnum);
1089 #else
1090 err = _("Host not found");
1091 #endif
1092 ne_strnzcpy(buf, err, bufsiz);
1093 #endif /* WIN32 */
1094 return buf;
1095 }
1096
1097 char *ne_iaddr_print(const ne_inet_addr *ia, char *buf, size_t bufsiz)
1098 {
1099 #if defined(USE_GETADDRINFO) && defined(HAVE_INET_NTOP)
1100 const char *ret;
1101 #ifdef AF_INET6
1102 if (ia->ai_family == AF_INET6) {
1103 struct sockaddr_in6 *in6 = SACAST(in6, ia->ai_addr);
1104 ret = inet_ntop(AF_INET6, &in6->sin6_addr, buf, bufsiz);
1105 } else
1106 #endif
1107 if (ia->ai_family == AF_INET) {
1108 struct sockaddr_in *in = SACAST(in, ia->ai_addr);
1109 ret = inet_ntop(AF_INET, &in->sin_addr, buf, bufsiz);
1110 } else
1111 ret = NULL;
1112 if (ret == NULL)
1113 ne_strnzcpy(buf, "[IP address]", bufsiz);
1114 #elif defined(USE_GETADDRINFO) && defined(NI_NUMERICHOST)
1115 /* use getnameinfo instead for Win32, which lacks inet_ntop: */
1116 if (getnameinfo(ia->ai_addr, ia->ai_addrlen, buf, bufsiz, NULL, 0,
1117 NI_NUMERICHOST))
1118 ne_strnzcpy(buf, "[IP address]", bufsiz);
1119 #else /* USE_GETADDRINFO */
1120 ne_strnzcpy(buf, inet_ntoa(*ia), bufsiz);
1121 #endif
1122 return buf;
1123 }
1124
1125 unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buf)
1126 {
1127 #ifdef USE_GETADDRINFO
1128 #ifdef AF_INET6
1129 if (ia->ai_family == AF_INET6) {
1130 struct sockaddr_in6 *in6 = SACAST(in6, ia->ai_addr);
1131 return memcpy(buf, in6->sin6_addr.s6_addr, sizeof in6->sin6_addr.s6_addr);
1132 } else
1133 #endif /* AF_INET6 */
1134 {
1135 struct sockaddr_in *in = SACAST(in, ia->ai_addr);
1136 return memcpy(buf, &in->sin_addr.s_addr, sizeof in->sin_addr.s_addr);
1137 }
1138 #else /* !USE_GETADDRINFO */
1139 return memcpy(buf, &ia->s_addr, sizeof ia->s_addr);
1140 #endif
1141 }
1142
1143 ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type)
1144 {
1145 #if defined(USE_GETADDRINFO) && defined(HAVE_INET_PTON)
1146 char dst[sizeof(struct in6_addr)];
1147 int af = type == ne_iaddr_ipv6 ? AF_INET6 : AF_INET;
1148
1149 if (inet_pton(af, addr, dst) != 1) {
1150 return NULL;
1151 }
1152
1153 return ne_iaddr_make(type, (unsigned char *)dst);
1154 #elif defined(USE_GETADDRINFO) && !defined(HAVE_INET_PTON)
1155 /* For Windows, which lacks inet_pton(). */
1156 struct addrinfo *ai, *rv, hints;
1157
1158 memset(&hints, 0, sizeof hints);
1159 hints.ai_socktype = SOCK_STREAM;
1160 hints.ai_flags = AI_NUMERICHOST;
1161 hints.ai_family = type == ne_iaddr_ipv6 ? AF_INET6 : AF_INET;
1162
1163 if (getaddrinfo(addr, NULL, &hints, &ai)) {
1164 return NULL;
1165 }
1166
1167 /* Copy the returned addrinfo, since it needs to be ne_free()-able
1168 * later; must only call freeaddrinfo() on ai. */
1169 rv = ne_calloc(sizeof *rv);
1170 memcpy(rv, ai, sizeof *rv);
1171 rv->ai_next = NULL;
1172 rv->ai_canonname = NULL;
1173 rv->ai_addr = ne_calloc(ai->ai_addrlen);
1174 memcpy(rv->ai_addr, ai->ai_addr, ai->ai_addrlen);
1175 freeaddrinfo(ai);
1176
1177 return rv;
1178 #else /* !USE_GETADDRINFO */
1179 struct in_addr a;
1180
1181 if (type == ne_iaddr_ipv6) {
1182 return NULL;
1183 }
1184
1185 #ifdef WIN32
1186 /* inet_addr() is broken because INADDR_NONE is a valid
1187 * broadcast address, so only use it on Windows. */
1188 a.s_addr = inet_addr(addr);
1189 if (a.s_addr == INADDR_NONE) {
1190 return NULL;
1191 }
1192 #else /* !WIN32 */
1193 if (inet_aton(addr, &a) == 0) {
1194 return NULL;
1195 }
1196 #endif
1197
1198 return ne_iaddr_make(ne_iaddr_ipv4, (unsigned char *)&a.s_addr);
1199 #endif /* !USE_GETADDRINFO */
1200 }
1201
1202 int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz)
1203 {
1204 #ifdef USE_GETADDRINFO
1205 return getnameinfo(ia->ai_addr, ia->ai_addrlen, buf, bufsiz,
1206 NULL, 0, 0);
1207 #else
1208 struct hostent *hp;
1209
1210 /* Cast to const void *; some old libc headers apparently expect
1211 * const char * here. */
1212 hp = gethostbyaddr((const void *)ia, sizeof *ia, AF_INET);
1213 if (hp && hp->h_name) {
1214 ne_strnzcpy(buf, hp->h_name, bufsiz);
1215 return 0;
1216 }
1217 return -1;
1218 #endif
1219 }
1220
1221 void ne_addr_destroy(ne_sock_addr *addr)
1222 {
1223 #ifdef USE_GETADDRINFO
1224 /* Note that ->result is only valid for successful invocations of
1225 * getaddrinfo. */
1226 if (!addr->errnum && addr->result)
1227 freeaddrinfo(addr->result);
1228 #else
1229 if (addr->addrs)
1230 ne_free(addr->addrs);
1231 if (addr->name)
1232 ne_free(addr->name);
1233 #endif
1234 ne_free(addr);
1235 }
1236
1237 /* Perform a connect() for given fd, handling EINTR retries. Returns
1238 * zero on success or -1 on failure, in which case, ne_errno is set
1239 * appropriately. */
1240 static int raw_connect(int fd, const struct sockaddr *sa, size_t salen)
1241 {
1242 int ret;
1243
1244 do {
1245 ret = connect(fd, sa, salen);
1246 } while (ret < 0 && NE_ISINTR(ne_errno));
1247
1248 return ret;
1249 }
1250
1251 /* Perform a connect() for fd to address sa of length salen, with a
1252 * timeout if supported on this platform. Returns zero on success or
1253 * NE_SOCK_* on failure, with sock->error set appropriately. */
1254 static int timed_connect(ne_socket *sock, int fd,
1255 const struct sockaddr *sa, size_t salen)
1256 {
1257 int ret;
1258
1259 #ifdef USE_NONBLOCKING_CONNECT
1260 if (sock->cotimeout) {
1261 int errnum, flags;
1262
1263 /* Get flags and then set O_NONBLOCK. */
1264 flags = fcntl(fd, F_GETFL);
1265 if (flags & O_NONBLOCK) {
1266 /* This socket was created using SOCK_NONBLOCK... flip the
1267 * bit for restoring flags later. */
1268 flags &= ~O_NONBLOCK;
1269 }
1270 else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
1271 set_strerror(sock, errno);
1272 return NE_SOCK_ERROR;
1273 }
1274
1275 ret = raw_connect(fd, sa, salen);
1276 if (ret == -1) {
1277 errnum = ne_errno;
1278 if (NE_ISINPROGRESS(errnum)) {
1279 ret = raw_poll(fd, 1, sock->cotimeout);
1280 if (ret > 0) { /* poll got data */
1281 socklen_t len = sizeof(errnum);
1282
1283 /* Check whether there is a pending error for the
1284 * socket. Per Stevens UNPv1§15.4, Solaris will
1285 * return a pending error via errno by failing the
1286 * getsockopt() call. */
1287
1288 errnum = 0;
1289 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errnum, &len))
1290 errnum = errno;
1291
1292 if (errnum == 0) {
1293 ret = 0;
1294 } else {
1295 set_strerror(sock, errnum);
1296 ret = NE_SOCK_ERROR;
1297 }
1298 } else if (ret == 0) { /* poll timed out */
1299 set_error(sock, _("Connection timed out"));
1300 ret = NE_SOCK_TIMEOUT;
1301 } else /* poll failed */ {
1302 set_strerror(sock, errno);
1303 ret = NE_SOCK_ERROR;
1304 }
1305 } else /* non-EINPROGRESS error from connect() */ {
1306 set_strerror(sock, errnum);
1307 ret = NE_SOCK_ERROR;
1308 }
1309 }
1310
1311 /* Reset to old flags; fail on error if no previous error. */
1312 if (fcntl(fd, F_SETFL, flags) == -1 && !ret) {
1313 set_strerror(sock, errno);
1314 ret = NE_SOCK_ERROR;
1315 }
1316 } else
1317 #endif /* USE_NONBLOCKING_CONNECT */
1318 {
1319 ret = raw_connect(fd, sa, salen);
1320
1321 if (ret < 0) {
1322 set_strerror(sock, ne_errno);
1323 ret = NE_SOCK_ERROR;
1324 }
1325 }
1326
1327 return ret;
1328 }
1329
1330 /* Connect socket to address 'addr' on given 'port'. Returns zero on
1331 * success or NE_SOCK_* on failure with sock->error set
1332 * appropriately. */
1333 static int connect_socket(ne_socket *sock, int fd,
1334 const ne_inet_addr *addr, unsigned int port)
1335 {
1336 #ifdef USE_GETADDRINFO
1337 #ifdef AF_INET6
1338 /* fill in the _family field for AIX 4.3, which forgets to do so. */
1339 if (addr->ai_family == AF_INET6) {
1340 struct sockaddr_in6 in6;
1341 memcpy(&in6, addr->ai_addr, sizeof in6);
1342 in6.sin6_port = port;
1343 in6.sin6_family = AF_INET6;
1344 return timed_connect(sock, fd, (struct sockaddr *)&in6, sizeof in6);
1345 } else
1346 #endif
1347 if (addr->ai_family == AF_INET) {
1348 struct sockaddr_in in;
1349 memcpy(&in, addr->ai_addr, sizeof in);
1350 in.sin_port = port;
1351 in.sin_family = AF_INET;
1352 return timed_connect(sock, fd, (struct sockaddr *)&in, sizeof in);
1353 } else {
1354 set_strerror(sock, EINVAL);
1355 return NE_SOCK_ERROR;
1356 }
1357 #else
1358 struct sockaddr_in sa = {0};
1359 sa.sin_family = AF_INET;
1360 sa.sin_port = port;
1361 sa.sin_addr = *addr;
1362 return timed_connect(sock, fd, (struct sockaddr *)&sa, sizeof sa);
1363 #endif
1364 }
1365
1366 ne_socket *ne_sock_create(void)
1367 {
1368 ne_socket *sock = ne_calloc(sizeof *sock);
1369 sock->rdtimeout = SOCKET_READ_TIMEOUT;
1370 sock->cotimeout = 0;
1371 sock->bufpos = sock->buffer;
1372 sock->ops = &iofns_raw;
1373 sock->fd = -1;
1374 return sock;
1375 }
1376
1377
1378 #ifdef USE_GETADDRINFO
1379 #define ia_family(a) ((a)->ai_family)
1380 #define ia_proto(a) ((a)->ai_protocol)
1381 #else
1382 #define ia_family(a) AF_INET
1383 #define ia_proto(a) 0
1384 #endif
1385
1386 void ne_sock_prebind(ne_socket *sock, const ne_inet_addr *addr,
1387 unsigned int port)
1388 {
1389 sock->lport = port;
1390 sock->laddr = addr ? addr : &dummy_laddr;
1391 }
1392
1393 /* Bind socket 'fd' to address/port 'addr' and 'port', for subsequent
1394 * connect() to address of family 'peer_family'. */
1395 static int do_bind(int fd, int peer_family,
1396 const ne_inet_addr *addr, unsigned int port)
1397 {
1398 #if defined(HAVE_SETSOCKOPT) && defined(SO_REUSEADDR) && defined(SOL_SOCKET)
1399 {
1400 int flag = 1;
1401
1402 (void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof flag);
1403 /* An error here is not fatal, so ignore it. */
1404 }
1405 #endif
1406
1407
1408 #if defined(USE_GETADDRINFO) && defined(AF_INET6)
1409 /* Use a sockaddr_in6 if an AF_INET6 local address is specified, or
1410 * if no address is specified and the peer address is AF_INET6: */
1411 if ((addr != &dummy_laddr && addr->ai_family == AF_INET6)
1412 || (addr == &dummy_laddr && peer_family == AF_INET6)) {
1413 struct sockaddr_in6 in6;
1414
1415 if (addr == &dummy_laddr)
1416 memset(&in6, 0, sizeof in6);
1417 else
1418 memcpy(&in6, addr->ai_addr, sizeof in6);
1419 in6.sin6_port = htons(port);
1420 /* fill in the _family field for AIX 4.3, which forgets to do so. */
1421 in6.sin6_family = AF_INET6;
1422
1423 return bind(fd, (struct sockaddr *)&in6, sizeof in6);
1424 } else
1425 #endif
1426 {
1427 struct sockaddr_in in;
1428
1429 if (addr == &dummy_laddr)
1430 memset(&in, 0, sizeof in);
1431 else {
1432 #ifdef USE_GETADDRINFO
1433 memcpy(&in, addr->ai_addr, sizeof in);
1434 #else
1435 in.sin_addr = *addr;
1436 #endif
1437 }
1438 in.sin_port = htons(port);
1439 in.sin_family = AF_INET;
1440
1441 return bind(fd, (struct sockaddr *)&in, sizeof in);
1442 }
1443 }
1444
1445 #ifdef SOCK_CLOEXEC
1446 /* sock_cloexec is initialized to SOCK_CLOEXEC and cleared to zero if
1447 * a socket() call ever fails with EINVAL; not strictly thread-safe
1448 * but in practice it will not matter if two threads race accessing
1449 * the variable. */
1450 static int sock_cloexec = SOCK_CLOEXEC;
1451 #define RETRY_ON_EINVAL
1452 #else
1453 #define sock_cloexec 0
1454 #endif
1455
1456 int ne_sock_connect(ne_socket *sock,
1457 const ne_inet_addr *addr, unsigned int port)
1458 {
1459 int fd, ret;
1460 int type = SOCK_STREAM | sock_cloexec;
1461
1462 #if defined(RETRY_ON_EINVAL) && defined(SOCK_NONBLOCK) \
1463 && defined(USE_NONBLOCKING_CONNECT)
1464 /* If the SOCK_NONBLOCK flag is defined, and the retry-on-EINVAL
1465 * logic is enabled, and the socket has a configured timeout, then
1466 * also use the SOCK_NONBLOCK flag to save enabling O_NONBLOCK
1467 * later. */
1468 if (sock->cotimeout && sock_cloexec) {
1469 type |= SOCK_NONBLOCK;
1470 }
1471 #endif
1472
1473 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
1474 * implementations do not set ai_socktype, e.g. RHL6.2. */
1475 fd = socket(ia_family(addr), type, ia_proto(addr));
1476 #ifdef RETRY_ON_EINVAL
1477 /* Handle forwards compat for new glibc on an older kernels; clear
1478 * the sock_cloexec flag and retry the call: */
1479 if (fd < 0 && sock_cloexec && errno == EINVAL) {
1480 sock_cloexec = 0;
1481 fd = socket(ia_family(addr), SOCK_STREAM, ia_proto(addr));
1482 }
1483 #endif
1484 if (fd < 0) {
1485 set_strerror(sock, ne_errno);
1486 return -1;
1487 }
1488
1489 #if !defined(NE_USE_POLL) && !defined(WIN32)
1490 if (fd > FD_SETSIZE) {
1491 ne_close(fd);
1492 set_error(sock, _("Socket descriptor number exceeds FD_SETSIZE"));
1493 return NE_SOCK_ERROR;
1494 }
1495 #endif
1496
1497 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) \
1498 && defined(FD_CLOEXEC)
1499 /* Set the FD_CLOEXEC bit for the new fd, if the socket was not
1500 * created with the CLOEXEC bit already set. */
1501 if (!sock_cloexec && (ret = fcntl(fd, F_GETFD)) >= 0) {
1502 fcntl(fd, F_SETFD, ret | FD_CLOEXEC);
1503 /* ignore failure; not a critical error. */
1504 }
1505 #endif
1506
1507 if (sock->laddr && (sock->laddr == &dummy_laddr ||
1508 ia_family(sock->laddr) == ia_family(addr))) {
1509 ret = do_bind(fd, ia_family(addr), sock->laddr, sock->lport);
1510 if (ret < 0) {
1511 int errnum = ne_errno;
1512 ne_close(fd);
1513 set_strerror(sock, errnum);
1514 return NE_SOCK_ERROR;
1515 }
1516 }
1517
1518 #if defined(HAVE_SETSOCKOPT) && (defined(TCP_NODELAY) || defined(WIN32))
1519 { /* Disable the Nagle algorithm. */
1520 int flag = 1;
1521 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
1522 }
1523 #endif
1524
1525 ret = connect_socket(sock, fd, addr, htons(port));
1526 if (ret == 0)
1527 sock->fd = fd;
1528 else
1529 ne_close(fd);
1530
1531 return ret;
1532 }
1533
1534 ne_inet_addr *ne_sock_peer(ne_socket *sock, unsigned int *port)
1535 {
1536 union saun {
1537 struct sockaddr sa;
1538 struct sockaddr_in sin;
1539 #if defined(USE_GETADDRINFO) && defined(AF_INET6)
1540 struct sockaddr_in6 sin6;
1541 #endif
1542 } saun;
1543 socklen_t len = sizeof saun;
1544 ne_inet_addr *ia;
1545 struct sockaddr *sad = (struct sockaddr *)&saun;
1546
1547 if (getpeername(sock->fd, sad, &len) != 0) {
1548 set_strerror(sock, errno);
1549 return NULL;
1550 }
1551
1552 #if !defined(USE_GETADDRINFO) || !defined(AF_INET6)
1553 if (sad->sa_family != AF_INET) {
1554 set_error(sock, _("Socket family not supported"));
1555 return NULL;
1556 }
1557 #endif
1558
1559 ia = ne_calloc(sizeof *ia);
1560 #ifdef USE_GETADDRINFO
1561 ia->ai_addr = ne_malloc(sizeof *ia);
1562 ia->ai_addrlen = len;
1563 memcpy(ia->ai_addr, sad, len);
1564 ia->ai_family = saun.sa.sa_family;
1565 #else
1566 memcpy(ia, &saun.sin.sin_addr.s_addr, sizeof *ia);
1567 #endif
1568
1569 #if defined(USE_GETADDRINFO) && defined(AF_INET6)
1570 *port = ntohs(saun.sa.sa_family == AF_INET ?
1571 saun.sin.sin_port : saun.sin6.sin6_port);
1572 #else
1573 *port = ntohs(saun.sin.sin_port);
1574 #endif
1575
1576 return ia;
1577 }
1578
1579 ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw)
1580 {
1581 ne_inet_addr *ia;
1582 #if !defined(AF_INET6) || !defined(USE_GETADDRINFO)
1583 /* fail if IPv6 address is given if IPv6 is not supported. */
1584 if (type == ne_iaddr_ipv6)
1585 return NULL;
1586 #endif
1587 ia = ne_calloc(sizeof *ia);
1588 #ifdef USE_GETADDRINFO
1589 /* ai_protocol and ai_socktype aren't used by connect_socket() so
1590 * ignore them here. (for now) */
1591 if (type == ne_iaddr_ipv4) {
1592 struct sockaddr_in *in4 = ne_calloc(sizeof *in4);
1593 ia->ai_family = AF_INET;
1594 ia->ai_addr = (struct sockaddr *)in4;
1595 ia->ai_addrlen = sizeof *in4;
1596 in4->sin_family = AF_INET;
1597 memcpy(&in4->sin_addr.s_addr, raw, sizeof in4->sin_addr.s_addr);
1598 }
1599 #ifdef AF_INET6
1600 else {
1601 struct sockaddr_in6 *in6 = ne_calloc(sizeof *in6);
1602 ia->ai_family = AF_INET6;
1603 ia->ai_addr = (struct sockaddr *)in6;
1604 ia->ai_addrlen = sizeof *in6;
1605 in6->sin6_family = AF_INET6;
1606 memcpy(&in6->sin6_addr, raw, sizeof in6->sin6_addr.s6_addr);
1607 }
1608 #endif
1609 #else /* !USE_GETADDRINFO */
1610 memcpy(&ia->s_addr, raw, sizeof ia->s_addr);
1611 #endif
1612 return ia;
1613 }
1614
1615 ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia)
1616 {
1617 #if defined(USE_GETADDRINFO) && defined(AF_INET6)
1618 return ia->ai_family == AF_INET6 ? ne_iaddr_ipv6 : ne_iaddr_ipv4;
1619 #else
1620 return ne_iaddr_ipv4;
1621 #endif
1622 }
1623
1624 int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2)
1625 {
1626 #ifdef USE_GETADDRINFO
1627 if (i1->ai_family != i2->ai_family)
1628 return i2->ai_family - i1->ai_family;
1629 if (i1->ai_family == AF_INET) {
1630 struct sockaddr_in *in1 = SACAST(in, i1->ai_addr),
1631 *in2 = SACAST(in, i2->ai_addr);
1632 return memcmp(&in1->sin_addr.s_addr, &in2->sin_addr.s_addr,
1633 sizeof in1->sin_addr.s_addr);
1634 }
1635 #ifdef AF_INET6
1636 else if (i1->ai_family == AF_INET6) {
1637 struct sockaddr_in6 *in1 = SACAST(in6, i1->ai_addr),
1638 *in2 = SACAST(in6, i2->ai_addr);
1639 return memcmp(in1->sin6_addr.s6_addr, in2->sin6_addr.s6_addr,
1640 sizeof in1->sin6_addr.s6_addr);
1641 }
1642 #endif /* AF_INET6 */
1643 else
1644 return -1;
1645 #else
1646 return memcmp(&i1->s_addr, &i2->s_addr, sizeof i1->s_addr);
1647 #endif /* USE_GETADDRINFO */
1648 }
1649
1650 void ne_iaddr_free(ne_inet_addr *addr)
1651 {
1652 #ifdef USE_GETADDRINFO
1653 ne_free(addr->ai_addr);
1654 #endif
1655 ne_free(addr);
1656 }
1657
1658 int ne_sock_accept(ne_socket *sock, int listener)
1659 {
1660 int fd = accept(listener, NULL, NULL);
1661
1662 if (fd < 0) {
1663 set_strerror(sock, ne_errno);
1664 return -1;
1665 }
1666
1667 sock->fd = fd;
1668 return 0;
1669 }
1670
1671 int ne_sock_fd(const ne_socket *sock)
1672 {
1673 return sock->fd;
1674 }
1675
1676 void ne_sock_read_timeout(ne_socket *sock, int timeout)
1677 {
1678 sock->rdtimeout = timeout;
1679 }
1680
1681 void ne_sock_connect_timeout(ne_socket *sock, int timeout)
1682 {
1683 sock->cotimeout = timeout;
1684 }
1685
1686 #ifdef NE_HAVE_SSL
1687
1688 #ifdef HAVE_GNUTLS
1689 /* Dumb server session cache implementation for GNUTLS; holds a single
1690 * session. */
1691
1692 /* Copy datum 'src' to 'dest'. */
1693 static void copy_datum(gnutls_datum_t *dest, gnutls_datum_t *src)
1694 {
1695 dest->size = src->size;
1696 dest->data = memcpy(gnutls_malloc(src->size), src->data, src->size);
1697 }
1698
1699 /* Callback to store a session 'data' with id 'key'. */
1700 static int store_sess(void *userdata, gnutls_datum_t key, gnutls_datum_t data)
1701 {
1702 ne_ssl_context *ctx = userdata;
1703
1704 if (ctx->cache.server.key.data) {
1705 gnutls_free(ctx->cache.server.key.data);
1706 gnutls_free(ctx->cache.server.data.data);
1707 }
1708
1709 copy_datum(&ctx->cache.server.key, &key);
1710 copy_datum(&ctx->cache.server.data, &data);
1711
1712 return 0;
1713 }
1714
1715 /* Returns non-zero if d1 and d2 are the same datum. */
1716 static int match_datum(gnutls_datum_t *d1, gnutls_datum_t *d2)
1717 {
1718 return d1->size == d2->size
1719 && memcmp(d1->data, d2->data, d1->size) == 0;
1720 }
1721
1722 /* Callback to retrieve a session of id 'key'. */
1723 static gnutls_datum_t retrieve_sess(void *userdata, gnutls_datum_t key)
1724 {
1725 ne_ssl_context *ctx = userdata;
1726 gnutls_datum_t ret = { NULL, 0 };
1727
1728 if (match_datum(&ctx->cache.server.key, &key)) {
1729 copy_datum(&ret, &ctx->cache.server.data);
1730 }
1731
1732 return ret;
1733 }
1734
1735 /* Callback to remove a session of id 'key'; stub needed but
1736 * implementation seems unnecessary. */
1737 static int remove_sess(void *userdata, gnutls_datum_t key)
1738 {
1739 return -1;
1740 }
1741 #endif
1742
1743 int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx)
1744 {
1745 int ret;
1746 ne_ssl_socket ssl;
1747
1748 #if defined(HAVE_OPENSSL)
1749 ssl = SSL_new(ctx->ctx);
1750
1751 SSL_set_fd(ssl, sock->fd);
1752
1753 sock->ssl = ssl;
1754 ret = SSL_accept(ssl);
1755 if (ret != 1) {
1756 return error_ossl(sock, ret);
1757 }
1758
1759 if (SSL_session_reused(ssl)) {
1760 NE_DEBUG(NE_DBG_SSL, "ssl: Server reused session.\n");
1761 }
1762 #elif defined(HAVE_GNUTLS)
1763 unsigned int verify_status;
1764
1765 gnutls_init(&ssl, GNUTLS_SERVER);
1766 gnutls_credentials_set(ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred);
1767 gnutls_set_default_priority(ssl);
1768
1769 /* Set up dummy session cache. */
1770 gnutls_db_set_store_function(ssl, store_sess);
1771 gnutls_db_set_retrieve_function(ssl, retrieve_sess);
1772 gnutls_db_set_remove_function(ssl, remove_sess);
1773 gnutls_db_set_ptr(ssl, ctx);
1774
1775 if (ctx->verify)
1776 gnutls_certificate_server_set_request(ssl, GNUTLS_CERT_REQUIRE);
1777
1778 sock->ssl = ssl;
1779 gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr_t)(long)sock->fd);
1780 ret = gnutls_handshake(ssl);
1781 if (ret < 0) {
1782 return error_gnutls(sock, ret);
1783 }
1784 if (ctx->verify && (gnutls_certificate_verify_peers2(ssl, &verify_status) || verify_status)) {
1785 set_error(sock, _("Client certificate verification failed"));
1786 return NE_SOCK_ERROR;
1787 }
1788 #endif
1789 sock->ops = &iofns_ssl;
1790 return 0;
1791 }
1792
1793 int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata)
1794 {
1795 int ret;
1796
1797 #if defined(HAVE_OPENSSL)
1798 SSL *ssl;
1799
1800 if (seed_ssl_prng()) {
1801 set_error(sock, _("SSL disabled due to lack of entropy"));
1802 return NE_SOCK_ERROR;
1803 }
1804
1805 sock->ssl = ssl = SSL_new(ctx->ctx);
1806 if (!ssl) {
1807 set_error(sock, _("Could not create SSL structure"));
1808 return NE_SOCK_ERROR;
1809 }
1810
1811 SSL_set_app_data(ssl, userdata);
1812 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1813 SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
1814 #else
1815 SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY);
1816 #endif
1817 SSL_set_fd(ssl, sock->fd);
1818 sock->ops = &iofns_ssl;
1819
1820 #ifdef SSL_set_tlsext_host_name
1821 if (ctx->hostname) {
1822 /* Try to enable SNI, but ignore failure (should only fail for
1823 * >255 char hostnames, which are probably not legal
1824 * anyway). */
1825 if (SSL_set_tlsext_host_name(ssl, ctx->hostname) != 1) {
1826 ERR_clear_error();
1827 }
1828 }
1829 #endif
1830
1831 if (ctx->sess)
1832 SSL_set_session(ssl, ctx->sess);
1833
1834 ret = SSL_connect(ssl);
1835 if (ret != 1) {
1836 error_ossl(sock, ret);
1837 SSL_free(ssl);
1838 sock->ssl = NULL;
1839 return NE_SOCK_ERROR;
1840 }
1841 #elif defined(HAVE_GNUTLS)
1842 /* DH and RSA params are set in ne_ssl_context_create */
1843 gnutls_init(&sock->ssl, GNUTLS_CLIENT);
1844 gnutls_set_default_priority(sock->ssl);
1845 gnutls_session_set_ptr(sock->ssl, userdata);
1846 gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred);
1847
1848 if (ctx->hostname) {
1849 gnutls_server_name_set(sock->ssl, GNUTLS_NAME_DNS, ctx->hostname,
1850 strlen(ctx->hostname));
1851 }
1852
1853 gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr_t)(long)sock->fd);
1854
1855 if (ctx->cache.client.data) {
1856 #if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
1857 gnutls_session_set_data(sock->ssl,
1858 ctx->cache.client.data,
1859 ctx->cache.client.size);
1860 #else
1861 gnutls_session_set_data(sock->ssl,
1862 ctx->cache.client.data,
1863 ctx->cache.client.len);
1864 #endif
1865 }
1866 sock->ops = &iofns_ssl;
1867
1868 do {
1869 ret = gnutls_handshake(sock->ssl);
1870 } while (RETRY_GNUTLS(sock, ret));
1871 if (ret < 0) {
1872 error_gnutls(sock, ret);
1873 return NE_SOCK_ERROR;
1874 }
1875
1876 if (!gnutls_session_is_resumed(sock->ssl)) {
1877 /* New session. The old method of using the _get_data
1878 * function seems to be broken with 1.3.0 and later*/
1879 #if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
1880 gnutls_session_get_data2(sock->ssl, &ctx->cache.client);
1881 #else
1882 ctx->cache.client.len = 0;
1883 if (gnutls_session_get_data(sock->ssl, NULL,
1884 &ctx->cache.client.len) == 0) {
1885 ctx->cache.client.data = ne_malloc(ctx->cache.client.len);
1886 gnutls_session_get_data(sock->ssl, ctx->cache.client.data,
1887 &ctx->cache.client.len);
1888 }
1889 #endif
1890 }
1891 #endif
1892 return 0;
1893 }
1894
1895 ne_ssl_socket ne__sock_sslsock(ne_socket *sock)
1896 {
1897 return sock->ssl;
1898 }
1899
1900 #endif
1901
1902 int ne_sock_sessid(ne_socket *sock, unsigned char *buf, size_t *buflen)
1903 {
1904 #ifdef NE_HAVE_SSL
1905 #ifdef HAVE_GNUTLS
1906 if (sock->ssl) {
1907 return gnutls_session_get_id(sock->ssl, buf, buflen);
1908 } else {
1909 return -1;
1910 }
1911 #else
1912 SSL_SESSION *sess;
1913 const unsigned char *idbuf;
1914 unsigned int idlen;
1915
1916 if (!sock->ssl) {
1917 return -1;
1918 }
1919
1920 sess = SSL_get0_session(sock->ssl);
1921
1922 idbuf = SSL_SESSION_get_id(sess, &idlen);
1923 if (!buf) {
1924 *buflen = idlen;
1925 return 0;
1926 }
1927
1928 if (*buflen < idlen) {
1929 return -1;
1930 }
1931
1932 *buflen = idlen;
1933 memcpy(buf, idbuf, idlen);
1934 return 0;
1935 #endif
1936 #else
1937 return -1;
1938 #endif
1939 }
1940
1941 char *ne_sock_cipher(ne_socket *sock)
1942 {
1943 #ifdef NE_HAVE_SSL
1944 if (sock->ssl) {
1945 #ifdef HAVE_OPENSSL
1946 const char *name = SSL_get_cipher(sock->ssl);
1947 return ne_strdup(name);
1948 #elif defined(HAVE_GNUTLS)
1949 const char *name = gnutls_cipher_get_name(gnutls_cipher_get(sock->ssl));
1950 return ne_strdup(name);
1951 #endif
1952 }
1953 else
1954 #endif /* NE_HAVE_SSL */
1955 {
1956 return NULL;
1957 }
1958 }
1959
1960 const char *ne_sock_error(const ne_socket *sock)
1961 {
1962 return sock->error;
1963 }
1964
1965 void ne_sock_set_error(ne_socket *sock, const char *format, ...)
1966 {
1967 va_list params;
1968
1969 va_start(params, format);
1970 ne_vsnprintf(sock->error, sizeof sock->error, format, params);
1971 va_end(params);
1972 }
1973
1974 int ne_sock_close(ne_socket *sock)
1975 {
1976 int ret;
1977
1978 /* Per API description - for an SSL connection, simply send the
1979 * close_notify but do not wait for the peer's response. */
1980 #if defined(HAVE_OPENSSL)
1981 if (sock->ssl) {
1982 SSL_shutdown(sock->ssl);
1983 SSL_free(sock->ssl);
1984 }
1985 #elif defined(HAVE_GNUTLS)
1986 if (sock->ssl) {
1987 do {
1988 ret = gnutls_bye(sock->ssl, GNUTLS_SHUT_WR);
1989 } while (ret < 0
1990 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
1991 gnutls_deinit(sock->ssl);
1992 }
1993 #endif
1994
1995 if (sock->fd < 0)
1996 ret = 0;
1997 else
1998 ret = ne_close(sock->fd);
1999 ne_free(sock);
2000 return ret;
2001 }