diff options
Diffstat (limited to 'lib/dns/gssapictx.c')
-rw-r--r-- | lib/dns/gssapictx.c | 88 |
1 files changed, 75 insertions, 13 deletions
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index 11eadb9..f365a64 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gssapictx.c,v 1.12 2008/04/03 06:09:04 tbox Exp $ */ +/* $Id: gssapictx.c,v 1.12.118.5 2010-12-22 02:37:55 marka Exp $ */ #include <config.h> @@ -29,6 +29,7 @@ #include <isc/mem.h> #include <isc/once.h> #include <isc/print.h> +#include <isc/platform.h> #include <isc/random.h> #include <isc/string.h> #include <isc/time.h> @@ -66,6 +67,7 @@ * we include SPNEGO's OID. */ #if defined(GSSAPI) +#include ISC_PLATFORM_KRB5HEADER static unsigned char krb5_mech_oid_bytes[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 @@ -130,7 +132,7 @@ name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer, namep = &tname; } - result = dns_name_totext(namep, ISC_FALSE, buffer); + result = dns_name_toprincipal(namep, buffer); isc_buffer_putuint8(buffer, 0); isc_buffer_usedregion(buffer, &r); REGION_TO_GBUFFER(r, *gbuffer); @@ -191,6 +193,54 @@ log_cred(const gss_cred_id_t cred) { } #endif +#ifdef GSSAPI +/* + * check for the most common configuration errors. + * + * The errors checked for are: + * - tkey-gssapi-credential doesn't start with DNS/ + * - the default realm in /etc/krb5.conf and the + * tkey-gssapi-credential bind config option don't match + */ +static void +dst_gssapi_check_config(const char *gss_name) { + const char *p; + krb5_context krb5_ctx; + char *krb5_realm = NULL; + + if (strncasecmp(gss_name, "DNS/", 4) != 0) { + gss_log(ISC_LOG_ERROR, "tkey-gssapi-credential (%s) " + "should start with 'DNS/'", gss_name); + return; + } + + if (krb5_init_context(&krb5_ctx) != 0) { + gss_log(ISC_LOG_ERROR, "Unable to initialise krb5 context"); + return; + } + if (krb5_get_default_realm(krb5_ctx, &krb5_realm) != 0) { + gss_log(ISC_LOG_ERROR, "Unable to get krb5 default realm"); + krb5_free_context(krb5_ctx); + return; + } + p = strchr(gss_name, '/'); + if (p == NULL) { + gss_log(ISC_LOG_ERROR, "badly formatted " + "tkey-gssapi-credentials (%s)", gss_name); + krb5_free_context(krb5_ctx); + return; + } + if (strcasecmp(p + 1, krb5_realm) != 0) { + gss_log(ISC_LOG_ERROR, "default realm from krb5.conf (%s) " + "does not match tkey-gssapi-credential (%s)", + krb5_realm, gss_name); + krb5_free_context(krb5_ctx); + return; + } + krb5_free_context(krb5_ctx); +} +#endif + isc_result_t dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, gss_cred_id_t *cred) @@ -223,6 +273,8 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); if (gret != GSS_S_COMPLETE) { + dst_gssapi_check_config((char *)array); + gss_log(3, "failed gss_import_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); @@ -254,6 +306,7 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, initiate ? "initiate" : "accept", (char *)gnamebuf.value, gss_error_tostring(gret, minor, buf, sizeof(buf))); + dst_gssapi_check_config((char *)array); return (ISC_R_FAILURE); } @@ -283,12 +336,15 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name, char rbuf[DNS_NAME_FORMATSIZE]; char *sname; char *rname; + isc_buffer_t buffer; /* * It is far, far easier to write the names we are looking at into * a string, and do string operations on them. */ - dns_name_format(signer, sbuf, sizeof(sbuf)); + isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); + dns_name_toprincipal(signer, &buffer); + isc_buffer_putuint8(&buffer, 0); if (name != NULL) dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); @@ -298,11 +354,11 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name, * does not exist, we don't have something we like, so we fail our * compare. */ - rname = strstr(sbuf, "\\@"); + rname = strchr(sbuf, '@'); if (rname == NULL) return (isc_boolean_false); *rname = '\0'; - rname += 2; + rname++; /* * Find the host portion of the signer's name. We do this by @@ -352,12 +408,15 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name, char *sname; char *nname; char *rname; + isc_buffer_t buffer; /* * It is far, far easier to write the names we are looking at into * a string, and do string operations on them. */ - dns_name_format(signer, sbuf, sizeof(sbuf)); + isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); + dns_name_toprincipal(signer, &buffer); + isc_buffer_putuint8(&buffer, 0); if (name != NULL) dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); @@ -367,17 +426,17 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name, * does not exist, we don't have something we like, so we fail our * compare. */ - rname = strstr(sbuf, "\\@"); + rname = strchr(sbuf, '@'); if (rname == NULL) return (isc_boolean_false); - sname = strstr(sbuf, "\\$"); + sname = strchr(sbuf, '$'); if (sname == NULL) return (isc_boolean_false); /* * Verify that the $ and @ follow one another. */ - if (rname - sname != 2) + if (rname - sname != 1) return (isc_boolean_false); /* @@ -389,8 +448,7 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name, * machinename$@EXAMPLE.COM * format. */ - *rname = '\0'; - rname += 2; + rname++; *sname = '\0'; sname = sbuf; @@ -488,8 +546,12 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, gintokenp = NULL; } + /* + * Note that we don't set GSS_C_SEQUENCE_FLAG as Windows DNS + * servers don't like it. + */ flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG | - GSS_C_SEQUENCE_FLAG | GSS_C_INTEG_FLAG; + GSS_C_INTEG_FLAG; gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx, gname, GSS_SPNEGO_MECHANISM, flags, |