1 /* $NetBSD: test_context.c,v 1.1.1.2 2014/04/24 12:45:29 pettai Exp $ */
4 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of KTH nor the names of its contributors may be
20 * used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "krb5/gsskrb5_locl.h"
38 #include <krb5/getarg.h>
39 #include <gssapi/gssapi.h>
40 #include <gssapi/gssapi_krb5.h>
41 #include <gssapi/gssapi_spnego.h>
42 #include <gssapi/gssapi_ntlm.h>
43 #include "test_common.h"
45 static char *type_string
;
46 static char *mech_string
;
47 static char *ret_mech_string
;
48 static char *client_name
;
49 static char *client_password
;
50 static int dns_canon_flag
= -1;
51 static int mutual_auth_flag
= 0;
52 static int dce_style_flag
= 0;
53 static int wrapunwrap_flag
= 0;
54 static int iov_flag
= 0;
55 static int getverifymic_flag
= 0;
56 static int deleg_flag
= 0;
57 static int policy_deleg_flag
= 0;
58 static int server_no_deleg_flag
= 0;
59 static int ei_flag
= 0;
60 static char *gsskrb5_acceptor_identity
= NULL
;
61 static char *session_enctype_string
= NULL
;
62 static int client_time_offset
= 0;
63 static int server_time_offset
= 0;
64 static int max_loops
= 0;
65 static char *limit_enctype_string
= NULL
;
66 static int version_flag
= 0;
67 static int verbose_flag
= 0;
68 static int help_flag
= 0;
70 static krb5_context context
;
71 static krb5_enctype limit_enctype
= 0;
77 { "krb5", NULL
/* GSS_KRB5_MECHANISM */ },
78 { "spnego", NULL
/* GSS_SPNEGO_MECHANISM */ },
79 { "ntlm", NULL
/* GSS_NTLM_MECHANISM */ },
80 { "sasl-digest-md5", NULL
/* GSS_SASL_DIGEST_MD5_MECHANISM */ }
86 o2n
[0].oid
= GSS_KRB5_MECHANISM
;
87 o2n
[1].oid
= GSS_SPNEGO_MECHANISM
;
88 o2n
[2].oid
= GSS_NTLM_MECHANISM
;
89 o2n
[3].oid
= GSS_SASL_DIGEST_MD5_MECHANISM
;
93 string_to_oid(const char *name
)
96 for (i
= 0; i
< sizeof(o2n
)/sizeof(o2n
[0]); i
++)
97 if (strcasecmp(name
, o2n
[i
].name
) == 0)
99 errx(1, "name '%s' not unknown", name
);
103 oid_to_string(const gss_OID oid
)
106 for (i
= 0; i
< sizeof(o2n
)/sizeof(o2n
[0]); i
++)
107 if (gss_oid_equal(oid
, o2n
[i
].oid
))
109 return "unknown oid";
113 loop(gss_OID mechoid
,
114 gss_OID nameoid
, const char *target
,
115 gss_cred_id_t init_cred
,
116 gss_ctx_id_t
*sctx
, gss_ctx_id_t
*cctx
,
117 gss_OID
*actual_mech
,
118 gss_cred_id_t
*deleg_cred
)
120 int server_done
= 0, client_done
= 0;
122 OM_uint32 maj_stat
, min_stat
;
123 gss_name_t gss_target_name
;
124 gss_buffer_desc input_token
, output_token
;
125 OM_uint32 flags
= 0, ret_cflags
, ret_sflags
;
126 gss_OID actual_mech_client
;
127 gss_OID actual_mech_server
;
129 *actual_mech
= GSS_C_NO_OID
;
131 flags
|= GSS_C_INTEG_FLAG
;
132 flags
|= GSS_C_CONF_FLAG
;
134 if (mutual_auth_flag
)
135 flags
|= GSS_C_MUTUAL_FLAG
;
137 flags
|= GSS_C_DCE_STYLE
;
139 flags
|= GSS_C_DELEG_FLAG
;
140 if (policy_deleg_flag
)
141 flags
|= GSS_C_DELEG_POLICY_FLAG
;
143 input_token
.value
= rk_UNCONST(target
);
144 input_token
.length
= strlen(target
);
146 maj_stat
= gss_import_name(&min_stat
,
150 if (GSS_ERROR(maj_stat
))
151 err(1, "import name creds failed with: %d", maj_stat
);
153 input_token
.length
= 0;
154 input_token
.value
= NULL
;
156 while (!server_done
|| !client_done
) {
159 gsskrb5_set_time_offset(client_time_offset
);
161 maj_stat
= gss_init_sec_context(&min_stat
,
174 if (GSS_ERROR(maj_stat
))
175 errx(1, "init_sec_context: %s",
176 gssapi_err(maj_stat
, min_stat
, mechoid
));
177 if (maj_stat
& GSS_S_CONTINUE_NEEDED
)
182 gsskrb5_get_time_offset(&client_time_offset
);
184 if (client_done
&& server_done
)
187 if (input_token
.length
!= 0)
188 gss_release_buffer(&min_stat
, &input_token
);
190 gsskrb5_set_time_offset(server_time_offset
);
192 maj_stat
= gss_accept_sec_context(&min_stat
,
196 GSS_C_NO_CHANNEL_BINDINGS
,
203 if (GSS_ERROR(maj_stat
))
204 errx(1, "accept_sec_context: %s",
205 gssapi_err(maj_stat
, min_stat
, actual_mech_server
));
207 gsskrb5_get_time_offset(&server_time_offset
);
209 if (output_token
.length
!= 0)
210 gss_release_buffer(&min_stat
, &output_token
);
212 if (maj_stat
& GSS_S_CONTINUE_NEEDED
)
217 if (output_token
.length
!= 0)
218 gss_release_buffer(&min_stat
, &output_token
);
219 if (input_token
.length
!= 0)
220 gss_release_buffer(&min_stat
, &input_token
);
221 gss_release_name(&min_stat
, &gss_target_name
);
223 if (deleg_flag
|| policy_deleg_flag
) {
224 if (server_no_deleg_flag
) {
225 if (*deleg_cred
!= GSS_C_NO_CREDENTIAL
)
226 errx(1, "got delegated cred but didn't expect one");
227 } else if (*deleg_cred
== GSS_C_NO_CREDENTIAL
)
228 errx(1, "asked for delegarated cred but did get one");
229 } else if (*deleg_cred
!= GSS_C_NO_CREDENTIAL
)
230 errx(1, "got deleg_cred cred but didn't ask");
232 if (gss_oid_equal(actual_mech_server
, actual_mech_client
) == 0)
233 errx(1, "mech mismatch");
234 *actual_mech
= actual_mech_server
;
236 if (max_loops
&& num_loops
> max_loops
)
237 errx(1, "num loops %d was lager then max loops %d",
238 num_loops
, max_loops
);
241 printf("server time offset: %d\n", server_time_offset
);
242 printf("client time offset: %d\n", client_time_offset
);
243 printf("num loops %d\n", num_loops
);
248 wrapunwrap(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, int flags
, gss_OID mechoid
)
250 gss_buffer_desc input_token
, output_token
, output_token2
;
251 OM_uint32 min_stat
, maj_stat
;
255 input_token
.value
= "foo";
256 input_token
.length
= 3;
258 maj_stat
= gss_wrap(&min_stat
, cctx
, flags
, 0, &input_token
,
259 &conf_state
, &output_token
);
260 if (maj_stat
!= GSS_S_COMPLETE
)
261 errx(1, "gss_wrap failed: %s",
262 gssapi_err(maj_stat
, min_stat
, mechoid
));
264 maj_stat
= gss_unwrap(&min_stat
, sctx
, &output_token
,
265 &output_token2
, &conf_state
, &qop_state
);
266 if (maj_stat
!= GSS_S_COMPLETE
)
267 errx(1, "gss_unwrap failed: %s",
268 gssapi_err(maj_stat
, min_stat
, mechoid
));
270 gss_release_buffer(&min_stat
, &output_token
);
271 gss_release_buffer(&min_stat
, &output_token2
);
273 #if 0 /* doesn't work for NTLM yet */
274 if (!!conf_state
!= !!flags
)
275 errx(1, "conf_state mismatch");
280 #define USE_HEADER_ONLY 2
281 #define USE_SIGN_ONLY 4
285 wrapunwrap_iov(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, int flags
, gss_OID mechoid
)
287 krb5_data token
, header
, trailer
;
288 OM_uint32 min_stat
, maj_stat
;
290 int conf_state
, conf_state2
;
291 gss_iov_buffer_desc iov
[6];
294 char header_data
[9] = "ABCheader";
295 char trailer_data
[10] = "trailerXYZ";
297 char token_data
[16] = "0123456789abcdef";
299 memset(&iov
, 0, sizeof(iov
));
301 if (flags
& USE_SIGN_ONLY
) {
302 header
.data
= header_data
;
304 trailer
.data
= trailer_data
;
313 token
.data
= token_data
;
316 iov_len
= sizeof(iov
)/sizeof(iov
[0]);
318 memset(iov
, 0, sizeof(iov
));
320 iov
[0].type
= GSS_IOV_BUFFER_TYPE_HEADER
| GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
;
322 if (header
.length
!= 0) {
323 iov
[1].type
= GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
324 iov
[1].buffer
.length
= header
.length
;
325 iov
[1].buffer
.value
= header
.data
;
327 iov
[1].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
328 iov
[1].buffer
.length
= 0;
329 iov
[1].buffer
.value
= NULL
;
331 iov
[2].type
= GSS_IOV_BUFFER_TYPE_DATA
;
332 iov
[2].buffer
.length
= token
.length
;
333 iov
[2].buffer
.value
= token
.data
;
334 if (trailer
.length
!= 0) {
335 iov
[3].type
= GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
336 iov
[3].buffer
.length
= trailer
.length
;
337 iov
[3].buffer
.value
= trailer
.data
;
339 iov
[3].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
340 iov
[3].buffer
.length
= 0;
341 iov
[3].buffer
.value
= NULL
;
343 if (dce_style_flag
) {
344 iov
[4].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
346 iov
[4].type
= GSS_IOV_BUFFER_TYPE_PADDING
| GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
;
348 iov
[4].buffer
.length
= 0;
349 iov
[4].buffer
.value
= 0;
350 if (dce_style_flag
) {
351 iov
[5].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
352 } else if (flags
& USE_HEADER_ONLY
) {
353 iov
[5].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
355 iov
[5].type
= GSS_IOV_BUFFER_TYPE_TRAILER
| GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
;
357 iov
[5].buffer
.length
= 0;
358 iov
[5].buffer
.value
= 0;
360 maj_stat
= gss_wrap_iov(&min_stat
, cctx
, dce_style_flag
|| flags
& USE_CONF
, 0, &conf_state
,
362 if (maj_stat
!= GSS_S_COMPLETE
)
363 errx(1, "gss_wrap_iov failed");
366 iov
[0].buffer
.length
+
367 iov
[1].buffer
.length
+
368 iov
[2].buffer
.length
+
369 iov
[3].buffer
.length
+
370 iov
[4].buffer
.length
+
371 iov
[5].buffer
.length
;
372 token
.data
= emalloc(token
.length
);
375 memcpy(p
, iov
[0].buffer
.value
, iov
[0].buffer
.length
);
376 p
+= iov
[0].buffer
.length
;
377 memcpy(p
, iov
[1].buffer
.value
, iov
[1].buffer
.length
);
378 p
+= iov
[1].buffer
.length
;
379 memcpy(p
, iov
[2].buffer
.value
, iov
[2].buffer
.length
);
380 p
+= iov
[2].buffer
.length
;
381 memcpy(p
, iov
[3].buffer
.value
, iov
[3].buffer
.length
);
382 p
+= iov
[3].buffer
.length
;
383 memcpy(p
, iov
[4].buffer
.value
, iov
[4].buffer
.length
);
384 p
+= iov
[4].buffer
.length
;
385 memcpy(p
, iov
[5].buffer
.value
, iov
[5].buffer
.length
);
386 p
+= iov
[5].buffer
.length
;
388 assert(p
- ((unsigned char *)token
.data
) == token
.length
);
390 if ((flags
& (USE_SIGN_ONLY
|FORCE_IOV
)) == 0) {
391 gss_buffer_desc input
, output
;
393 input
.value
= token
.data
;
394 input
.length
= token
.length
;
396 maj_stat
= gss_unwrap(&min_stat
, sctx
, &input
,
397 &output
, &conf_state2
, &qop_state
);
399 if (maj_stat
!= GSS_S_COMPLETE
)
400 errx(1, "gss_unwrap from gss_wrap_iov failed: %s",
401 gssapi_err(maj_stat
, min_stat
, mechoid
));
403 gss_release_buffer(&min_stat
, &output
);
405 maj_stat
= gss_unwrap_iov(&min_stat
, sctx
, &conf_state2
, &qop_state
,
408 if (maj_stat
!= GSS_S_COMPLETE
)
409 errx(1, "gss_unwrap_iov failed: %x %s", flags
,
410 gssapi_err(maj_stat
, min_stat
, mechoid
));
413 if (conf_state2
!= conf_state
)
414 errx(1, "conf state wrong for iov: %x", flags
);
421 getverifymic(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, gss_OID mechoid
)
423 gss_buffer_desc input_token
, output_token
;
424 OM_uint32 min_stat
, maj_stat
;
427 input_token
.value
= "bar";
428 input_token
.length
= 3;
430 maj_stat
= gss_get_mic(&min_stat
, cctx
, 0, &input_token
,
432 if (maj_stat
!= GSS_S_COMPLETE
)
433 errx(1, "gss_get_mic failed: %s",
434 gssapi_err(maj_stat
, min_stat
, mechoid
));
436 maj_stat
= gss_verify_mic(&min_stat
, sctx
, &input_token
,
437 &output_token
, &qop_state
);
438 if (maj_stat
!= GSS_S_COMPLETE
)
439 errx(1, "gss_verify_mic failed: %s",
440 gssapi_err(maj_stat
, min_stat
, mechoid
));
442 gss_release_buffer(&min_stat
, &output_token
);
448 gss_ctx_id_t ctx
= GSS_C_NO_CONTEXT
;
449 gss_cred_id_t cred
= GSS_C_NO_CREDENTIAL
;
450 gss_name_t name
= GSS_C_NO_NAME
;
451 gss_OID_set oidset
= GSS_C_NO_OID_SET
;
454 gss_delete_sec_context(&junk
, &ctx
, NULL
);
455 gss_release_cred(&junk
, &cred
);
456 gss_release_name(&junk
, &name
);
457 gss_release_oid_set(&junk
, &oidset
);
464 static struct getargs args
[] = {
465 {"name-type",0, arg_string
, &type_string
, "type of name", NULL
},
466 {"mech-type",0, arg_string
, &mech_string
, "type of mech", NULL
},
467 {"ret-mech-type",0, arg_string
, &ret_mech_string
,
468 "type of return mech", NULL
},
469 {"dns-canonicalize",0,arg_negative_flag
, &dns_canon_flag
,
470 "use dns to canonicalize", NULL
},
471 {"mutual-auth",0, arg_flag
, &mutual_auth_flag
,"mutual auth", NULL
},
472 {"client-name", 0, arg_string
, &client_name
, "client name", NULL
},
473 {"client-password", 0, arg_string
, &client_password
, "client password", NULL
},
474 {"limit-enctype",0, arg_string
, &limit_enctype_string
, "enctype", NULL
},
475 {"dce-style",0, arg_flag
, &dce_style_flag
, "dce-style", NULL
},
476 {"wrapunwrap",0, arg_flag
, &wrapunwrap_flag
, "wrap/unwrap", NULL
},
477 {"iov", 0, arg_flag
, &iov_flag
, "wrap/unwrap iov", NULL
},
478 {"getverifymic",0, arg_flag
, &getverifymic_flag
,
479 "get and verify mic", NULL
},
480 {"delegate",0, arg_flag
, &deleg_flag
, "delegate credential", NULL
},
481 {"policy-delegate",0, arg_flag
, &policy_deleg_flag
, "policy delegate credential", NULL
},
482 {"server-no-delegate",0, arg_flag
, &server_no_deleg_flag
,
483 "server should get a credential", NULL
},
484 {"export-import-cred",0, arg_flag
, &ei_flag
, "test export/import cred", NULL
},
485 {"gsskrb5-acceptor-identity", 0, arg_string
, &gsskrb5_acceptor_identity
, "keytab", NULL
},
486 {"session-enctype", 0, arg_string
, &session_enctype_string
, "enctype", NULL
},
487 {"client-time-offset", 0, arg_integer
, &client_time_offset
, "time", NULL
},
488 {"server-time-offset", 0, arg_integer
, &server_time_offset
, "time", NULL
},
489 {"max-loops", 0, arg_integer
, &max_loops
, "time", NULL
},
490 {"version", 0, arg_flag
, &version_flag
, "print version", NULL
},
491 {"verbose", 'v', arg_flag
, &verbose_flag
, "verbose", NULL
},
492 {"help", 0, arg_flag
, &help_flag
, NULL
, NULL
}
498 arg_printusage (args
, sizeof(args
)/sizeof(*args
),
499 NULL
, "service@host");
504 main(int argc
, char **argv
)
507 OM_uint32 min_stat
, maj_stat
;
508 gss_ctx_id_t cctx
, sctx
;
510 gss_OID nameoid
, mechoid
, actual_mech
, actual_mech2
;
511 gss_cred_id_t client_cred
= GSS_C_NO_CREDENTIAL
, deleg_cred
= GSS_C_NO_CREDENTIAL
;
512 gss_name_t cname
= GSS_C_NO_NAME
;
513 gss_buffer_desc credential_data
= GSS_C_EMPTY_BUFFER
;
515 setprogname(argv
[0]);
519 if (krb5_init_context(&context
))
520 errx(1, "krb5_init_context");
522 cctx
= sctx
= GSS_C_NO_CONTEXT
;
524 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &optind
))
541 if (dns_canon_flag
!= -1)
542 gsskrb5_set_dns_canonicalize(dns_canon_flag
);
544 if (type_string
== NULL
)
545 nameoid
= GSS_C_NT_HOSTBASED_SERVICE
;
546 else if (strcmp(type_string
, "hostbased-service") == 0)
547 nameoid
= GSS_C_NT_HOSTBASED_SERVICE
;
548 else if (strcmp(type_string
, "krb5-principal-name") == 0)
549 nameoid
= GSS_KRB5_NT_PRINCIPAL_NAME
;
551 errx(1, "%s not suppported", type_string
);
553 if (mech_string
== NULL
)
554 mechoid
= GSS_KRB5_MECHANISM
;
556 mechoid
= string_to_oid(mech_string
);
558 if (gsskrb5_acceptor_identity
) {
559 maj_stat
= gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity
);
561 errx(1, "gsskrb5_acceptor_identity: %s",
562 gssapi_err(maj_stat
, 0, GSS_C_NO_OID
));
565 if (client_password
) {
566 credential_data
.value
= client_password
;
567 credential_data
.length
= strlen(client_password
);
573 cn
.value
= client_name
;
574 cn
.length
= strlen(client_name
);
576 maj_stat
= gss_import_name(&min_stat
, &cn
, GSS_C_NT_USER_NAME
, &cname
);
578 errx(1, "gss_import_name: %s",
579 gssapi_err(maj_stat
, min_stat
, GSS_C_NO_OID
));
582 if (client_password
) {
583 maj_stat
= gss_acquire_cred_with_password(&min_stat
,
592 if (GSS_ERROR(maj_stat
))
593 errx(1, "gss_acquire_cred_with_password: %s",
594 gssapi_err(maj_stat
, min_stat
, GSS_C_NO_OID
));
596 maj_stat
= gss_acquire_cred(&min_stat
,
604 if (GSS_ERROR(maj_stat
))
605 errx(1, "gss_acquire_cred: %s",
606 gssapi_err(maj_stat
, min_stat
, GSS_C_NO_OID
));
609 if (limit_enctype_string
) {
612 ret
= krb5_string_to_enctype(context
,
613 limit_enctype_string
,
616 krb5_err(context
, 1, ret
, "krb5_string_to_enctype");
621 if (client_cred
== NULL
)
622 errx(1, "client_cred missing");
624 maj_stat
= gss_krb5_set_allowable_enctypes(&min_stat
, client_cred
,
627 errx(1, "gss_krb5_set_allowable_enctypes: %s",
628 gssapi_err(maj_stat
, min_stat
, GSS_C_NO_OID
));
631 loop(mechoid
, nameoid
, argv
[0], client_cred
,
632 &sctx
, &cctx
, &actual_mech
, &deleg_cred
);
635 printf("resulting mech: %s\n", oid_to_string(actual_mech
));
637 if (ret_mech_string
) {
640 retoid
= string_to_oid(ret_mech_string
);
642 if (gss_oid_equal(retoid
, actual_mech
) == 0)
643 errx(1, "actual_mech mech is not the expected type %s",
647 /* XXX should be actual_mech */
648 if (gss_oid_equal(mechoid
, GSS_KRB5_MECHANISM
)) {
650 gss_buffer_desc authz_data
;
651 gss_buffer_desc in
, out1
, out2
;
652 krb5_keyblock
*keyblock
, *keyblock2
;
656 ret
= krb5_timeofday(context
, &now
);
658 errx(1, "krb5_timeofday failed");
661 maj_stat
= gss_krb5_export_lucid_sec_context(&min_stat
,
665 if (maj_stat
!= GSS_S_COMPLETE
)
666 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
667 gssapi_err(maj_stat
, min_stat
, actual_mech
));
670 maj_stat
= gss_krb5_free_lucid_sec_context(&maj_stat
, ctx
);
671 if (maj_stat
!= GSS_S_COMPLETE
)
672 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
673 gssapi_err(maj_stat
, min_stat
, actual_mech
));
676 maj_stat
= gss_krb5_export_lucid_sec_context(&min_stat
,
680 if (maj_stat
!= GSS_S_COMPLETE
)
681 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
682 gssapi_err(maj_stat
, min_stat
, actual_mech
));
683 maj_stat
= gss_krb5_free_lucid_sec_context(&min_stat
, ctx
);
684 if (maj_stat
!= GSS_S_COMPLETE
)
685 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
686 gssapi_err(maj_stat
, min_stat
, actual_mech
));
688 maj_stat
= gsskrb5_extract_authtime_from_sec_context(&min_stat
,
691 if (maj_stat
!= GSS_S_COMPLETE
)
692 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
693 gssapi_err(maj_stat
, min_stat
, actual_mech
));
696 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
697 "time authtime is before now: %ld %ld",
698 (long)time
, (long)now
);
700 maj_stat
= gsskrb5_extract_service_keyblock(&min_stat
,
703 if (maj_stat
!= GSS_S_COMPLETE
)
704 errx(1, "gsskrb5_export_service_keyblock failed: %s",
705 gssapi_err(maj_stat
, min_stat
, actual_mech
));
707 krb5_free_keyblock(context
, keyblock
);
709 maj_stat
= gsskrb5_get_subkey(&min_stat
,
712 if (maj_stat
!= GSS_S_COMPLETE
713 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
714 errx(1, "gsskrb5_get_subkey server failed: %s",
715 gssapi_err(maj_stat
, min_stat
, actual_mech
));
717 if (maj_stat
!= GSS_S_COMPLETE
)
719 else if (limit_enctype
&& keyblock
->keytype
!= limit_enctype
)
720 errx(1, "gsskrb5_get_subkey wrong enctype");
722 maj_stat
= gsskrb5_get_subkey(&min_stat
,
725 if (maj_stat
!= GSS_S_COMPLETE
726 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
727 errx(1, "gsskrb5_get_subkey client failed: %s",
728 gssapi_err(maj_stat
, min_stat
, actual_mech
));
730 if (maj_stat
!= GSS_S_COMPLETE
)
732 else if (limit_enctype
&& keyblock
->keytype
!= limit_enctype
)
733 errx(1, "gsskrb5_get_subkey wrong enctype");
735 if (keyblock
|| keyblock2
) {
736 if (keyblock
== NULL
)
737 errx(1, "server missing token keyblock");
738 if (keyblock2
== NULL
)
739 errx(1, "client missing token keyblock");
741 if (keyblock
->keytype
!= keyblock2
->keytype
)
742 errx(1, "enctype mismatch");
743 if (keyblock
->keyvalue
.length
!= keyblock2
->keyvalue
.length
)
744 errx(1, "key length mismatch");
745 if (memcmp(keyblock
->keyvalue
.data
, keyblock2
->keyvalue
.data
,
746 keyblock2
->keyvalue
.length
) != 0)
747 errx(1, "key data mismatch");
750 if (session_enctype_string
) {
751 krb5_enctype enctype
;
753 ret
= krb5_string_to_enctype(context
,
754 session_enctype_string
,
758 krb5_err(context
, 1, ret
, "krb5_string_to_enctype");
760 if (enctype
!= keyblock
->keytype
)
761 errx(1, "keytype is not the expected %d != %d",
762 (int)enctype
, (int)keyblock2
->keytype
);
766 krb5_free_keyblock(context
, keyblock
);
768 krb5_free_keyblock(context
, keyblock2
);
770 maj_stat
= gsskrb5_get_initiator_subkey(&min_stat
,
773 if (maj_stat
!= GSS_S_COMPLETE
774 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
775 errx(1, "gsskrb5_get_initiator_subkey failed: %s",
776 gssapi_err(maj_stat
, min_stat
, actual_mech
));
778 if (maj_stat
== GSS_S_COMPLETE
) {
780 if (limit_enctype
&& keyblock
->keytype
!= limit_enctype
)
781 errx(1, "gsskrb5_get_initiator_subkey wrong enctype");
782 krb5_free_keyblock(context
, keyblock
);
785 maj_stat
= gsskrb5_extract_authz_data_from_sec_context(&min_stat
,
789 if (maj_stat
== GSS_S_COMPLETE
)
790 gss_release_buffer(&min_stat
, &authz_data
);
793 memset(&out1
, 0, sizeof(out1
));
794 memset(&out2
, 0, sizeof(out2
));
799 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_FULL
, &in
,
801 gss_pseudo_random(&min_stat
, cctx
, GSS_C_PRF_KEY_FULL
, &in
,
804 if (out1
.length
!= out2
.length
)
805 errx(1, "prf len mismatch");
806 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
807 errx(1, "prf data mismatch");
809 gss_release_buffer(&min_stat
, &out1
);
811 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_FULL
, &in
,
814 if (out1
.length
!= out2
.length
)
815 errx(1, "prf len mismatch");
816 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
817 errx(1, "prf data mismatch");
819 gss_release_buffer(&min_stat
, &out1
);
820 gss_release_buffer(&min_stat
, &out2
);
825 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_PARTIAL
, &in
,
827 gss_pseudo_random(&min_stat
, cctx
, GSS_C_PRF_KEY_PARTIAL
, &in
,
830 if (out1
.length
!= out2
.length
)
831 errx(1, "prf len mismatch");
832 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
833 errx(1, "prf data mismatch");
835 gss_release_buffer(&min_stat
, &out1
);
836 gss_release_buffer(&min_stat
, &out2
);
839 getverifymic_flag
= 1;
842 if (wrapunwrap_flag
) {
843 wrapunwrap(cctx
, sctx
, 0, actual_mech
);
844 wrapunwrap(cctx
, sctx
, 1, actual_mech
);
845 wrapunwrap(sctx
, cctx
, 0, actual_mech
);
846 wrapunwrap(sctx
, cctx
, 1, actual_mech
);
850 wrapunwrap_iov(cctx
, sctx
, 0, actual_mech
);
851 wrapunwrap_iov(cctx
, sctx
, USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
852 wrapunwrap_iov(cctx
, sctx
, USE_HEADER_ONLY
, actual_mech
);
853 wrapunwrap_iov(cctx
, sctx
, USE_CONF
, actual_mech
);
854 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
, actual_mech
);
856 wrapunwrap_iov(cctx
, sctx
, FORCE_IOV
, actual_mech
);
857 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|FORCE_IOV
, actual_mech
);
858 wrapunwrap_iov(cctx
, sctx
, USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
859 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
861 wrapunwrap_iov(cctx
, sctx
, USE_SIGN_ONLY
|FORCE_IOV
, actual_mech
);
862 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_SIGN_ONLY
|FORCE_IOV
, actual_mech
);
863 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
|USE_SIGN_ONLY
|FORCE_IOV
, actual_mech
);
866 wrapunwrap_iov(cctx
, sctx
, 0, actual_mech
);
867 wrapunwrap_iov(cctx
, sctx
, FORCE_IOV
, actual_mech
);
869 wrapunwrap_iov(cctx
, sctx
, USE_CONF
, actual_mech
);
870 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|FORCE_IOV
, actual_mech
);
872 wrapunwrap_iov(cctx
, sctx
, USE_SIGN_ONLY
, actual_mech
);
873 wrapunwrap_iov(cctx
, sctx
, USE_SIGN_ONLY
|FORCE_IOV
, actual_mech
);
875 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_SIGN_ONLY
, actual_mech
);
876 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_SIGN_ONLY
|FORCE_IOV
, actual_mech
);
878 wrapunwrap_iov(cctx
, sctx
, USE_HEADER_ONLY
, actual_mech
);
879 wrapunwrap_iov(cctx
, sctx
, USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
881 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
, actual_mech
);
882 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
885 if (getverifymic_flag
) {
886 getverifymic(cctx
, sctx
, actual_mech
);
887 getverifymic(cctx
, sctx
, actual_mech
);
888 getverifymic(sctx
, cctx
, actual_mech
);
889 getverifymic(sctx
, cctx
, actual_mech
);
893 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
894 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
896 if (deleg_cred
!= GSS_C_NO_CREDENTIAL
) {
897 gss_cred_id_t cred2
= GSS_C_NO_CREDENTIAL
;
901 printf("checking actual mech (%s) on delegated cred\n",
902 oid_to_string(actual_mech
));
903 loop(actual_mech
, nameoid
, argv
[0], deleg_cred
, &sctx
, &cctx
, &actual_mech2
, &cred2
);
905 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
906 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
908 gss_release_cred(&min_stat
, &cred2
);
910 /* try again using SPNEGO */
912 printf("checking spnego on delegated cred\n");
913 loop(GSS_SPNEGO_MECHANISM
, nameoid
, argv
[0], deleg_cred
, &sctx
, &cctx
,
914 &actual_mech2
, &cred2
);
916 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
917 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
919 gss_release_cred(&min_stat
, &cred2
);
921 /* check export/import */
924 maj_stat
= gss_export_cred(&min_stat
, deleg_cred
, &cb
);
925 if (maj_stat
!= GSS_S_COMPLETE
)
926 errx(1, "export failed: %s",
927 gssapi_err(maj_stat
, min_stat
, NULL
));
929 maj_stat
= gss_import_cred(&min_stat
, &cb
, &cred2
);
930 if (maj_stat
!= GSS_S_COMPLETE
)
931 errx(1, "import failed: %s",
932 gssapi_err(maj_stat
, min_stat
, NULL
));
934 gss_release_buffer(&min_stat
, &cb
);
935 gss_release_cred(&min_stat
, &deleg_cred
);
938 printf("checking actual mech (%s) on export/imported cred\n",
939 oid_to_string(actual_mech
));
940 loop(actual_mech
, nameoid
, argv
[0], cred2
, &sctx
, &cctx
,
941 &actual_mech2
, &deleg_cred
);
943 gss_release_cred(&min_stat
, &deleg_cred
);
945 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
946 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
948 /* try again using SPNEGO */
950 printf("checking SPNEGO on export/imported cred\n");
951 loop(GSS_SPNEGO_MECHANISM
, nameoid
, argv
[0], cred2
, &sctx
, &cctx
,
952 &actual_mech2
, &deleg_cred
);
954 gss_release_cred(&min_stat
, &deleg_cred
);
956 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
957 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
959 gss_release_cred(&min_stat
, &cred2
);
962 gss_release_cred(&min_stat
, &deleg_cred
);
969 krb5_free_context(context
);