1 /*
2 * Copyright 2016-2024 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 #ifndef _GNU_SOURCE
11 # define _GNU_SOURCE
12 #endif
13
14 /*
15 * VC configurations may define UNICODE, to indicate to the C RTL that
16 * WCHAR functions are preferred.
17 * This affects functions like gai_strerror(), which is implemented as
18 * an alias macro for gai_strerrorA() (which returns a const char *) or
19 * gai_strerrorW() (which returns a const WCHAR *). This source file
20 * assumes POSIX declarations, so prefer the non-UNICODE definitions.
21 */
22 #undef UNICODE
23
24 #include <assert.h>
25 #include <string.h>
26
27 #include "bio_local.h"
28 #include <openssl/crypto.h>
29
30 #ifndef OPENSSL_NO_SOCK
31 #include <openssl/err.h>
32 #include <openssl/buffer.h>
33 #include "internal/thread_once.h"
34
35 CRYPTO_RWLOCK *bio_lookup_lock;
36 static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
37
38 /*
39 * Throughout this file and bio_local.h, the existence of the macro
40 * AI_PASSIVE is used to detect the availability of struct addrinfo,
41 * getnameinfo() and getaddrinfo(). If that macro doesn't exist,
42 * we use our own implementation instead, using gethostbyname,
43 * getservbyname and a few other.
44 */
45
46 /**********************************************************************
47 *
48 * Address structure
49 *
50 */
51
BIO_ADDR_new(void)52 BIO_ADDR *BIO_ADDR_new(void)
53 {
54 BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
55
56 if (ret == NULL)
57 return NULL;
58
59 ret->sa.sa_family = AF_UNSPEC;
60 return ret;
61 }
62
BIO_ADDR_free(BIO_ADDR * ap)63 void BIO_ADDR_free(BIO_ADDR *ap)
64 {
65 OPENSSL_free(ap);
66 }
67
BIO_ADDR_copy(BIO_ADDR * dst,const BIO_ADDR * src)68 int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src)
69 {
70 if (dst == NULL || src == NULL)
71 return 0;
72
73 if (src->sa.sa_family == AF_UNSPEC) {
74 BIO_ADDR_clear(dst);
75 return 1;
76 }
77
78 return BIO_ADDR_make(dst, &src->sa);
79 }
80
BIO_ADDR_dup(const BIO_ADDR * ap)81 BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap)
82 {
83 BIO_ADDR *ret = NULL;
84
85 if (ap != NULL) {
86 ret = BIO_ADDR_new();
87 if (ret != NULL && !BIO_ADDR_copy(ret, ap)) {
88 BIO_ADDR_free(ret);
89 ret = NULL;
90 }
91 }
92 return ret;
93 }
94
BIO_ADDR_clear(BIO_ADDR * ap)95 void BIO_ADDR_clear(BIO_ADDR *ap)
96 {
97 memset(ap, 0, sizeof(*ap));
98 ap->sa.sa_family = AF_UNSPEC;
99 }
100
101 /*
102 * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
103 * of a struct sockaddr.
104 */
BIO_ADDR_make(BIO_ADDR * ap,const struct sockaddr * sa)105 int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
106 {
107 if (sa->sa_family == AF_INET) {
108 memcpy(&(ap->s_in), sa, sizeof(struct sockaddr_in));
109 return 1;
110 }
111 #if OPENSSL_USE_IPV6
112 if (sa->sa_family == AF_INET6) {
113 memcpy(&(ap->s_in6), sa, sizeof(struct sockaddr_in6));
114 return 1;
115 }
116 #endif
117 #ifndef OPENSSL_NO_UNIX_SOCK
118 if (sa->sa_family == AF_UNIX) {
119 memcpy(&(ap->s_un), sa, sizeof(struct sockaddr_un));
120 return 1;
121 }
122 #endif
123
124 return 0;
125 }
126
BIO_ADDR_rawmake(BIO_ADDR * ap,int family,const void * where,size_t wherelen,unsigned short port)127 int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
128 const void *where, size_t wherelen,
129 unsigned short port)
130 {
131 #ifndef OPENSSL_NO_UNIX_SOCK
132 if (family == AF_UNIX) {
133 if (wherelen + 1 > sizeof(ap->s_un.sun_path))
134 return 0;
135 memset(&ap->s_un, 0, sizeof(ap->s_un));
136 ap->s_un.sun_family = family;
137 strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
138 return 1;
139 }
140 #endif
141 if (family == AF_INET) {
142 if (wherelen != sizeof(struct in_addr))
143 return 0;
144 memset(&ap->s_in, 0, sizeof(ap->s_in));
145 ap->s_in.sin_family = family;
146 ap->s_in.sin_port = port;
147 ap->s_in.sin_addr = *(struct in_addr *)where;
148 return 1;
149 }
150 #if OPENSSL_USE_IPV6
151 if (family == AF_INET6) {
152 if (wherelen != sizeof(struct in6_addr))
153 return 0;
154 memset(&ap->s_in6, 0, sizeof(ap->s_in6));
155 ap->s_in6.sin6_family = family;
156 ap->s_in6.sin6_port = port;
157 ap->s_in6.sin6_addr = *(struct in6_addr *)where;
158 return 1;
159 }
160 #endif
161
162 return 0;
163 }
164
BIO_ADDR_family(const BIO_ADDR * ap)165 int BIO_ADDR_family(const BIO_ADDR *ap)
166 {
167 return ap->sa.sa_family;
168 }
169
BIO_ADDR_rawaddress(const BIO_ADDR * ap,void * p,size_t * l)170 int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
171 {
172 size_t len = 0;
173 const void *addrptr = NULL;
174
175 if (ap->sa.sa_family == AF_INET) {
176 len = sizeof(ap->s_in.sin_addr);
177 addrptr = &ap->s_in.sin_addr;
178 }
179 #if OPENSSL_USE_IPV6
180 else if (ap->sa.sa_family == AF_INET6) {
181 len = sizeof(ap->s_in6.sin6_addr);
182 addrptr = &ap->s_in6.sin6_addr;
183 }
184 #endif
185 #ifndef OPENSSL_NO_UNIX_SOCK
186 else if (ap->sa.sa_family == AF_UNIX) {
187 len = strlen(ap->s_un.sun_path);
188 addrptr = &ap->s_un.sun_path;
189 }
190 #endif
191
192 if (addrptr == NULL)
193 return 0;
194
195 if (p != NULL) {
196 memcpy(p, addrptr, len);
197 }
198 if (l != NULL)
199 *l = len;
200
201 return 1;
202 }
203
BIO_ADDR_rawport(const BIO_ADDR * ap)204 unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
205 {
206 if (ap->sa.sa_family == AF_INET)
207 return ap->s_in.sin_port;
208 #if OPENSSL_USE_IPV6
209 if (ap->sa.sa_family == AF_INET6)
210 return ap->s_in6.sin6_port;
211 #endif
212 return 0;
213 }
214
215 /*-
216 * addr_strings - helper function to get host and service names
217 * @ap: the BIO_ADDR that has the input info
218 * @numeric: 0 if actual names should be returned, 1 if the numeric
219 * representation should be returned.
220 * @hostname: a pointer to a pointer to a memory area to store the
221 * hostname or numeric representation. Unused if NULL.
222 * @service: a pointer to a pointer to a memory area to store the
223 * service name or numeric representation. Unused if NULL.
224 *
225 * The return value is 0 on failure, with the error code in the error
226 * stack, and 1 on success.
227 */
addr_strings(const BIO_ADDR * ap,int numeric,char ** hostname,char ** service)228 static int addr_strings(const BIO_ADDR *ap, int numeric,
229 char **hostname, char **service)
230 {
231 if (BIO_sock_init() != 1)
232 return 0;
233
234 if (1) {
235 #ifdef AI_PASSIVE
236 int ret = 0;
237 char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
238 int flags = 0;
239
240 if (numeric)
241 flags |= NI_NUMERICHOST | NI_NUMERICSERV;
242
243 if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
244 BIO_ADDR_sockaddr_size(ap),
245 host, sizeof(host), serv, sizeof(serv),
246 flags)) != 0) {
247 # ifdef EAI_SYSTEM
248 if (ret == EAI_SYSTEM) {
249 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
250 "calling getnameinfo()");
251 } else
252 # endif
253 {
254 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, gai_strerror(ret));
255 }
256 return 0;
257 }
258
259 /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
260 * leaves it with whatever garbage that happens to be there.
261 * However, we initialise serv with the empty string (serv[0]
262 * is therefore NUL), so it gets real easy to detect when things
263 * didn't go the way one might expect.
264 */
265 if (serv[0] == '\0') {
266 BIO_snprintf(serv, sizeof(serv), "%d",
267 ntohs(BIO_ADDR_rawport(ap)));
268 }
269
270 if (hostname != NULL)
271 *hostname = OPENSSL_strdup(host);
272 if (service != NULL)
273 *service = OPENSSL_strdup(serv);
274 } else {
275 #endif
276 if (hostname != NULL)
277 *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
278 if (service != NULL) {
279 char serv[6]; /* port is 16 bits => max 5 decimal digits */
280 BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
281 *service = OPENSSL_strdup(serv);
282 }
283 }
284
285 if ((hostname != NULL && *hostname == NULL)
286 || (service != NULL && *service == NULL)) {
287 if (hostname != NULL) {
288 OPENSSL_free(*hostname);
289 *hostname = NULL;
290 }
291 if (service != NULL) {
292 OPENSSL_free(*service);
293 *service = NULL;
294 }
295 return 0;
296 }
297
298 return 1;
299 }
300
BIO_ADDR_hostname_string(const BIO_ADDR * ap,int numeric)301 char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
302 {
303 char *hostname = NULL;
304
305 if (addr_strings(ap, numeric, &hostname, NULL))
306 return hostname;
307
308 return NULL;
309 }
310
BIO_ADDR_service_string(const BIO_ADDR * ap,int numeric)311 char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
312 {
313 char *service = NULL;
314
315 if (addr_strings(ap, numeric, NULL, &service))
316 return service;
317
318 return NULL;
319 }
320
BIO_ADDR_path_string(const BIO_ADDR * ap)321 char *BIO_ADDR_path_string(const BIO_ADDR *ap)
322 {
323 #ifndef OPENSSL_NO_UNIX_SOCK
324 if (ap->sa.sa_family == AF_UNIX)
325 return OPENSSL_strdup(ap->s_un.sun_path);
326 #endif
327 return NULL;
328 }
329
330 /*
331 * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
332 * for a given BIO_ADDR. In reality, this is simply a type safe cast.
333 * The returned struct sockaddr is const, so it can't be tampered with.
334 */
BIO_ADDR_sockaddr(const BIO_ADDR * ap)335 const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
336 {
337 return &(ap->sa);
338 }
339
340 /*
341 * BIO_ADDR_sockaddr_noconst - non-public function that does the same
342 * as BIO_ADDR_sockaddr, but returns a non-const. USE WITH CARE, as
343 * it allows you to tamper with the data (and thereby the contents
344 * of the input BIO_ADDR).
345 */
BIO_ADDR_sockaddr_noconst(BIO_ADDR * ap)346 struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
347 {
348 return &(ap->sa);
349 }
350
351 /*
352 * BIO_ADDR_sockaddr_size - non-public function that returns the size
353 * of the struct sockaddr the BIO_ADDR is using. If the protocol family
354 * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
355 * the size of the BIO_ADDR type is returned.
356 */
BIO_ADDR_sockaddr_size(const BIO_ADDR * ap)357 socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
358 {
359 if (ap->sa.sa_family == AF_INET)
360 return sizeof(ap->s_in);
361 #if OPENSSL_USE_IPV6
362 if (ap->sa.sa_family == AF_INET6)
363 return sizeof(ap->s_in6);
364 #endif
365 #ifndef OPENSSL_NO_UNIX_SOCK
366 if (ap->sa.sa_family == AF_UNIX)
367 return sizeof(ap->s_un);
368 #endif
369 return sizeof(*ap);
370 }
371
372 /**********************************************************************
373 *
374 * Address info database
375 *
376 */
377
BIO_ADDRINFO_next(const BIO_ADDRINFO * bai)378 const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
379 {
380 if (bai != NULL)
381 return bai->bai_next;
382 return NULL;
383 }
384
BIO_ADDRINFO_family(const BIO_ADDRINFO * bai)385 int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
386 {
387 if (bai != NULL)
388 return bai->bai_family;
389 return 0;
390 }
391
BIO_ADDRINFO_socktype(const BIO_ADDRINFO * bai)392 int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
393 {
394 if (bai != NULL)
395 return bai->bai_socktype;
396 return 0;
397 }
398
BIO_ADDRINFO_protocol(const BIO_ADDRINFO * bai)399 int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
400 {
401 if (bai != NULL) {
402 if (bai->bai_protocol != 0)
403 return bai->bai_protocol;
404
405 #ifndef OPENSSL_NO_UNIX_SOCK
406 if (bai->bai_family == AF_UNIX)
407 return 0;
408 #endif
409
410 switch (bai->bai_socktype) {
411 case SOCK_STREAM:
412 return IPPROTO_TCP;
413 case SOCK_DGRAM:
414 return IPPROTO_UDP;
415 default:
416 break;
417 }
418 }
419 return 0;
420 }
421
422 /*
423 * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
424 * of the struct sockaddr inside the BIO_ADDRINFO.
425 */
BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO * bai)426 socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
427 {
428 if (bai != NULL)
429 return bai->bai_addrlen;
430 return 0;
431 }
432
433 /*
434 * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
435 * as the struct sockaddr it is.
436 */
BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO * bai)437 const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
438 {
439 if (bai != NULL)
440 return bai->bai_addr;
441 return NULL;
442 }
443
BIO_ADDRINFO_address(const BIO_ADDRINFO * bai)444 const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
445 {
446 if (bai != NULL)
447 return (BIO_ADDR *)bai->bai_addr;
448 return NULL;
449 }
450
BIO_ADDRINFO_free(BIO_ADDRINFO * bai)451 void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
452 {
453 if (bai == NULL)
454 return;
455
456 #ifdef AI_PASSIVE
457 # ifndef OPENSSL_NO_UNIX_SOCK
458 # define _cond bai->bai_family != AF_UNIX
459 # else
460 # define _cond 1
461 # endif
462 if (_cond) {
463 freeaddrinfo(bai);
464 return;
465 }
466 #endif
467
468 /* Free manually when we know that addrinfo_wrap() was used.
469 * See further comment above addrinfo_wrap()
470 */
471 while (bai != NULL) {
472 BIO_ADDRINFO *next = bai->bai_next;
473 OPENSSL_free(bai->bai_addr);
474 OPENSSL_free(bai);
475 bai = next;
476 }
477 }
478
479 /**********************************************************************
480 *
481 * Service functions
482 *
483 */
484
485 /*-
486 * The specs in hostserv can take these forms:
487 *
488 * host:service => *host = "host", *service = "service"
489 * host:* => *host = "host", *service = NULL
490 * host: => *host = "host", *service = NULL
491 * :service => *host = NULL, *service = "service"
492 * *:service => *host = NULL, *service = "service"
493 *
494 * in case no : is present in the string, the result depends on
495 * hostserv_prio, as follows:
496 *
497 * when hostserv_prio == BIO_PARSE_PRIO_HOST
498 * host => *host = "host", *service untouched
499 *
500 * when hostserv_prio == BIO_PARSE_PRIO_SERV
501 * service => *host untouched, *service = "service"
502 *
503 */
BIO_parse_hostserv(const char * hostserv,char ** host,char ** service,enum BIO_hostserv_priorities hostserv_prio)504 int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
505 enum BIO_hostserv_priorities hostserv_prio)
506 {
507 const char *h = NULL; size_t hl = 0;
508 const char *p = NULL; size_t pl = 0;
509
510 if (*hostserv == '[') {
511 if ((p = strchr(hostserv, ']')) == NULL)
512 goto spec_err;
513 h = hostserv + 1;
514 hl = p - h;
515 p++;
516 if (*p == '\0')
517 p = NULL;
518 else if (*p != ':')
519 goto spec_err;
520 else {
521 p++;
522 pl = strlen(p);
523 }
524 } else {
525 const char *p2 = strrchr(hostserv, ':');
526 p = strchr(hostserv, ':');
527
528 /*-
529 * Check for more than one colon. There are three possible
530 * interpretations:
531 * 1. IPv6 address with port number, last colon being separator.
532 * 2. IPv6 address only.
533 * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
534 * IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
535 * Because of this ambiguity, we currently choose to make it an
536 * error.
537 */
538 if (p != p2)
539 goto amb_err;
540
541 if (p != NULL) {
542 h = hostserv;
543 hl = p - h;
544 p++;
545 pl = strlen(p);
546 } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
547 h = hostserv;
548 hl = strlen(h);
549 } else {
550 p = hostserv;
551 pl = strlen(p);
552 }
553 }
554
555 if (p != NULL && strchr(p, ':'))
556 goto spec_err;
557
558 if (h != NULL && host != NULL) {
559 if (hl == 0
560 || (hl == 1 && h[0] == '*')) {
561 *host = NULL;
562 } else {
563 *host = OPENSSL_strndup(h, hl);
564 if (*host == NULL)
565 return 0;
566 }
567 }
568 if (p != NULL && service != NULL) {
569 if (pl == 0
570 || (pl == 1 && p[0] == '*')) {
571 *service = NULL;
572 } else {
573 *service = OPENSSL_strndup(p, pl);
574 if (*service == NULL)
575 return 0;
576 }
577 }
578
579 return 1;
580 amb_err:
581 ERR_raise(ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
582 return 0;
583 spec_err:
584 ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE);
585 return 0;
586 }
587
588 /* addrinfo_wrap is used to build our own addrinfo "chain".
589 * (it has only one entry, so calling it a chain may be a stretch)
590 * It should ONLY be called when getaddrinfo() and friends
591 * aren't available, OR when dealing with a non IP protocol
592 * family, such as AF_UNIX
593 *
594 * the return value is 1 on success, or 0 on failure, which
595 * only happens if a memory allocation error occurred.
596 */
addrinfo_wrap(int family,int socktype,const void * where,size_t wherelen,unsigned short port,BIO_ADDRINFO ** bai)597 static int addrinfo_wrap(int family, int socktype,
598 const void *where, size_t wherelen,
599 unsigned short port,
600 BIO_ADDRINFO **bai)
601 {
602 if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL)
603 return 0;
604
605 (*bai)->bai_family = family;
606 (*bai)->bai_socktype = socktype;
607 if (socktype == SOCK_STREAM)
608 (*bai)->bai_protocol = IPPROTO_TCP;
609 if (socktype == SOCK_DGRAM)
610 (*bai)->bai_protocol = IPPROTO_UDP;
611 #ifndef OPENSSL_NO_UNIX_SOCK
612 if (family == AF_UNIX)
613 (*bai)->bai_protocol = 0;
614 #endif
615 {
616 /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
617 just an advanced cast of BIO_ADDR* to struct sockaddr *
618 by the power of union, so while it may seem that we're
619 creating a memory leak here, we are not. It will be
620 all right. */
621 BIO_ADDR *addr = BIO_ADDR_new();
622 if (addr != NULL) {
623 BIO_ADDR_rawmake(addr, family, where, wherelen, port);
624 (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
625 }
626 }
627 (*bai)->bai_next = NULL;
628 if ((*bai)->bai_addr == NULL) {
629 BIO_ADDRINFO_free(*bai);
630 *bai = NULL;
631 return 0;
632 }
633 return 1;
634 }
635
DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)636 DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
637 {
638 bio_lookup_lock = CRYPTO_THREAD_lock_new();
639 return bio_lookup_lock != NULL;
640 }
641
BIO_lookup(const char * host,const char * service,enum BIO_lookup_type lookup_type,int family,int socktype,BIO_ADDRINFO ** res)642 int BIO_lookup(const char *host, const char *service,
643 enum BIO_lookup_type lookup_type,
644 int family, int socktype, BIO_ADDRINFO **res)
645 {
646 return BIO_lookup_ex(host, service, lookup_type, family, socktype, 0, res);
647 }
648
649 /*-
650 * BIO_lookup_ex - look up the host and service you want to connect to.
651 * @host: the host (or node, in case family == AF_UNIX) you want to connect to.
652 * @service: the service you want to connect to.
653 * @lookup_type: declare intent with the result, client or server.
654 * @family: the address family you want to use. Use AF_UNSPEC for any, or
655 * AF_INET, AF_INET6 or AF_UNIX.
656 * @socktype: The socket type you want to use. Can be SOCK_STREAM, SOCK_DGRAM
657 * or 0 for all.
658 * @protocol: The protocol to use, e.g. IPPROTO_TCP or IPPROTO_UDP or 0 for all.
659 * Note that some platforms may not return IPPROTO_SCTP without
660 * explicitly requesting it (i.e. IPPROTO_SCTP may not be returned
661 * with 0 for the protocol)
662 * @res: Storage place for the resulting list of returned addresses
663 *
664 * This will do a lookup of the host and service that you want to connect to.
665 * It returns a linked list of different addresses you can try to connect to.
666 *
667 * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
668 *
669 * The return value is 1 on success or 0 in case of error.
670 */
BIO_lookup_ex(const char * host,const char * service,int lookup_type,int family,int socktype,int protocol,BIO_ADDRINFO ** res)671 int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
672 int family, int socktype, int protocol, BIO_ADDRINFO **res)
673 {
674 int ret = 0; /* Assume failure */
675
676 switch (family) {
677 case AF_INET:
678 #if OPENSSL_USE_IPV6
679 case AF_INET6:
680 #endif
681 #ifndef OPENSSL_NO_UNIX_SOCK
682 case AF_UNIX:
683 #endif
684 #ifdef AF_UNSPEC
685 case AF_UNSPEC:
686 #endif
687 break;
688 default:
689 ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
690 return 0;
691 }
692
693 #ifndef OPENSSL_NO_UNIX_SOCK
694 if (family == AF_UNIX) {
695 if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
696 return 1;
697 else
698 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
699 return 0;
700 }
701 #endif
702
703 if (BIO_sock_init() != 1)
704 return 0;
705
706 if (1) {
707 #ifdef AI_PASSIVE
708 int gai_ret = 0, old_ret = 0;
709 struct addrinfo hints;
710
711 memset(&hints, 0, sizeof(hints));
712
713 hints.ai_family = family;
714 hints.ai_socktype = socktype;
715 hints.ai_protocol = protocol;
716 # ifdef AI_ADDRCONFIG
717 # ifdef AF_UNSPEC
718 if (host != NULL && family == AF_UNSPEC)
719 # endif
720 hints.ai_flags |= AI_ADDRCONFIG;
721 # endif
722
723 if (lookup_type == BIO_LOOKUP_SERVER)
724 hints.ai_flags |= AI_PASSIVE;
725
726 /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
727 * macro magic in bio_local.h
728 */
729 # if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST)
730 retry:
731 # endif
732 switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
733 # ifdef EAI_SYSTEM
734 case EAI_SYSTEM:
735 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
736 "calling getaddrinfo()");
737 ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
738 break;
739 # endif
740 # ifdef EAI_MEMORY
741 case EAI_MEMORY:
742 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
743 gai_strerror(old_ret ? old_ret : gai_ret));
744 break;
745 # endif
746 case 0:
747 ret = 1; /* Success */
748 break;
749 default:
750 # if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST)
751 if (hints.ai_flags & AI_ADDRCONFIG) {
752 hints.ai_flags &= ~AI_ADDRCONFIG;
753 hints.ai_flags |= AI_NUMERICHOST;
754 old_ret = gai_ret;
755 goto retry;
756 }
757 # endif
758 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
759 gai_strerror(old_ret ? old_ret : gai_ret));
760 break;
761 }
762 } else {
763 #endif
764 const struct hostent *he;
765 /*
766 * Because struct hostent is defined for 32-bit pointers only with
767 * VMS C, we need to make sure that '&he_fallback_address' and
768 * '&he_fallback_addresses' are 32-bit pointers
769 */
770 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
771 # pragma pointer_size save
772 # pragma pointer_size 32
773 #endif
774 /* Windows doesn't seem to have in_addr_t */
775 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
776 static uint32_t he_fallback_address;
777 static const char *he_fallback_addresses[] = {
778 (char *)&he_fallback_address, NULL
779 };
780 #else
781 static in_addr_t he_fallback_address;
782 static const char *he_fallback_addresses[] = {
783 (char *)&he_fallback_address, NULL
784 };
785 #endif
786 static const struct hostent he_fallback = {
787 NULL, NULL, AF_INET, sizeof(he_fallback_address),
788 (char **)&he_fallback_addresses
789 };
790 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
791 # pragma pointer_size restore
792 #endif
793
794 struct servent *se;
795 /* Apparently, on WIN64, s_proto and s_port have traded places... */
796 #ifdef _WIN64
797 struct servent se_fallback = { NULL, NULL, NULL, 0 };
798 #else
799 struct servent se_fallback = { NULL, NULL, 0, NULL };
800 #endif
801
802 if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
803 /* Should this be raised inside do_bio_lookup_init()? */
804 ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB);
805 return 0;
806 }
807
808 if (!CRYPTO_THREAD_write_lock(bio_lookup_lock))
809 return 0;
810
811 he_fallback_address = INADDR_ANY;
812 if (host == NULL) {
813 he = &he_fallback;
814 switch (lookup_type) {
815 case BIO_LOOKUP_CLIENT:
816 he_fallback_address = INADDR_LOOPBACK;
817 break;
818 case BIO_LOOKUP_SERVER:
819 he_fallback_address = INADDR_ANY;
820 break;
821 default:
822 /* We forgot to handle a lookup type! */
823 assert("We forgot to handle a lookup type!" == NULL);
824 ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
825 ret = 0;
826 goto err;
827 }
828 } else {
829 he = gethostbyname(host);
830
831 if (he == NULL) {
832 #ifndef OPENSSL_SYS_WINDOWS
833 /*
834 * This might be misleading, because h_errno is used as if
835 * it was errno. To minimize mixup add 1000. Underlying
836 * reason for this is that hstrerror is declared obsolete,
837 * not to mention that a) h_errno is not always guaranteed
838 * to be meaningless; b) hstrerror can reside in yet another
839 * library, linking for sake of hstrerror is an overkill;
840 * c) this path is not executed on contemporary systems
841 * anyway [above getaddrinfo/gai_strerror is]. We just let
842 * system administrator figure this out...
843 */
844 # if defined(OPENSSL_SYS_VXWORKS)
845 /* h_errno doesn't exist on VxWorks */
846 ERR_raise_data(ERR_LIB_SYS, 1000,
847 "calling gethostbyname()");
848 # else
849 ERR_raise_data(ERR_LIB_SYS, 1000 + h_errno,
850 "calling gethostbyname()");
851 # endif
852 #else
853 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
854 "calling gethostbyname()");
855 #endif
856 ret = 0;
857 goto err;
858 }
859 }
860
861 if (service == NULL) {
862 se_fallback.s_port = 0;
863 se_fallback.s_proto = NULL;
864 se = &se_fallback;
865 } else {
866 char *endp = NULL;
867 long portnum = strtol(service, &endp, 10);
868
869 /*
870 * Because struct servent is defined for 32-bit pointers only with
871 * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
872 */
873 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
874 # pragma pointer_size save
875 # pragma pointer_size 32
876 #endif
877 char *proto = NULL;
878 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
879 # pragma pointer_size restore
880 #endif
881
882 switch (socktype) {
883 case SOCK_STREAM:
884 proto = "tcp";
885 break;
886 case SOCK_DGRAM:
887 proto = "udp";
888 break;
889 }
890
891 if (endp != service && *endp == '\0'
892 && portnum > 0 && portnum < 65536) {
893 se_fallback.s_port = htons((unsigned short)portnum);
894 se_fallback.s_proto = proto;
895 se = &se_fallback;
896 } else if (endp == service) {
897 se = getservbyname(service, proto);
898
899 if (se == NULL) {
900 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
901 "calling getservbyname()");
902 goto err;
903 }
904 } else {
905 ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE);
906 goto err;
907 }
908 }
909
910 *res = NULL;
911
912 {
913 /*
914 * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
915 * we must make sure our iterator designates the same element type, hence
916 * the pointer size dance.
917 */
918 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
919 # pragma pointer_size save
920 # pragma pointer_size 32
921 #endif
922 char **addrlistp;
923 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
924 # pragma pointer_size restore
925 #endif
926 size_t addresses;
927 BIO_ADDRINFO *tmp_bai = NULL;
928
929 /* The easiest way to create a linked list from an
930 array is to start from the back */
931 for (addrlistp = he->h_addr_list; *addrlistp != NULL;
932 addrlistp++)
933 ;
934
935 for (addresses = addrlistp - he->h_addr_list;
936 addrlistp--, addresses-- > 0; ) {
937 if (!addrinfo_wrap(he->h_addrtype, socktype,
938 *addrlistp, he->h_length,
939 se->s_port, &tmp_bai))
940 goto addrinfo_wrap_err;
941 tmp_bai->bai_next = *res;
942 *res = tmp_bai;
943 continue;
944 addrinfo_wrap_err:
945 BIO_ADDRINFO_free(*res);
946 *res = NULL;
947 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
948 ret = 0;
949 goto err;
950 }
951
952 ret = 1;
953 }
954 err:
955 CRYPTO_THREAD_unlock(bio_lookup_lock);
956 }
957
958 return ret;
959 }
960
961 #endif /* OPENSSL_NO_SOCK */
962