"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 }