Home | History | Annotate | Line # | Download | only in lib
s_socket.c revision 1.3
      1 /*
      2  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /* socket-related functions used by s_client and s_server */
     11 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include <errno.h>
     15 #include <signal.h>
     16 #include <openssl/opensslconf.h>
     17 
     18 /*
     19  * With IPv6, it looks like Digital has mixed up the proper order of
     20  * recursive header file inclusion, resulting in the compiler complaining
     21  * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
     22  * needed to have fileno() declared correctly...  So let's define u_int
     23  */
     24 #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
     25 # define __U_INT
     26 typedef unsigned int u_int;
     27 #endif
     28 
     29 #ifdef _WIN32
     30 # include <process.h>
     31 
     32 /* MSVC renamed some POSIX functions to have an underscore prefix. */
     33 # ifdef _MSC_VER
     34 #  define getpid _getpid
     35 # endif
     36 #endif
     37 
     38 #ifndef OPENSSL_NO_SOCK
     39 
     40 # include "apps.h"
     41 # include "s_apps.h"
     42 # include "internal/sockets.h"
     43 
     44 # if defined(__TANDEM)
     45 #  if defined(OPENSSL_TANDEM_FLOSS)
     46 #   include <floss.h(floss_read)>
     47 #  endif
     48 # endif
     49 
     50 # include <openssl/bio.h>
     51 # include <openssl/err.h>
     52 
     53 /* Keep track of our peer's address for the cookie callback */
     54 BIO_ADDR *ourpeer = NULL;
     55 
     56 /*
     57  * init_client - helper routine to set up socket communication
     58  * @sock: pointer to storage of resulting socket.
     59  * @host: the host name or path (for AF_UNIX) to connect to.
     60  * @port: the port to connect to (ignored for AF_UNIX).
     61  * @bindhost: source host or path (for AF_UNIX).
     62  * @bindport: source port (ignored for AF_UNIX).
     63  * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
     64  *  AF_UNSPEC
     65  * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
     66  * @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
     67  *
     68  * This will create a socket and use it to connect to a host:port, or if
     69  * family == AF_UNIX, to the path found in host.
     70  *
     71  * If the host has more than one address, it will try them one by one until
     72  * a successful connection is established.  The resulting socket will be
     73  * found in *sock on success, it will be given INVALID_SOCKET otherwise.
     74  *
     75  * Returns 1 on success, 0 on failure.
     76  */
     77 int init_client(int *sock, const char *host, const char *port,
     78                 const char *bindhost, const char *bindport,
     79                 int family, int type, int protocol)
     80 {
     81     BIO_ADDRINFO *res = NULL;
     82     BIO_ADDRINFO *bindaddr = NULL;
     83     const BIO_ADDRINFO *ai = NULL;
     84     const BIO_ADDRINFO *bi = NULL;
     85     int found = 0;
     86     int ret;
     87 
     88     if (BIO_sock_init() != 1)
     89         return 0;
     90 
     91     ret = BIO_lookup_ex(host, port, BIO_LOOKUP_CLIENT, family, type, protocol,
     92                         &res);
     93     if (ret == 0) {
     94         ERR_print_errors(bio_err);
     95         return 0;
     96     }
     97 
     98     if (bindhost != NULL || bindport != NULL) {
     99         ret = BIO_lookup_ex(bindhost, bindport, BIO_LOOKUP_CLIENT,
    100                             family, type, protocol, &bindaddr);
    101         if (ret == 0) {
    102             ERR_print_errors (bio_err);
    103             goto out;
    104         }
    105     }
    106 
    107     ret = 0;
    108     for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
    109         /* Admittedly, these checks are quite paranoid, we should not get
    110          * anything in the BIO_ADDRINFO chain that we haven't
    111          * asked for. */
    112         OPENSSL_assert((family == AF_UNSPEC
    113                         || family == BIO_ADDRINFO_family(ai))
    114                        && (type == 0 || type == BIO_ADDRINFO_socktype(ai))
    115                        && (protocol == 0
    116                            || protocol == BIO_ADDRINFO_protocol(ai)));
    117 
    118         if (bindaddr != NULL) {
    119             for (bi = bindaddr; bi != NULL; bi = BIO_ADDRINFO_next(bi)) {
    120                 if (BIO_ADDRINFO_family(bi) == BIO_ADDRINFO_family(ai))
    121                     break;
    122             }
    123             if (bi == NULL)
    124                 continue;
    125             ++found;
    126         }
    127 
    128         *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
    129                            BIO_ADDRINFO_protocol(ai), 0);
    130         if (*sock == INVALID_SOCKET) {
    131             /* Maybe the kernel doesn't support the socket family, even if
    132              * BIO_lookup() added it in the returned result...
    133              */
    134             continue;
    135         }
    136 
    137         if (bi != NULL) {
    138             if (!BIO_bind(*sock, BIO_ADDRINFO_address(bi),
    139                           BIO_SOCK_REUSEADDR)) {
    140                 BIO_closesocket(*sock);
    141                 *sock = INVALID_SOCKET;
    142                 break;
    143             }
    144         }
    145 
    146 #ifndef OPENSSL_NO_SCTP
    147         if (protocol == IPPROTO_SCTP) {
    148             /*
    149              * For SCTP we have to set various options on the socket prior to
    150              * connecting. This is done automatically by BIO_new_dgram_sctp().
    151              * We don't actually need the created BIO though so we free it again
    152              * immediately.
    153              */
    154             BIO *tmpbio = BIO_new_dgram_sctp(*sock, BIO_NOCLOSE);
    155 
    156             if (tmpbio == NULL) {
    157                 ERR_print_errors(bio_err);
    158                 return 0;
    159             }
    160             BIO_free(tmpbio);
    161         }
    162 #endif
    163 
    164         if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai),
    165                          BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) {
    166             BIO_closesocket(*sock);
    167             *sock = INVALID_SOCKET;
    168             continue;
    169         }
    170 
    171         /* Success, don't try any more addresses */
    172         break;
    173     }
    174 
    175     if (*sock == INVALID_SOCKET) {
    176         if (bindaddr != NULL && !found) {
    177             BIO_printf(bio_err, "Can't bind %saddress for %s%s%s\n",
    178 #ifdef AF_INET6
    179                        BIO_ADDRINFO_family(res) == AF_INET6 ? "IPv6 " :
    180 #endif
    181                        BIO_ADDRINFO_family(res) == AF_INET ? "IPv4 " :
    182                        BIO_ADDRINFO_family(res) == AF_UNIX ? "unix " : "",
    183                        bindhost != NULL ? bindhost : "",
    184                        bindport != NULL ? ":" : "",
    185                        bindport != NULL ? bindport : "");
    186             ERR_clear_error();
    187             ret = 0;
    188         }
    189         ERR_print_errors(bio_err);
    190     } else {
    191         /* Remove any stale errors from previous connection attempts */
    192         ERR_clear_error();
    193         ret = 1;
    194     }
    195 out:
    196     if (bindaddr != NULL) {
    197         BIO_ADDRINFO_free (bindaddr);
    198     }
    199     BIO_ADDRINFO_free(res);
    200     return ret;
    201 }
    202 
    203 int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
    204 {
    205     int success = 1;
    206 
    207     if (BIO_printf(out, "ACCEPT") <= 0)
    208         return 0;
    209     if (with_address) {
    210         union BIO_sock_info_u info;
    211         char *hostname = NULL;
    212         char *service = NULL;
    213 
    214         if ((info.addr = BIO_ADDR_new()) != NULL
    215             && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)
    216             && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL
    217             && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) {
    218             success = BIO_printf(out,
    219                                  strchr(hostname, ':') == NULL
    220                                  ? /* IPv4 */ " %s:%s"
    221                                  : /* IPv6 */ " [%s]:%s",
    222                                  hostname, service) > 0;
    223         } else {
    224             (void)BIO_printf(out, "unknown:error\n");
    225             success = 0;
    226         }
    227         OPENSSL_free(hostname);
    228         OPENSSL_free(service);
    229         BIO_ADDR_free(info.addr);
    230     }
    231     if (with_pid)
    232         success = success && BIO_printf(out, " PID=%d", getpid()) > 0;
    233     success = success && BIO_printf(out, "\n") > 0;
    234     (void)BIO_flush(out);
    235 
    236     return success;
    237 }
    238 
    239 /*
    240  * do_server - helper routine to perform a server operation
    241  * @accept_sock: pointer to storage of resulting socket.
    242  * @host: the host name or path (for AF_UNIX) to connect to.
    243  * @port: the port to connect to (ignored for AF_UNIX).
    244  * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
    245  *  AF_UNSPEC
    246  * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
    247  * @cb: pointer to a function that receives the accepted socket and
    248  *  should perform the communication with the connecting client.
    249  * @context: pointer to memory that's passed verbatim to the cb function.
    250  * @naccept: number of times an incoming connect should be accepted.  If -1,
    251  *  unlimited number.
    252  *
    253  * This will create a socket and use it to listen to a host:port, or if
    254  * family == AF_UNIX, to the path found in host, then start accepting
    255  * incoming connections and run cb on the resulting socket.
    256  *
    257  * 0 on failure, something other on success.
    258  */
    259 int do_server(int *accept_sock, const char *host, const char *port,
    260               int family, int type, int protocol, do_server_cb cb,
    261               unsigned char *context, int naccept, BIO *bio_s_out)
    262 {
    263     int asock = 0;
    264     int sock;
    265     int i;
    266     BIO_ADDRINFO *res = NULL;
    267     const BIO_ADDRINFO *next;
    268     int sock_family, sock_type, sock_protocol, sock_port;
    269     const BIO_ADDR *sock_address;
    270     int sock_family_fallback = AF_UNSPEC;
    271     const BIO_ADDR *sock_address_fallback = NULL;
    272     int sock_options = BIO_SOCK_REUSEADDR;
    273     int ret = 0;
    274 
    275     if (BIO_sock_init() != 1)
    276         return 0;
    277 
    278     if (!BIO_lookup_ex(host, port, BIO_LOOKUP_SERVER, family, type, protocol,
    279                        &res)) {
    280         ERR_print_errors(bio_err);
    281         return 0;
    282     }
    283 
    284     /* Admittedly, these checks are quite paranoid, we should not get
    285      * anything in the BIO_ADDRINFO chain that we haven't asked for */
    286     OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
    287                    && (type == 0 || type == BIO_ADDRINFO_socktype(res))
    288                    && (protocol == 0 || protocol == BIO_ADDRINFO_protocol(res)));
    289 
    290     sock_family = BIO_ADDRINFO_family(res);
    291     sock_type = BIO_ADDRINFO_socktype(res);
    292     sock_protocol = BIO_ADDRINFO_protocol(res);
    293     sock_address = BIO_ADDRINFO_address(res);
    294     next = BIO_ADDRINFO_next(res);
    295 #ifdef AF_INET6
    296     if (sock_family == AF_INET6)
    297         sock_options |= BIO_SOCK_V6_ONLY;
    298     if (next != NULL
    299             && BIO_ADDRINFO_socktype(next) == sock_type
    300             && BIO_ADDRINFO_protocol(next) == sock_protocol) {
    301         if (sock_family == AF_INET
    302                 && BIO_ADDRINFO_family(next) == AF_INET6) {
    303             /* In case AF_INET6 is returned but not supported by the
    304              * kernel, retry with the first detected address family */
    305             sock_family_fallback = sock_family;
    306             sock_address_fallback = sock_address;
    307             sock_family = AF_INET6;
    308             sock_address = BIO_ADDRINFO_address(next);
    309         } else if (sock_family == AF_INET6
    310                    && BIO_ADDRINFO_family(next) == AF_INET) {
    311             sock_options &= ~BIO_SOCK_V6_ONLY;
    312         }
    313     }
    314 #endif
    315 
    316     asock = BIO_socket(sock_family, sock_type, sock_protocol, 0);
    317     if (asock == INVALID_SOCKET && sock_family_fallback != AF_UNSPEC) {
    318         asock = BIO_socket(sock_family_fallback, sock_type, sock_protocol, 0);
    319         sock_address = sock_address_fallback;
    320     }
    321     if (asock == INVALID_SOCKET
    322         || !BIO_listen(asock, sock_address, sock_options)) {
    323         BIO_ADDRINFO_free(res);
    324         ERR_print_errors(bio_err);
    325         if (asock != INVALID_SOCKET)
    326             BIO_closesocket(asock);
    327         goto end;
    328     }
    329 
    330 #ifndef OPENSSL_NO_SCTP
    331     if (protocol == IPPROTO_SCTP) {
    332         /*
    333          * For SCTP we have to set various options on the socket prior to
    334          * accepting. This is done automatically by BIO_new_dgram_sctp().
    335          * We don't actually need the created BIO though so we free it again
    336          * immediately.
    337          */
    338         BIO *tmpbio = BIO_new_dgram_sctp(asock, BIO_NOCLOSE);
    339 
    340         if (tmpbio == NULL) {
    341             BIO_closesocket(asock);
    342             ERR_print_errors(bio_err);
    343             goto end;
    344         }
    345         BIO_free(tmpbio);
    346     }
    347 #endif
    348 
    349     sock_port = BIO_ADDR_rawport(sock_address);
    350 
    351     BIO_ADDRINFO_free(res);
    352     res = NULL;
    353 
    354     if (!report_server_accept(bio_s_out, asock, sock_port == 0, 0)) {
    355         BIO_closesocket(asock);
    356         ERR_print_errors(bio_err);
    357         goto end;
    358     }
    359 
    360     if (accept_sock != NULL)
    361         *accept_sock = asock;
    362     for (;;) {
    363         char sink[64];
    364         struct timeval timeout;
    365         fd_set readfds;
    366 
    367         if (type == SOCK_STREAM) {
    368             BIO_ADDR_free(ourpeer);
    369             ourpeer = BIO_ADDR_new();
    370             if (ourpeer == NULL) {
    371                 BIO_closesocket(asock);
    372                 ERR_print_errors(bio_err);
    373                 goto end;
    374             }
    375             do {
    376                 sock = BIO_accept_ex(asock, ourpeer, 0);
    377             } while (sock < 0 && BIO_sock_should_retry(sock));
    378             if (sock < 0) {
    379                 ERR_print_errors(bio_err);
    380                 BIO_closesocket(asock);
    381                 break;
    382             }
    383 
    384             if (naccept != -1)
    385                 naccept--;
    386             if (naccept == 0)
    387                 BIO_closesocket(asock);
    388 
    389             BIO_set_tcp_ndelay(sock, 1);
    390             i = (*cb)(sock, type, protocol, context);
    391 
    392             /*
    393              * If we ended with an alert being sent, but still with data in the
    394              * network buffer to be read, then calling BIO_closesocket() will
    395              * result in a TCP-RST being sent. On some platforms (notably
    396              * Windows) then this will result in the peer immediately abandoning
    397              * the connection including any buffered alert data before it has
    398              * had a chance to be read. Shutting down the sending side first,
    399              * and then closing the socket sends TCP-FIN first followed by
    400              * TCP-RST. This seems to allow the peer to read the alert data.
    401              */
    402             shutdown(sock, 1); /* SHUT_WR */
    403             /*
    404              * We just said we have nothing else to say, but it doesn't mean
    405              * that the other side has nothing. It's even recommended to
    406              * consume incoming data. [In testing context this ensures that
    407              * alerts are passed on...]
    408              */
    409             timeout.tv_sec = 0;
    410             timeout.tv_usec = 500000;  /* some extreme round-trip */
    411             do {
    412                 FD_ZERO(&readfds);
    413                 openssl_fdset(sock, &readfds);
    414             } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
    415                      && readsocket(sock, sink, sizeof(sink)) > 0);
    416 
    417             BIO_closesocket(sock);
    418         } else {
    419             if (naccept != -1)
    420                 naccept--;
    421 
    422             i = (*cb)(asock, type, protocol, context);
    423         }
    424 
    425         if (i < 0 || naccept == 0) {
    426             BIO_closesocket(asock);
    427             ret = i;
    428             break;
    429         }
    430     }
    431  end:
    432 # ifdef AF_UNIX
    433     if (family == AF_UNIX)
    434         unlink(host);
    435 # endif
    436     BIO_ADDR_free(ourpeer);
    437     ourpeer = NULL;
    438     return ret;
    439 }
    440 
    441 void do_ssl_shutdown(SSL *ssl)
    442 {
    443     int ret;
    444 
    445     do {
    446         /* We only do unidirectional shutdown */
    447         ret = SSL_shutdown(ssl);
    448         if (ret < 0) {
    449             switch (SSL_get_error(ssl, ret)) {
    450             case SSL_ERROR_WANT_READ:
    451             case SSL_ERROR_WANT_WRITE:
    452             case SSL_ERROR_WANT_ASYNC:
    453             case SSL_ERROR_WANT_ASYNC_JOB:
    454                 /* We just do busy waiting. Nothing clever */
    455                 continue;
    456             }
    457             ret = 0;
    458         }
    459     } while (ret < 0);
    460 }
    461 
    462 #endif  /* OPENSSL_NO_SOCK */
    463