krb5 commit: Stop using wshelper for SRV/TXT lookups

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/67de45e349912caccfba73aff6ebda111281e819
commit 67de45e349912caccfba73aff6ebda111281e819
Author: Greg Hudson <[email protected]>
Date:   Sun Jun 3 16:41:18 2018 -0400

    Stop using wshelper for SRV/TXT lookups
    
    Add Windows-specific versions of k5_try_realm_txt_rr(),
    k5_make_uri_query(), and krb5int_make_srv_query_realm(), bypassing
    wshelper and using DnsQuery_UTF8() directly.  Windows does not
    currently know how to decode URI records and has no interface to allow
    the caller to do so, so disable URI lookups on Windows for now.
    
    Add a comment that dnsglue.h is not used on Windows (since DnsQuery
    parses out and decodes SRV and TXT records for us), and remove the
    header conditionals from it.
    
    ticket: 8687

 src/config/win-pre.in     |   21 +--------
 src/lib/Makefile.in       |    2 +-
 src/lib/krb5/os/dnsglue.c |  108 ++++++++++++++++++++++++++++++++++----------
 src/lib/krb5/os/dnsglue.h |    7 +--
 src/lib/krb5/os/dnssrv.c  |   79 +++++++++++++++++++++++++++++++-
 5 files changed, 164 insertions(+), 53 deletions(-)

diff --git a/src/config/win-pre.in b/src/config/win-pre.in
index 8190415..384868f 100644
--- a/src/config/win-pre.in
+++ b/src/config/win-pre.in
@@ -88,25 +88,8 @@ C=.^\
 srcdir = .
 top_srcdir = $(srcdir)\$(BUILDTOP)
 
-DNS_LIB=$(BUILDTOP)\util\wshelper\$(OUTPRE)$(DLIB).lib
-DNS_INC=$(BUILDTOP)\windows\include
-
-!if defined(KRB5_NO_WSHELPER)
-DNSMSG=resolver
-!else
-DNSMSG=wshelper
-DNSFLAGS=-DWSHELPER=1
-!endif
-!if !defined(DNS_INC)
-!message Must define DNS_INC to point to $(DNSMSG) includes dir!
-!error
-!endif
-!if !defined(DNS_LIB)
-!message Must define DNS_LIB to point to $(DNSMSG) library!
-!error
-!endif
-DNSLIBS=$(DNS_LIB)
-DNSFLAGS=-I$(DNS_INC) $(DNSFLAGS) -DKRB5_DNS_LOOKUP=1
+DNSLIBS=dnsapi.lib
+DNSFLAGS=-DKRB5_DNS_LOOKUP=1
 !if defined(KRB5_USE_DNS_REALMS)
 DNSFLAGS=$(DNSFLAGS) -DKRB5_DNS_LOOKUP_REALM=1
 !endif
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 7f50b7d..6817184 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -118,7 +118,7 @@ clean-windows::
 ##WIN32##	  $(PLIBS) $(PGLUE) $(PRES) $(CLIB) $(SLIB) $(WINLIBS)
 ##WIN32##	$(_VC_MANIFEST_EMBED_DLL)
 
-##WIN32##$(KLIB): $(KDEF) $(KLIBS) $(KGLUE) $(KRES) $(CLIB) $(SLIB) $(MITLIBS) $(DNSLIBS)
+##WIN32##$(KLIB): $(KDEF) $(KLIBS) $(KGLUE) $(KRES) $(CLIB) $(SLIB) $(MITLIBS)
 ##WIN32##	link $(WINDLLFLAGS) -def:$(KDEF) -out:$*.dll \
 ##WIN32##	  $(KLIBS) $(KGLUE) $(KRES) $(CLIB) $(SLIB) $(MITLIBS) $(DNSLIBS) $(WINLIBS)
 ##WIN32##	$(_VC_MANIFEST_EMBED_DLL)
diff --git a/src/lib/krb5/os/dnsglue.c b/src/lib/krb5/os/dnsglue.c
index 86138c4..59ff929 100644
--- a/src/lib/krb5/os/dnsglue.c
+++ b/src/lib/krb5/os/dnsglue.c
@@ -24,9 +24,13 @@
  * or implied warranty.
  */
 
-#include "autoconf.h"
+#include "k5-int.h"
+#include "os-proto.h"
+
 #ifdef KRB5_DNS_LOOKUP
 
+#ifndef _WIN32
+
 #include "dnsglue.h"
 #ifdef __APPLE__
 #include <dns.h>
@@ -352,12 +356,85 @@ out:
     return -1;
 }
 
-#endif
+#endif /* !HAVE_NS_INITPARSE */
+#endif /* not _WIN32 */
+
+/* Construct a DNS label of the form "prefix[.name.]".  name may be NULL. */
+static char *
+txt_lookup_name(const char *prefix, const char *name)
+{
+    struct k5buf buf;
+
+    k5_buf_init_dynamic(&buf);
+
+    if (name == NULL || name[0] == '\0') {
+        k5_buf_add(&buf, prefix);
+    } else {
+        k5_buf_add_fmt(&buf, "%s.%s", prefix, name);
+
+        /*
+         * Realm names don't (normally) end with ".", but if the query doesn't
+         * end with "." and doesn't get an answer as is, the resolv code will
+         * try appending the local domain.  Since the realm names are
+         * absolutes, let's stop that.
+         *
+         * But only if a name has been specified.  If we are performing a
+         * search on the prefix alone then the intention is to allow the local
+         * domain or domain search lists to be expanded.
+         */
+
+        if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.')
+            k5_buf_add(&buf, ".");
+    }
+
+    return buf.data;
+}
 
 /*
  * Try to look up a TXT record pointing to a Kerberos realm
  */
 
+#ifdef _WIN32
+
+#include <windns.h>
+
+krb5_error_code
+k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name,
+                    char **realm)
+{
+    krb5_error_code ret = 0;
+    char *txtname = NULL;
+    PDNS_RECORD rr = NULL;
+    DNS_STATUS st;
+
+    *realm = NULL;
+
+    txtname = txt_lookup_name(prefix, name);
+    if (txtname == NULL)
+        return ENOMEM;
+
+    st = DnsQuery_UTF8(txtname, DNS_TYPE_TEXT, DNS_QUERY_STANDARD, NULL,
+                       &rr, NULL);
+    if (st != ERROR_SUCCESS || rr == NULL) {
+        TRACE_TXT_LOOKUP_NOTFOUND(context, txtname);
+        ret = KRB5_ERR_HOST_REALM_UNKNOWN;
+        goto cleanup;
+    }
+
+    *realm = strdup(rr->Data.TXT.pStringArray[0]);
+    if (*realm == NULL)
+        ret = ENOMEM;
+    TRACE_TXT_LOOKUP_SUCCESS(context, txtname, *realm);
+
+cleanup:
+    free(txtname);
+    if (rr != NULL)
+        DnsRecordListFree(rr, DnsFreeRecordList);
+    return ret;
+}
+
+#else /* _WIN32 */
+
 krb5_error_code
 k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name,
                     char **realm)
@@ -367,34 +444,14 @@ k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name,
     char *txtname = NULL;
     int ret, rdlen, len;
     struct krb5int_dns_state *ds = NULL;
-    struct k5buf buf;
 
     /*
      * Form our query, and send it via DNS
      */
 
-    k5_buf_init_dynamic(&buf);
-    if (name == NULL || name[0] == '\0') {
-        k5_buf_add(&buf, prefix);
-    } else {
-        k5_buf_add_fmt(&buf, "%s.%s", prefix, name);
-
-        /* Realm names don't (normally) end with ".", but if the query
-           doesn't end with "." and doesn't get an answer as is, the
-           resolv code will try appending the local domain.  Since the
-           realm names are absolutes, let's stop that.
-
-           But only if a name has been specified.  If we are performing
-           a search on the prefix alone then the intention is to allow
-           the local domain or domain search lists to be expanded.
-        */
-
-        if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.')
-            k5_buf_add(&buf, ".");
-    }
-    if (k5_buf_status(&buf) != 0)
-        return KRB5_ERR_HOST_REALM_UNKNOWN;
-    txtname = buf.data;
+    txtname = txt_lookup_name(prefix, name);
+    if (txtname == NULL)
+        return ENOMEM;
     ret = krb5int_dns_init(&ds, txtname, C_IN, T_TXT);
     if (ret < 0) {
         TRACE_TXT_LOOKUP_NOTFOUND(context, txtname);
@@ -428,4 +485,5 @@ errout:
     return retval;
 }
 
+#endif /* not _WIN32 */
 #endif /* KRB5_DNS_LOOKUP */
diff --git a/src/lib/krb5/os/dnsglue.h b/src/lib/krb5/os/dnsglue.h
index b5d054a..9e98735 100644
--- a/src/lib/krb5/os/dnsglue.h
+++ b/src/lib/krb5/os/dnsglue.h
@@ -26,7 +26,8 @@
 
 /*
  * Glue layer for DNS resolver, to make parsing of replies easier
- * whether we are using BIND 4, 8, or 9.
+ * whether we are using BIND 4, 8, or 9.  This header is not used on
+ * Windows.
  */
 
 /*
@@ -50,15 +51,11 @@
 
 #include "k5-int.h"
 #include "os-proto.h"
-#ifdef WSHELPER
-#include <wshelper.h>
-#else /* WSHELPER */
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
 #include <netdb.h>
-#endif /* WSHELPER */
 
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>          /* for MAXHOSTNAMELEN */
diff --git a/src/lib/krb5/os/dnssrv.c b/src/lib/krb5/os/dnssrv.c
index ff14b56..02ba879 100644
--- a/src/lib/krb5/os/dnssrv.c
+++ b/src/lib/krb5/os/dnssrv.c
@@ -26,8 +26,8 @@
 
 #include "autoconf.h"
 #ifdef KRB5_DNS_LOOKUP
-
-#include "dnsglue.h"
+#include "k5-int.h"
+#include "os-proto.h"
 
 /*
  * Lookup a KDC via DNS SRV records
@@ -102,6 +102,77 @@ place_srv_entry(struct srv_dns_entry **head, struct srv_dns_entry *new)
     }
 }
 
+#ifdef _WIN32
+
+#include <windns.h>
+
+krb5_error_code
+k5_make_uri_query(krb5_context context, const krb5_data *realm,
+                  const char *service, struct srv_dns_entry **answers)
+{
+    /* Windows does not currently support the URI record type or make it
+     * possible to query for a record type it does not have support for. */
+    *answers = NULL;
+    return 0;
+}
+
+krb5_error_code
+krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
+                             const char *service, const char *protocol,
+                             struct srv_dns_entry **answers)
+{
+    char *name = NULL;
+    DNS_STATUS st;
+    PDNS_RECORD records, rr;
+    struct srv_dns_entry *head = NULL, *srv = NULL;
+
+    *answers = NULL;
+
+    name = make_lookup_name(realm, service, protocol);
+    if (name == NULL)
+        return 0;
+
+    TRACE_DNS_SRV_SEND(context, name);
+
+    st = DnsQuery_UTF8(name, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &records,
+                       NULL);
+    if (st != ERROR_SUCCESS)
+        return 0;
+
+    for (rr = records; rr != NULL; rr = rr->pNext) {
+        if (rr->wType != DNS_TYPE_SRV)
+            continue;
+
+        srv = malloc(sizeof(struct srv_dns_entry));
+        if (srv == NULL)
+            goto cleanup;
+
+        srv->priority = rr->Data.SRV.wPriority;
+        srv->weight = rr->Data.SRV.wWeight;
+        srv->port = rr->Data.SRV.wPort;
+        /* Make sure the name looks fully qualified to the resolver. */
+        if (asprintf(&srv->host, "%s.", rr->Data.SRV.pNameTarget) < 0) {
+            free(srv);
+            goto cleanup;
+        }
+
+        TRACE_DNS_SRV_ANS(context, srv->host, srv->port, srv->priority,
+                          srv->weight);
+        place_srv_entry(&head, srv);
+    }
+
+cleanup:
+    free(name);
+    if (records != NULL)
+        DnsRecordListFree(records, DnsFreeRecordList);
+    *answers = head;
+    return 0;
+}
+
+#else /* _WIN32 */
+
+#include "dnsglue.h"
+
 /* Query the URI RR, collecting weight, priority, and target. */
 krb5_error_code
 k5_make_uri_query(krb5_context context, const krb5_data *realm,
@@ -251,4 +322,6 @@ out:
     *answers = head;
     return 0;
 }
-#endif
+
+#endif /* not _WIN32 */
+#endif /* KRB5_DNS_LOOKUP */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.