Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix transit path validation CVE-2017-6594
Commit f469fc6 (2010-10-02) inadvertently caused the previous hop realm
to not be added to the transit path of issued tickets.  This may, in
some cases, enable bypass of capath policy in Heimdal versions 1.5
through 7.2.

Note, this may break sites that rely on the bug.  With the bug some
incomplete [capaths] worked, that should not have.  These may now break
authentication in some cross-realm configurations.
  • Loading branch information
Viktor Dukhovni authored and nicowilliams committed Apr 13, 2017
1 parent d5dd5aa commit b1e6991
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
14 changes: 14 additions & 0 deletions NEWS
@@ -1,3 +1,17 @@
Release Notes - Heimdal - Version Heimdal 7.3

Security

- Fix transit path validation. Commit f469fc6 (2010-10-02) inadvertently
caused the previous hop realm to not be added to the transit path
of issued tickets. This may, in some cases, enable bypass of capath
policy in Heimdal versions 1.5 through 7.2.

Note, this may break sites that rely on the bug. With the bug some
incomplete [capaths] worked, that should not have. These may now break
authentication in some cross-realm configurations.
(CVE-2017-6594)

Release Notes - Heimdal - Version Heimdal 7.2

Bug fixes
Expand Down
12 changes: 10 additions & 2 deletions kdc/krb5tgs.c
Expand Up @@ -655,8 +655,12 @@ fix_transited_encoding(krb5_context context,
"Decoding transited encoding");
return ret;
}

/*
* If the realm of the presented tgt is neither the client nor the server
* realm, it is a transit realm and must be added to transited set.
*/
if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
/* not us, so add the previous realm to transited set */
if (num_realms + 1 > UINT_MAX/sizeof(*realms)) {
ret = ERANGE;
goto free_realms;
Expand Down Expand Up @@ -737,6 +741,7 @@ tgs_make_reply(krb5_context context,
const char *server_name,
hdb_entry_ex *client,
krb5_principal client_principal,
const char *tgt_realm,
hdb_entry_ex *krbtgt,
krb5_enctype krbtgt_etype,
krb5_principals spp,
Expand Down Expand Up @@ -798,7 +803,7 @@ tgs_make_reply(krb5_context context,
&tgt->transited, &et,
krb5_principal_get_realm(context, client_principal),
krb5_principal_get_realm(context, server->entry.principal),
krb5_principal_get_realm(context, krbtgt->entry.principal));
tgt_realm);
if(ret)
goto out;

Expand Down Expand Up @@ -1519,6 +1524,8 @@ tgs_build_reply(krb5_context context,
krb5_keyblock sessionkey;
krb5_kvno kvno;
krb5_data rspac;
const char *tgt_realm = /* Realm of TGT issuer */
krb5_principal_get_realm(context, krbtgt->entry.principal);
const char *our_realm = /* Realm of this KDC */
krb5_principal_get_comp_string(context, krbtgt->entry.principal, 1);
char **capath = NULL;
Expand Down Expand Up @@ -2324,6 +2331,7 @@ tgs_build_reply(krb5_context context,
spn,
client,
cp,
tgt_realm,
krbtgt_out,
tkey_sign->key.keytype,
spp,
Expand Down
17 changes: 17 additions & 0 deletions tests/kdc/check-kdc.in
Expand Up @@ -53,6 +53,7 @@ R4=TEST4.H5L.SE
R5=SOME-REALM5.FR
R6=SOME-REALM6.US
R7=SOME-REALM7.UK
R8=SOME-REALM8.UK

H1=H1.$R
H2=H2.$R
Expand Down Expand Up @@ -148,6 +149,12 @@ ${kadmin} \
--realm-max-renewable-life=1month \
${R7} || exit 1

${kadmin} \
init \
--realm-max-ticket-life=1day \
--realm-max-renewable-life=1month \
${R8} || exit 1

${kadmin} \
init \
--realm-max-ticket-life=1day \
Expand Down Expand Up @@ -191,6 +198,7 @@ ${kadmin} add -p foo --use-defaults foo@${R4} || exit 1
${kadmin5} add -p foo --use-defaults foo@${R5} || exit 1
${kadmin} add -p foo --use-defaults foo@${R6} || exit 1
${kadmin} add -p foo --use-defaults foo@${R7} || exit 1
${kadmin} add -p foo --use-defaults foo@${R8} || exit 1
${kadmin} add -p foo --use-defaults foo@${H1} || exit 1
${kadmin} add -p foo --use-defaults foo/host.${h1}@${H1} || exit 1
${kadmin} add -p foo --use-defaults foo@${H2} || exit 1
Expand Down Expand Up @@ -249,6 +257,9 @@ ${kadmin} add -p cross2 --use-defaults krbtgt/${R5}@${R6} || exit 1
${kadmin} add -p cross1 --use-defaults krbtgt/${R7}@${R6} || exit 1
${kadmin} add -p cross2 --use-defaults krbtgt/${R6}@${R7} || exit 1

${kadmin} add -p cross1 --use-defaults krbtgt/${R8}@${R6} || exit 1
${kadmin} add -p cross2 --use-defaults krbtgt/${R6}@${R8} || exit 1

${kadmin} add -p cross1 --use-defaults krbtgt/${H1}@${R} || exit 1
${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${H1} || exit 1

Expand Down Expand Up @@ -284,6 +295,7 @@ ${kadmin} check ${R4} || exit 1
${kadmin5} check ${R5} || exit 1
${kadmin} check ${R6} || exit 1
${kadmin} check ${R7} || exit 1
${kadmin} check ${R8} || exit 1
${kadmin} check ${H1} || exit 1
${kadmin} check ${H2} || exit 1
${kadmin} check ${H3} || exit 1
Expand Down Expand Up @@ -388,6 +400,8 @@ echo "Getting x-realm tickets with capaths for $R -> $R6"
${kgetcred} foo@${R6} || { ec=1 ; eval "${testfailed}"; }
echo "Getting x-realm tickets with capaths for $R -> $R7"
${kgetcred} foo@${R7} || { ec=1 ; eval "${testfailed}"; }
echo "Should not get x-realm tickets with capaths for $R -> $R8"
${kgetcred} foo@${R8} && { ec=1 ; eval "${testfailed}"; }
${kdestroy}

echo "Testing capaths logic (reverse order)"
Expand Down Expand Up @@ -418,10 +432,13 @@ ${kinit} --password-file=${objdir}/foopassword \

echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $H1"
${kgetcred} --hostbased --canonicalize foo host.${h1} || { ec=1 ; eval "${testfailed}"; }
fgrep "cross-realm ${H3} -> ${H1} via [${H2}, ${R}]" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $R"
${kgetcred} --hostbased --canonicalize foo host.${r} || { ec=1 ; eval "${testfailed}"; }
fgrep "cross-realm ${H3} -> ${R} via [${H2}]" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $H2"
${kgetcred} --hostbased --canonicalize foo host.${h2} || { ec=1 ; eval "${testfailed}"; }
fgrep "cross-realm ${H3} -> ${H2}" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
${kdestroy}

echo "Testing multi-hop [capaths] referral logic"
Expand Down
4 changes: 4 additions & 0 deletions tests/kdc/krb5.conf.in
Expand Up @@ -40,6 +40,9 @@
SOME-REALM7.UK = {
kdc = localhost:@port@
}
SOME-REALM8.UK = {
kdc = localhost:@port@
}
TEST-HTTP.H5L.SE = {
kdc = http/localhost:@port@
}
Expand Down Expand Up @@ -147,6 +150,7 @@
SOME-REALM6.US = SOME-REALM5.FR
SOME-REALM7.UK = SOME-REALM6.US
SOME-REALM7.UK = SOME-REALM5.FR
SOME-REALM8.UK = SOME-REALM6.US
}
H4.H2.TEST.H5L.SE = {
H1.TEST.H5L.SE = H3.H2.TEST.H5L.SE
Expand Down

0 comments on commit b1e6991

Please sign in to comment.