Package: heimdal / 7.1.0+dfsg-13+deb9u3

CVE-2017-6594 Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
commit d7bf245e793a9f9ec565e07dae9372597c0ece69
Author: Viktor Dukhovni <viktor@twosigma.com>
Date:   Wed Aug 10 23:31:14 2016 +0000

    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.

diff --git a/kdc/krb5tgs.c b/kdc/krb5tgs.c
index 6048b9c55..98503812f 100644
--- a/kdc/krb5tgs.c
+++ b/kdc/krb5tgs.c
@@ -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;
@@ -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,
@@ -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;
 
@@ -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;
@@ -2324,6 +2331,7 @@ server_lookup:
 			 spn,
 			 client,
 			 cp,
+                         tgt_realm,
 			 krbtgt_out,
 			 tkey_sign->key.keytype,
 			 spp,
diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in
index 235113425..f6e78ccac 100644
--- a/tests/kdc/check-kdc.in
+++ b/tests/kdc/check-kdc.in
@@ -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
@@ -152,6 +153,12 @@ ${kadmin} \
     init \
     --realm-max-ticket-life=1day \
     --realm-max-renewable-life=1month \
+    ${R8} || exit 1
+
+${kadmin} \
+    init \
+    --realm-max-ticket-life=1day \
+    --realm-max-renewable-life=1month \
     ${H1} || exit 1
 
 ${kadmin} \
@@ -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
@@ -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
 
@@ -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
@@ -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)"
@@ -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"
diff --git a/tests/kdc/krb5.conf.in b/tests/kdc/krb5.conf.in
index cc2dedb2d..849e773d0 100644
--- a/tests/kdc/krb5.conf.in
+++ b/tests/kdc/krb5.conf.in
@@ -40,6 +40,9 @@
 	SOME-REALM7.UK = {
 		kdc = localhost:@port@
 	}
+	SOME-REALM8.UK = {
+		kdc = localhost:@port@
+	}
 	TEST-HTTP.H5L.SE = {
 		kdc = http/localhost:@port@
 	}
@@ -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