Imported Upstream version 1.15.1
[platform/upstream/krb5.git] / src / lib / krb5 / ccache / t_cc.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/ccache/t_cc.c */
3 /*
4  * Copyright 2000 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.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26
27 #include "k5-int.h"
28 #include "cc-int.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include "autoconf.h"
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #include "com_err.h"
36
37 #define KRB5_OK 0
38
39 krb5_creds test_creds;
40
41 int debug=0;
42
43 static void
44 init_structs(void)
45 {
46     static int add=0x12345;
47
48     static krb5_address addr;
49
50     static krb5_address *addrs[] = {
51         &addr,
52         0,
53     };
54
55     addr.magic = KV5M_ADDRESS;
56     addr.addrtype = ADDRTYPE_INET;
57     addr.length = 4;
58     addr.contents = (krb5_octet *) &add;
59
60     test_creds.magic = KV5M_CREDS;
61     test_creds.client = NULL;
62     test_creds.server = NULL;
63
64     test_creds.keyblock.magic = KV5M_KEYBLOCK;
65     test_creds.keyblock.contents = 0;
66     test_creds.keyblock.enctype = 1;
67     test_creds.keyblock.length = 1;
68     test_creds.keyblock.contents = (unsigned char *) "1";
69     test_creds.times.authtime = 1111;
70     test_creds.times.starttime = 2222;
71     test_creds.times.endtime = 3333;
72     test_creds.times.renew_till = 4444;
73     test_creds.is_skey = 1;
74     test_creds.ticket_flags = 5555;
75     test_creds.addresses = addrs;
76
77 #define SET_TICKET(ent, str) {ent.magic = KV5M_DATA; ent.length = sizeof(str); ent.data = str;}
78     SET_TICKET(test_creds.ticket, "This is ticket 1");
79     SET_TICKET(test_creds.second_ticket, "This is ticket 2");
80     test_creds.authdata = NULL;
81 }
82
83 static krb5_error_code
84 init_test_cred(krb5_context context)
85 {
86     krb5_error_code kret;
87     unsigned int i;
88     krb5_authdata *a;
89 #define REALM "REALM"
90     kret = krb5_build_principal(context, &test_creds.client, sizeof(REALM), REALM,
91                                 "client-comp1", "client-comp2", NULL);
92     if(kret)
93         return kret;
94
95     kret = krb5_build_principal(context, &test_creds.server, sizeof(REALM), REALM,
96                                 "server-comp1", "server-comp2", NULL);
97     if(kret) {
98         krb5_free_principal(context, test_creds.client);
99         test_creds.client = 0;
100         goto cleanup;
101     }
102
103     test_creds.authdata = malloc (3 * sizeof(krb5_authdata *));
104     if (!test_creds.authdata) {
105         kret = ENOMEM;
106         goto cleanup;
107     }
108
109     for (i = 0 ; i <= 2 ; i++) {
110         test_creds.authdata[i] = 0;
111     }
112     a = (krb5_authdata *) malloc(sizeof(krb5_authdata));
113     if(!a) {
114         kret = ENOMEM;
115         goto cleanup;
116     }
117     a->magic = KV5M_AUTHDATA;
118     a->ad_type = KRB5_AUTHDATA_IF_RELEVANT;
119     a->contents = (krb5_octet * ) malloc(1);
120     if(!a->contents) {
121         free(a);
122         kret = ENOMEM;
123         goto cleanup;
124     }
125     a->contents[0]=5;
126     a->length = 1;
127     test_creds.authdata[0] = a;
128
129     a = (krb5_authdata *) malloc(sizeof(krb5_authdata));
130     if(!a) {
131         kret = ENOMEM;
132         goto cleanup;
133     }
134     a->magic = KV5M_AUTHDATA;
135     a->ad_type = KRB5_AUTHDATA_KDC_ISSUED;
136     a->contents = (krb5_octet * ) malloc(2);
137     if(!a->contents) {
138         free(a);
139         kret = ENOMEM;
140         goto cleanup;
141     }
142     a->contents[0]=4;
143     a->contents[1]=6;
144     a->length = 2;
145     test_creds.authdata[1] = a;
146
147 cleanup:
148     if(kret) {
149         if (test_creds.client) {
150             krb5_free_principal(context, test_creds.client);
151             test_creds.client = 0;
152         }
153         if (test_creds.server) {
154             krb5_free_principal(context, test_creds.server);
155             test_creds.server = 0;
156
157         }
158         if (test_creds.authdata) {
159             krb5_free_authdata(context, test_creds.authdata);
160             test_creds.authdata = 0;
161         }
162     }
163
164     return kret;
165 }
166
167 static void
168 free_test_cred(krb5_context context)
169 {
170     krb5_free_principal(context, test_creds.client);
171
172     krb5_free_principal(context, test_creds.server);
173
174     if(test_creds.authdata) {
175         krb5_free_authdata(context, test_creds.authdata);
176         test_creds.authdata = 0;
177     }
178 }
179
180 #define CHECK(kret,msg)                                 \
181     if (kret != KRB5_OK) {                              \
182         com_err(msg, kret, "");                         \
183         fflush(stderr);                                 \
184         exit(1);                                        \
185     } else if(debug) printf("%s went ok\n", msg);
186
187 #define CHECK_STR(str,msg)                              \
188     if (str == 0) {                                     \
189         com_err(msg, kret, "");                         \
190         exit(1);                                        \
191     } else if(debug) printf("%s went ok\n", msg);
192
193 #define CHECK_BOOL(expr,errstr,msg)                     \
194     if (expr) {                                         \
195         fprintf(stderr, "%s %s\n", msg, errstr);        \
196         exit(1);                                        \
197     } else if(debug) printf("%s went ok\n", msg);
198
199 #define CHECK_FAIL(experr, kret, msg)           \
200     if (experr != kret) { CHECK(kret, msg);}
201
202 static void
203 cc_test(krb5_context context, const char *name, krb5_flags flags)
204 {
205     krb5_ccache id, id2;
206     krb5_creds creds;
207     krb5_error_code kret;
208     krb5_cc_cursor cursor;
209     krb5_principal tmp;
210
211     const char *c_name;
212     char newcache[300];
213     char *save_type;
214
215     kret = init_test_cred(context);
216     CHECK(kret, "init_creds");
217
218     kret = krb5_cc_resolve(context, name, &id);
219     CHECK(kret, "resolve");
220     kret = krb5_cc_initialize(context, id, test_creds.client);
221     CHECK(kret, "initialize");
222
223     c_name = krb5_cc_get_name(context, id);
224     CHECK_STR(c_name, "get_name");
225
226     c_name = krb5_cc_get_type(context, id);
227     CHECK_STR(c_name, "get_type");
228     save_type=strdup(c_name);
229     CHECK_STR(save_type, "copying type");
230
231     kret = krb5_cc_store_cred(context, id, &test_creds);
232     CHECK(kret, "store");
233
234     kret = krb5_cc_get_principal(context, id, &tmp);
235     CHECK(kret, "get_principal");
236
237     CHECK_BOOL(krb5_realm_compare(context, tmp, test_creds.client) != TRUE,
238                "realms do not match", "realm_compare");
239
240
241     CHECK_BOOL(krb5_principal_compare(context, tmp, test_creds.client) != TRUE,
242                "principals do not match", "principal_compare");
243
244     krb5_free_principal(context, tmp);
245
246     kret = krb5_cc_set_flags (context, id, flags);
247     CHECK(kret, "set_flags");
248
249     kret = krb5_cc_start_seq_get(context, id, &cursor);
250     CHECK(kret, "start_seq_get");
251     kret = 0;
252     while (kret != KRB5_CC_END) {
253         if(debug) printf("Calling next_cred\n");
254         kret = krb5_cc_next_cred(context, id, &cursor, &creds);
255         if(kret == KRB5_CC_END) {
256             if(debug) printf("next_cred: ok at end\n");
257         }
258         else {
259             CHECK(kret, "next_cred");
260             krb5_free_cred_contents(context, &creds);
261         }
262
263     }
264     kret = krb5_cc_end_seq_get(context, id, &cursor);
265     CHECK(kret, "end_seq_get");
266
267     kret = krb5_cc_close(context, id);
268     CHECK(kret, "close");
269
270
271     /* ------------------------------------------------- */
272     kret = krb5_cc_resolve(context, name, &id);
273     CHECK(kret, "resolve2");
274
275     {
276         /* Copy the cache test*/
277         snprintf(newcache, sizeof(newcache), "%s.new", name);
278         kret = krb5_cc_resolve(context, newcache, &id2);
279         CHECK(kret, "resolve of new cache");
280
281         /* This should fail as the new creds are not initialized */
282         kret = krb5_cc_copy_creds(context, id, id2);
283         CHECK_FAIL(KRB5_FCC_NOFILE, kret, "copy_creds");
284
285         kret = krb5_cc_initialize(context, id2, test_creds.client);
286         CHECK(kret, "initialize of id2");
287
288         kret = krb5_cc_copy_creds(context, id, id2);
289         CHECK(kret, "copy_creds");
290
291         kret = krb5_cc_destroy(context, id2);
292         CHECK(kret, "destroy new cache");
293     }
294
295     /* Destroy the first cache */
296     kret = krb5_cc_destroy(context, id);
297     CHECK(kret, "destroy");
298
299     /* ----------------------------------------------------- */
300     /* Tests the generate new code */
301     kret = krb5_cc_new_unique(context, save_type,
302                               NULL, &id2);
303     CHECK(kret, "new_unique");
304
305     kret = krb5_cc_initialize(context, id2, test_creds.client);
306     CHECK(kret, "initialize");
307
308     kret = krb5_cc_store_cred(context, id2, &test_creds);
309     CHECK(kret, "store");
310
311     kret = krb5_cc_destroy(context, id2);
312     CHECK(kret, "destroy id2");
313
314     free(save_type);
315     free_test_cred(context);
316
317 }
318
319 /*
320  * Checks if a credential type is registered with the library
321  */
322 static int
323 check_registered(krb5_context context, const char *prefix)
324 {
325     char name[300];
326     krb5_error_code kret;
327     krb5_ccache id;
328
329     snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid());
330
331     kret = krb5_cc_resolve(context, name, &id);
332     if(kret != KRB5_OK) {
333         if(kret == KRB5_CC_UNKNOWN_TYPE)
334             return 0;
335         com_err("Checking on credential type", kret, "%s", prefix);
336         fflush(stderr);
337         return 0;
338     }
339
340     kret = krb5_cc_close(context, id);
341     if(kret != KRB5_OK) {
342         com_err("Checking on credential type - closing", kret, "%s", prefix);
343         fflush(stderr);
344     }
345
346     return 1;
347 }
348
349
350 static void
351 do_test(krb5_context context, const char *prefix)
352 {
353     char name[300];
354
355     snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid());
356     printf("Starting test on %s\n", name);
357     cc_test (context, name, 0);
358     cc_test (context, name, !0);
359     printf("Test on %s passed\n", name);
360 }
361
362 static void
363 test_misc(krb5_context context)
364 {
365     /* Tests for certain error returns */
366     krb5_error_code       kret;
367     krb5_ccache id;
368     const krb5_cc_ops *ops_save;
369
370     fprintf(stderr, "Testing miscellaneous error conditions\n");
371
372     kret = krb5_cc_resolve(context, "unknown_method_ep:/tmp/name", &id);
373     if (kret != KRB5_CC_UNKNOWN_TYPE) {
374         CHECK(kret, "resolve unknown type");
375     }
376
377     /* Test for not specifiying a cache type with no defaults */
378     ops_save = krb5_cc_dfl_ops;
379     krb5_cc_dfl_ops = 0;
380
381     kret = krb5_cc_resolve(context, "/tmp/e", &id);
382     if (kret != KRB5_CC_BADNAME) {
383         CHECK(kret, "resolve no builtin type");
384     }
385
386     krb5_cc_dfl_ops = ops_save;
387
388 }
389 extern const krb5_cc_ops krb5_mcc_ops;
390 extern const krb5_cc_ops krb5_fcc_ops;
391
392 int
393 main(void)
394 {
395     krb5_context context;
396     krb5_error_code     kret;
397
398     if ((kret = krb5_init_context(&context))) {
399         printf("Couldn't initialize krb5 library: %s\n",
400                error_message(kret));
401         exit(1);
402     }
403
404     kret = krb5_cc_register(context, &krb5_mcc_ops,0);
405     if(kret && kret != KRB5_CC_TYPE_EXISTS) {
406         CHECK(kret, "register_mem");
407     }
408
409     kret = krb5_cc_register(context, &krb5_fcc_ops,0);
410     if(kret && kret != KRB5_CC_TYPE_EXISTS) {
411         CHECK(kret, "register_mem");
412     }
413
414     /* Registering a second time tests for error return */
415     kret = krb5_cc_register(context, &krb5_fcc_ops,0);
416     if(kret != KRB5_CC_TYPE_EXISTS) {
417         CHECK(kret, "register_mem");
418     }
419
420     /* Registering with override should work */
421     kret = krb5_cc_register(context, &krb5_fcc_ops,1);
422     CHECK(kret, "register_mem override");
423
424     init_structs();
425
426     test_misc(context);
427     do_test(context, "");
428
429     if (check_registered(context, "KEYRING:process:"))
430         do_test(context, "KEYRING:process:");
431     else
432         printf("Skiping KEYRING: test - unregistered type\n");
433
434     do_test(context, "MEMORY:");
435     do_test(context, "FILE:");
436
437     krb5_free_context(context);
438     return 0;
439 }