Fix autoconf 2.70 compatibility
[platform/upstream/krb5.git] / src / lib / krb5 / krb / t_ser.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/t_ser.c - Test serialization */
3 /*
4  * Copyright 1995 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 "com_err.h"
29 #include "auth_con.h"
30
31 #include <ctype.h>
32
33 static const char stuff[]="You can't take a pointer to a function and convert \
34 it to a pointer to char; ANSI doesn't say it'll work, and in fact on the HPPA \
35 you can lose some bits of the function pointer, and get a pointer that you \
36 can't safely dereference.  This test file used to make this mistake, often.";
37
38 /*
39  * Dump an external representation.
40  */
41 static void
42 print_erep(krb5_octet *erep, size_t elen)
43 {
44     unsigned int i, j;
45
46     for (i=0; i<elen; ) {
47         printf("%08d: ", i);
48         for (j=0; j<15; j++) {
49             if ((i+j) < elen)
50                 printf("%02x ", erep[i+j]);
51             else
52                 printf("-- ");
53         }
54         printf("\t");
55         for (j=0; j<15; j++) {
56             if ((i+j) < elen) {
57                 if (isprint(erep[i+j]) && (erep[i+j] != '\n'))
58                     printf("%c", erep[i+j]);
59                 else
60                     printf(".");
61             }
62             else
63                 printf("-");
64         }
65         printf("\n");
66         i += 15;
67     }
68 }
69
70 /*
71  * Do a serialization test.
72  */
73 static krb5_error_code
74 ser_data(int verbose, char *msg, krb5_pointer ctx, krb5_magic dtype)
75 {
76     krb5_error_code     kret;
77     krb5_context        ser_ctx;
78     krb5_pointer        nctx;
79     krb5_octet          *outrep, *ibuf, *outrep2;
80     size_t              outlen, ilen, outlen2;
81
82     /* Initialize context and initialize all Kerberos serializers */
83     if ((kret = krb5_init_context(&ser_ctx))) {
84         printf("Couldn't initialize krb5 library: %s\n",
85                error_message(kret));
86         exit(1);
87     }
88     krb5_ser_context_init(ser_ctx);
89     krb5_ser_auth_context_init(ser_ctx);
90     krb5_ser_ccache_init(ser_ctx);
91     krb5_ser_rcache_init(ser_ctx);
92     krb5_ser_keytab_init(ser_ctx);
93
94     /* Externalize the data */
95     kret = krb5_externalize_data(ser_ctx, ctx, &outrep, &outlen);
96     if (!kret) {
97         if (verbose) {
98             printf("%s: externalized in %d bytes\n", msg, (int)outlen);
99             print_erep(outrep, outlen);
100         }
101
102         /* Now attempt to re-constitute it */
103         ibuf = outrep;
104         ilen = outlen;
105         kret = krb5_internalize_opaque(ser_ctx,
106                                        dtype,
107                                        (krb5_pointer *) &nctx,
108                                        &ibuf,
109                                        &ilen);
110         if (!kret) {
111             if (ilen)
112                 printf("%s: %d bytes left over after internalize\n",
113                        msg, (int)ilen);
114             /* Now attempt to re-externalize it */
115             kret = krb5_externalize_data(ser_ctx, nctx, &outrep2, &outlen2);
116             if (!kret) {
117                 /* Compare the results. */
118                 if ((outlen2 != outlen) ||
119                     memcmp(outrep, outrep2, outlen)) {
120                     printf("%s: comparison failed\n", msg);
121                     print_erep(outrep2, outlen2);
122                 }
123                 else {
124                     if (verbose)
125                         printf("%s: compare succeeded\n", msg);
126                 }
127                 free(outrep2);
128             }
129             else
130                 printf("%s: second externalize returned %d\n", msg, kret);
131
132             /* Free the data */
133             switch (dtype) {
134             case KV5M_CONTEXT:
135                 krb5_free_context((krb5_context) nctx);
136                 break;
137             case KV5M_AUTH_CONTEXT:
138                 krb5_auth_con_free(ser_ctx, (krb5_auth_context) nctx);
139                 break;
140             case KV5M_CCACHE:
141                 krb5_cc_close(ser_ctx, (krb5_ccache) nctx);
142                 break;
143             case KV5M_RCACHE:
144                 krb5_rc_close(ser_ctx, (krb5_rcache) nctx);
145                 break;
146             case KV5M_KEYTAB:
147                 krb5_kt_close(ser_ctx, (krb5_keytab) nctx);
148                 break;
149             case KV5M_ENCRYPT_BLOCK:
150                 if (nctx) {
151                     krb5_encrypt_block *eblock;
152
153                     eblock = (krb5_encrypt_block *) nctx;
154                     if (eblock->key)
155                         krb5_free_keyblock(ser_ctx, eblock->key);
156                     free(eblock);
157                 }
158                 break;
159             case KV5M_PRINCIPAL:
160                 krb5_free_principal(ser_ctx, (krb5_principal) nctx);
161                 break;
162             case KV5M_CHECKSUM:
163                 krb5_free_checksum(ser_ctx, (krb5_checksum *) nctx);
164                 break;
165             default:
166                 printf("don't know how to free %d\n", dtype);
167                 break;
168             }
169         }
170         else
171             printf("%s: internalize returned %d\n", msg, kret);
172         free(outrep);
173     }
174     else
175         printf("%s: externalize_data returned %d\n", msg, kret);
176     krb5_free_context(ser_ctx);
177     return(kret);
178 }
179
180 /*
181  * Serialize krb5_context.
182  */
183 static krb5_error_code
184 ser_kcontext_test(krb5_context kcontext, int verbose)
185 {
186     krb5_error_code     kret;
187     profile_t           sprofile;
188     char                dbname[128];
189
190     snprintf(dbname, sizeof(dbname), "temp_%d", (int) getpid());
191     sprofile = kcontext->profile;
192     kcontext->profile = (profile_t) NULL;
193     if (!(kret = ser_data(verbose, "> Context with no profile",
194                           (krb5_pointer) kcontext,
195                           KV5M_CONTEXT))) {
196         kcontext->profile = sprofile;
197         if (!(kret = ser_data(verbose, "> Context with no realm",
198                               (krb5_pointer) kcontext,
199                               KV5M_CONTEXT)) &&
200             !(kret = krb5_set_default_realm(kcontext, "this.is.a.test"))) {
201             if (!(kret = ser_data(verbose, "> Context with default realm",
202                                   (krb5_pointer) kcontext,
203                                   KV5M_CONTEXT))) {
204                 if (verbose)
205                     printf("* krb5_context test succeeded\n");
206             }
207         }
208     }
209     if (kret)
210         printf("* krb5_context test failed\n");
211     return(kret);
212 }
213
214 /*
215  * Serialize krb5_auth_context.
216  */
217 static krb5_error_code
218 ser_acontext_test(krb5_context kcontext, int verbose)
219 {
220     krb5_error_code     kret;
221     krb5_auth_context   actx;
222     krb5_address        local_address;
223     krb5_address        remote_address;
224     krb5_octet          laddr_bytes[16];
225     krb5_octet          raddr_bytes[16];
226     krb5_keyblock       ukeyblock;
227     krb5_octet          keydata[8];
228     krb5_authenticator  aent;
229     char                clname[128];
230     krb5_authdata       *adatalist[3];
231     krb5_authdata       adataent;
232
233     actx = (krb5_auth_context) NULL;
234     if (!(kret = krb5_auth_con_init(kcontext, &actx)) &&
235         !(kret = ser_data(verbose, "> Vanilla auth context",
236                           (krb5_pointer) actx,
237                           KV5M_AUTH_CONTEXT))) {
238         memset(&local_address, 0, sizeof(local_address));
239         memset(&remote_address, 0, sizeof(remote_address));
240         memset(laddr_bytes, 0, sizeof(laddr_bytes));
241         memset(raddr_bytes, 0, sizeof(raddr_bytes));
242         local_address.addrtype = ADDRTYPE_INET;
243         local_address.length = sizeof(laddr_bytes);
244         local_address.contents = laddr_bytes;
245         laddr_bytes[0] = 6;
246         laddr_bytes[1] = 2;
247         laddr_bytes[2] = 69;
248         laddr_bytes[3] = 16;
249         laddr_bytes[4] = 1;
250         laddr_bytes[5] = 0;
251         laddr_bytes[6] = 0;
252         laddr_bytes[7] = 127;
253         remote_address.addrtype = ADDRTYPE_INET;
254         remote_address.length = sizeof(raddr_bytes);
255         remote_address.contents = raddr_bytes;
256         raddr_bytes[0] = 6;
257         raddr_bytes[1] = 2;
258         raddr_bytes[2] = 70;
259         raddr_bytes[3] = 16;
260         raddr_bytes[4] = 1;
261         raddr_bytes[5] = 0;
262         raddr_bytes[6] = 0;
263         raddr_bytes[7] = 127;
264         if (!(kret = krb5_auth_con_setaddrs(kcontext, actx,
265                                             &local_address,
266                                             &remote_address)) &&
267             !(kret = krb5_auth_con_setports(kcontext, actx,
268                                             &local_address,
269                                             &remote_address)) &&
270             !(kret = ser_data(verbose, "> Auth context with addrs/ports",
271                               (krb5_pointer) actx,
272                               KV5M_AUTH_CONTEXT))) {
273             memset(&ukeyblock, 0, sizeof(ukeyblock));
274             memset(keydata, 0, sizeof(keydata));
275             ukeyblock.enctype = ENCTYPE_DES_CBC_MD5;
276             ukeyblock.length = sizeof(keydata);
277             ukeyblock.contents = keydata;
278             keydata[0] = 0xde;
279             keydata[1] = 0xad;
280             keydata[2] = 0xbe;
281             keydata[3] = 0xef;
282             keydata[4] = 0xfe;
283             keydata[5] = 0xed;
284             keydata[6] = 0xf0;
285             keydata[7] = 0xd;
286             if (!(kret = krb5_auth_con_setuseruserkey(kcontext, actx,
287                                                       &ukeyblock)) &&
288                 !(kret = ser_data(verbose, "> Auth context with user key",
289                                   (krb5_pointer) actx,
290                                   KV5M_AUTH_CONTEXT)) &&
291                 !(kret = krb5_auth_con_initivector(kcontext, actx)) &&
292                 !(kret = ser_data(verbose, "> Auth context with new vector",
293                                   (krb5_pointer) actx,
294                                   KV5M_AUTH_CONTEXT)) &&
295                 !(kret = ser_data(verbose, "> Auth context with set vector",
296                                   (krb5_pointer) actx,
297                                   KV5M_AUTH_CONTEXT))) {
298                 /*
299                  * Finally, add an authenticator.
300                  */
301                 memset(&aent, 0, sizeof(aent));
302                 aent.magic = KV5M_AUTHENTICATOR;
303                 snprintf(clname, sizeof(clname),
304                          "help/me/%d@this.is.a.test", (int) getpid());
305                 actx->authentp = &aent;
306                 if (!(kret = krb5_parse_name(kcontext, clname,
307                                              &aent.client)) &&
308                     !(kret = ser_data(verbose,
309                                       "> Auth context with authenticator",
310                                       (krb5_pointer) actx,
311                                       KV5M_AUTH_CONTEXT))) {
312                     adataent.magic = KV5M_AUTHDATA;
313                     adataent.ad_type = 123;
314                     adataent.length = 128;
315                     adataent.contents = (krb5_octet *) stuff;
316                     adatalist[0] = &adataent;
317                     adatalist[1] = &adataent;
318                     adatalist[2] = (krb5_authdata *) NULL;
319                     aent.authorization_data = adatalist;
320                     if (!(kret = ser_data(verbose,
321                                           "> Auth context with full auth",
322                                           (krb5_pointer) actx,
323                                           KV5M_AUTH_CONTEXT))) {
324                         if (verbose)
325                             printf("* krb5_auth_context test succeeded\n");
326                     }
327                     krb5_free_principal(kcontext, aent.client);
328                 }
329                 actx->authentp = (krb5_authenticator *) NULL;
330             }
331         }
332     }
333     if (actx)
334         krb5_auth_con_free(kcontext, actx);
335     if (kret)
336         printf("* krb5_auth_context test failed\n");
337     return(kret);
338 }
339
340 /*
341  * Serialize krb5_ccache
342  */
343 static krb5_error_code
344 ser_ccache_test(krb5_context kcontext, int verbose)
345 {
346     krb5_error_code     kret;
347     char                ccname[128];
348     char                princname[256];
349     krb5_ccache         ccache;
350     krb5_principal      principal;
351
352     snprintf(ccname, sizeof(ccname), "temp_cc_%d", (int) getpid());
353     snprintf(princname, sizeof(princname),
354              "zowie%d/instance%d@this.is.a.test",
355              (int) getpid(), (int) getpid());
356     if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) &&
357         !(kret = ser_data(verbose, "> Resolved default ccache",
358                           (krb5_pointer) ccache, KV5M_CCACHE)) &&
359         !(kret = krb5_parse_name(kcontext, princname, &principal)) &&
360         !(kret = krb5_cc_initialize(kcontext, ccache, principal)) &&
361         !(kret = ser_data(verbose, "> Initialized default ccache",
362                           (krb5_pointer) ccache, KV5M_CCACHE)) &&
363         !(kret = krb5_cc_destroy(kcontext, ccache))) {
364         krb5_free_principal(kcontext, principal);
365         snprintf(ccname, sizeof(ccname), "FILE:temp_cc_%d", (int) getpid());
366         snprintf(princname, sizeof(princname), "xxx%d/i%d@this.is.a.test",
367                  (int) getpid(), (int) getpid());
368         if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) &&
369             !(kret = ser_data(verbose, "> Resolved FILE ccache",
370                               (krb5_pointer) ccache, KV5M_CCACHE)) &&
371             !(kret = krb5_parse_name(kcontext, princname, &principal)) &&
372             !(kret = krb5_cc_initialize(kcontext, ccache, principal)) &&
373             !(kret = ser_data(verbose, "> Initialized FILE ccache",
374                               (krb5_pointer) ccache, KV5M_CCACHE)) &&
375             !(kret = krb5_cc_destroy(kcontext, ccache))) {
376             krb5_free_principal(kcontext, principal);
377
378             if (verbose)
379                 printf("* ccache test succeeded\n");
380         }
381     }
382     if (kret)
383         printf("* krb5_ccache test failed\n");
384     return(kret);
385 }
386
387 /*
388  * Serialize krb5_keytab.
389  */
390 static krb5_error_code
391 ser_keytab_test(krb5_context kcontext, int verbose)
392 {
393     krb5_error_code     kret;
394     char                ccname[128];
395     krb5_keytab         keytab;
396
397     snprintf(ccname, sizeof(ccname), "temp_kt_%d", (int) getpid());
398     if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
399         !(kret = ser_data(verbose, "> Resolved default keytab",
400                           (krb5_pointer) keytab, KV5M_KEYTAB)) &&
401         !(kret = krb5_kt_close(kcontext, keytab))) {
402         snprintf(ccname, sizeof(ccname), "FILE:temp_kt_%d", (int) getpid());
403         if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
404             !(kret = ser_data(verbose, "> Resolved FILE keytab",
405                               (krb5_pointer) keytab, KV5M_KEYTAB)) &&
406             !(kret = krb5_kt_close(kcontext, keytab))) {
407             snprintf(ccname, sizeof(ccname),
408                      "WRFILE:temp_kt_%d", (int) getpid());
409             if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
410                 !(kret = ser_data(verbose, "> Resolved WRFILE keytab",
411                                   (krb5_pointer) keytab, KV5M_KEYTAB)) &&
412                 !(kret = krb5_kt_close(kcontext, keytab))) {
413                 if (verbose)
414                     printf("* keytab test succeeded\n");
415             }
416         }
417     }
418     if (kret)
419         printf("* krb5_keytab test failed\n");
420     return(kret);
421 }
422
423 /*
424  * Serialize krb5_rcache.
425  */
426 static krb5_error_code
427 ser_rcache_test(krb5_context kcontext, int verbose)
428 {
429     krb5_error_code     kret;
430     char                rcname[128];
431     krb5_rcache         rcache;
432
433     snprintf(rcname, sizeof(rcname), "dfl:temp_rc_%d", (int) getpid());
434     if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname)) &&
435         !(kret = ser_data(verbose, "> Resolved FILE rcache",
436                           (krb5_pointer) rcache, KV5M_RCACHE)) &&
437         !(kret = krb5_rc_initialize(kcontext, rcache, 3600*24)) &&
438         !(kret = ser_data(verbose, "> Initialized FILE rcache",
439                           (krb5_pointer) rcache, KV5M_RCACHE)) &&
440         !(kret = krb5_rc_destroy(kcontext, rcache))) {
441         if (verbose)
442             printf("* rcache test succeeded\n");
443     }
444     if (kret)
445         printf("* krb5_rcache test failed\n");
446     return(kret);
447 }
448
449 /*
450  * Serialize krb5_principal
451  */
452 static krb5_error_code
453 ser_princ_test(krb5_context kcontext, int verbose)
454 {
455     krb5_error_code     kret;
456     krb5_principal      princ;
457     char                pname[1024];
458
459     snprintf(pname, sizeof(pname),
460              "the/quick/brown/fox/jumped/over/the/lazy/dog/%d@this.is.a.test",
461              (int) getpid());
462     if (!(kret = krb5_parse_name(kcontext, pname, &princ))) {
463         if (!(kret = ser_data(verbose, "> Principal",
464                               (krb5_pointer) princ, KV5M_PRINCIPAL))) {
465             if (verbose)
466                 printf("* principal test succeeded\n");
467         }
468         krb5_free_principal(kcontext, princ);
469     }
470     if (kret)
471         printf("* principal test failed\n");
472     return(kret);
473 }
474
475 /*
476  * Serialize krb5_checksum.
477  */
478 static krb5_error_code
479 ser_cksum_test(krb5_context kcontext, int verbose)
480 {
481     krb5_error_code     kret;
482     krb5_checksum       checksum;
483     krb5_octet          ckdata[24];
484
485     memset(&checksum, 0, sizeof(krb5_checksum));
486     checksum.magic = KV5M_CHECKSUM;
487     if (!(kret = ser_data(verbose, "> NULL checksum",
488                           (krb5_pointer) &checksum, KV5M_CHECKSUM))) {
489         checksum.checksum_type = 123;
490         checksum.length = sizeof(ckdata);
491         checksum.contents = ckdata;
492         memcpy(ckdata, &stuff, sizeof(ckdata));
493         if (!(kret = ser_data(verbose, "> checksum with data",
494                               (krb5_pointer) &checksum, KV5M_CHECKSUM))) {
495             if (verbose)
496                 printf("* checksum test succeeded\n");
497         }
498     }
499     if (kret)
500         printf("* checksum test failed\n");
501     return(kret);
502 }
503
504 /*
505  * Main procedure.
506  */
507 int
508 main(int argc, char **argv)
509 {
510     krb5_error_code     kret;
511     krb5_context        kcontext;
512     int                 do_atest, do_ctest, do_ktest, do_rtest, do_xtest;
513     int                 do_etest, do_ptest, do_stest;
514     int                 verbose;
515     int                 option;
516     extern char         *optarg;
517     char                ch_err;
518
519     kret = 0;
520     verbose = 0;
521     do_atest = 1;
522     do_xtest = 1;
523     do_ctest = 1;
524     do_etest = 1;
525     do_ktest = 1;
526     do_ptest = 1;
527     do_rtest = 1;
528     do_stest = 1;
529     while ((option = getopt(argc, argv, "acekprsxvACKPRSX")) != -1) {
530         switch (option) {
531         case 'a':
532             do_atest = 0;
533             break;
534         case 'c':
535             do_ctest = 0;
536             break;
537         case 'e':
538             do_etest = 0;
539             break;
540         case 'k':
541             do_ktest = 0;
542             break;
543         case 'p':
544             do_ptest = 0;
545             break;
546         case 'r':
547             do_rtest = 0;
548             break;
549         case 's':
550             do_stest = 0;
551             break;
552         case 'x':
553             do_xtest = 0;
554             break;
555         case 'v':
556             verbose = 1;
557             break;
558         case 'A':
559             do_atest = 1;
560             break;
561         case 'C':
562             do_ctest = 1;
563             break;
564         case 'K':
565             do_ktest = 1;
566             break;
567         case 'P':
568             do_ptest = 1;
569             break;
570         case 'R':
571             do_rtest = 1;
572             break;
573         case 'S':
574             do_stest = 1;
575             break;
576         case 'X':
577             do_xtest = 1;
578             break;
579         default:
580             fprintf(stderr,
581                     "%s: usage is %s [-acekprsxvACKPRSX]\n",
582                     argv[0], argv[0]);
583             exit(1);
584             break;
585         }
586     }
587     if ((kret = krb5_init_context(&kcontext))) {
588         com_err(argv[0], kret, "while initializing krb5");
589         exit(1);
590     }
591
592     if (do_xtest) {
593         ch_err = 'x';
594         kret = ser_kcontext_test(kcontext, verbose);
595         if (kret)
596             goto fail;
597     }
598     if (do_atest) {
599         ch_err = 'a';
600         kret = ser_acontext_test(kcontext, verbose);
601         if (kret)
602             goto fail;
603     }
604     if (do_ctest) {
605         ch_err = 'c';
606         kret = ser_ccache_test(kcontext, verbose);
607         if (kret)
608             goto fail;
609     }
610     if (do_ktest) {
611         ch_err = 'k';
612         kret = ser_keytab_test(kcontext, verbose);
613         if (kret)
614             goto fail;
615     }
616     if (do_rtest) {
617         ch_err = 'r';
618         kret = ser_rcache_test(kcontext, verbose);
619         if (kret)
620             goto fail;
621     }
622     if (do_ptest) {
623         ch_err = 'p';
624         kret = ser_princ_test(kcontext, verbose);
625         if (kret)
626             goto fail;
627     }
628     if (do_stest) {
629         ch_err = 's';
630         kret = ser_cksum_test(kcontext, verbose);
631         if (kret)
632             goto fail;
633     }
634     krb5_free_context(kcontext);
635
636     exit(0);
637 fail:
638     com_err(argv[0], kret, "--- test %cfailed", ch_err);
639     krb5_free_context(kcontext);
640     exit(1);
641 }