2285b0f4213c8d18ecf5f4a8a6c875ffea6c3e52
[krb5.git] / src / lib / krb5 / krb / init_ctx.c
1 /*
2  * lib/krb5/krb/init_ctx.c
3  *
4  * Copyright 1994 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  *
23  * krb5_init_contex()
24  */
25
26 /*
27  * Copyright (C) 1998 by the FundsXpress, INC.
28  * 
29  * All rights reserved.
30  * 
31  * Export of this software from the United States of America may require
32  * a specific license from the United States Government.  It is the
33  * responsibility of any person or organization contemplating export to
34  * obtain such a license before exporting.
35  * 
36  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
37  * distribute this software and its documentation for any purpose and
38  * without fee is hereby granted, provided that the above copyright
39  * notice appear in all copies and that both that copyright notice and
40  * this permission notice appear in supporting documentation, and that
41  * the name of FundsXpress. not be used in advertising or publicity pertaining
42  * to distribution of the software without specific, written prior
43  * permission.  FundsXpress makes no representations about the suitability of
44  * this software for any purpose.  It is provided "as is" without express
45  * or implied warranty.
46  * 
47  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
49  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
50  */
51
52 #include "k5-int.h"
53 #include <ctype.h>
54 #include "brand.c"
55
56 #if (defined(_MSDOS) || defined(_WIN32))
57 extern krb5_error_code krb5_vercheck();
58 #endif
59
60 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
61 krb5_init_context(context)
62         krb5_context *context;
63 {
64         krb5_context ctx = 0;
65         krb5_error_code retval;
66         krb5_timestamp now;
67         krb5_data seed;
68         int tmp;
69
70         /* Initialize error tables */
71         krb5_init_ets(ctx);
72
73 #if (defined(_MSDOS) || defined(_WIN32))
74         /*
75          * krb5_vercheck() is defined in win_glue.c, and this is
76          * where we handle the timebomb and version server checks.
77          */
78         retval = krb5_vercheck();
79         if (retval)
80                 return retval;
81 #endif
82
83         *context = 0;
84
85         ctx = malloc(sizeof(struct _krb5_context));
86         if (!ctx)
87                 return ENOMEM;
88         memset(ctx, 0, sizeof(struct _krb5_context));
89         ctx->magic = KV5M_CONTEXT;
90
91         /* Set the default encryption types, possible defined in krb5/conf */
92         if ((retval = krb5_set_default_in_tkt_ktypes(ctx, NULL)))
93                 goto cleanup;
94
95         if ((retval = krb5_set_default_tgs_ktypes(ctx, NULL)))
96                 goto cleanup;
97
98         if ((retval = krb5_os_init_context(ctx)))
99                 goto cleanup;
100
101         /* initialize the prng (not well, but passable) */
102         if ((retval = krb5_timeofday(ctx, &now)))
103                 goto cleanup;
104         seed.length = sizeof(now);
105         seed.data = (char *) &now;
106         if ((retval = krb5_c_random_seed(ctx, &seed)))
107                 goto cleanup;
108
109         ctx->default_realm = 0;
110         profile_get_integer(ctx->profile, "libdefaults", "clockskew",
111                             0, 5 * 60, &tmp);
112         ctx->clockskew = tmp;
113
114 #if 0
115         /* Default ticket lifetime is currently not supported */
116         profile_get_integer(ctx->profile, "libdefaults", "tkt_lifetime",
117                             0, 10 * 60 * 60, &tmp);
118         ctx->tkt_lifetime = tmp;
119 #endif
120
121         /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2)  */
122         /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
123         profile_get_integer(ctx->profile, "libdefaults",
124                             "kdc_req_checksum_type", 0, CKSUMTYPE_RSA_MD5, 
125                             &tmp);
126         ctx->kdc_req_sumtype = tmp;
127
128         profile_get_integer(ctx->profile, "libdefaults",
129                             "ap_req_checksum_type", 0, CKSUMTYPE_RSA_MD5,
130                             &tmp);
131         ctx->default_ap_req_sumtype = tmp;
132
133         profile_get_integer(ctx->profile, "libdefaults",
134                             "safe_checksum_type", 0,
135                             CKSUMTYPE_RSA_MD5_DES, &tmp);
136         ctx->default_safe_sumtype = tmp;
137
138         profile_get_integer(ctx->profile, "libdefaults",
139                             "kdc_default_options", 0,
140                             KDC_OPT_RENEWABLE_OK, &tmp);
141         ctx->kdc_default_options = KDC_OPT_RENEWABLE_OK;
142 #ifdef macintosh
143 #define DEFAULT_KDC_TIMESYNC 1
144 #else
145 #define DEFAULT_KDC_TIMESYNC 0
146 #endif
147         profile_get_integer(ctx->profile, "libdefaults",
148                             "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC,
149                             &tmp);
150         ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
151
152         /*
153          * We use a default file credentials cache of 3.  See
154          * lib/krb5/krb/ccache/file/fcc.h for a description of the
155          * credentials cache types.
156          *
157          * Note: DCE 1.0.3a only supports a cache type of 1
158          *      DCE 1.1 supports a cache type of 2.
159          */
160 #ifdef macintosh
161 #define DEFAULT_CCACHE_TYPE 4
162 #else
163 #define DEFAULT_CCACHE_TYPE 3
164 #endif
165         profile_get_integer(ctx->profile, "libdefaults", "ccache_type",
166                             0, DEFAULT_CCACHE_TYPE, &tmp);
167         ctx->fcc_default_format = tmp + 0x0500;
168         ctx->scc_default_format = tmp + 0x0500;
169
170         *context = ctx;
171         return 0;
172
173 cleanup:
174         krb5_free_context(ctx);
175         return retval;
176 }
177
178 KRB5_DLLIMP void KRB5_CALLCONV
179 krb5_free_context(ctx)
180         krb5_context    ctx;
181 {
182      krb5_free_ets(ctx);
183      krb5_os_free_context(ctx);
184
185      if (ctx->in_tkt_ktypes)
186           free(ctx->in_tkt_ktypes);
187
188      if (ctx->tgs_ktypes)
189           free(ctx->tgs_ktypes);
190
191      if (ctx->default_realm)
192           free(ctx->default_realm);
193
194      if (ctx->ser_ctx_count && ctx->ser_ctx)
195          free(ctx->ser_ctx);
196
197      ctx->magic = 0;
198      free(ctx);
199 }
200
201 /*
202  * Set the desired default ktypes, making sure they are valid.
203  */
204 krb5_error_code
205 krb5_set_default_in_tkt_ktypes(context, ktypes)
206         krb5_context context;
207         const krb5_enctype *ktypes;
208 {
209     krb5_enctype * new_ktypes;
210     int i;
211
212     if (ktypes) {
213         for (i = 0; ktypes[i]; i++) {
214             if (!valid_enctype(ktypes[i])) 
215                 return KRB5_PROG_ETYPE_NOSUPP;
216         }
217
218         /* Now copy the default ktypes into the context pointer */
219         if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
220             memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
221         else
222             return ENOMEM;
223
224     } else {
225         i = 0;
226         new_ktypes = 0;
227     }
228
229     if (context->in_tkt_ktypes) 
230         free(context->in_tkt_ktypes);
231     context->in_tkt_ktypes = new_ktypes;
232     context->in_tkt_ktype_count = i;
233     return 0;
234 }
235
236 static krb5_error_code
237 get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list)
238      krb5_context context;
239      krb5_enctype **ktypes;
240      char *profstr;
241      int ctx_count;
242      krb5_enctype FAR *ctx_list;
243 {
244     krb5_enctype *old_ktypes;
245
246     if (context->in_tkt_ktype_count) {
247         /* application-set defaults */
248         if ((old_ktypes = 
249              (krb5_enctype *)malloc(sizeof(krb5_enctype) *
250                                     (ctx_count + 1)))) {
251             memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count);
252             old_ktypes[ctx_count] = 0;
253         } else {
254             return ENOMEM;
255         }
256     } else {
257         /*
258            XXX - For now, we only support libdefaults
259            Perhaps this should be extended to allow for per-host / per-realm
260            session key types.
261          */
262
263         char *retval;
264         char *sp, *ep;
265         int i, j, count;
266         krb5_error_code code;
267
268         code = profile_get_string(context->profile, "libdefaults", profstr,
269                                   NULL,
270                                   "des3-hmac-sha1 des-cbc-md5 des-cbc-crc",
271                                   &retval);
272         if (code)
273             return code;
274
275         count = 0;
276         sp = retval;
277         while (sp) {
278             for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++)
279                 ;
280             if (*ep) {
281                 *ep++ = '\0';
282                 while (isspace(*ep))
283                     ep++;
284             } else
285                 ep = (char *) NULL;
286
287             count++;
288             sp = ep;
289         }
290         
291         if ((old_ktypes =
292              (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
293             (krb5_enctype *) NULL)
294             return ENOMEM;
295         
296         sp = retval;
297         j = 0;
298         i = 1;
299         while (1) {
300             if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
301                 j++;
302
303             if (i++ >= count)
304                 break;
305
306             /* skip to next token */
307             while (*sp) sp++;
308             while (! *sp) sp++;
309         }
310
311         old_ktypes[j] = (krb5_enctype) 0;
312         free(retval);
313     }
314
315     *ktypes = old_ktypes;
316     return 0;
317 }
318
319 krb5_error_code
320 krb5_get_default_in_tkt_ktypes(context, ktypes)
321     krb5_context context;
322     krb5_enctype **ktypes;
323 {
324     return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes",
325                                   context->in_tkt_ktype_count,
326                                   context->in_tkt_ktypes));
327 }
328
329 krb5_error_code
330 krb5_set_default_tgs_ktypes(context, ktypes)
331         krb5_context context;
332         const krb5_enctype *ktypes;
333 {
334     krb5_enctype * new_ktypes;
335     int i;
336
337     if (ktypes) {
338         for (i = 0; ktypes[i]; i++) {
339             if (!valid_enctype(ktypes[i])) 
340                 return KRB5_PROG_ETYPE_NOSUPP;
341         }
342
343         /* Now copy the default ktypes into the context pointer */
344         if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
345             memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
346         else
347             return ENOMEM;
348
349     } else {
350         i = 0;
351         new_ktypes = (krb5_enctype *)NULL;
352     }
353
354     if (context->tgs_ktypes) 
355         free(context->tgs_ktypes);
356     context->tgs_ktypes = new_ktypes;
357     context->tgs_ktype_count = i;
358     return 0;
359 }
360
361 krb5_error_code
362 krb5_get_tgs_ktypes(context, princ, ktypes)
363     krb5_context context;
364     krb5_const_principal princ;
365     krb5_enctype **ktypes;
366 {
367     return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
368                                   context->tgs_ktype_count,
369                                   context->tgs_ktypes));
370 }
371
372 krb5_error_code
373 krb5_get_permitted_enctypes(context, ktypes)
374     krb5_context context;
375     krb5_enctype **ktypes;
376 {
377     return(get_profile_etype_list(context, ktypes, "permitted_enctypes",
378                                   context->tgs_ktype_count,
379                                   context->tgs_ktypes));
380 }
381
382 krb5_boolean
383 krb5_is_permitted_enctype(context, etype)
384      krb5_context context;
385      krb5_enctype etype;
386 {
387     krb5_enctype *list, *ptr;
388     krb5_boolean ret;
389
390     if (krb5_get_permitted_enctypes(context, &list))
391         return(0);
392
393     
394     ret = 0;
395
396     for (ptr = list; *ptr; ptr++)
397         if (*ptr == etype)
398             ret = 1;
399
400     krb5_xfree(list);
401
402     return(ret);
403 }