Branch data Line data Source code
1 : : /* krb5context.c --- Kerberos 5 security context self tests.
2 : : * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Simon Josefsson
3 : : *
4 : : * This file is part of the Generic Security Service (GSS).
5 : : *
6 : : * GSS is free software; you can redistribute it and/or modify it
7 : : * under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 3 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * GSS is distributed in the hope that it will be useful, but WITHOUT
12 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 : : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 : : * License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with GSS; if not, see http://www.gnu.org/licenses or write to
18 : : * the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 : : * Floor, Boston, MA 02110-1301, USA.
20 : : *
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <stdio.h>
26 : : #include <stdlib.h>
27 : : #include <stdarg.h>
28 : : #include <ctype.h>
29 : : #include <string.h>
30 : :
31 : : /* Get GSS prototypes. */
32 : : #include <gss.h>
33 : :
34 : : /* Get Shishi prototypes. */
35 : : #include <shishi.h>
36 : :
37 : : #include "utils.c"
38 : :
39 : : static void
40 : 0 : display_status_1 (const char *m, OM_uint32 code, int type)
41 : : {
42 : : OM_uint32 maj_stat, min_stat;
43 : : gss_buffer_desc msg;
44 : : OM_uint32 msg_ctx;
45 : :
46 : 0 : msg_ctx = 0;
47 : : do
48 : : {
49 : 0 : maj_stat = gss_display_status (&min_stat, code,
50 : : type, GSS_C_NO_OID, &msg_ctx, &msg);
51 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
52 : 0 : printf ("GSS-API display_status failed on code %d type %d\n",
53 : : code, type);
54 : : else
55 : : {
56 [ # # ]: 0 : printf ("GSS-API error %s (%s): %.*s\n",
57 : : m, type == GSS_C_GSS_CODE ? "major" : "minor",
58 : : (int) msg.length, (char *) msg.value);
59 : :
60 : 0 : gss_release_buffer (&min_stat, &msg);
61 : : }
62 : : }
63 [ # # ][ # # ]: 0 : while (!GSS_ERROR (maj_stat) && msg_ctx);
64 : 0 : }
65 : :
66 : : static void
67 : 0 : display_status (const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat)
68 : : {
69 : 0 : display_status_1 (msg, maj_stat, GSS_C_GSS_CODE);
70 : 0 : display_status_1 (msg, min_stat, GSS_C_MECH_CODE);
71 : 0 : }
72 : :
73 : : int
74 : 1 : main (int argc, char *argv[])
75 : : {
76 : : gss_uint32 maj_stat, min_stat, ret_flags, time_rec;
77 : : gss_buffer_desc bufdesc, bufdesc2;
78 : 1 : gss_name_t servername = GSS_C_NO_NAME, name;
79 : 1 : gss_ctx_id_t cctx = GSS_C_NO_CONTEXT;
80 : 1 : gss_ctx_id_t sctx = GSS_C_NO_CONTEXT;
81 : : gss_cred_id_t server_creds;
82 : : Shishi *handle;
83 : : size_t i;
84 : : struct gss_channel_bindings_struct cb;
85 : :
86 : 1 : memset (&cb, 0, sizeof (cb));
87 : 1 : cb.application_data.length = 3;
88 : 1 : cb.application_data.value = (char *) "hej";
89 : :
90 : : do
91 [ + - ][ - + ]: 1 : if (strcmp (argv[argc - 1], "-v") == 0 ||
92 : 1 : strcmp (argv[argc - 1], "--verbose") == 0)
93 : 0 : debug = 1;
94 [ + - ][ - + ]: 1 : else if (strcmp (argv[argc - 1], "-b") == 0 ||
95 : 1 : strcmp (argv[argc - 1], "--break-on-error") == 0)
96 : 0 : break_on_error = 1;
97 [ + - ][ + - ]: 1 : else if (strcmp (argv[argc - 1], "-h") == 0 ||
[ - + ]
98 : 1 : strcmp (argv[argc - 1], "-?") == 0 ||
99 : 1 : strcmp (argv[argc - 1], "--help") == 0)
100 : : {
101 : 0 : printf ("Usage: %s [-vbh?] [--verbose] [--break-on-error] [--help]\n",
102 : : argv[0]);
103 : 0 : return 1;
104 : : }
105 [ - + ]: 1 : while (argc-- > 1);
106 : :
107 : 1 : handle = shishi ();
108 : :
109 : : /* Name of service. */
110 : :
111 : 1 : bufdesc.value = (char *) "host@latte.josefsson.org";
112 : 1 : bufdesc.length = strlen (bufdesc.value);
113 : :
114 : 1 : maj_stat = gss_import_name (&min_stat, &bufdesc,
115 : : GSS_C_NT_HOSTBASED_SERVICE, &servername);
116 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
117 : 0 : fail ("gss_import_name (host/server)\n");
118 : :
119 : : /* Get credential, for server. */
120 : :
121 : 1 : maj_stat = gss_acquire_cred (&min_stat, servername, 0,
122 : : GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
123 : : &server_creds, NULL, NULL);
124 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
125 : : {
126 : 0 : fail ("gss_acquire_cred");
127 : 0 : display_status ("acquire credentials", maj_stat, min_stat);
128 : : }
129 : :
130 [ + + ]: 4 : for (i = 0; i < 3; i++)
131 : : {
132 : : /* Start client. */
133 : :
134 [ + + + - ]: 3 : switch (i)
135 : : {
136 : : case 0:
137 : 1 : maj_stat = gss_init_sec_context (&min_stat,
138 : : GSS_C_NO_CREDENTIAL,
139 : : &cctx,
140 : : servername,
141 : : GSS_KRB5,
142 : : GSS_C_MUTUAL_FLAG |
143 : : GSS_C_REPLAY_FLAG |
144 : : GSS_C_SEQUENCE_FLAG,
145 : : 0,
146 : : GSS_C_NO_CHANNEL_BINDINGS,
147 : : GSS_C_NO_BUFFER, NULL,
148 : : &bufdesc2, NULL, NULL);
149 [ - + ]: 1 : if (maj_stat != GSS_S_CONTINUE_NEEDED)
150 : 0 : fail ("loop 0 init failure\n");
151 : 1 : break;
152 : :
153 : : case 1:
154 : : /* Default OID, channel bindings. */
155 : 1 : maj_stat = gss_init_sec_context (&min_stat,
156 : : GSS_C_NO_CREDENTIAL,
157 : : &cctx,
158 : : servername,
159 : : GSS_C_NO_OID,
160 : : GSS_C_MUTUAL_FLAG |
161 : : GSS_C_REPLAY_FLAG |
162 : : GSS_C_SEQUENCE_FLAG,
163 : : 0,
164 : : &cb,
165 : : GSS_C_NO_BUFFER, NULL,
166 : : &bufdesc2, NULL, NULL);
167 [ - + ]: 1 : if (maj_stat != GSS_S_CONTINUE_NEEDED)
168 : 0 : fail ("loop 0 init failure\n");
169 : 1 : break;
170 : :
171 : : case 2:
172 : : /* No mutual authentication. */
173 : 1 : maj_stat = gss_init_sec_context (&min_stat,
174 : : GSS_C_NO_CREDENTIAL,
175 : : &cctx,
176 : : servername,
177 : : GSS_KRB5,
178 : : GSS_C_REPLAY_FLAG |
179 : : GSS_C_CONF_FLAG |
180 : : GSS_C_SEQUENCE_FLAG,
181 : : 0,
182 : : GSS_C_NO_CHANNEL_BINDINGS,
183 : : GSS_C_NO_BUFFER, NULL,
184 : : &bufdesc2, &ret_flags, NULL);
185 [ - + ]: 1 : if (ret_flags != (GSS_C_REPLAY_FLAG |
186 : : GSS_C_CONF_FLAG |
187 : : GSS_C_SEQUENCE_FLAG | GSS_C_PROT_READY_FLAG))
188 : 0 : fail ("loop 2 ret_flags failure (%d)\n", ret_flags);
189 [ - + ]: 1 : if (maj_stat != GSS_S_COMPLETE)
190 : 0 : fail ("loop 1 init failure\n");
191 : 1 : break;
192 : :
193 : : default:
194 : 0 : fail ("default?!\n");
195 : : break;
196 : : }
197 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
198 : : {
199 : 0 : fail ("gss_accept_sec_context failure\n");
200 : 0 : display_status ("accept_sec_context", maj_stat, min_stat);
201 : : }
202 : :
203 [ - + ]: 3 : if (debug)
204 : : {
205 : 0 : char *p = bufdesc2.value;
206 : 0 : Shishi_asn1 apreq = shishi_der2asn1_apreq (handle,
207 : : p + 17,
208 : 0 : bufdesc2.length - 17);
209 : 0 : printf ("\nClient AP-REQ:\n\n");
210 : 0 : shishi_apreq_print (handle, stdout, apreq);
211 : : }
212 : :
213 : : /* Start server. */
214 : :
215 [ + + + - ]: 3 : switch (i)
216 : : {
217 : : case 0:
218 : 1 : maj_stat = gss_accept_sec_context (&min_stat,
219 : : &sctx,
220 : : server_creds,
221 : : &bufdesc2,
222 : : GSS_C_NO_CHANNEL_BINDINGS,
223 : : &name,
224 : : NULL,
225 : : &bufdesc,
226 : : &ret_flags, &time_rec, NULL);
227 [ - + ]: 1 : if (ret_flags != (GSS_C_MUTUAL_FLAG |
228 : : /* XXX GSS_C_REPLAY_FLAG |
229 : : GSS_C_SEQUENCE_FLAG | */
230 : : GSS_C_PROT_READY_FLAG))
231 : 0 : fail ("loop 0 accept flag failure (%d)\n", ret_flags);
232 : 1 : break;
233 : :
234 : : case 1:
235 : 1 : maj_stat = gss_accept_sec_context (&min_stat,
236 : : &sctx,
237 : : server_creds,
238 : : &bufdesc2,
239 : : &cb,
240 : : &name,
241 : : NULL,
242 : : &bufdesc,
243 : : &ret_flags, &time_rec, NULL);
244 : 1 : break;
245 : :
246 : : case 2:
247 : 1 : maj_stat = gss_accept_sec_context (&min_stat,
248 : : &sctx,
249 : : server_creds,
250 : : &bufdesc2,
251 : : GSS_C_NO_CHANNEL_BINDINGS,
252 : : &name,
253 : : NULL,
254 : : &bufdesc,
255 : : &ret_flags, &time_rec, NULL);
256 : 1 : break;
257 : : default:
258 : 0 : fail ("default?!\n");
259 : : break;
260 : : }
261 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
262 : : {
263 : 0 : fail ("gss_accept_sec_context failure\n");
264 : 0 : display_status ("accept_sec_context", maj_stat, min_stat);
265 : : }
266 : :
267 [ - + ]: 3 : if (debug)
268 : : {
269 : 0 : char *p = bufdesc2.value;
270 : : Shishi_asn1 aprep =
271 : 0 : shishi_der2asn1_aprep (handle, p + 15, bufdesc.length - 15);
272 : 0 : printf ("\nServer AP-REP:\n\n");
273 : 0 : shishi_aprep_print (handle, stdout, aprep);
274 : : }
275 : :
276 [ + + + ]: 3 : switch (i)
277 : : {
278 : : case 0:
279 : 1 : maj_stat = gss_init_sec_context (&min_stat,
280 : : GSS_C_NO_CREDENTIAL,
281 : : &cctx,
282 : : servername,
283 : : GSS_KRB5,
284 : : GSS_C_MUTUAL_FLAG |
285 : : GSS_C_REPLAY_FLAG |
286 : : GSS_C_SEQUENCE_FLAG,
287 : : 0,
288 : : GSS_C_NO_CHANNEL_BINDINGS,
289 : : &bufdesc, NULL,
290 : : &bufdesc2, NULL, NULL);
291 : 1 : break;
292 : :
293 : : case 1:
294 : : /* Check ret_flags. */
295 : 1 : maj_stat = gss_init_sec_context (&min_stat,
296 : : GSS_C_NO_CREDENTIAL,
297 : : &cctx,
298 : : servername,
299 : : GSS_KRB5,
300 : : GSS_C_MUTUAL_FLAG |
301 : : GSS_C_REPLAY_FLAG |
302 : : GSS_C_SEQUENCE_FLAG,
303 : : 0,
304 : : GSS_C_NO_CHANNEL_BINDINGS,
305 : : &bufdesc, NULL,
306 : : &bufdesc2, &ret_flags, &time_rec);
307 [ - + ]: 1 : if (ret_flags != (GSS_C_MUTUAL_FLAG |
308 : : GSS_C_REPLAY_FLAG |
309 : : GSS_C_SEQUENCE_FLAG | GSS_C_PROT_READY_FLAG))
310 : 0 : fail ("loop 1 ret_flags failure (%d)\n", ret_flags);
311 : : break;
312 : :
313 : : /* No case 2. */
314 : :
315 : : default:
316 : : break;
317 : : }
318 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
319 : : {
320 : 0 : fail ("gss_init_sec_context failure (2)\n");
321 : 0 : display_status ("init_sec_context", maj_stat, min_stat);
322 : : }
323 : :
324 : : {
325 : : gss_buffer_desc pt, pt2, ct;
326 : : int conf_state;
327 : : gss_qop_t qop_state;
328 : :
329 : 3 : pt.value = (char *) "foo";
330 : 3 : pt.length = strlen (pt.value) + 1;
331 : 3 : maj_stat = gss_wrap (&min_stat, cctx, 0, 0, &pt, &conf_state, &ct);
332 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
333 : : {
334 : 0 : fail ("client gss_wrap failure\n");
335 : 0 : display_status ("client wrap", maj_stat, min_stat);
336 : : }
337 : :
338 : 3 : maj_stat = gss_unwrap (&min_stat, sctx,
339 : : &ct, &pt2, &conf_state, &qop_state);
340 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
341 : : {
342 : 0 : fail ("server gss_unwrap failure\n");
343 : 0 : display_status ("client wrap", maj_stat, min_stat);
344 : : }
345 : :
346 [ + - ][ - + ]: 3 : if (pt.length != pt2.length
347 : 6 : || memcmp (pt2.value, pt.value, pt.length) != 0)
348 : 0 : fail ("wrap+unwrap failed (%d, %d, %.*s)\n",
349 : : pt.length, pt2.length, pt2.length, (char *) pt2.value);
350 : :
351 : 3 : gss_release_buffer (&min_stat, &ct);
352 : 3 : gss_release_buffer (&min_stat, &pt2);
353 : : }
354 : :
355 : 3 : maj_stat = gss_delete_sec_context (&min_stat, &cctx, GSS_C_NO_BUFFER);
356 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
357 : : {
358 : 0 : fail ("client gss_delete_sec_context failure\n");
359 : 0 : display_status ("client delete_sec_context", maj_stat, min_stat);
360 : : }
361 : :
362 : 3 : maj_stat = gss_delete_sec_context (&min_stat, &sctx, GSS_C_NO_BUFFER);
363 [ - + ]: 3 : if (GSS_ERROR (maj_stat))
364 : : {
365 : 0 : fail ("server gss_delete_sec_context failure\n");
366 : 0 : display_status ("server delete_sec_context", maj_stat, min_stat);
367 : : }
368 : :
369 : 3 : success ("loop %d ok\n", i);
370 : : }
371 : :
372 : : /* Clean up. */
373 : :
374 : 1 : maj_stat = gss_release_cred (&min_stat, &server_creds);
375 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
376 : : {
377 : 0 : fail ("gss_release_cred");
378 : 0 : display_status ("release credentials", maj_stat, min_stat);
379 : : }
380 : :
381 : 1 : maj_stat = gss_release_name (&min_stat, &servername);
382 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
383 : : {
384 : 0 : fail ("gss_release_name failure\n");
385 : 0 : display_status ("gss_release_name", maj_stat, min_stat);
386 : : }
387 : :
388 : 1 : shishi_done (handle);
389 : :
390 : : /* We're done. */
391 : :
392 [ - + ]: 1 : if (debug)
393 : 0 : printf ("Kerberos 5 security context self tests done with %d errors\n",
394 : : error_count);
395 : :
396 : 1 : return error_count ? 1 : 0;
397 : : }
|