Skip to content

Commit

Permalink
Test that PAC is the first authdata element
Browse files Browse the repository at this point in the history
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]

(cherry picked from commit d40d7c8)

ticket: 8872
version_fixed: 1.18
  • Loading branch information
iboukris authored and greghudson committed Feb 10, 2020
1 parent ca0e1e9 commit 0117361
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
7 changes: 4 additions & 3 deletions src/plugins/kdb/test/kdb_test.c
Expand Up @@ -897,10 +897,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;

Expand Down
54 changes: 47 additions & 7 deletions src/tests/adata.c
Expand Up @@ -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)
Expand Down Expand Up @@ -206,21 +207,26 @@ 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;

if (ad->ad_type == KRB5_AUTHDATA_IF_RELEVANT ||
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);

Expand All @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0117361

Please sign in to comment.