]> git.ipfire.org Git - ipfire-3.x.git/blob - krb5/patches/krb5-1.10.2-keytab-etype.patch
4750a5cd687032ff0269b3142f234d622a542ec1
[ipfire-3.x.git] / krb5 / patches / krb5-1.10.2-keytab-etype.patch
1 (Had to drop the changes to src/tests/t_keytab.py, which didn't exist in 1.10.)
2
3 commit d1da158f47ea604bed4d5db5e98a976a9e54ccd0
4 Author: Greg Hudson <ghudson@mit.edu>
5 Date: Thu Apr 19 17:55:10 2012 +0000
6
7 Unify krb5_get_init_creds_keytab code paths
8
9 Use krb5_init_creds_set_keytab in krb5_get_init_creds_keytab, so that
10 processing added to the former will be used by the latter. This is
11 slightly awkward because of the way we do the use_master fallback, in
12 that we have to duplicate some of krb5int_get_init_creds.
13
14 Based on a patch from Stef Walter.
15
16 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25817 dc483132-0cff-0310-8789-dd5450dbe970
17
18 diff --git a/src/lib/krb5/krb/deps b/src/lib/krb5/krb/deps
19 index fe2d54c..8c4db77 100644
20 --- a/src/lib/krb5/krb/deps
21 +++ b/src/lib/krb5/krb/deps
22 @@ -473,7 +473,8 @@ gic_keytab.so gic_keytab.po $(OUTPRE)gic_keytab.$(OBJEXT): \
23 $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
24 $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
25 $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
26 - $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h
27 + $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h \
28 + int-proto.h
29 gic_opt.so gic_opt.po $(OUTPRE)gic_opt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
30 $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
31 $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
32 diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
33 index aaabc4e..681b648 100644
34 --- a/src/lib/krb5/krb/get_in_tkt.c
35 +++ b/src/lib/krb5/krb/get_in_tkt.c
36 @@ -542,10 +542,9 @@ krb5_init_creds_free(krb5_context context,
37 free(ctx);
38 }
39
40 -static krb5_error_code
41 -init_creds_get(krb5_context context,
42 - krb5_init_creds_context ctx,
43 - int *use_master)
44 +krb5_error_code
45 +k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
46 + int *use_master)
47 {
48 krb5_error_code code;
49 krb5_data request;
50 @@ -599,7 +598,7 @@ krb5_init_creds_get(krb5_context context,
51 {
52 int use_master = 0;
53
54 - return init_creds_get(context, ctx, &use_master);
55 + return k5_init_creds_get(context, ctx, &use_master);
56 }
57
58 krb5_error_code KRB5_CALLCONV
59 @@ -1664,7 +1663,7 @@ krb5int_get_init_creds(krb5_context context,
60 goto cleanup;
61 }
62
63 - code = init_creds_get(context, ctx, use_master);
64 + code = k5_init_creds_get(context, ctx, use_master);
65 if (code != 0)
66 goto cleanup;
67
68 diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
69 index 88de6a8..e59177f 100644
70 --- a/src/lib/krb5/krb/gic_keytab.c
71 +++ b/src/lib/krb5/krb/gic_keytab.c
72 @@ -26,6 +26,7 @@
73 #ifndef LEAN_CLIENT
74
75 #include "k5-int.h"
76 +#include "int-proto.h"
77 #include "init_creds_ctx.h"
78
79 static krb5_error_code
80 @@ -87,6 +88,44 @@ krb5_init_creds_set_keytab(krb5_context context,
81 return 0;
82 }
83
84 +static krb5_error_code
85 +get_init_creds_keytab(krb5_context context, krb5_creds *creds,
86 + krb5_principal client, krb5_keytab keytab,
87 + krb5_deltat start_time, char *in_tkt_service,
88 + krb5_get_init_creds_opt *options, int *use_master)
89 +{
90 + krb5_error_code ret;
91 + krb5_init_creds_context ctx = NULL;
92 +
93 + ret = krb5_init_creds_init(context, client, NULL, NULL, start_time,
94 + options, &ctx);
95 + if (ret != 0)
96 + goto cleanup;
97 +
98 + if (in_tkt_service) {
99 + ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
100 + if (ret != 0)
101 + goto cleanup;
102 + }
103 +
104 + ret = krb5_init_creds_set_keytab(context, ctx, keytab);
105 + if (ret != 0)
106 + goto cleanup;
107 +
108 + ret = k5_init_creds_get(context, ctx, use_master);
109 + if (ret != 0)
110 + goto cleanup;
111 +
112 + ret = krb5_init_creds_get_creds(context, ctx, creds);
113 + if (ret != 0)
114 + goto cleanup;
115 +
116 +cleanup:
117 + krb5_init_creds_free(context, ctx);
118 +
119 + return ret;
120 +}
121 +
122 krb5_error_code KRB5_CALLCONV
123 krb5_get_init_creds_keytab(krb5_context context,
124 krb5_creds *creds,
125 @@ -111,10 +150,8 @@ krb5_get_init_creds_keytab(krb5_context context,
126
127 /* first try: get the requested tkt from any kdc */
128
129 - ret = krb5int_get_init_creds(context, creds, client, NULL, NULL,
130 - start_time, in_tkt_service, options,
131 - get_as_key_keytab, (void *) keytab,
132 - &use_master,NULL);
133 + ret = get_init_creds_keytab(context, creds, client, keytab, start_time,
134 + in_tkt_service, options, &use_master);
135
136 /* check for success */
137
138 @@ -132,10 +169,9 @@ krb5_get_init_creds_keytab(krb5_context context,
139 if (!use_master) {
140 use_master = 1;
141
142 - ret2 = krb5int_get_init_creds(context, creds, client, NULL, NULL,
143 - start_time, in_tkt_service, options,
144 - get_as_key_keytab, (void *) keytab,
145 - &use_master, NULL);
146 + ret2 = get_init_creds_keytab(context, creds, client, keytab,
147 + start_time, in_tkt_service, options,
148 + &use_master);
149
150 if (ret2 == 0) {
151 ret = 0;
152 diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
153 index 6b16095..899579f 100644
154 --- a/src/lib/krb5/krb/int-proto.h
155 +++ b/src/lib/krb5/krb/int-proto.h
156 @@ -196,4 +196,8 @@ krb5int_mk_setpw_req(krb5_context context, krb5_auth_context auth_context,
157 void
158 k5_ccselect_free_context(krb5_context context);
159
160 +krb5_error_code
161 +k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
162 + int *use_master);
163 +
164 #endif /* KRB5_INT_FUNC_PROTO__ */
165
166 commit 8230c4b7b7323cdef2a6c877deb710a15380f40f
167 Author: Greg Hudson <ghudson@mit.edu>
168 Date: Thu Apr 19 17:55:14 2012 +0000
169
170 Use etypes from keytab in krb5_gic_keytab
171
172 When getting initial credentials with a keytab, filter the list of
173 request enctypes based on the keys in the keytab.
174
175 Based on a patch from Stef Walter.
176
177 ticket: 2131
178
179 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25818 dc483132-0cff-0310-8789-dd5450dbe970
180
181 diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
182 index 3749cf9..36eb23b 100644
183 --- a/src/include/k5-trace.h
184 +++ b/src/include/k5-trace.h
185 @@ -187,6 +187,10 @@
186 #define TRACE_INIT_CREDS_GAK(c, salt, s2kparams) \
187 TRACE(c, (c, "Getting AS key, salt \"{data}\", params \"{data}\"", \
188 salt, s2kparams))
189 +#define TRACE_INIT_CREDS_KEYTAB_LOOKUP(c, etypes) \
190 + TRACE(c, (c, "Looked up etypes in keytab: {etypes}", etypes))
191 +#define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code) \
192 + TRACE(c, (c, "Couldn't lookup etypes in keytab: {kerr}", code))
193 #define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \
194 TRACE(c, (c, "Decrypt with preauth AS key failed: {kerr}", code))
195 #define TRACE_INIT_CREDS_RESTART_FAST(c) \
196 diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
197 index e59177f..3554b25 100644
198 --- a/src/lib/krb5/krb/gic_keytab.c
199 +++ b/src/lib/krb5/krb/gic_keytab.c
200 @@ -77,14 +77,132 @@ get_as_key_keytab(krb5_context context,
201 return(ret);
202 }
203
204 +/* Return the list of etypes available for client in keytab. */
205 +static krb5_error_code
206 +lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab,
207 + krb5_principal client, krb5_enctype **etypes_out)
208 +{
209 + krb5_kt_cursor cursor;
210 + krb5_keytab_entry entry;
211 + krb5_enctype *p, *etypes = NULL;
212 + krb5_kvno max_kvno = 0;
213 + krb5_error_code ret;
214 + size_t count = 0;
215 +
216 + *etypes_out = NULL;
217 +
218 + if (keytab->ops->start_seq_get == NULL)
219 + return EINVAL;
220 + ret = krb5_kt_start_seq_get(context, keytab, &cursor);
221 + if (ret != 0)
222 + return ret;
223 +
224 + for (;;) {
225 + ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
226 + if (ret == KRB5_KT_END)
227 + break;
228 + if (ret)
229 + goto cleanup;
230 +
231 + if (!krb5_c_valid_enctype(entry.key.enctype))
232 + continue;
233 + if (!krb5_principal_compare(context, entry.principal, client))
234 + continue;
235 + /* Make sure our list is for the highest kvno found for client. */
236 + if (entry.vno > max_kvno) {
237 + free(etypes);
238 + etypes = NULL;
239 + count = 0;
240 + max_kvno = entry.vno;
241 + } else if (entry.vno != max_kvno)
242 + continue;
243 +
244 + /* Leave room for the terminator and possibly a second entry. */
245 + p = realloc(etypes, (count + 3) * sizeof(*etypes));
246 + if (p == NULL) {
247 + ret = ENOMEM;
248 + goto cleanup;
249 + }
250 + etypes = p;
251 + etypes[count++] = entry.key.enctype;
252 + /* All DES key types work with des-cbc-crc, which is more likely to be
253 + * accepted by the KDC (since MIT KDCs refuse des-cbc-md5). */
254 + if (entry.key.enctype == ENCTYPE_DES_CBC_MD5 ||
255 + entry.key.enctype == ENCTYPE_DES_CBC_MD4)
256 + etypes[count++] = ENCTYPE_DES_CBC_CRC;
257 + etypes[count] = 0;
258 + }
259 +
260 + ret = 0;
261 + *etypes_out = etypes;
262 + etypes = NULL;
263 +cleanup:
264 + krb5_kt_end_seq_get(context, keytab, &cursor);
265 + free(etypes);
266 + return ret;
267 +}
268 +
269 +/* Return true if search_for is in etype_list. */
270 +static krb5_boolean
271 +check_etypes_have(krb5_enctype *etype_list, krb5_enctype search_for)
272 +{
273 + int i;
274 +
275 + if (!etype_list)
276 + return FALSE;
277 +
278 + for (i = 0; etype_list[i] != 0; i++) {
279 + if (etype_list[i] == search_for)
280 + return TRUE;
281 + }
282 +
283 + return FALSE;
284 +}
285 +
286 krb5_error_code KRB5_CALLCONV
287 krb5_init_creds_set_keytab(krb5_context context,
288 krb5_init_creds_context ctx,
289 krb5_keytab keytab)
290 {
291 + krb5_enctype *etype_list;
292 + krb5_error_code ret;
293 + int i, j;
294 + char *name;
295 +
296 ctx->gak_fct = get_as_key_keytab;
297 ctx->gak_data = keytab;
298
299 + ret = lookup_etypes_for_keytab(context, keytab, ctx->request->client,
300 + &etype_list);
301 + if (ret) {
302 + TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(context, ret);
303 + return 0;
304 + }
305 +
306 + TRACE_INIT_CREDS_KEYTAB_LOOKUP(context, etype_list);
307 +
308 + /* Filter the ktypes list based on what's in the keytab */
309 + for (i = 0, j = 0; i < ctx->request->nktypes; i++) {
310 + if (check_etypes_have(etype_list, ctx->request->ktype[i])) {
311 + ctx->request->ktype[j] = ctx->request->ktype[i];
312 + j++;
313 + }
314 + }
315 + ctx->request->nktypes = j;
316 + free(etype_list);
317 +
318 + /* Error out now if there's no overlap. */
319 + if (ctx->request->nktypes == 0) {
320 + ret = krb5_unparse_name(context, ctx->request->client, &name);
321 + if (ret == 0) {
322 + krb5_set_error_message(context, KRB5_KT_NOTFOUND,
323 + _("Keytab contains no suitable keys for "
324 + "%s"), name);
325 + }
326 + krb5_free_unparsed_name(context, name);
327 + return KRB5_KT_NOTFOUND;
328 + }
329 +
330 return 0;
331 }
332