Coverage Report

Created: 2022-10-16 06:45

/src/openssl/crypto/bio/b_sock.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/bio/b_sock.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <stdio.h>
60
#include <stdlib.h>
61
#include <errno.h>
62
#define USE_SOCKETS
63
#include "cryptlib.h"
64
#include <openssl/bio.h>
65
#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
66
# include <netdb.h>
67
# if defined(NETWARE_CLIB)
68
#  include <sys/ioctl.h>
69
NETDB_DEFINE_CONTEXT
70
# endif
71
#endif
72
#ifndef OPENSSL_NO_SOCK
73
# include <openssl/dso.h>
74
0
# define SOCKET_PROTOCOL IPPROTO_TCP
75
# ifdef SO_MAXCONN
76
#  define MAX_LISTEN  SO_MAXCONN
77
# elif defined(SOMAXCONN)
78
0
#  define MAX_LISTEN  SOMAXCONN
79
# else
80
#  define MAX_LISTEN  32
81
# endif
82
# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
83
static int wsa_init_done = 0;
84
# endif
85
86
/*
87
 * WSAAPI specifier is required to make indirect calls to run-time
88
 * linked WinSock 2 functions used in this module, to be specific
89
 * [get|free]addrinfo and getnameinfo. This is because WinSock uses
90
 * uses non-C calling convention, __stdcall vs. __cdecl, on x86
91
 * Windows. On non-WinSock platforms WSAAPI needs to be void.
92
 */
93
# ifndef WSAAPI
94
#  define WSAAPI
95
# endif
96
97
# if 0
98
static unsigned long BIO_ghbn_hits = 0L;
99
static unsigned long BIO_ghbn_miss = 0L;
100
101
#  define GHBN_NUM        4
102
static struct ghbn_cache_st {
103
    char name[129];
104
    struct hostent *ent;
105
    unsigned long order;
106
} ghbn_cache[GHBN_NUM];
107
# endif
108
109
static int get_ip(const char *str, unsigned char *ip);
110
# if 0
111
static void ghbn_free(struct hostent *a);
112
static struct hostent *ghbn_dup(struct hostent *a);
113
# endif
114
int BIO_get_host_ip(const char *str, unsigned char *ip)
115
0
{
116
0
    int i;
117
0
    int err = 1;
118
0
    int locked = 0;
119
0
    struct hostent *he;
120
121
0
    i = get_ip(str, ip);
122
0
    if (i < 0) {
123
0
        BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS);
124
0
        goto err;
125
0
    }
126
127
    /*
128
     * At this point, we have something that is most probably correct in some
129
     * way, so let's init the socket.
130
     */
131
0
    if (BIO_sock_init() != 1)
132
0
        return 0;               /* don't generate another error code here */
133
134
    /*
135
     * If the string actually contained an IP address, we need not do
136
     * anything more
137
     */
138
0
    if (i > 0)
139
0
        return (1);
140
141
    /* do a gethostbyname */
142
0
    CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
143
0
    locked = 1;
144
0
    he = BIO_gethostbyname(str);
145
0
    if (he == NULL) {
146
0
        BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
147
0
        goto err;
148
0
    }
149
150
    /* cast to short because of win16 winsock definition */
151
0
    if ((short)he->h_addrtype != AF_INET) {
152
0
        BIOerr(BIO_F_BIO_GET_HOST_IP,
153
0
               BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
154
0
        goto err;
155
0
    }
156
0
    for (i = 0; i < 4; i++)
157
0
        ip[i] = he->h_addr_list[0][i];
158
0
    err = 0;
159
160
0
 err:
161
0
    if (locked)
162
0
        CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
163
0
    if (err) {
164
0
        ERR_add_error_data(2, "host=", str);
165
0
        return 0;
166
0
    } else
167
0
        return 1;
168
0
}
169
170
int BIO_get_port(const char *str, unsigned short *port_ptr)
171
0
{
172
0
    int i;
173
0
    struct servent *s;
174
175
0
    if (str == NULL) {
176
0
        BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
177
0
        return (0);
178
0
    }
179
0
    i = atoi(str);
180
0
    if (i != 0)
181
0
        *port_ptr = (unsigned short)i;
182
0
    else {
183
0
        CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
184
        /*
185
         * Note: under VMS with SOCKETSHR, it seems like the first parameter
186
         * is 'char *', instead of 'const char *'
187
         */
188
0
# ifndef CONST_STRICT
189
0
        s = getservbyname((char *)str, "tcp");
190
# else
191
        s = getservbyname(str, "tcp");
192
# endif
193
0
        if (s != NULL)
194
0
            *port_ptr = ntohs((unsigned short)s->s_port);
195
0
        CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
196
0
        if (s == NULL) {
197
0
            if (strcmp(str, "http") == 0)
198
0
                *port_ptr = 80;
199
0
            else if (strcmp(str, "telnet") == 0)
200
0
                *port_ptr = 23;
201
0
            else if (strcmp(str, "socks") == 0)
202
0
                *port_ptr = 1080;
203
0
            else if (strcmp(str, "https") == 0)
204
0
                *port_ptr = 443;
205
0
            else if (strcmp(str, "ssl") == 0)
206
0
                *port_ptr = 443;
207
0
            else if (strcmp(str, "ftp") == 0)
208
0
                *port_ptr = 21;
209
0
            else if (strcmp(str, "gopher") == 0)
210
0
                *port_ptr = 70;
211
# if 0
212
            else if (strcmp(str, "wais") == 0)
213
                *port_ptr = 21;
214
# endif
215
0
            else {
216
0
                SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error());
217
0
                ERR_add_error_data(3, "service='", str, "'");
218
0
                return (0);
219
0
            }
220
0
        }
221
0
    }
222
0
    return (1);
223
0
}
224
225
int BIO_sock_error(int sock)
226
0
{
227
0
    int j, i;
228
0
    union {
229
0
        size_t s;
230
0
        int i;
231
0
    } size;
232
233
# if defined(OPENSSL_SYS_BEOS_R5)
234
    return 0;
235
# endif
236
237
    /* heuristic way to adapt for platforms that expect 64-bit optlen */
238
0
    size.s = 0, size.i = sizeof(j);
239
    /*
240
     * Note: under Windows the third parameter is of type (char *) whereas
241
     * under other systems it is (void *) if you don't have a cast it will
242
     * choke the compiler: if you do have a cast then you can either go for
243
     * (char *) or (void *).
244
     */
245
0
    i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size);
246
0
    if (i < 0)
247
0
        return (1);
248
0
    else
249
0
        return (j);
250
0
}
251
252
# if 0
253
long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
254
{
255
    int i;
256
    char **p;
257
258
    switch (cmd) {
259
    case BIO_GHBN_CTRL_HITS:
260
        return (BIO_ghbn_hits);
261
        /* break; */
262
    case BIO_GHBN_CTRL_MISSES:
263
        return (BIO_ghbn_miss);
264
        /* break; */
265
    case BIO_GHBN_CTRL_CACHE_SIZE:
266
        return (GHBN_NUM);
267
        /* break; */
268
    case BIO_GHBN_CTRL_GET_ENTRY:
269
        if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) {
270
            p = (char **)parg;
271
            if (p == NULL)
272
                return (0);
273
            *p = ghbn_cache[iarg].name;
274
            ghbn_cache[iarg].name[128] = '\0';
275
            return (1);
276
        }
277
        return (0);
278
        /* break; */
279
    case BIO_GHBN_CTRL_FLUSH:
280
        for (i = 0; i < GHBN_NUM; i++)
281
            ghbn_cache[i].order = 0;
282
        break;
283
    default:
284
        return (0);
285
    }
286
    return (1);
287
}
288
# endif
289
290
# if 0
291
static struct hostent *ghbn_dup(struct hostent *a)
292
{
293
    struct hostent *ret;
294
    int i, j;
295
296
    MemCheck_off();
297
    ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
298
    if (ret == NULL)
299
        return (NULL);
300
    memset(ret, 0, sizeof(struct hostent));
301
302
    for (i = 0; a->h_aliases[i] != NULL; i++) ;
303
    i++;
304
    ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *));
305
    if (ret->h_aliases == NULL)
306
        goto err;
307
    memset(ret->h_aliases, 0, i * sizeof(char *));
308
309
    for (i = 0; a->h_addr_list[i] != NULL; i++) ;
310
    i++;
311
    ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *));
312
    if (ret->h_addr_list == NULL)
313
        goto err;
314
    memset(ret->h_addr_list, 0, i * sizeof(char *));
315
316
    j = strlen(a->h_name) + 1;
317
    if ((ret->h_name = OPENSSL_malloc(j)) == NULL)
318
        goto err;
319
    memcpy((char *)ret->h_name, a->h_name, j);
320
    for (i = 0; a->h_aliases[i] != NULL; i++) {
321
        j = strlen(a->h_aliases[i]) + 1;
322
        if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL)
323
            goto err;
324
        memcpy(ret->h_aliases[i], a->h_aliases[i], j);
325
    }
326
    ret->h_length = a->h_length;
327
    ret->h_addrtype = a->h_addrtype;
328
    for (i = 0; a->h_addr_list[i] != NULL; i++) {
329
        if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL)
330
            goto err;
331
        memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length);
332
    }
333
    if (0) {
334
 err:
335
        if (ret != NULL)
336
            ghbn_free(ret);
337
        ret = NULL;
338
    }
339
    MemCheck_on();
340
    return (ret);
341
}
342
343
static void ghbn_free(struct hostent *a)
344
{
345
    int i;
346
347
    if (a == NULL)
348
        return;
349
350
    if (a->h_aliases != NULL) {
351
        for (i = 0; a->h_aliases[i] != NULL; i++)
352
            OPENSSL_free(a->h_aliases[i]);
353
        OPENSSL_free(a->h_aliases);
354
    }
355
    if (a->h_addr_list != NULL) {
356
        for (i = 0; a->h_addr_list[i] != NULL; i++)
357
            OPENSSL_free(a->h_addr_list[i]);
358
        OPENSSL_free(a->h_addr_list);
359
    }
360
    if (a->h_name != NULL)
361
        OPENSSL_free(a->h_name);
362
    OPENSSL_free(a);
363
}
364
365
# endif
366
367
struct hostent *BIO_gethostbyname(const char *name)
368
0
{
369
0
# if 1
370
    /*
371
     * Caching gethostbyname() results forever is wrong, so we have to let
372
     * the true gethostbyname() worry about this
373
     */
374
#  if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
375
    return gethostbyname((char *)name);
376
#  else
377
0
    return gethostbyname(name);
378
0
#  endif
379
# else
380
    struct hostent *ret;
381
    int i, lowi = 0, j;
382
    unsigned long low = (unsigned long)-1;
383
384
#  if 0
385
    /*
386
     * It doesn't make sense to use locking here: The function interface is
387
     * not thread-safe, because threads can never be sure when some other
388
     * thread destroys the data they were given a pointer to.
389
     */
390
    CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
391
#  endif
392
    j = strlen(name);
393
    if (j < 128) {
394
        for (i = 0; i < GHBN_NUM; i++) {
395
            if (low > ghbn_cache[i].order) {
396
                low = ghbn_cache[i].order;
397
                lowi = i;
398
            }
399
            if (ghbn_cache[i].order > 0) {
400
                if (strncmp(name, ghbn_cache[i].name, 128) == 0)
401
                    break;
402
            }
403
        }
404
    } else
405
        i = GHBN_NUM;
406
407
    if (i == GHBN_NUM) {        /* no hit */
408
        BIO_ghbn_miss++;
409
        /*
410
         * Note: under VMS with SOCKETSHR, it seems like the first parameter
411
         * is 'char *', instead of 'const char *'
412
         */
413
#  ifndef CONST_STRICT
414
        ret = gethostbyname((char *)name);
415
#  else
416
        ret = gethostbyname(name);
417
#  endif
418
419
        if (ret == NULL)
420
            goto end;
421
        if (j > 128) {          /* too big to cache */
422
#  if 0
423
            /*
424
             * If we were trying to make this function thread-safe (which is
425
             * bound to fail), we'd have to give up in this case (or allocate
426
             * more memory).
427
             */
428
            ret = NULL;
429
#  endif
430
            goto end;
431
        }
432
433
        /* else add to cache */
434
        if (ghbn_cache[lowi].ent != NULL)
435
            ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
436
        ghbn_cache[lowi].name[0] = '\0';
437
438
        if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) {
439
            BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE);
440
            goto end;
441
        }
442
        strncpy(ghbn_cache[lowi].name, name, 128);
443
        ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits;
444
    } else {
445
        BIO_ghbn_hits++;
446
        ret = ghbn_cache[i].ent;
447
        ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits;
448
    }
449
 end:
450
#  if 0
451
    CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
452
#  endif
453
    return (ret);
454
# endif
455
0
}
456
457
int BIO_sock_init(void)
458
0
{
459
# ifdef OPENSSL_SYS_WINDOWS
460
    static struct WSAData wsa_state;
461
462
    if (!wsa_init_done) {
463
        int err;
464
465
        wsa_init_done = 1;
466
        memset(&wsa_state, 0, sizeof(wsa_state));
467
        /*
468
         * Not making wsa_state available to the rest of the code is formally
469
         * wrong. But the structures we use are [beleived to be] invariable
470
         * among Winsock DLLs, while API availability is [expected to be]
471
         * probed at run-time with DSO_global_lookup.
472
         */
473
        if (WSAStartup(0x0202, &wsa_state) != 0) {
474
            err = WSAGetLastError();
475
            SYSerr(SYS_F_WSASTARTUP, err);
476
            BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
477
            return (-1);
478
        }
479
    }
480
# endif                         /* OPENSSL_SYS_WINDOWS */
481
# ifdef WATT32
482
    extern int _watt_do_exit;
483
    _watt_do_exit = 0;          /* don't make sock_init() call exit() */
484
    if (sock_init())
485
        return (-1);
486
# endif
487
488
# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
489
    WORD wVerReq;
490
    WSADATA wsaData;
491
    int err;
492
493
    if (!wsa_init_done) {
494
        wsa_init_done = 1;
495
        wVerReq = MAKEWORD(2, 0);
496
        err = WSAStartup(wVerReq, &wsaData);
497
        if (err != 0) {
498
            SYSerr(SYS_F_WSASTARTUP, err);
499
            BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
500
            return (-1);
501
        }
502
    }
503
# endif
504
505
0
    return (1);
506
0
}
507
508
void BIO_sock_cleanup(void)
509
0
{
510
# ifdef OPENSSL_SYS_WINDOWS
511
    if (wsa_init_done) {
512
        wsa_init_done = 0;
513
#  if 0                         /* this call is claimed to be non-present in
514
                                 * Winsock2 */
515
        WSACancelBlockingCall();
516
#  endif
517
        WSACleanup();
518
    }
519
# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
520
    if (wsa_init_done) {
521
        wsa_init_done = 0;
522
        WSACleanup();
523
    }
524
# endif
525
0
}
526
527
# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
528
529
int BIO_socket_ioctl(int fd, long type, void *arg)
530
0
{
531
0
    int i;
532
533
#  ifdef __DJGPP__
534
    i = ioctlsocket(fd, type, (char *)arg);
535
#  else
536
#   if defined(OPENSSL_SYS_VMS)
537
    /*-
538
     * 2011-02-18 SMS.
539
     * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
540
     * observe that all the consumers pass in an "unsigned long *",
541
     * so we arrange a local copy with a short pointer, and use
542
     * that, instead.
543
     */
544
#    if __INITIAL_POINTER_SIZE == 64
545
#     define ARG arg_32p
546
#     pragma pointer_size save
547
#     pragma pointer_size 32
548
    unsigned long arg_32;
549
    unsigned long *arg_32p;
550
#     pragma pointer_size restore
551
    arg_32p = &arg_32;
552
    arg_32 = *((unsigned long *)arg);
553
#    else                       /* __INITIAL_POINTER_SIZE == 64 */
554
#     define ARG arg
555
#    endif                      /* __INITIAL_POINTER_SIZE == 64 [else] */
556
#   else                        /* defined(OPENSSL_SYS_VMS) */
557
0
#    define ARG arg
558
0
#   endif                       /* defined(OPENSSL_SYS_VMS) [else] */
559
560
0
    i = ioctlsocket(fd, type, ARG);
561
0
#  endif                        /* __DJGPP__ */
562
0
    if (i < 0)
563
0
        SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
564
0
    return (i);
565
0
}
566
# endif                         /* __VMS_VER */
567
568
/*
569
 * The reason I have implemented this instead of using sscanf is because
570
 * Visual C 1.52c gives an unresolved external when linking a DLL :-(
571
 */
572
static int get_ip(const char *str, unsigned char ip[4])
573
0
{
574
0
    unsigned int tmp[4];
575
0
    int num = 0, c, ok = 0;
576
577
0
    tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
578
579
0
    for (;;) {
580
0
        c = *(str++);
581
0
        if ((c >= '0') && (c <= '9')) {
582
0
            ok = 1;
583
0
            tmp[num] = tmp[num] * 10 + c - '0';
584
0
            if (tmp[num] > 255)
585
0
                return (0);
586
0
        } else if (c == '.') {
587
0
            if (!ok)
588
0
                return (-1);
589
0
            if (num == 3)
590
0
                return (0);
591
0
            num++;
592
0
            ok = 0;
593
0
        } else if (c == '\0' && (num == 3) && ok)
594
0
            break;
595
0
        else
596
0
            return (0);
597
0
    }
598
0
    ip[0] = tmp[0];
599
0
    ip[1] = tmp[1];
600
0
    ip[2] = tmp[2];
601
0
    ip[3] = tmp[3];
602
0
    return (1);
603
0
}
604
605
int BIO_get_accept_socket(char *host, int bind_mode)
606
0
{
607
0
    int ret = 0;
608
0
    union {
609
0
        struct sockaddr sa;
610
0
        struct sockaddr_in sa_in;
611
0
# if OPENSSL_USE_IPV6
612
0
        struct sockaddr_in6 sa_in6;
613
0
# endif
614
0
    } server, client;
615
0
    int s = INVALID_SOCKET, cs, addrlen;
616
0
    unsigned char ip[4];
617
0
    unsigned short port;
618
0
    char *str = NULL, *e;
619
0
    char *h, *p;
620
0
    unsigned long l;
621
0
    int err_num;
622
623
0
    if (BIO_sock_init() != 1)
624
0
        return (INVALID_SOCKET);
625
626
0
    if ((str = BUF_strdup(host)) == NULL)
627
0
        return (INVALID_SOCKET);
628
629
0
    h = p = NULL;
630
0
    h = str;
631
0
    for (e = str; *e; e++) {
632
0
        if (*e == ':') {
633
0
            p = e;
634
0
        } else if (*e == '/') {
635
0
            *e = '\0';
636
0
            break;
637
0
        }
638
0
    }
639
0
    if (p)
640
0
        *p++ = '\0';            /* points at last ':', '::port' is special
641
                                 * [see below] */
642
0
    else
643
0
        p = h, h = NULL;
644
645
0
# ifdef EAI_FAMILY
646
0
    do {
647
0
        static union {
648
0
            void *p;
649
0
            int (WSAAPI *f) (const char *, const char *,
650
0
                             const struct addrinfo *, struct addrinfo **);
651
0
        } p_getaddrinfo = {
652
0
            NULL
653
0
        };
654
0
        static union {
655
0
            void *p;
656
0
            void (WSAAPI *f) (struct addrinfo *);
657
0
        } p_freeaddrinfo = {
658
0
            NULL
659
0
        };
660
0
        struct addrinfo *res, hint;
661
662
0
        if (p_getaddrinfo.p == NULL) {
663
0
            if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL
664
0
                || (p_freeaddrinfo.p =
665
0
                    DSO_global_lookup("freeaddrinfo")) == NULL)
666
0
                p_getaddrinfo.p = (void *)-1;
667
0
        }
668
0
        if (p_getaddrinfo.p == (void *)-1)
669
0
            break;
670
671
        /*
672
         * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris,
673
         * default to IPv6 without any hint. Also note that commonly IPv6
674
         * wildchard socket can service IPv4 connections just as well...
675
         */
676
0
        memset(&hint, 0, sizeof(hint));
677
0
        hint.ai_flags = AI_PASSIVE;
678
0
        if (h) {
679
0
            if (strchr(h, ':')) {
680
0
                if (h[1] == '\0')
681
0
                    h = NULL;
682
0
#  if OPENSSL_USE_IPV6
683
0
                hint.ai_family = AF_INET6;
684
#  else
685
                h = NULL;
686
#  endif
687
0
            } else if (h[0] == '*' && h[1] == '\0') {
688
0
                hint.ai_family = AF_INET;
689
0
                h = NULL;
690
0
            }
691
0
        }
692
693
0
        if ((*p_getaddrinfo.f) (h, p, &hint, &res))
694
0
            break;
695
696
0
        addrlen = res->ai_addrlen <= sizeof(server) ?
697
0
            res->ai_addrlen : sizeof(server);
698
0
        memcpy(&server, res->ai_addr, addrlen);
699
700
0
        (*p_freeaddrinfo.f) (res);
701
0
        goto again;
702
0
    } while (0);
703
0
# endif
704
705
0
    if (!BIO_get_port(p, &port))
706
0
        goto err;
707
708
0
    memset((char *)&server, 0, sizeof(server));
709
0
    server.sa_in.sin_family = AF_INET;
710
0
    server.sa_in.sin_port = htons(port);
711
0
    addrlen = sizeof(server.sa_in);
712
713
0
    if (h == NULL || strcmp(h, "*") == 0)
714
0
        server.sa_in.sin_addr.s_addr = INADDR_ANY;
715
0
    else {
716
0
        if (!BIO_get_host_ip(h, &(ip[0])))
717
0
            goto err;
718
0
        l = (unsigned long)
719
0
            ((unsigned long)ip[0] << 24L) |
720
0
            ((unsigned long)ip[1] << 16L) |
721
0
            ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
722
0
        server.sa_in.sin_addr.s_addr = htonl(l);
723
0
    }
724
725
0
 again:
726
0
    s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
727
0
    if (s == INVALID_SOCKET) {
728
0
        SYSerr(SYS_F_SOCKET, get_last_socket_error());
729
0
        ERR_add_error_data(3, "port='", host, "'");
730
0
        BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
731
0
        goto err;
732
0
    }
733
0
# ifdef SO_REUSEADDR
734
0
    if (bind_mode == BIO_BIND_REUSEADDR) {
735
0
        int i = 1;
736
737
0
        ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
738
0
        bind_mode = BIO_BIND_NORMAL;
739
0
    }
740
0
# endif
741
0
    if (bind(s, &server.sa, addrlen) == -1) {
742
0
# ifdef SO_REUSEADDR
743
0
        err_num = get_last_socket_error();
744
0
        if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
745
#  ifdef OPENSSL_SYS_WINDOWS
746
            /*
747
             * Some versions of Windows define EADDRINUSE to a dummy value.
748
             */
749
            (err_num == WSAEADDRINUSE))
750
#  else
751
0
            (err_num == EADDRINUSE))
752
0
#  endif
753
0
        {
754
0
            client = server;
755
0
            if (h == NULL || strcmp(h, "*") == 0) {
756
0
#  if OPENSSL_USE_IPV6
757
0
                if (client.sa.sa_family == AF_INET6) {
758
0
                    memset(&client.sa_in6.sin6_addr, 0,
759
0
                           sizeof(client.sa_in6.sin6_addr));
760
0
                    client.sa_in6.sin6_addr.s6_addr[15] = 1;
761
0
                } else
762
0
#  endif
763
0
                if (client.sa.sa_family == AF_INET) {
764
0
                    client.sa_in.sin_addr.s_addr = htonl(0x7F000001);
765
0
                } else
766
0
                    goto err;
767
0
            }
768
0
            cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
769
0
            if (cs != INVALID_SOCKET) {
770
0
                int ii;
771
0
                ii = connect(cs, &client.sa, addrlen);
772
0
                closesocket(cs);
773
0
                if (ii == INVALID_SOCKET) {
774
0
                    bind_mode = BIO_BIND_REUSEADDR;
775
0
                    closesocket(s);
776
0
                    goto again;
777
0
                }
778
                /* else error */
779
0
            }
780
            /* else error */
781
0
        }
782
0
# endif
783
0
        SYSerr(SYS_F_BIND, err_num);
784
0
        ERR_add_error_data(3, "port='", host, "'");
785
0
        BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
786
0
        goto err;
787
0
    }
788
0
    if (listen(s, MAX_LISTEN) == -1) {
789
0
        SYSerr(SYS_F_BIND, get_last_socket_error());
790
0
        ERR_add_error_data(3, "port='", host, "'");
791
0
        BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
792
0
        goto err;
793
0
    }
794
0
    ret = 1;
795
0
 err:
796
0
    if (str != NULL)
797
0
        OPENSSL_free(str);
798
0
    if ((ret == 0) && (s != INVALID_SOCKET)) {
799
0
        closesocket(s);
800
0
        s = INVALID_SOCKET;
801
0
    }
802
0
    return (s);
803
0
}
804
805
int BIO_accept(int sock, char **addr)
806
0
{
807
0
    int ret = INVALID_SOCKET;
808
0
    unsigned long l;
809
0
    unsigned short port;
810
0
    char *p;
811
812
0
    struct {
813
        /*
814
         * As for following union. Trouble is that there are platforms
815
         * that have socklen_t and there are platforms that don't, on
816
         * some platforms socklen_t is int and on some size_t. So what
817
         * one can do? One can cook #ifdef spaghetti, which is nothing
818
         * but masochistic. Or one can do union between int and size_t.
819
         * One naturally does it primarily for 64-bit platforms where
820
         * sizeof(int) != sizeof(size_t). But would it work? Note that
821
         * if size_t member is initialized to 0, then later int member
822
         * assignment naturally does the job on little-endian platforms
823
         * regardless accept's expectations! What about big-endians?
824
         * If accept expects int*, then it works, and if size_t*, then
825
         * length value would appear as unreasonably large. But this
826
         * won't prevent it from filling in the address structure. The
827
         * trouble of course would be if accept returns more data than
828
         * actual buffer can accomodate and overwrite stack... That's
829
         * where early OPENSSL_assert comes into picture. Besides, the
830
         * only 64-bit big-endian platform found so far that expects
831
         * size_t* is HP-UX, where stack grows towards higher address.
832
         * <appro>
833
         */
834
0
        union {
835
0
            size_t s;
836
0
            int i;
837
0
        } len;
838
0
        union {
839
0
            struct sockaddr sa;
840
0
            struct sockaddr_in sa_in;
841
0
# if OPENSSL_USE_IPV6
842
0
            struct sockaddr_in6 sa_in6;
843
0
# endif
844
0
        } from;
845
0
    } sa;
846
847
0
    sa.len.s = 0;
848
0
    sa.len.i = sizeof(sa.from);
849
0
    memset(&sa.from, 0, sizeof(sa.from));
850
0
    ret = accept(sock, &sa.from.sa, (void *)&sa.len);
851
0
    if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) {
852
0
        OPENSSL_assert(sa.len.s <= sizeof(sa.from));
853
0
        sa.len.i = (int)sa.len.s;
854
        /* use sa.len.i from this point */
855
0
    }
856
0
    if (ret == INVALID_SOCKET) {
857
0
        if (BIO_sock_should_retry(ret))
858
0
            return -2;
859
0
        SYSerr(SYS_F_ACCEPT, get_last_socket_error());
860
0
        BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
861
0
        goto end;
862
0
    }
863
864
0
    if (addr == NULL)
865
0
        goto end;
866
867
0
# ifdef EAI_FAMILY
868
0
    do {
869
0
        char h[NI_MAXHOST], s[NI_MAXSERV];
870
0
        size_t nl;
871
0
        static union {
872
0
            void *p;
873
0
            int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ ,
874
0
                             char *, size_t, char *, size_t, int);
875
0
        } p_getnameinfo = {
876
0
            NULL
877
0
        };
878
        /*
879
         * 2nd argument to getnameinfo is specified to be socklen_t.
880
         * Unfortunately there is a number of environments where socklen_t is
881
         * not defined. As it's passed by value, it's safe to pass it as
882
         * size_t... <appro>
883
         */
884
885
0
        if (p_getnameinfo.p == NULL) {
886
0
            if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL)
887
0
                p_getnameinfo.p = (void *)-1;
888
0
        }
889
0
        if (p_getnameinfo.p == (void *)-1)
890
0
            break;
891
892
0
        if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s,
893
0
                                sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV))
894
0
            break;
895
0
        nl = strlen(h) + strlen(s) + 2;
896
0
        p = *addr;
897
0
        if (p) {
898
0
            *p = '\0';
899
0
            p = OPENSSL_realloc(p, nl);
900
0
        } else {
901
0
            p = OPENSSL_malloc(nl);
902
0
        }
903
0
        if (p == NULL) {
904
0
            BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
905
0
            goto end;
906
0
        }
907
0
        *addr = p;
908
0
        BIO_snprintf(*addr, nl, "%s:%s", h, s);
909
0
        goto end;
910
0
    } while (0);
911
0
# endif
912
0
    if (sa.from.sa.sa_family != AF_INET)
913
0
        goto end;
914
0
    l = ntohl(sa.from.sa_in.sin_addr.s_addr);
915
0
    port = ntohs(sa.from.sa_in.sin_port);
916
0
    if (*addr == NULL) {
917
0
        if ((p = OPENSSL_malloc(24)) == NULL) {
918
0
            BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
919
0
            goto end;
920
0
        }
921
0
        *addr = p;
922
0
    }
923
0
    BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d",
924
0
                 (unsigned char)(l >> 24L) & 0xff,
925
0
                 (unsigned char)(l >> 16L) & 0xff,
926
0
                 (unsigned char)(l >> 8L) & 0xff,
927
0
                 (unsigned char)(l) & 0xff, port);
928
0
 end:
929
0
    return (ret);
930
0
}
931
932
int BIO_set_tcp_ndelay(int s, int on)
933
0
{
934
0
    int ret = 0;
935
# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
936
    int opt;
937
938
#  ifdef SOL_TCP
939
    opt = SOL_TCP;
940
#  else
941
#   ifdef IPPROTO_TCP
942
    opt = IPPROTO_TCP;
943
#   endif
944
#  endif
945
946
    ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
947
# endif
948
0
    return (ret == 0);
949
0
}
950
951
int BIO_socket_nbio(int s, int mode)
952
0
{
953
0
    int ret = -1;
954
0
    int l;
955
956
0
    l = mode;
957
0
# ifdef FIONBIO
958
0
    ret = BIO_socket_ioctl(s, FIONBIO, &l);
959
0
# endif
960
0
    return (ret == 0);
961
0
}
962
#endif