From: Isaac Boukris Date: Sat, 1 Feb 2020 12:21:39 +0000 (+0100) Subject: Test that PAC is the first authdata element X-Git-Tag: krb5-1.19-beta1~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1033%2Fhead;p=thirdparty%2Fkrb5.git Test that PAC is the first authdata element In the test KDB module, set the PAC as the first authdata element. In adata.c, add PAC service verification and verify that a PAC does not appear in authdata elements after the first. [ghudson@mit.edu: minor style changes; edited commit message] ticket: 8872 --- diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c index 4f8ea78644..8aac306aa3 100644 --- a/src/plugins/kdb/test/kdb_test.c +++ b/src/plugins/kdb/test/kdb_test.c @@ -922,10 +922,11 @@ test_sign_authdata(krb5_context context, unsigned int flags, test_ad->contents = (uint8_t *)estrdup("db-authdata-test"); test_ad->length = strlen((char *)test_ad->contents); - /* Assemble the authdata into a one-element or two-element list. */ + /* Assemble the authdata into a one-element or two-element list. + * The PAC must be the first element. */ list = ealloc(3 * sizeof(*list)); - list[0] = test_ad; - list[1] = pac_ad; + list[0] = (pac_ad != NULL) ? pac_ad : test_ad; + list[1] = (pac_ad != NULL) ? test_ad : NULL; list[2] = NULL; *signed_auth_data = list; diff --git a/src/tests/adata.c b/src/tests/adata.c index d3bd08e307..3869aec1d5 100644 --- a/src/tests/adata.c +++ b/src/tests/adata.c @@ -56,7 +56,8 @@ static krb5_context ctx; static void display_authdata_list(krb5_authdata **list, krb5_keyblock *skey, - krb5_keyblock *tktkey, char prefix_byte); + krb5_keyblock *tktkey, char prefix_byte, + krb5_boolean pac_expected); static void check(krb5_error_code code) @@ -206,7 +207,7 @@ display_binary_or_ascii(krb5_authdata *ad) * must be the ticket session key. */ static void display_authdata(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey, - int prefix_byte) + int prefix_byte, krb5_boolean pac_expected) { krb5_authdata **inner_ad; @@ -214,13 +215,18 @@ display_authdata(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey, ad->ad_type == KRB5_AUTHDATA_MANDATORY_FOR_KDC || ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED || ad->ad_type == KRB5_AUTHDATA_CAMMAC) { + if (ad->ad_type != KRB5_AUTHDATA_IF_RELEVANT) + pac_expected = FALSE; /* Decode and display the contents. */ inner_ad = get_container_contents(ad, skey, tktkey); - display_authdata_list(inner_ad, skey, tktkey, get_prefix_byte(ad)); + display_authdata_list(inner_ad, skey, tktkey, get_prefix_byte(ad), + pac_expected); krb5_free_authdata(ctx, inner_ad); return; } + assert(!pac_expected || ad->ad_type == KRB5_AUTHDATA_WIN2K_PAC); + printf("%c", prefix_byte); printf("%d: ", (int)ad->ad_type); @@ -233,12 +239,43 @@ display_authdata(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey, static void display_authdata_list(krb5_authdata **list, krb5_keyblock *skey, - krb5_keyblock *tktkey, char prefix_byte) + krb5_keyblock *tktkey, char prefix_byte, + krb5_boolean pac_expected) { if (list == NULL) return; - for (; *list != NULL; list++) - display_authdata(*list, skey, tktkey, prefix_byte); + /* Only expect a PAC in the first element, if at all. */ + for (; *list != NULL; list++) { + display_authdata(*list, skey, tktkey, prefix_byte, pac_expected); + pac_expected = FALSE; + } +} + +/* If a PAC is present in enc_part2, verify its service signature with key and + * set *has_pac to true. */ +static void +check_pac(krb5_context context, krb5_enc_tkt_part *enc_part2, + const krb5_keyblock *key, krb5_boolean *has_pac) +{ + krb5_authdata **authdata; + krb5_pac pac; + + *has_pac = FALSE; + + check(krb5_find_authdata(context, enc_part2->authorization_data, NULL, + KRB5_AUTHDATA_WIN2K_PAC, &authdata)); + if (authdata == NULL) + return; + + assert(authdata[1] == NULL); + check(krb5_pac_parse(context, authdata[0]->contents, authdata[0]->length, + &pac)); + krb5_free_authdata(context, authdata); + + check(krb5_pac_verify(context, pac, enc_part2->times.authtime, + enc_part2->client, key, NULL)); + krb5_pac_free(context, pac); + *has_pac = TRUE; } int @@ -252,6 +289,7 @@ main(int argc, char **argv) krb5_ticket *ticket; krb5_authdata **req_authdata = NULL, *ad; krb5_keytab_entry ktent; + krb5_boolean with_pac; size_t count; int c; @@ -311,8 +349,10 @@ main(int argc, char **argv) ticket->enc_part.enctype, &ktent)); check(krb5_decrypt_tkt_part(ctx, &ktent.key, ticket)); + check_pac(ctx, ticket->enc_part2, &ktent.key, &with_pac); display_authdata_list(ticket->enc_part2->authorization_data, - ticket->enc_part2->session, &ktent.key, ' '); + ticket->enc_part2->session, &ktent.key, ' ', + with_pac); while (count > 0) { free(req_authdata[--count]->contents);