krb5 commit: Enforce auth indicator restrictions in KDC

Greg Hudson ghudson at mit.edu
Wed Jul 22 13:29:41 EDT 2015


https://github.com/krb5/krb5/commit/24dc279b9b14fe8d6674fdd2a9210c1e1fb52e37
commit 24dc279b9b14fe8d6674fdd2a9210c1e1fb52e37
Author: Greg Hudson <ghudson at mit.edu>
Date:   Wed Jan 28 17:10:36 2015 -0500

    Enforce auth indicator restrictions in KDC
    
    If the string attribute "require_auth" is set on a the server
    principal of an AS or TGS request, deny the request unless one of the
    named indicators is present was asserted for the client's initial
    authentication.
    
    ticket: 8157

 src/include/kdb.h    |    1 +
 src/kdc/do_as_req.c  |    7 +++++++
 src/kdc/do_tgs_req.c |    6 ++++++
 src/kdc/kdc_util.c   |   36 ++++++++++++++++++++++++++++++++++++
 src/kdc/kdc_util.h   |    4 ++++
 5 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/src/include/kdb.h b/src/include/kdb.h
index 67d7557..9d3bf9d 100644
--- a/src/include/kdb.h
+++ b/src/include/kdb.h
@@ -137,6 +137,7 @@
 
 /* String attribute names recognized by krb5 */
 #define KRB5_KDB_SK_SESSION_ENCTYPES            "session_enctypes"
+#define KRB5_KDB_SK_REQUIRE_AUTH                "require_auth"
 
 #if !defined(_WIN32)
 
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 1a76ada..64e849d 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -198,6 +198,13 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
         goto egress;
     }
 
+    errcode = check_indicators(kdc_context, state->server,
+                               state->auth_indicators);
+    if (errcode) {
+        state->status = "HIGHER_AUTHENTICATION_REQUIRED";
+        goto egress;
+    }
+
     state->ticket_reply.enc_part2 = &state->enc_tkt_reply;
 
     /*
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index d196569..cb2cf35 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -392,6 +392,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
         }
     }
 
+    errcode = check_indicators(kdc_context, server, auth_indicators);
+    if (errcode) {
+        status = "HIGHER_AUTHENTICATION_REQUIRED";
+        goto cleanup;
+    }
+
     if (is_referral)
         ticket_reply.server = server->princ;
     else
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index ec36510..776e130 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -774,6 +774,42 @@ validate_forwardable(krb5_kdc_req *request, krb5_db_entry client,
         return 0;
 }
 
+/* Return KRB5KDC_ERR_POLICY if indicators does not contain the required auth
+ * indicators for server, ENOMEM on allocation error, 0 otherwise. */
+krb5_error_code
+check_indicators(krb5_context context, krb5_db_entry *server,
+                 krb5_data *const *indicators)
+{
+    krb5_error_code ret;
+    char *str = NULL, *copy = NULL, *save, *ind;
+
+    ret = krb5_dbe_get_string(context, server, KRB5_KDB_SK_REQUIRE_AUTH, &str);
+    if (ret || str == NULL)
+        goto cleanup;
+    copy = strdup(str);
+    if (copy == NULL) {
+        ret = ENOMEM;
+        goto cleanup;
+    }
+
+    /* Look for any of the space-separated strings in indicators. */
+    ind = strtok_r(copy, " ", &save);
+    while (ind != NULL) {
+        if (authind_contains(indicators, ind))
+            goto cleanup;
+        ind = strtok_r(NULL, " ", &save);
+    }
+
+    ret = KRB5KDC_ERR_POLICY;
+    k5_setmsg(context, ret,
+              _("Required auth indicators not present in ticket: %s"), str);
+
+cleanup:
+    krb5_dbe_free_string(context, str);
+    free(copy);
+    return ret;
+}
+
 #define ASN1_ID_CLASS   (0xc0)
 #define ASN1_ID_TYPE    (0x20)
 #define ASN1_ID_TAG     (0x1f)
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 9b4a5df..0f49ca0 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -95,6 +95,10 @@ validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
                       krb5_ticket *, krb5_timestamp,
                       const char **, krb5_pa_data ***);
 
+krb5_error_code
+check_indicators(krb5_context context, krb5_db_entry *server,
+                 krb5_data *const *indicators);
+
 int
 fetch_asn1_field (unsigned char *, unsigned int, unsigned int, krb5_data *);
 


More information about the cvs-krb5 mailing list