2 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of KTH nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "krb5/gsskrb5_locl.h"
38 #include <gssapi_krb5.h>
39 #include <gssapi_spnego.h>
40 #include <gssapi_ntlm.h>
41 #include "test_common.h"
45 static char *type_string
;
46 static char *mech_string
;
47 static char *ret_mech_string
;
48 static int dns_canon_flag
= -1;
49 static int mutual_auth_flag
= 0;
50 static int dce_style_flag
= 0;
51 static int wrapunwrap_flag
= 0;
52 static int iov_flag
= 0;
53 static int getverifymic_flag
= 0;
54 static int deleg_flag
= 0;
55 static int policy_deleg_flag
= 0;
56 static int server_no_deleg_flag
= 0;
57 static char *gsskrb5_acceptor_identity
= NULL
;
58 static char *session_enctype_string
= NULL
;
59 static int client_time_offset
= 0;
60 static int server_time_offset
= 0;
61 static int max_loops
= 0;
62 static int version_flag
= 0;
63 static int verbose_flag
= 0;
64 static int help_flag
= 0;
70 { "krb5", &GSS_KRB5_MECHANISM
},
71 { "spnego", &GSS_SPNEGO_MECHANISM
},
72 { "ntlm", &GSS_NTLM_MECHANISM
},
73 { "sasl-digest-md5", &GSS_SASL_DIGEST_MD5_MECHANISM
}
77 string_to_oid(const char *name
)
80 for (i
= 0; i
< sizeof(o2n
)/sizeof(o2n
[0]); i
++)
81 if (strcasecmp(name
, o2n
[i
].name
) == 0)
83 errx(1, "name '%s' not unknown", name
);
87 oid_to_string(const gss_OID oid
)
90 for (i
= 0; i
< sizeof(o2n
)/sizeof(o2n
[0]); i
++)
91 if (gss_oid_equal(oid
, *o2n
[i
].oid
))
98 gss_OID nameoid
, const char *target
,
99 gss_cred_id_t init_cred
,
100 gss_ctx_id_t
*sctx
, gss_ctx_id_t
*cctx
,
101 gss_OID
*actual_mech
,
102 gss_cred_id_t
*deleg_cred
)
104 int server_done
= 0, client_done
= 0;
106 OM_uint32 maj_stat
, min_stat
;
107 gss_name_t gss_target_name
;
108 gss_buffer_desc input_token
, output_token
;
109 OM_uint32 flags
= 0, ret_cflags
, ret_sflags
;
110 gss_OID actual_mech_client
;
111 gss_OID actual_mech_server
;
113 *actual_mech
= GSS_C_NO_OID
;
115 flags
|= GSS_C_INTEG_FLAG
;
116 flags
|= GSS_C_CONF_FLAG
;
118 if (mutual_auth_flag
)
119 flags
|= GSS_C_MUTUAL_FLAG
;
121 flags
|= GSS_C_DCE_STYLE
;
123 flags
|= GSS_C_DELEG_FLAG
;
124 if (policy_deleg_flag
)
125 flags
|= GSS_C_DELEG_POLICY_FLAG
;
127 input_token
.value
= rk_UNCONST(target
);
128 input_token
.length
= strlen(target
);
130 maj_stat
= gss_import_name(&min_stat
,
134 if (GSS_ERROR(maj_stat
))
135 err(1, "import name creds failed with: %d", maj_stat
);
137 input_token
.length
= 0;
138 input_token
.value
= NULL
;
140 while (!server_done
|| !client_done
) {
143 gsskrb5_set_time_offset(client_time_offset
);
145 maj_stat
= gss_init_sec_context(&min_stat
,
158 if (GSS_ERROR(maj_stat
))
159 errx(1, "init_sec_context: %s",
160 gssapi_err(maj_stat
, min_stat
, mechoid
));
161 if (maj_stat
& GSS_S_CONTINUE_NEEDED
)
166 gsskrb5_get_time_offset(&client_time_offset
);
168 if (client_done
&& server_done
)
171 if (input_token
.length
!= 0)
172 gss_release_buffer(&min_stat
, &input_token
);
174 gsskrb5_set_time_offset(server_time_offset
);
176 maj_stat
= gss_accept_sec_context(&min_stat
,
180 GSS_C_NO_CHANNEL_BINDINGS
,
187 if (GSS_ERROR(maj_stat
))
188 errx(1, "accept_sec_context: %s",
189 gssapi_err(maj_stat
, min_stat
, actual_mech_server
));
191 gsskrb5_get_time_offset(&server_time_offset
);
193 if (output_token
.length
!= 0)
194 gss_release_buffer(&min_stat
, &output_token
);
196 if (maj_stat
& GSS_S_CONTINUE_NEEDED
)
201 if (output_token
.length
!= 0)
202 gss_release_buffer(&min_stat
, &output_token
);
203 if (input_token
.length
!= 0)
204 gss_release_buffer(&min_stat
, &input_token
);
205 gss_release_name(&min_stat
, &gss_target_name
);
207 if (deleg_flag
|| policy_deleg_flag
) {
208 if (server_no_deleg_flag
) {
209 if (*deleg_cred
!= GSS_C_NO_CREDENTIAL
)
210 errx(1, "got delegated cred but didn't expect one");
211 } else if (*deleg_cred
== GSS_C_NO_CREDENTIAL
)
212 errx(1, "asked for delegarated cred but did get one");
213 } else if (*deleg_cred
!= GSS_C_NO_CREDENTIAL
)
214 errx(1, "got deleg_cred cred but didn't ask");
216 if (gss_oid_equal(actual_mech_server
, actual_mech_client
) == 0)
217 errx(1, "mech mismatch");
218 *actual_mech
= actual_mech_server
;
220 if (max_loops
&& num_loops
> max_loops
)
221 errx(1, "num loops %d was lager then max loops %d",
222 num_loops
, max_loops
);
225 printf("server time offset: %d\n", server_time_offset
);
226 printf("client time offset: %d\n", client_time_offset
);
227 printf("num loops %d\n", num_loops
);
232 wrapunwrap(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, int flags
, gss_OID mechoid
)
234 gss_buffer_desc input_token
, output_token
, output_token2
;
235 OM_uint32 min_stat
, maj_stat
;
239 input_token
.value
= "foo";
240 input_token
.length
= 3;
242 maj_stat
= gss_wrap(&min_stat
, cctx
, flags
, 0, &input_token
,
243 &conf_state
, &output_token
);
244 if (maj_stat
!= GSS_S_COMPLETE
)
245 errx(1, "gss_wrap failed: %s",
246 gssapi_err(maj_stat
, min_stat
, mechoid
));
248 maj_stat
= gss_unwrap(&min_stat
, sctx
, &output_token
,
249 &output_token2
, &conf_state
, &qop_state
);
250 if (maj_stat
!= GSS_S_COMPLETE
)
251 errx(1, "gss_unwrap failed: %s",
252 gssapi_err(maj_stat
, min_stat
, mechoid
));
253 #if 0 /* doesn't work for NTLM yet */
254 if (!!conf_state
!= !!flags
)
255 errx(1, "conf_state mismatch");
260 #define USE_HEADER_ONLY 2
261 #define USE_SIGN_ONLY 4
265 wrapunwrap_iov(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, int flags
, gss_OID mechoid
)
267 krb5_data token
, header
, trailer
;
268 OM_uint32 min_stat
, maj_stat
;
270 int conf_state
, conf_state2
;
271 gss_iov_buffer_desc iov
[5];
274 char header_data
[9] = "ABCheader";
275 char trailer_data
[10] = "trailerXYZ";
277 char token_data
[16] = "0123456789abcdef";
279 memset(&iov
, 0, sizeof(iov
));
281 if (flags
& USE_SIGN_ONLY
) {
282 header
.data
= header_data
;
284 trailer
.data
= trailer_data
;
293 token
.data
= token_data
;
296 iov_len
= sizeof(iov
)/sizeof(iov
[0]);
298 memset(iov
, 0, sizeof(iov
));
300 if (flags
& USE_HEADER_ONLY
)
301 iov_len
-= 1; /* skip trailer */
303 iov
[0].type
= GSS_IOV_BUFFER_TYPE_HEADER
| GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
;
305 if (header
.length
!= 0) {
306 iov
[1].type
= GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
307 iov
[1].buffer
.length
= header
.length
;
308 iov
[1].buffer
.value
= header
.data
;
310 iov
[1].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
311 iov
[1].buffer
.length
= 0;
312 iov
[1].buffer
.value
= NULL
;
314 iov
[2].type
= GSS_IOV_BUFFER_TYPE_DATA
;
315 iov
[2].buffer
.length
= token
.length
;
316 iov
[2].buffer
.value
= token
.data
;
317 if (trailer
.length
!= 0) {
318 iov
[3].type
= GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
319 iov
[3].buffer
.length
= trailer
.length
;
320 iov
[3].buffer
.value
= trailer
.data
;
322 iov
[3].type
= GSS_IOV_BUFFER_TYPE_EMPTY
;
323 iov
[3].buffer
.length
= 0;
324 iov
[3].buffer
.value
= NULL
;
326 iov
[4].type
= GSS_IOV_BUFFER_TYPE_TRAILER
| GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
;
327 iov
[4].buffer
.length
= 0;
328 iov
[4].buffer
.value
= 0;
330 maj_stat
= gss_wrap_iov(&min_stat
, cctx
, flags
& USE_CONF
, 0, &conf_state
,
332 if (maj_stat
!= GSS_S_COMPLETE
)
333 errx(1, "gss_wrap_iov failed");
336 iov
[0].buffer
.length
+
337 iov
[1].buffer
.length
+
338 iov
[2].buffer
.length
+
339 iov
[3].buffer
.length
+
340 iov
[4].buffer
.length
;
341 token
.data
= emalloc(token
.length
);
344 memcpy(p
, iov
[0].buffer
.value
, iov
[0].buffer
.length
);
345 p
+= iov
[0].buffer
.length
;
346 memcpy(p
, iov
[1].buffer
.value
, iov
[1].buffer
.length
);
347 p
+= iov
[1].buffer
.length
;
348 memcpy(p
, iov
[2].buffer
.value
, iov
[2].buffer
.length
);
349 p
+= iov
[2].buffer
.length
;
350 memcpy(p
, iov
[3].buffer
.value
, iov
[3].buffer
.length
);
351 p
+= iov
[3].buffer
.length
;
352 memcpy(p
, iov
[4].buffer
.value
, iov
[4].buffer
.length
);
353 p
+= iov
[4].buffer
.length
;
355 assert(p
- ((unsigned char *)token
.data
) == token
.length
);
357 if ((flags
& (USE_SIGN_ONLY
|FORCE_IOV
)) == 0) {
358 gss_buffer_desc input
, output
;
360 input
.value
= token
.data
;
361 input
.length
= token
.length
;
363 maj_stat
= gss_unwrap(&min_stat
, sctx
, &input
,
364 &output
, &conf_state2
, &qop_state
);
366 if (maj_stat
!= GSS_S_COMPLETE
)
367 errx(1, "gss_unwrap failed: %s",
368 gssapi_err(maj_stat
, min_stat
, mechoid
));
370 gss_release_buffer(&min_stat
, &output
);
372 maj_stat
= gss_unwrap_iov(&min_stat
, sctx
, &conf_state2
, &qop_state
,
375 if (maj_stat
!= GSS_S_COMPLETE
)
376 errx(1, "gss_unwrap_iov failed: %x %s", flags
,
377 gssapi_err(maj_stat
, min_stat
, mechoid
));
380 if (conf_state2
!= conf_state
)
381 errx(1, "conf state wrong for iov: %x", flags
);
388 getverifymic(gss_ctx_id_t cctx
, gss_ctx_id_t sctx
, gss_OID mechoid
)
390 gss_buffer_desc input_token
, output_token
;
391 OM_uint32 min_stat
, maj_stat
;
394 input_token
.value
= "bar";
395 input_token
.length
= 3;
397 maj_stat
= gss_get_mic(&min_stat
, cctx
, 0, &input_token
,
399 if (maj_stat
!= GSS_S_COMPLETE
)
400 errx(1, "gss_get_mic failed: %s",
401 gssapi_err(maj_stat
, min_stat
, mechoid
));
403 maj_stat
= gss_verify_mic(&min_stat
, sctx
, &input_token
,
404 &output_token
, &qop_state
);
405 if (maj_stat
!= GSS_S_COMPLETE
)
406 errx(1, "gss_verify_mic failed: %s",
407 gssapi_err(maj_stat
, min_stat
, mechoid
));
413 gss_ctx_id_t ctx
= GSS_C_NO_CONTEXT
;
414 gss_cred_id_t cred
= GSS_C_NO_CREDENTIAL
;
415 gss_name_t name
= GSS_C_NO_NAME
;
416 gss_OID_set oidset
= GSS_C_NO_OID_SET
;
419 gss_delete_sec_context(&junk
, &ctx
, NULL
);
420 gss_release_cred(&junk
, &cred
);
421 gss_release_name(&junk
, &name
);
422 gss_release_oid_set(&junk
, &oidset
);
429 static struct getargs args
[] = {
430 {"name-type",0, arg_string
, &type_string
, "type of name", NULL
},
431 {"mech-type",0, arg_string
, &mech_string
, "type of mech", NULL
},
432 {"ret-mech-type",0, arg_string
, &ret_mech_string
,
433 "type of return mech", NULL
},
434 {"dns-canonicalize",0,arg_negative_flag
, &dns_canon_flag
,
435 "use dns to canonicalize", NULL
},
436 {"mutual-auth",0, arg_flag
, &mutual_auth_flag
,"mutual auth", NULL
},
437 {"dce-style",0, arg_flag
, &dce_style_flag
, "dce-style", NULL
},
438 {"wrapunwrap",0, arg_flag
, &wrapunwrap_flag
, "wrap/unwrap", NULL
},
439 {"iov", 0, arg_flag
, &iov_flag
, "wrap/unwrap iov", NULL
},
440 {"getverifymic",0, arg_flag
, &getverifymic_flag
,
441 "get and verify mic", NULL
},
442 {"delegate",0, arg_flag
, &deleg_flag
, "delegate credential", NULL
},
443 {"policy-delegate",0, arg_flag
, &policy_deleg_flag
, "policy delegate credential", NULL
},
444 {"server-no-delegate",0, arg_flag
, &server_no_deleg_flag
,
445 "server should get a credential", NULL
},
446 {"gsskrb5-acceptor-identity", 0, arg_string
, &gsskrb5_acceptor_identity
, "keytab", NULL
},
447 {"session-enctype", 0, arg_string
, &session_enctype_string
, "enctype", NULL
},
448 {"client-time-offset", 0, arg_integer
, &client_time_offset
, "time", NULL
},
449 {"server-time-offset", 0, arg_integer
, &server_time_offset
, "time", NULL
},
450 {"max-loops", 0, arg_integer
, &max_loops
, "time", NULL
},
451 {"version", 0, arg_flag
, &version_flag
, "print version", NULL
},
452 {"verbose", 'v', arg_flag
, &verbose_flag
, "verbose", NULL
},
453 {"help", 0, arg_flag
, &help_flag
, NULL
, NULL
}
459 arg_printusage (args
, sizeof(args
)/sizeof(*args
),
460 NULL
, "service@host");
465 main(int argc
, char **argv
)
468 OM_uint32 min_stat
, maj_stat
;
469 gss_ctx_id_t cctx
, sctx
;
471 gss_OID nameoid
, mechoid
, actual_mech
;
472 gss_cred_id_t deleg_cred
= GSS_C_NO_CREDENTIAL
;
474 setprogname(argv
[0]);
476 cctx
= sctx
= GSS_C_NO_CONTEXT
;
478 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &optind
))
495 if (dns_canon_flag
!= -1)
496 gsskrb5_set_dns_canonicalize(dns_canon_flag
);
498 if (type_string
== NULL
)
499 nameoid
= GSS_C_NT_HOSTBASED_SERVICE
;
500 else if (strcmp(type_string
, "hostbased-service") == 0)
501 nameoid
= GSS_C_NT_HOSTBASED_SERVICE
;
502 else if (strcmp(type_string
, "krb5-principal-name") == 0)
503 nameoid
= GSS_KRB5_NT_PRINCIPAL_NAME
;
505 errx(1, "%s not suppported", type_string
);
507 if (mech_string
== NULL
)
508 mechoid
= GSS_KRB5_MECHANISM
;
510 mechoid
= string_to_oid(mech_string
);
512 if (gsskrb5_acceptor_identity
)
513 gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity
);
515 loop(mechoid
, nameoid
, argv
[0], GSS_C_NO_CREDENTIAL
,
516 &sctx
, &cctx
, &actual_mech
, &deleg_cred
);
519 printf("resulting mech: %s\n", oid_to_string(actual_mech
));
521 if (ret_mech_string
) {
524 retoid
= string_to_oid(ret_mech_string
);
526 if (gss_oid_equal(retoid
, actual_mech
) == 0)
527 errx(1, "actual_mech mech is not the expected type %s",
531 /* XXX should be actual_mech */
532 if (gss_oid_equal(mechoid
, GSS_KRB5_MECHANISM
)) {
533 krb5_context context
;
535 gss_buffer_desc authz_data
;
536 gss_buffer_desc in
, out1
, out2
;
537 krb5_keyblock
*keyblock
, *keyblock2
;
541 ret
= krb5_init_context(&context
);
543 errx(1, "krb5_init_context");
545 ret
= krb5_timeofday(context
, &now
);
547 errx(1, "krb5_timeofday failed");
550 maj_stat
= gss_krb5_export_lucid_sec_context(&min_stat
,
554 if (maj_stat
!= GSS_S_COMPLETE
)
555 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
556 gssapi_err(maj_stat
, min_stat
, actual_mech
));
559 maj_stat
= gss_krb5_free_lucid_sec_context(&maj_stat
, ctx
);
560 if (maj_stat
!= GSS_S_COMPLETE
)
561 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
562 gssapi_err(maj_stat
, min_stat
, actual_mech
));
565 maj_stat
= gss_krb5_export_lucid_sec_context(&min_stat
,
569 if (maj_stat
!= GSS_S_COMPLETE
)
570 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
571 gssapi_err(maj_stat
, min_stat
, actual_mech
));
572 maj_stat
= gss_krb5_free_lucid_sec_context(&min_stat
, ctx
);
573 if (maj_stat
!= GSS_S_COMPLETE
)
574 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
575 gssapi_err(maj_stat
, min_stat
, actual_mech
));
577 maj_stat
= gsskrb5_extract_authtime_from_sec_context(&min_stat
,
580 if (maj_stat
!= GSS_S_COMPLETE
)
581 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
582 gssapi_err(maj_stat
, min_stat
, actual_mech
));
585 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
586 "time authtime is before now: %ld %ld",
587 (long)time
, (long)now
);
589 maj_stat
= gsskrb5_extract_service_keyblock(&min_stat
,
592 if (maj_stat
!= GSS_S_COMPLETE
)
593 errx(1, "gsskrb5_export_service_keyblock failed: %s",
594 gssapi_err(maj_stat
, min_stat
, actual_mech
));
596 krb5_free_keyblock(context
, keyblock
);
598 maj_stat
= gsskrb5_get_subkey(&min_stat
,
601 if (maj_stat
!= GSS_S_COMPLETE
602 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
603 errx(1, "gsskrb5_get_subkey server failed: %s",
604 gssapi_err(maj_stat
, min_stat
, actual_mech
));
606 if (maj_stat
!= GSS_S_COMPLETE
)
609 maj_stat
= gsskrb5_get_subkey(&min_stat
,
612 if (maj_stat
!= GSS_S_COMPLETE
613 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
614 errx(1, "gsskrb5_get_subkey client failed: %s",
615 gssapi_err(maj_stat
, min_stat
, actual_mech
));
617 if (maj_stat
!= GSS_S_COMPLETE
)
620 if (keyblock
|| keyblock2
) {
621 if (keyblock
== NULL
)
622 errx(1, "server missing token keyblock");
623 if (keyblock2
== NULL
)
624 errx(1, "client missing token keyblock");
626 if (keyblock
->keytype
!= keyblock2
->keytype
)
627 errx(1, "enctype mismatch");
628 if (keyblock
->keyvalue
.length
!= keyblock2
->keyvalue
.length
)
629 errx(1, "key length mismatch");
630 if (memcmp(keyblock
->keyvalue
.data
, keyblock2
->keyvalue
.data
,
631 keyblock2
->keyvalue
.length
) != 0)
632 errx(1, "key data mismatch");
635 if (session_enctype_string
) {
636 krb5_enctype enctype
;
638 ret
= krb5_string_to_enctype(context
,
639 session_enctype_string
,
643 krb5_err(context
, 1, ret
, "krb5_string_to_enctype");
645 if (enctype
!= keyblock
->keytype
)
646 errx(1, "keytype is not the expected %d != %d",
647 (int)enctype
, (int)keyblock2
->keytype
);
651 krb5_free_keyblock(context
, keyblock
);
653 krb5_free_keyblock(context
, keyblock2
);
655 maj_stat
= gsskrb5_get_initiator_subkey(&min_stat
,
658 if (maj_stat
!= GSS_S_COMPLETE
659 && (!(maj_stat
== GSS_S_FAILURE
&& min_stat
== GSS_KRB5_S_KG_NO_SUBKEY
)))
660 errx(1, "gsskrb5_get_initiator_subkey failed: %s",
661 gssapi_err(maj_stat
, min_stat
, actual_mech
));
663 if (maj_stat
== GSS_S_COMPLETE
)
664 krb5_free_keyblock(context
, keyblock
);
666 maj_stat
= gsskrb5_extract_authz_data_from_sec_context(&min_stat
,
670 if (maj_stat
== GSS_S_COMPLETE
)
671 gss_release_buffer(&min_stat
, &authz_data
);
673 krb5_free_context(context
);
676 memset(&out1
, 0, sizeof(out1
));
677 memset(&out2
, 0, sizeof(out2
));
682 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_FULL
, &in
,
684 gss_pseudo_random(&min_stat
, cctx
, GSS_C_PRF_KEY_FULL
, &in
,
687 if (out1
.length
!= out2
.length
)
688 errx(1, "prf len mismatch");
689 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
690 errx(1, "prf data mismatch");
692 gss_release_buffer(&min_stat
, &out1
);
694 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_FULL
, &in
,
697 if (out1
.length
!= out2
.length
)
698 errx(1, "prf len mismatch");
699 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
700 errx(1, "prf data mismatch");
702 gss_release_buffer(&min_stat
, &out1
);
703 gss_release_buffer(&min_stat
, &out2
);
708 gss_pseudo_random(&min_stat
, sctx
, GSS_C_PRF_KEY_PARTIAL
, &in
,
710 gss_pseudo_random(&min_stat
, cctx
, GSS_C_PRF_KEY_PARTIAL
, &in
,
713 if (out1
.length
!= out2
.length
)
714 errx(1, "prf len mismatch");
715 if (memcmp(out1
.value
, out2
.value
, out1
.length
) != 0)
716 errx(1, "prf data mismatch");
718 gss_release_buffer(&min_stat
, &out1
);
719 gss_release_buffer(&min_stat
, &out2
);
722 getverifymic_flag
= 1;
725 if (wrapunwrap_flag
) {
726 wrapunwrap(cctx
, sctx
, 0, actual_mech
);
727 wrapunwrap(cctx
, sctx
, 1, actual_mech
);
728 wrapunwrap(sctx
, cctx
, 0, actual_mech
);
729 wrapunwrap(sctx
, cctx
, 1, actual_mech
);
733 wrapunwrap_iov(cctx
, sctx
, 0, actual_mech
);
734 wrapunwrap_iov(cctx
, sctx
, USE_CONF
, actual_mech
);
735 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
, actual_mech
);
737 wrapunwrap_iov(cctx
, sctx
, FORCE_IOV
, actual_mech
);
738 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|FORCE_IOV
, actual_mech
);
739 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
|FORCE_IOV
, actual_mech
);
741 wrapunwrap_iov(cctx
, sctx
, USE_CONF
|USE_HEADER_ONLY
|USE_SIGN_ONLY
, actual_mech
);
744 if (getverifymic_flag
) {
745 getverifymic(cctx
, sctx
, actual_mech
);
746 getverifymic(cctx
, sctx
, actual_mech
);
747 getverifymic(sctx
, cctx
, actual_mech
);
748 getverifymic(sctx
, cctx
, actual_mech
);
752 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
753 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);
755 if (deleg_cred
!= GSS_C_NO_CREDENTIAL
) {
756 gss_cred_id_t deleg_cred2
= GSS_C_NO_CREDENTIAL
;
758 loop(mechoid
, nameoid
, argv
[0], deleg_cred
, &cctx
, &sctx
, &actual_mech
, &deleg_cred2
);
760 gss_release_cred(&min_stat
, &deleg_cred2
);
762 gss_delete_sec_context(&min_stat
, &cctx
, NULL
);
763 gss_delete_sec_context(&min_stat
, &sctx
, NULL
);