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