From f8b041cd406a720710429a55925bde875370ea99 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Thu, 7 Jan 2016 17:17:09 +0000 Subject: [PATCH 1/8] Bug fix for segmentation fault when using NULL pin. Unit test to come in later update. --- src/pubkey-pinning.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pubkey-pinning.c b/src/pubkey-pinning.c index 2f685ad3..6e7cdf39 100644 --- a/src/pubkey-pinning.c +++ b/src/pubkey-pinning.c @@ -99,7 +99,7 @@ getdns_dict* getdns_pubkey_pin_create_from_string( getdns_dict* out = NULL; /* we only do sha256 right now, make sure this is well-formed */ - if (strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH)) + if (!str || strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH)) return NULL; for (i = PIN_PREFIX_LENGTH; i < PIN_PREFIX_LENGTH + B64_ENCODED_SHA256_LENGTH - 1; i++) if (!((str[i] >= 'a' && str[i] <= 'z') || From 7e9563faed0473e83a5ba4f029ff66239ad4156f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Jan 2016 18:47:03 -0500 Subject: [PATCH 2/8] Added a wincrypt adapter to read CA trust certs from Windows CA store and feed them into openssl for TLS hostname authentication --- m4/acx_getaddrinfo.m4 | 6 ++-- src/context.c | 73 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/m4/acx_getaddrinfo.m4 b/m4/acx_getaddrinfo.m4 index e88e1ddd..a4af9e1d 100644 --- a/m4/acx_getaddrinfo.m4 +++ b/m4/acx_getaddrinfo.m4 @@ -32,12 +32,12 @@ dnl see if on windows if test "$ac_cv_header_windows_h" = "yes"; then AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) USE_WINSOCK="1" - LIBS="$LIBS -lws2_32" + LIBS="$LIBS -lws2_32 -lcrypt32" fi ], dnl no quick getaddrinfo, try mingw32 and winsock2 library. ORIGLIBS="$LIBS" -LIBS="$LIBS -lws2_32" +LIBS="$LIBS -lws2_32 -lcrypt32" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [ @@ -62,7 +62,7 @@ AC_LINK_IFELSE( )], [ ac_cv_func_getaddrinfo="yes" -dnl already: LIBS="$LIBS -lws2_32" +dnl already: LIBS="$LIBS -lws2_32 -lcrypt32" AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) USE_WINSOCK="1" ], diff --git a/src/context.c b/src/context.c index c47d4992..ae592017 100644 --- a/src/context.c +++ b/src/context.c @@ -43,7 +43,15 @@ #else #include #include -typedef unsigned short in_port_t; +typedef unsigned short in_port_t; + +#include +#include +#include + +#include +#include +#include #endif #include @@ -130,6 +138,66 @@ static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*, /* Stuff to make it compile pedantically */ #define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code; + +#ifdef USE_WINSOCK +// For windows, the CA trust store is not read by openssl. +// Add code to open the trust store using wincrypt API and add +// the root certs into openssl trust store +X509_STORE *store; +X509_STORE_CTX *sslctx = NULL; +void add_cacerts_to_openssl_store(struct getdns_context *context) +{ + HCERTSTORE hSystemStore; + PCCERT_CONTEXT pTargetCert = NULL; + + // Call wincrypt's CertOpenStore to open the CA root store. + + if ((hSystemStore = CertOpenStore( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + // mingw does not have this const: replace with 1 << 16 from code + // CERT_SYSTEM_STORE_CURRENT_USER, + 1 << 16, + L"root")) == 0) + { + DEBUG_STUB("*** %s(CertOpenStore failed)\n", __FUNCTION__); + return; + } + store = SSL_CTX_get_cert_store(context->tls_ctx); + + // iterate over the windows cert store and add to openssl store + while (pTargetCert = CertEnumCertificatesInStore( + hSystemStore, + pTargetCert)) + { + BYTE* cert = pTargetCert->pbCertEncoded; + X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); + if (!cert1) { + DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, + "unable to parse certificate in memory"); + } + else { + if (X509_STORE_add_cert(store, cert1) == 0) + DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, + "error adding certificate"); + X509_free(cert1); + } + } + // Clean up memory and quit. + + if (pTargetCert) + CertFreeCertificateContext(pTargetCert); + if (hSystemStore) + { + if (!CertCloseStore( + hSystemStore, 0)) + DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, "CertCloseStore failed"); + } + +} +#endif + static void destroy_local_host(_getdns_rbnode_t * node, void *arg) { getdns_context *context = (getdns_context *)arg; @@ -2631,7 +2699,8 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context, #ifndef USE_WINSOCK return GETDNS_RETURN_BAD_CONTEXT; #else - printf("Warning! Bad TLS context, check openssl version on Windows!\n");; + printf("Warning! Bad TLS context, check openssl version on Windows!\n"); + add_cacerts_to_openssl_store(context); #endif /* Be strict and only use the cipher suites recommended in RFC7525 Unless we later fallback to opportunistic. */ From 111794158c106d2ca7af712dce8857d49ba64905 Mon Sep 17 00:00:00 2001 From: Sara Dickinson Date: Wed, 27 Jan 2016 12:50:16 +0000 Subject: [PATCH 3/8] Improve Windows CA handling code --- src/context.c | 173 ++++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 83 deletions(-) diff --git a/src/context.c b/src/context.c index ae592017..65889664 100644 --- a/src/context.c +++ b/src/context.c @@ -43,14 +43,14 @@ #else #include #include -typedef unsigned short in_port_t; - -#include -#include -#include - -#include -#include +typedef unsigned short in_port_t; + +#include +#include +#include + +#include +#include #include #endif @@ -143,57 +143,59 @@ static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*, // For windows, the CA trust store is not read by openssl. // Add code to open the trust store using wincrypt API and add // the root certs into openssl trust store -X509_STORE *store; -X509_STORE_CTX *sslctx = NULL; -void add_cacerts_to_openssl_store(struct getdns_context *context) +static int +add_WIN_cacerts_to_openssl_store(SSL_CTX *tls_ctx) { - HCERTSTORE hSystemStore; - PCCERT_CONTEXT pTargetCert = NULL; - - // Call wincrypt's CertOpenStore to open the CA root store. - - if ((hSystemStore = CertOpenStore( - CERT_STORE_PROV_SYSTEM, - 0, - NULL, - // mingw does not have this const: replace with 1 << 16 from code - // CERT_SYSTEM_STORE_CURRENT_USER, - 1 << 16, - L"root")) == 0) - { - DEBUG_STUB("*** %s(CertOpenStore failed)\n", __FUNCTION__); - return; - } - store = SSL_CTX_get_cert_store(context->tls_ctx); - - // iterate over the windows cert store and add to openssl store - while (pTargetCert = CertEnumCertificatesInStore( - hSystemStore, - pTargetCert)) - { - BYTE* cert = pTargetCert->pbCertEncoded; - X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); - if (!cert1) { - DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, - "unable to parse certificate in memory"); - } - else { - if (X509_STORE_add_cert(store, cert1) == 0) - DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, - "error adding certificate"); - X509_free(cert1); - } - } - // Clean up memory and quit. - - if (pTargetCert) - CertFreeCertificateContext(pTargetCert); - if (hSystemStore) - { - if (!CertCloseStore( - hSystemStore, 0)) - DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, "CertCloseStore failed"); - } + HCERTSTORE hSystemStore; + PCCERT_CONTEXT pTargetCert = NULL; + + if !(tls_ctx) + return 1; + + // Call wincrypt's CertOpenStore to open the CA root store. + + if ((hSystemStore = CertOpenStore( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + // mingw does not have this const: replace with 1 << 16 from code + // CERT_SYSTEM_STORE_CURRENT_USER, + 1 << 16, + L"root")) == 0) + { + return 1; + } + + X509_STORE *store = SSL_CTX_get_cert_store(tls_ctx); + if (!store) + return 1; + + // iterate over the windows cert store and add to openssl store + while (pTargetCert = CertEnumCertificatesInStore( + hSystemStore, + pTargetCert)) + { + BYTE* cert = pTargetCert->pbCertEncoded; + X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); + if (!cert1) + return 1; + else { + if (X509_STORE_add_cert(store, cert1) == 0) + return 1; + X509_free(cert1); + } + } + + // Clean up memory and quit. + if (pTargetCert) + CertFreeCertificateContext(pTargetCert); + if (hSystemStore) + { + if (!CertCloseStore( + hSystemStore, 0)) + return 1; + } + return 0; } #endif @@ -2691,31 +2693,7 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context, /* Transport can in theory be set per query in stub mode */ if (context->resolution_type == GETDNS_RESOLUTION_STUB && tls_is_in_transports_list(context) == 1) { - if (context->tls_ctx == NULL) { -#ifdef HAVE_TLS_v1_2 - /* Create client context, use TLS v1.2 only for now */ - context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method()); - if(context->tls_ctx == NULL) -#ifndef USE_WINSOCK - return GETDNS_RETURN_BAD_CONTEXT; -#else - printf("Warning! Bad TLS context, check openssl version on Windows!\n"); - add_cacerts_to_openssl_store(context); -#endif - /* Be strict and only use the cipher suites recommended in RFC7525 - Unless we later fallback to opportunistic. */ - const char* const PREFERRED_CIPHERS = "EECDH+aRSA+AESGCM:EECDH+aECDSA+AESGCM:EDH+aRSA+AESGCM"; - if (!SSL_CTX_set_cipher_list(context->tls_ctx, PREFERRED_CIPHERS)) - return GETDNS_RETURN_BAD_CONTEXT; - if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) - return GETDNS_RETURN_BAD_CONTEXT; -#else - if (tls_only_is_in_transports_list(context) == 1) - return GETDNS_RETURN_BAD_CONTEXT; - /* A null tls_ctx will make TLS fail and fallback to the other - transports will kick-in.*/ -#endif - } + /* Check minimum require authentication level*/ if (tls_only_is_in_transports_list(context) == 1 && context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED) { context->tls_auth_min = GETDNS_AUTHENTICATION_REQUIRED; @@ -2724,6 +2702,35 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context, else { context->tls_auth_min = GETDNS_AUTHENTICATION_NONE; } + + if (context->tls_ctx == NULL) { +#ifdef HAVE_TLS_v1_2 + /* Create client context, use TLS v1.2 only for now */ + context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method()); + if(context->tls_ctx == NULL) + return GETDNS_RETURN_BAD_CONTEXT; + /* Be strict and only use the cipher suites recommended in RFC7525 + Unless we later fallback to opportunistic. */ + const char* const PREFERRED_CIPHERS = "EECDH+aRSA+AESGCM:EECDH+aECDSA+AESGCM:EDH+aRSA+AESGCM"; + if (!SSL_CTX_set_cipher_list(context->tls_ctx, PREFERRED_CIPHERS)) + return GETDNS_RETURN_BAD_CONTEXT; + /* For strict authentication, we must have local root certs available + Set up is done only when the tls_ctx is created (per getdns_context)*/ +#ifndef USE_WINSOCK + if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { +#else + if (!add_WIN_cacerts_to_openssl_store(context)) { +#endif /* USE_WINSOCK */ + if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) + return GETDNS_RETURN_BAD_CONTEXT; + } +#else /* HAVE_TLS_v1_2 */ + if (tls_only_is_in_transports_list(context) == 1) + return GETDNS_RETURN_BAD_CONTEXT; + /* A null tls_ctx will make TLS fail and fallback to the other + transports will kick-in.*/ +#endif /* HAVE_TLS_v1_2 */ + } } /* Block use of TLS ONLY in recursive mode as it won't work */ From 504881fc6fbfdd3391e3bafb5ef5f97ef3fd3ec8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Jan 2016 16:30:50 -0500 Subject: [PATCH 4/8] Minor fixes to compile and run the CA trust store adapter from Windows to openopenSSL --- src/context.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/context.c b/src/context.c index 65889664..4acc049b 100644 --- a/src/context.c +++ b/src/context.c @@ -144,13 +144,15 @@ static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*, // Add code to open the trust store using wincrypt API and add // the root certs into openssl trust store static int -add_WIN_cacerts_to_openssl_store(SSL_CTX *tls_ctx) +add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) { HCERTSTORE hSystemStore; PCCERT_CONTEXT pTargetCert = NULL; - if !(tls_ctx) - return 1; + // load just once per context lifetime for this version of getdns + // TODO: dynamically update CA trust changes as they are available + if (!tls_ctx) + return 0; // Call wincrypt's CertOpenStore to open the CA root store. @@ -158,30 +160,33 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX *tls_ctx) CERT_STORE_PROV_SYSTEM, 0, NULL, - // mingw does not have this const: replace with 1 << 16 from code + // NOTE: mingw does not have this const: replace with 1 << 16 from code // CERT_SYSTEM_STORE_CURRENT_USER, 1 << 16, L"root")) == 0) { - return 1; + return 0; } - X509_STORE *store = SSL_CTX_get_cert_store(tls_ctx); + X509_STORE* store = SSL_CTX_get_cert_store(tls_ctx); if (!store) - return 1; + return 0; // iterate over the windows cert store and add to openssl store while (pTargetCert = CertEnumCertificatesInStore( hSystemStore, pTargetCert)) { - BYTE* cert = pTargetCert->pbCertEncoded; X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); if (!cert1) - return 1; + // do not return if a cert fails, continue and retrieve the rest + DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, + "unable to parse certificate in memory"); else { + // do not return if a cert add to store fails, continue and retrieve the rest if (X509_STORE_add_cert(store, cert1) == 0) - return 1; + DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, + "error adding certificate"); X509_free(cert1); } } @@ -193,9 +198,9 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX *tls_ctx) { if (!CertCloseStore( hSystemStore, 0)) - return 1; + return 0; } - return 0; + return 1; } #endif @@ -2719,7 +2724,7 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context, #ifndef USE_WINSOCK if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { #else - if (!add_WIN_cacerts_to_openssl_store(context)) { + if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) { #endif /* USE_WINSOCK */ if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) return GETDNS_RETURN_BAD_CONTEXT; From f5290b6a68cb74a5c738c4701f81b8f15ab16750 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 31 Jan 2016 00:13:09 -0500 Subject: [PATCH 5/8] add change from Sara to return if a cert conversion or add to store fails --- src/context.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/context.c b/src/context.c index 4acc049b..98c38cd1 100644 --- a/src/context.c +++ b/src/context.c @@ -177,16 +177,24 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) hSystemStore, pTargetCert)) { - X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); - if (!cert1) + X509 *cert1 = d2i_X509(NULL, + (const unsigned char **)&pTargetCert->pbCertEncoded, + pTargetCert->cbCertEncoded); + if (!cert1) { // do not return if a cert fails, continue and retrieve the rest - DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, - "unable to parse certificate in memory"); + DEBUG_STUB("*** %s(%s %d:%s)\n", __FUNCTION__, + "unable to parse certificate in memory", + ERR_get_error(), ERR_error_string(ERR_get_error(), NULL)); + return 0; + } else { // do not return if a cert add to store fails, continue and retrieve the rest - if (X509_STORE_add_cert(store, cert1) == 0) - DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, - "error adding certificate"); + if (X509_STORE_add_cert(store, cert1) == 0) { + DEBUG_STUB("*** %s(%s %d:%s)\n", __FUNCTION__, + "error adding certificate", ERR_get_error(), + ERR_error_string(ERR_get_error(), NULL)); + return 0; + } X509_free(cert1); } } From 170795ad0664a956f921e5edfc8eeb2e96a69783 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Feb 2016 10:56:45 -0500 Subject: [PATCH 6/8] More review changes and made comments C style, req Willem. --- src/context.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/context.c b/src/context.c index 98c38cd1..19249049 100644 --- a/src/context.c +++ b/src/context.c @@ -140,28 +140,28 @@ static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*, #ifdef USE_WINSOCK -// For windows, the CA trust store is not read by openssl. -// Add code to open the trust store using wincrypt API and add -// the root certs into openssl trust store +/* For windows, the CA trust store is not read by openssl. + Add code to open the trust store using wincrypt API and add + the root certs into openssl trust store */ static int add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) { HCERTSTORE hSystemStore; PCCERT_CONTEXT pTargetCert = NULL; - // load just once per context lifetime for this version of getdns - // TODO: dynamically update CA trust changes as they are available + /* load just once per context lifetime for this version of getdns + TODO: dynamically update CA trust changes as they are available */ if (!tls_ctx) return 0; - // Call wincrypt's CertOpenStore to open the CA root store. + /* Call wincrypt's CertOpenStore to open the CA root store. */ if ((hSystemStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, - NULL, - // NOTE: mingw does not have this const: replace with 1 << 16 from code - // CERT_SYSTEM_STORE_CURRENT_USER, + 0, + /* NOTE: mingw does not have this const: replace with 1 << 16 from code + CERT_SYSTEM_STORE_CURRENT_USER, */ 1 << 16, L"root")) == 0) { @@ -172,23 +172,28 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) if (!store) return 0; - // iterate over the windows cert store and add to openssl store - while (pTargetCert = CertEnumCertificatesInStore( - hSystemStore, - pTargetCert)) + /* failure if the CA store is empty or the call fails */ + if ((pTargetCert = CertEnumCertificatesInStore( + hSystemStore, pTargetCert)) == 0) { + DEBUG_STUB("*** %s(%s %d:%s)\n", __FUNCTION__, + "CA certificate store for Windows is empty."); + return 0; + } + /* iterate over the windows cert store and add to openssl store */ + do { X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); if (!cert1) { - // do not return if a cert fails, continue and retrieve the rest + /* return error if a cert fails */ DEBUG_STUB("*** %s(%s %d:%s)\n", __FUNCTION__, "unable to parse certificate in memory", ERR_get_error(), ERR_error_string(ERR_get_error(), NULL)); return 0; } else { - // do not return if a cert add to store fails, continue and retrieve the rest + /* return error if a cert add to store fails */ if (X509_STORE_add_cert(store, cert1) == 0) { DEBUG_STUB("*** %s(%s %d:%s)\n", __FUNCTION__, "error adding certificate", ERR_get_error(), @@ -197,9 +202,10 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) } X509_free(cert1); } - } + } while ((pTargetCert = CertEnumCertificatesInStore( + hSystemStore, pTargetCert)) != 0); - // Clean up memory and quit. + /* Clean up memory and quit. */ if (pTargetCert) CertFreeCertificateContext(pTargetCert); if (hSystemStore) @@ -209,7 +215,6 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) return 0; } return 1; - } #endif From db4207f60d9efa8f54ffc81e6cb8030a9033ff57 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Feb 2016 11:02:24 -0500 Subject: [PATCH 7/8] More review changes and made comments C style, req Willem. --- src/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index 19249049..78e6835f 100644 --- a/src/context.c +++ b/src/context.c @@ -51,7 +51,7 @@ typedef unsigned short in_port_t; #include #include -#include +#include #endif #include From 466302131e57266dd2820e78277fc2dd4dc10b78 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 3 Feb 2016 14:57:09 +0100 Subject: [PATCH 8/8] Don't treat "domain" or "search" as a nameserver. Continue the while fgets() loop as soon as we're done with "domain" or "search". Simplify the logic of the function by removing the if else constructs. --- src/context.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/context.c b/src/context.c index c47d4992..89491179 100644 --- a/src/context.c +++ b/src/context.c @@ -864,8 +864,9 @@ set_os_defaults(struct getdns_context *context) *token = 0; (void) strlcpy(domain, parse, sizeof(domain)); - - } else if (strncmp(parse, "search", 6) == 0) { + continue; + } + if (strncmp(parse, "search", 6) == 0) { parse += 6; do { parse += strspn(parse, " \t"); @@ -879,8 +880,9 @@ set_os_defaults(struct getdns_context *context) *token = prev_ch; parse = token; } while (*parse); - - } else if (strncmp(parse, "nameserver", 10) != 0) + continue; + } + if (strncmp(parse, "nameserver", 10) != 0) continue; parse += 10;