krb5 commit: Stop using wshelper for SRV/TXT lookups

Greg Hudson ghudson at mit.edu
Tue Jun 12 19:24:06 EDT 2018


https://github.com/krb5/krb5/commit/67de45e349912caccfba73aff6ebda111281e819
commit 67de45e349912caccfba73aff6ebda111281e819
Author: Greg Hudson <ghudson at mit.edu>
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 */


More information about the cvs-krb5 mailing list