From: Greg Hudson Date: Wed, 28 Jan 2015 22:10:36 +0000 (-0500) Subject: Enforce auth indicator restrictions in KDC X-Git-Tag: krb5-1.14-alpha1~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24dc279b9b14fe8d6674fdd2a9210c1e1fb52e37;p=thirdparty%2Fkrb5.git 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 --- diff --git a/src/include/kdb.h b/src/include/kdb.h index 67d7557556..9d3bf9d85f 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 1a76adabe6..64e849d5b1 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 d196569b3b..cb2cf35773 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 ec36510dae..776e130e55 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 9b4a5df5d9..0f49ca0813 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 *);