2 * SPNEGO wrapper for Kerberos5 GSS-API
3 * kouril@ics.muni.cz, 2003
6 #include "spnegokrb5_locl.h"
8 #define ALLOC(X) (X) = calloc(1, sizeof(*(X)))
10 #define OID_cmp(o1, o2) \
11 (((o1)->length == (o2)->length) && \
12 (memcmp((o1)->components, (o2)->components,(int) (o1)->length) == 0))
15 create_reply(OM_uint32 major_status, gss_OID mech, gss_buffer_t mech_token,
16 gss_buffer_t output_token)
18 NegTokenTarg targ_token;
19 unsigned char *buf = NULL;
24 memset(&targ_token, 0, sizeof(targ_token));
26 ALLOC(targ_token.negResult);
27 if (targ_token.negResult == NULL)
30 *targ_token.negResult = (major_status == 0) ? accept_completed : accept_incomplete;
32 ALLOC(targ_token.supportedMech);
33 if (targ_token.supportedMech == NULL) {
37 copy_MechType((oid*)mech, targ_token.supportedMech);
39 if (mech_token->length > 0) {
40 ALLOC(targ_token.responseToken);
41 if (targ_token.responseToken == NULL) {
45 targ_token.responseToken->data = malloc(mech_token->length);
46 memcpy(targ_token.responseToken->data, mech_token->value, mech_token->length);
47 targ_token.responseToken->length = mech_token->length;
50 ASN1_MALLOC_ENCODE(NegTokenTarg, buf, buf_size, &targ_token, &len, ret);
51 if (ret || buf_size != len) {
56 output_token->value = buf;
57 output_token->length = buf_size;
62 free_NegTokenTarg(&targ_token);
67 OM_uint32 gss_accept_sec_context_spnego
68 (OM_uint32 * minor_status,
69 gss_ctx_id_t * context_handle,
70 const gss_cred_id_t acceptor_cred_handle,
71 const gss_buffer_t input_token_buffer,
72 const gss_channel_bindings_t input_chan_bindings,
73 gss_name_t * src_name,
75 gss_buffer_t output_token,
76 OM_uint32 * ret_flags,
78 gss_cred_id_t * delegated_cred_handle)
80 NegTokenInit init_token;
81 OM_uint32 major_status;
82 gss_buffer_desc krb5_output_token = GSS_C_EMPTY_BUFFER;
83 gss_buffer_desc krb5_input_token = GSS_C_EMPTY_BUFFER;
87 memset(&init_token, 0, sizeof(init_token));
89 ret = decode_NegTokenInit(input_token_buffer->value,
90 input_token_buffer->length,
93 *minor_status = EINVAL; /* XXX */
94 return GSS_S_DEFECTIVE_TOKEN;
97 if (init_token.mechTypes == NULL || init_token.mechTypes->len == 0 ||
98 OID_cmp(&init_token.mechTypes->val[0], (oid *)GSS_KRB5_MECH)) {
99 *minor_status = EINVAL;
100 ret = GSS_S_BAD_MECH;
104 if (init_token.mechToken) {
105 krb5_input_token.value = init_token.mechToken->data;
106 krb5_input_token.length = init_token.mechToken->length;
109 major_status = gss_accept_sec_context(minor_status,
111 acceptor_cred_handle,
119 delegated_cred_handle);
120 if (GSS_ERROR(major_status)) {
125 ret = create_reply(major_status, GSS_KRB5_MECH, &krb5_output_token, output_token);
133 free_NegTokenInit(&init_token);