diff options
author | Cy Schubert <cy@FreeBSD.org> | 2025-04-25 14:41:24 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2025-04-25 14:41:24 +0000 |
commit | 44bab727dfe28451b777dc9e47db4f748b709182 (patch) | |
tree | b8abab888105843c7f120357a1e010bfd6d5ef8c /util/net_help.c | |
parent | 0a6d797cf6eb751d7eb613900cd19803e05d905f (diff) |
Diffstat (limited to 'util/net_help.c')
-rw-r--r-- | util/net_help.c | 163 |
1 files changed, 140 insertions, 23 deletions
diff --git a/util/net_help.c b/util/net_help.c index 5cf702ef9bca..8eca6b757ca8 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -92,11 +92,13 @@ int RRSET_ROUNDROBIN = 1; /** log tag queries with name instead of 'info' for filtering */ int LOG_TAG_QUERYREPLY = 0; +#ifdef HAVE_SSL static struct tls_session_ticket_key { unsigned char *key_name; unsigned char *aes_key; unsigned char *hmac_key; } *ticket_keys; +#endif /* HAVE_SSL */ #ifdef HAVE_SSL /** @@ -544,7 +546,7 @@ void log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; if(verbosity < v) @@ -575,7 +577,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, void log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; dname_str(name, buf); @@ -608,7 +610,7 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, { uint16_t port; const char* family = "unknown_family "; - char namebuf[LDNS_MAX_DOMAINLEN+1]; + char namebuf[LDNS_MAX_DOMAINLEN]; char dest[100]; int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; @@ -728,6 +730,52 @@ sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, } int +sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1, + struct sockaddr_storage* addr2, socklen_t len2) +{ + struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; + struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; + struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; + struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; + if(len1 < len2) + return -1; + if(len1 > len2) + return 1; + log_assert(len1 == len2); + if( p1_in->sin_family < p2_in->sin_family) + return -1; + if( p1_in->sin_family > p2_in->sin_family) + return 1; + log_assert( p1_in->sin_family == p2_in->sin_family ); + /* compare ip4 */ + if( p1_in->sin_family == AF_INET ) { + /* just order it, ntohs not required */ + if(p1_in->sin_port < p2_in->sin_port) + return -1; + if(p1_in->sin_port > p2_in->sin_port) + return 1; + log_assert(p1_in->sin_port == p2_in->sin_port); + return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); + } else if (p1_in6->sin6_family == AF_INET6) { + /* just order it, ntohs not required */ + if(p1_in6->sin6_port < p2_in6->sin6_port) + return -1; + if(p1_in6->sin6_port > p2_in6->sin6_port) + return 1; + if(p1_in6->sin6_scope_id < p2_in6->sin6_scope_id) + return -1; + if(p1_in6->sin6_scope_id > p2_in6->sin6_scope_id) + return 1; + log_assert(p1_in6->sin6_port == p2_in6->sin6_port); + return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, + INET6_SIZE); + } else { + /* eek unknown type, perform this comparison for sanity. */ + return memcmp(addr1, addr2, len1); + } +} + +int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) { if(len == (socklen_t)sizeof(struct sockaddr_in6) && @@ -1116,8 +1164,29 @@ log_cert(unsigned level, const char* str, void* cert) } #endif /* HAVE_SSL */ +#if defined(HAVE_SSL) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) +static int +dot_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, + unsigned char* outlen, const unsigned char* in, unsigned int inlen, + void* ATTR_UNUSED(arg)) +{ + static const unsigned char alpns[] = { 3, 'd', 'o', 't' }; + unsigned char* tmp_out; + int ret; + ret = SSL_select_next_proto(&tmp_out, outlen, alpns, sizeof(alpns), in, inlen); + if(ret == OPENSSL_NPN_NO_OVERLAP) { + /* Client sent ALPN but no overlap. Should have been error, + * but for privacy we continue without ALPN (e.g., if certain + * ALPNs are blocked) */ + return SSL_TLSEXT_ERR_NOACK; + } + *out = tmp_out; + return SSL_TLSEXT_ERR_OK; +} +#endif + #if defined(HAVE_SSL) && defined(HAVE_NGHTTP2) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) -static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, +static int doh_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* ATTR_UNUSED(arg)) { @@ -1131,6 +1200,24 @@ static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, } #endif +#ifdef HAVE_SSL +/* setup the callback for ticket keys */ +static int +setup_ticket_keys_cb(void* sslctx) +{ +# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { + return 0; + } +# else + if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { + return 0; + } +# endif + return 1; +} +#endif /* HAVE_SSL */ + int listen_sslctx_setup(void* ctxt) { @@ -1202,9 +1289,6 @@ listen_sslctx_setup(void* ctxt) #ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL SSL_CTX_set_security_level(ctx, 0); #endif -#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) && defined(HAVE_NGHTTP2) - SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL); -#endif #else (void)ctxt; #endif /* HAVE_SSL */ @@ -1239,7 +1323,10 @@ listen_sslctx_setup_2(void* ctxt) #endif /* HAVE_SSL */ } -void* listen_sslctx_create(char* key, char* pem, char* verifypem) +void* listen_sslctx_create(const char* key, const char* pem, + const char* verifypem, const char* tls_ciphers, + const char* tls_ciphersuites, int set_ticket_keys_cb, + int is_dot, int is_doh) { #ifdef HAVE_SSL SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); @@ -1290,11 +1377,52 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } + if(tls_ciphers && tls_ciphers[0]) { + if (!SSL_CTX_set_cipher_list(ctx, tls_ciphers)) { + log_err("failed to set tls-cipher %s", + tls_ciphers); + log_crypto_err("Error in SSL_CTX_set_cipher_list"); + SSL_CTX_free(ctx); + return NULL; + } + } +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + if(tls_ciphersuites && tls_ciphersuites[0]) { + if (!SSL_CTX_set_ciphersuites(ctx, tls_ciphersuites)) { + log_err("failed to set tls-ciphersuites %s", + tls_ciphersuites); + log_crypto_err("Error in SSL_CTX_set_ciphersuites"); + SSL_CTX_free(ctx); + return NULL; + } + } +#else + (void)tls_ciphersuites; /* variable unused. */ +#endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */ + if(set_ticket_keys_cb) { + if(!setup_ticket_keys_cb(ctx)) { + log_crypto_err("no support for TLS session ticket"); + SSL_CTX_free(ctx); + return NULL; + } + } + /* setup ALPN */ +#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) + if(is_dot) { + SSL_CTX_set_alpn_select_cb(ctx, dot_alpn_select_cb, NULL); + } else if(is_doh) { +#if defined(HAVE_NGHTTP2) + SSL_CTX_set_alpn_select_cb(ctx, doh_alpn_select_cb, NULL); +#endif + } +#endif /* HAVE_SSL_CTX_SET_ALPN_SELECT_CB */ return ctx; #else (void)key; (void)pem; (void)verifypem; + (void)tls_ciphers; (void)tls_ciphersuites; + (void)set_ticket_keys_cb; (void)is_dot; (void)is_doh; return NULL; -#endif +#endif /* HAVE_SSL */ } #ifdef USE_WINSOCK @@ -1654,7 +1782,7 @@ void ub_openssl_lock_delete(void) #endif /* OPENSSL_THREADS */ } -int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) { +int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys) { #ifdef HAVE_SSL size_t s = 1; struct config_strlist* p; @@ -1700,24 +1828,11 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses } /* terminate array with NULL key name entry */ keys->key_name = NULL; -# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB - if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { - log_err("no support for TLS session ticket"); - return 0; - } -# else - if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { - log_err("no support for TLS session ticket"); - return 0; - } -# endif return 1; #else - (void)sslctx; (void)tls_session_ticket_keys; return 0; #endif - } #ifdef HAVE_SSL @@ -1828,6 +1943,7 @@ int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name, } #endif /* HAVE_SSL */ +#ifdef HAVE_SSL void listen_sslctx_delete_ticket_keys(void) { @@ -1845,6 +1961,7 @@ listen_sslctx_delete_ticket_keys(void) free(ticket_keys); ticket_keys = NULL; } +#endif /* HAVE_SSL */ # ifndef USE_WINSOCK char* |