diff --git a/src/context.c b/src/context.c index 5728c83b..a5ddcb07 100644 --- a/src/context.c +++ b/src/context.c @@ -605,6 +605,7 @@ upstream_init(getdns_upstream *upstream, upstream->starttls_req = NULL; upstream->transport = GETDNS_TRANSPORT_TCP; upstream->tls_hs_state = GETDNS_HS_NONE; + upstream->tls_auth_name[0] = '\0'; upstream->tcp.write_error = 0; upstream->loop = NULL; (void) getdns_eventloop_event_init( @@ -1216,6 +1217,8 @@ getdns_set_base_dns_transports( if (!context || transport_count == 0 || transports == NULL) return GETDNS_RETURN_INVALID_PARAMETER; + /* TODO: restrict the use of each transport to once -> + sane list and correct max size for array*/ for(i=0; iaddr.ss_family = addr.ss_family; upstream_init(upstream, upstreams, ai); upstream->transport = getdns_upstream_transports[j]; + if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) { + if ((r = getdns_dict_get_bindata( + dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) { + /*TODO: VALIDATE THIS STRING!*/ + memcpy(upstream->tls_auth_name, + (char *)tls_auth_name->data, + tls_auth_name->size); + upstream->tls_auth_name[tls_auth_name->size] = '\0'; + } + } upstreams->count++; freeaddrinfo(ai); } @@ -2130,11 +2144,14 @@ getdns_context_prepare_for_resolution(struct getdns_context *context, #endif if(context->tls_ctx == NULL) return GETDNS_RETURN_BAD_CONTEXT; + SSL_CTX_set_verify(context->tls_ctx, SSL_VERIFY_PEER, NULL); + if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) + return GETDNS_RETURN_BAD_CONTEXT; } } /* Block use of STARTTLS/TLS ONLY in recursive mode as it won't work */ /* Note: If TLS is used in recursive mode this will try TLS on port - * 53 so it is blocked here. So is STARTTLS only at the moment. */ + * 53 so it is blocked here. So is 'STARTTLS only' at the moment. */ if (context->resolution_type == GETDNS_RESOLUTION_RECURSING && context->dns_transport_count == 1 && (context->dns_transports[0] == GETDNS_TRANSPORT_TLS || diff --git a/src/context.h b/src/context.h index 998b75b8..7c056c68 100644 --- a/src/context.h +++ b/src/context.h @@ -101,6 +101,7 @@ typedef struct getdns_upstream { getdns_eventloop_event event; getdns_eventloop *loop; getdns_tcp_state tcp; + char tls_auth_name[256]; /* Pipelining of TCP network requests */ getdns_network_req *write_queue; diff --git a/src/stub.c b/src/stub.c index f9d28379..d675179b 100644 --- a/src/stub.c +++ b/src/stub.c @@ -32,6 +32,7 @@ */ #include +#include #include "config.h" #include #include "stub.h" @@ -822,12 +823,14 @@ tls_failed(getdns_upstream *upstream) } static SSL* -tls_create_object(getdns_context *context, int fd) +tls_create_object(getdns_context *context, int fd, const char* auth_name) { /* Create SSL instance */ if (context->tls_ctx == NULL) return NULL; SSL* ssl = SSL_new(context->tls_ctx); + X509_VERIFY_PARAM *param; + if(!ssl) return NULL; /* Connect the SSL object with a file descriptor */ @@ -835,6 +838,10 @@ tls_create_object(getdns_context *context, int fd) SSL_free(ssl); return NULL; } + SSL_set_tlsext_host_name(ssl, auth_name); + param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + X509_VERIFY_PARAM_set1_host(param, auth_name, 0); SSL_set_connect_state(ssl); (void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); return ssl; @@ -1302,7 +1309,8 @@ upstream_read_cb(void *userarg) dnsreq = netreq->owner; if (is_starttls_response(netreq)) { upstream->tls_obj = tls_create_object(dnsreq->context, - upstream->fd); + upstream->fd, + upstream->tls_auth_name); if (upstream->tls_obj == NULL) upstream->tls_hs_state = GETDNS_HS_FAILED; upstream->tls_hs_state = GETDNS_HS_WRITE; @@ -1542,7 +1550,7 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport, return upstream->fd; fd = tcp_connect(upstream, transport); if (fd == -1) return -1; - upstream->tls_obj = tls_create_object(dnsreq->context, fd); + upstream->tls_obj = tls_create_object(dnsreq->context, fd, upstream->tls_auth_name); if (upstream->tls_obj == NULL) { close(fd); return -1; diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 31877010..e3309f66 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -55,6 +55,7 @@ ipaddr_dict(getdns_context *context, char *ipstr) char *s = strchr(ipstr, '%'), *scope_id_str = ""; char *p = strchr(ipstr, '@'), *portstr = ""; char *t = strchr(ipstr, '#'), *tls_portstr = ""; + char *n = strchr(ipstr, '~'), *tls_namestr = ""; uint8_t buf[sizeof(struct in6_addr)]; getdns_bindata addr; @@ -73,6 +74,10 @@ ipaddr_dict(getdns_context *context, char *ipstr) *t = 0; tls_portstr = t + 1; } + if (n) { + *n = 0; + tls_namestr = n + 1; + } if (strchr(ipstr, ':')) { getdns_dict_util_set_string(r, "address_type", "IPv6"); addr.size = 16; @@ -93,6 +98,9 @@ ipaddr_dict(getdns_context *context, char *ipstr) getdns_dict_set_int(r, "port", (int32_t)atoi(portstr)); if (*tls_portstr) getdns_dict_set_int(r, "tls_port", (int32_t)atoi(tls_portstr)); + if (*tls_namestr) { + getdns_dict_util_set_string(r, "tls_auth_name", tls_namestr); + } if (*scope_id_str) getdns_dict_util_set_string(r, "scope_id", scope_id_str);