Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/gssapi/common.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* tests/gssapi/common.c - Common utility functions for GSSAPI test programs */
3
/*
4
* Copyright (C) 2012 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
#include <stdio.h>
34
#include <string.h>
35
#include "common.h"
36
37
gss_OID_desc mech_krb5 = { 9, "\052\206\110\206\367\022\001\002\002" };
38
gss_OID_desc mech_spnego = { 6, "\053\006\001\005\005\002" };
39
gss_OID_desc mech_iakerb = { 6, "\053\006\001\005\002\005" };
40
gss_OID_set_desc mechset_krb5 = { 1, &mech_krb5 };
41
gss_OID_set_desc mechset_spnego = { 1, &mech_spnego };
42
gss_OID_set_desc mechset_iakerb = { 1, &mech_iakerb };
43
44
static void
45
display_status(const char *msg, OM_uint32 code, int type)
46
{
47
OM_uint32 min_stat, msg_ctx = 0;
48
gss_buffer_desc buf;
49
50
do {
51
(void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID,
52
&msg_ctx, &buf);
53
fprintf(stderr, "%s: %.*s\n", msg, (int)buf.length, (char *)buf.value);
54
(void)gss_release_buffer(&min_stat, &buf);
55
} while (msg_ctx != 0);
56
}
57
58
void
59
check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor)
60
{
61
if (GSS_ERROR(major)) {
62
display_status(msg, major, GSS_C_GSS_CODE);
63
display_status(msg, minor, GSS_C_MECH_CODE);
64
exit(1);
65
}
66
}
67
68
void
69
check_k5err(krb5_context context, const char *msg, krb5_error_code code)
70
{
71
const char *errmsg;
72
73
if (code) {
74
errmsg = krb5_get_error_message(context, code);
75
printf("%s: %s\n", msg, errmsg);
76
krb5_free_error_message(context, errmsg);
77
exit(1);
78
}
79
}
80
81
void
82
errout(const char *msg)
83
{
84
fprintf(stderr, "%s\n", msg);
85
exit(1);
86
}
87
88
gss_name_t
89
import_name(const char *str)
90
{
91
OM_uint32 major, minor;
92
gss_name_t name;
93
gss_buffer_desc buf;
94
gss_OID nametype = NULL;
95
96
if (*str == 'u')
97
nametype = GSS_C_NT_USER_NAME;
98
else if (*str == 'p')
99
nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
100
else if (*str == 'e')
101
nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME;
102
else if (*str == 'c')
103
nametype = (gss_OID)GSS_KRB5_NT_X509_CERT;
104
else if (*str == 'h')
105
nametype = GSS_C_NT_HOSTBASED_SERVICE;
106
if (nametype == NULL || str[1] != ':')
107
errout("names must begin with u: or p: or e: or c: or h:");
108
buf.value = (char *)str + 2;
109
buf.length = strlen(str) - 2;
110
major = gss_import_name(&minor, &buf, nametype, &name);
111
check_gsserr("gss_import_name", major, minor);
112
return name;
113
}
114
115
void
116
establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
117
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
118
gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech,
119
gss_cred_id_t *deleg_cred)
120
{
121
establish_contexts_ex(imech, icred, acred, tname, flags, ictx, actx,
122
GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_CHANNEL_BINDINGS,
123
NULL, src_name, amech, deleg_cred);
124
}
125
126
void
127
establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
128
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
129
gss_ctx_id_t *actx, gss_channel_bindings_t icb,
130
gss_channel_bindings_t acb, OM_uint32 *aret_flags,
131
gss_name_t *src_name, gss_OID *amech,
132
gss_cred_id_t *deleg_cred)
133
{
134
OM_uint32 minor, imaj, amaj;
135
gss_buffer_desc itok, atok;
136
137
*ictx = *actx = GSS_C_NO_CONTEXT;
138
imaj = amaj = GSS_S_CONTINUE_NEEDED;
139
itok.value = atok.value = NULL;
140
itok.length = atok.length = 0;
141
for (;;) {
142
(void)gss_release_buffer(&minor, &itok);
143
imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags,
144
GSS_C_INDEFINITE, icb, &atok, NULL, &itok,
145
NULL, NULL);
146
check_gsserr("gss_init_sec_context", imaj, minor);
147
if (amaj == GSS_S_COMPLETE)
148
break;
149
150
(void)gss_release_buffer(&minor, &atok);
151
amaj = gss_accept_sec_context(&minor, actx, acred, &itok, acb,
152
src_name, amech, &atok, aret_flags, NULL,
153
deleg_cred);
154
check_gsserr("gss_accept_sec_context", amaj, minor);
155
(void)gss_release_buffer(&minor, &itok);
156
if (imaj == GSS_S_COMPLETE)
157
break;
158
}
159
160
if (imaj != GSS_S_COMPLETE || amaj != GSS_S_COMPLETE)
161
errout("One side wants to continue after the other is done");
162
163
(void)gss_release_buffer(&minor, &itok);
164
(void)gss_release_buffer(&minor, &atok);
165
}
166
167
void
168
export_import_cred(gss_cred_id_t *cred)
169
{
170
OM_uint32 major, minor;
171
gss_buffer_desc buf;
172
173
major = gss_export_cred(&minor, *cred, &buf);
174
check_gsserr("gss_export_cred", major, minor);
175
(void)gss_release_cred(&minor, cred);
176
major = gss_import_cred(&minor, &buf, cred);
177
check_gsserr("gss_import_cred", major, minor);
178
(void)gss_release_buffer(&minor, &buf);
179
}
180
181
void
182
display_canon_name(const char *tag, gss_name_t name, gss_OID mech)
183
{
184
gss_name_t canon;
185
OM_uint32 major, minor;
186
gss_buffer_desc buf;
187
188
major = gss_canonicalize_name(&minor, name, mech, &canon);
189
check_gsserr("gss_canonicalize_name", major, minor);
190
191
major = gss_display_name(&minor, canon, &buf, NULL);
192
check_gsserr("gss_display_name", major, minor);
193
194
printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value);
195
196
(void)gss_release_name(&minor, &canon);
197
(void)gss_release_buffer(&minor, &buf);
198
}
199
200
void
201
display_oid(const char *tag, gss_OID oid)
202
{
203
OM_uint32 major, minor;
204
gss_buffer_desc buf;
205
206
major = gss_oid_to_str(&minor, oid, &buf);
207
check_gsserr("gss_oid_to_str", major, minor);
208
if (tag != NULL)
209
printf("%s:\t", tag);
210
printf("%.*s\n", (int)buf.length, (char *)buf.value);
211
(void)gss_release_buffer(&minor, &buf);
212
}
213
214
static void
215
dump_attribute(gss_name_t name, gss_buffer_t attribute, int noisy)
216
{
217
OM_uint32 major, minor;
218
gss_buffer_desc value;
219
gss_buffer_desc display_value;
220
int authenticated = 0;
221
int complete = 0;
222
int more = -1;
223
unsigned int i;
224
225
while (more != 0) {
226
value.value = NULL;
227
display_value.value = NULL;
228
229
major = gss_get_name_attribute(&minor, name, attribute, &authenticated,
230
&complete, &value, &display_value,
231
&more);
232
check_gsserr("gss_get_name_attribute", major, minor);
233
234
printf("Attribute %.*s %s %s\n\n%.*s\n",
235
(int)attribute->length, (char *)attribute->value,
236
authenticated ? "Authenticated" : "",
237
complete ? "Complete" : "",
238
(int)display_value.length, (char *)display_value.value);
239
240
if (noisy) {
241
for (i = 0; i < value.length; i++) {
242
if ((i % 32) == 0)
243
printf("\n");
244
printf("%02x", ((char *)value.value)[i] & 0xFF);
245
}
246
printf("\n\n");
247
}
248
249
(void)gss_release_buffer(&minor, &value);
250
(void)gss_release_buffer(&minor, &display_value);
251
}
252
}
253
254
void
255
enumerate_attributes(gss_name_t name, int noisy)
256
{
257
OM_uint32 major, minor;
258
int is_mechname;
259
gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
260
size_t i;
261
262
major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs);
263
check_gsserr("gss_inquire_name", major, minor);
264
265
if (attrs != GSS_C_NO_BUFFER_SET) {
266
for (i = 0; i < attrs->count; i++)
267
dump_attribute(name, &attrs->elements[i], noisy);
268
}
269
270
(void)gss_release_buffer_set(&minor, &attrs);
271
}
272
273
void
274
print_hex(FILE *fp, gss_buffer_t buf)
275
{
276
size_t i;
277
const unsigned char *bytes = buf->value;
278
279
for (i = 0; i < buf->length; i++)
280
printf("%02X", bytes[i]);
281
printf("\n");
282
}
283
284