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