1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* tests/etinfo.c - Test harness for KDC etype-info behavior */
3 /*
4 * Copyright (C) 2015 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 * Send an AS-REQ to the KDC for a specified principal, with an optionally
35 * specified request enctype list. Decode the output as either an AS-REP or a
36 * KRB-ERROR and display the PA-ETYPE-INFO2, PA-ETYPE-INFO, and PA-PW-SALT
37 * padata in the following format:
38 *
39 * error/asrep etype-info2/etype-info/pw-salt enctype salt [s2kparams]
40 *
41 * enctype is omitted for PA-PW-SALT entries. salt is displayed directly;
42 * s2kparams is displayed in uppercase hex.
43 */
44
45 #include "k5-int.h"
46
47 static krb5_context ctx;
48
49 static void
check(krb5_error_code code)50 check(krb5_error_code code)
51 {
52 const char *errmsg;
53
54 if (code) {
55 errmsg = krb5_get_error_message(ctx, code);
56 fprintf(stderr, "%s\n", errmsg);
57 krb5_free_error_message(ctx, errmsg);
58 exit(1);
59 }
60 }
61
62 static void
display_etinfo(krb5_etype_info_entry ** list,const char * l1,const char * l2)63 display_etinfo(krb5_etype_info_entry **list, const char *l1, const char *l2)
64 {
65 krb5_etype_info_entry *info;
66 char etname[256];
67 unsigned int i;
68
69 for (; *list != NULL; list++) {
70 info = *list;
71 check(krb5_enctype_to_name(info->etype, TRUE, etname, sizeof(etname)));
72 printf("%s %s %s ", l1, l2, etname);
73 if (info->length != KRB5_ETYPE_NO_SALT)
74 printf("%.*s", info->length, info->salt);
75 else
76 printf("(default)");
77 if (info->s2kparams.length > 0) {
78 printf(" ");
79 for (i = 0; i < info->s2kparams.length; i++)
80 printf("%02X", (unsigned char)info->s2kparams.data[i]);
81 }
82 printf("\n");
83 }
84 }
85
86 static void
display_padata(krb5_pa_data ** pa_list,const char * label)87 display_padata(krb5_pa_data **pa_list, const char *label)
88 {
89 krb5_pa_data *pa;
90 krb5_data d;
91 krb5_etype_info_entry **etinfo_list;
92
93 for (; pa_list != NULL && *pa_list != NULL; pa_list++) {
94 pa = *pa_list;
95 d = make_data(pa->contents, pa->length);
96 if (pa->pa_type == KRB5_PADATA_ETYPE_INFO2) {
97 check(decode_krb5_etype_info2(&d, &etinfo_list));
98 display_etinfo(etinfo_list, label, "etype_info2");
99 krb5_free_etype_info(ctx, etinfo_list);
100 } else if (pa->pa_type == KRB5_PADATA_ETYPE_INFO) {
101 check(decode_krb5_etype_info(&d, &etinfo_list));
102 display_etinfo(etinfo_list, label, "etype_info");
103 krb5_free_etype_info(ctx, etinfo_list);
104 } else if (pa->pa_type == KRB5_PADATA_PW_SALT) {
105 printf("%s pw_salt %.*s\n", label, (int)d.length, d.data);
106 } else if (pa->pa_type == KRB5_PADATA_AFS3_SALT) {
107 printf("%s afs3_salt %.*s\n", label, (int)d.length, d.data);
108 }
109 }
110 }
111
112 int
main(int argc,char ** argv)113 main(int argc, char **argv)
114 {
115 krb5_principal client;
116 krb5_get_init_creds_opt *opt;
117 krb5_init_creds_context icc;
118 krb5_data reply, request, realm;
119 krb5_error *error;
120 krb5_kdc_rep *asrep;
121 krb5_pa_data **padata;
122 krb5_preauthtype pa_type = KRB5_PADATA_NONE;
123 unsigned int flags;
124 int primary = 0;
125
126 if (argc < 2 || argc > 3) {
127 fprintf(stderr, "Usage: %s princname [patype]\n", argv[0]);
128 exit(1);
129 }
130 check(krb5_init_context(&ctx));
131 check(krb5_parse_name(ctx, argv[1], &client));
132 if (argc >= 3)
133 pa_type = atoi(argv[2]);
134
135 check(krb5_get_init_creds_opt_alloc(ctx, &opt));
136 if (pa_type != KRB5_PADATA_NONE)
137 krb5_get_init_creds_opt_set_preauth_list(opt, &pa_type, 1);
138
139 check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, opt, &icc));
140 reply = empty_data();
141 check(krb5_init_creds_step(ctx, icc, &reply, &request, &realm, &flags));
142 assert(flags == KRB5_INIT_CREDS_STEP_FLAG_CONTINUE);
143 check(krb5_sendto_kdc(ctx, &request, &realm, &reply, &primary, 0));
144
145 if (decode_krb5_error(&reply, &error) == 0) {
146 decode_krb5_padata_sequence(&error->e_data, &padata);
147 if (error->error == KDC_ERR_PREAUTH_REQUIRED) {
148 display_padata(padata, "error");
149 } else if (error->error == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED) {
150 display_padata(padata, "more");
151 } else {
152 fprintf(stderr, "Unexpected error %d\n", (int)error->error);
153 return 1;
154 }
155 krb5_free_pa_data(ctx, padata);
156 krb5_free_error(ctx, error);
157 } else if (decode_krb5_as_rep(&reply, &asrep) == 0) {
158 display_padata(asrep->padata, "asrep");
159 krb5_free_kdc_rep(ctx, asrep);
160 } else {
161 abort();
162 }
163
164 krb5_free_data_contents(ctx, &request);
165 krb5_free_data_contents(ctx, &reply);
166 krb5_free_data_contents(ctx, &realm);
167 krb5_get_init_creds_opt_free(ctx, opt);
168 krb5_init_creds_free(ctx, icc);
169 krb5_free_principal(ctx, client);
170 krb5_free_context(ctx);
171 return 0;
172 }
173