X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbio%2Fb_addr.c;h=d11268b6dc594aba555d80f41ccca810e3ffac40;hb=f245be91a7bb4ccfdff630f92390e7ae72c6ca98;hp=141f1a9ee9f2fe670ca4e6f63c69a475d5b7b41f;hpb=5114d8227e0516fffc0c8653f5118290709f6494;p=oweals%2Fopenssl.git diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c index 141f1a9ee9..d11268b6dc 100644 --- a/crypto/bio/b_addr.c +++ b/crypto/bio/b_addr.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,22 +7,22 @@ * https://www.openssl.org/source/license.html */ +#include #include -#include "bio_lcl.h" +#include "bio_local.h" #include #ifndef OPENSSL_NO_SOCK #include #include -#include -#include +#include "internal/thread_once.h" CRYPTO_RWLOCK *bio_lookup_lock; static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT; /* - * Throughout this file and bio_lcl.h, the existence of the macro + * Throughout this file and bio_local.h, the existence of the macro * AI_PASSIVE is used to detect the availability of struct addrinfo, * getnameinfo() and getaddrinfo(). If that macro doesn't exist, * we use our own implementation instead, using gethostbyname, @@ -66,18 +66,18 @@ void BIO_ADDR_clear(BIO_ADDR *ap) int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa) { if (sa->sa_family == AF_INET) { - ap->s_in = *(const struct sockaddr_in *)sa; + memcpy(&(ap->s_in), sa, sizeof(struct sockaddr_in)); return 1; } #ifdef AF_INET6 if (sa->sa_family == AF_INET6) { - ap->s_in6 = *(const struct sockaddr_in6 *)sa; + memcpy(&(ap->s_in6), sa, sizeof(struct sockaddr_in6)); return 1; } #endif #ifdef AF_UNIX - if (ap->sa.sa_family == AF_UNIX) { - ap->s_un = *(const struct sockaddr_un *)sa; + if (sa->sa_family == AF_UNIX) { + memcpy(&(ap->s_un), sa, sizeof(struct sockaddr_un)); return 1; } #endif @@ -565,11 +565,10 @@ static int addrinfo_wrap(int family, int socktype, unsigned short port, BIO_ADDRINFO **bai) { - OPENSSL_assert(bai != NULL); - - *bai = OPENSSL_zalloc(sizeof(**bai)); - if (*bai == NULL) + if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) { + BIOerr(BIO_F_ADDRINFO_WRAP, ERR_R_MALLOC_FAILURE); return 0; + } (*bai)->bai_family = family; (*bai)->bai_socktype = socktype; @@ -604,7 +603,8 @@ static int addrinfo_wrap(int family, int socktype, DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init) { - OPENSSL_init_crypto(0, NULL); + if (!OPENSSL_init_crypto(0, NULL)) + return 0; bio_lookup_lock = CRYPTO_THREAD_lock_new(); return bio_lookup_lock != NULL; } @@ -617,7 +617,7 @@ int BIO_lookup(const char *host, const char *service, } /*- - * BIO_lookup - look up the node and service you want to connect to. + * BIO_lookup_ex - look up the node and service you want to connect to. * @node: the node you want to connect to. * @service: the service you want to connect to. * @lookup_type: declare intent with the result, client or server. @@ -638,8 +638,7 @@ int BIO_lookup(const char *host, const char *service, * * The return value is 1 on success or 0 in case of error. */ -int BIO_lookup_ex(const char *host, const char *service, - enum BIO_lookup_type lookup_type, +int BIO_lookup_ex(const char *host, const char *service, int lookup_type, int family, int socktype, int protocol, BIO_ADDRINFO **res) { int ret = 0; /* Assume failure */ @@ -676,34 +675,56 @@ int BIO_lookup_ex(const char *host, const char *service, if (1) { #ifdef AI_PASSIVE - int gai_ret = 0; + int gai_ret = 0, old_ret = 0; struct addrinfo hints; - memset(&hints, 0, sizeof hints); + memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = protocol; +# ifdef AI_ADDRCONFIG +# ifdef AF_UNSPEC + if (family == AF_UNSPEC) +# endif + hints.ai_flags |= AI_ADDRCONFIG; +# endif if (lookup_type == BIO_LOOKUP_SERVER) hints.ai_flags |= AI_PASSIVE; /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to - * macro magic in bio_lcl.h + * macro magic in bio_local.h */ +# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST) + retry: +# endif switch ((gai_ret = getaddrinfo(host, service, &hints, res))) { # ifdef EAI_SYSTEM case EAI_SYSTEM: SYSerr(SYS_F_GETADDRINFO, get_last_socket_error()); BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); break; +# endif +# ifdef EAI_MEMORY + case EAI_MEMORY: + BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + break; # endif case 0: ret = 1; /* Success */ break; default: +# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST) + if (hints.ai_flags & AI_ADDRCONFIG) { + hints.ai_flags &= ~AI_ADDRCONFIG; + hints.ai_flags |= AI_NUMERICHOST; + old_ret = gai_ret; + goto retry; + } +# endif BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); - ERR_add_error_data(1, gai_strerror(gai_ret)); + ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret)); break; } } else { @@ -761,8 +782,11 @@ int BIO_lookup_ex(const char *host, const char *service, he_fallback_address = INADDR_ANY; break; default: - OPENSSL_assert(("We forgot to handle a lookup type!" == 0)); - break; + /* We forgot to handle a lookup type! */ + assert("We forgot to handle a lookup type!" == NULL); + BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_INTERNAL_ERROR); + ret = 0; + goto err; } } else { he = gethostbyname(host); @@ -780,7 +804,12 @@ int BIO_lookup_ex(const char *host, const char *service, * anyway [above getaddrinfo/gai_strerror is]. We just let * system administrator figure this out... */ +# if defined(OPENSSL_SYS_VXWORKS) + /* h_errno doesn't exist on VxWorks */ + SYSerr(SYS_F_GETHOSTBYNAME, 1000 ); +# else SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno); +# endif #else SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError()); #endif @@ -821,7 +850,7 @@ int BIO_lookup_ex(const char *host, const char *service, if (endp != service && *endp == '\0' && portnum > 0 && portnum < 65536) { - se_fallback.s_port = htons(portnum); + se_fallback.s_port = htons((unsigned short)portnum); se_fallback.s_proto = proto; se = &se_fallback; } else if (endp == service) {