xref: /freebsd/crypto/krb5/src/tests/icinterleave.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* tests/icinterleave.c - interleaved init_creds_step test harness */
3 /*
4  * Copyright (C) 2017 by the Massachusetts Institute of Technology.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in
16  *   the documentation and/or other materials provided with the
17  *   distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * This test harness performs multiple initial creds operations using
35  * krb5_init_creds_step(), interleaving the operations to test the scoping of
36  * the preauth state.  All principals must have the same password (or not
37  * require a password).
38  */
39 
40 #include "k5-int.h"
41 
42 static krb5_context ctx;
43 
44 static void
check(krb5_error_code code)45 check(krb5_error_code code)
46 {
47     const char *errmsg;
48 
49     if (code) {
50         errmsg = krb5_get_error_message(ctx, code);
51         fprintf(stderr, "%s\n", errmsg);
52         krb5_free_error_message(ctx, errmsg);
53         exit(1);
54     }
55 }
56 
57 int
main(int argc,char ** argv)58 main(int argc, char **argv)
59 {
60     const char *password;
61     char **princstrs;
62     krb5_principal client;
63     krb5_init_creds_context *iccs;
64     krb5_data req, *reps, realm;
65     krb5_boolean any_left;
66     int i, nclients, primary;
67     unsigned int flags;
68 
69     if (argc < 3) {
70         fprintf(stderr, "Usage: icinterleave password princ1 princ2 ...\n");
71         exit(1);
72     }
73     password = argv[1];
74     princstrs = argv + 2;
75     nclients = argc - 2;
76 
77     check(krb5_init_context(&ctx));
78 
79     /* Create an initial creds context for each client principal. */
80     iccs = calloc(nclients, sizeof(*iccs));
81     assert(iccs != NULL);
82     for (i = 0; i < nclients; i++) {
83         check(krb5_parse_name(ctx, princstrs[i], &client));
84         check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL,
85                                    &iccs[i]));
86         check(krb5_init_creds_set_password(ctx, iccs[i], password));
87         krb5_free_principal(ctx, client);
88     }
89 
90     reps = calloc(nclients, sizeof(*reps));
91     assert(reps != NULL);
92 
93     any_left = TRUE;
94     while (any_left) {
95         any_left = FALSE;
96         for (i = 0; i < nclients; i++)  {
97             if (iccs[i] == NULL)
98                 continue;
99             any_left = TRUE;
100 
101             printf("step %d\n", i + 1);
102 
103             req = empty_data();
104             realm = empty_data();
105             check(krb5_init_creds_step(ctx, iccs[i], &reps[i], &req, &realm,
106                                        &flags));
107             if (!(flags & KRB5_INIT_CREDS_STEP_FLAG_CONTINUE)) {
108                 printf("finish %d\n", i + 1);
109                 krb5_init_creds_free(ctx, iccs[i]);
110                 iccs[i] = NULL;
111                 continue;
112             }
113 
114             primary = 0;
115             krb5_free_data_contents(ctx, &reps[i]);
116             check(krb5_sendto_kdc(ctx, &req, &realm, &reps[i], &primary, 0));
117             krb5_free_data_contents(ctx, &req);
118             krb5_free_data_contents(ctx, &realm);
119         }
120     }
121 
122     for (i = 0; i < nclients; i++)
123         krb5_free_data_contents(ctx, &reps[i]);
124     free(reps);
125     free(iccs);
126     krb5_free_context(ctx);
127     return 0;
128 }
129