/*
* SPNEGO wrapper for Kerberos5 GSS-API
* kouril@ics.muni.cz, 2003
+ * (mostly based on Heimdal code)
*/
-#include <stdlib.h>
-#include <errno.h>
-#include <gssapi.h>
-#include <spnego_asn1.h>
-
-#define ALLOC(X) (X) = calloc(1, sizeof(*(X)))
+#include "spnegokrb5_locl.h"
static int
-add_mech(MechTypeList *mech_list, oid *mech)
+add_mech(MechTypeList *mech_list, gss_OID mech)
{
MechType *tmp;
+ int ret;
tmp = realloc(mech_list->val, (mech_list->len + 1) * sizeof(*tmp));
if (tmp == NULL)
return ENOMEM;
mech_list->val = tmp;
- copy_MechType(mech, mech_list->val + mech_list->len);
+
+ ret = der_get_oid(mech->elements, mech->length,
+ &mech_list->val[mech_list->len], NULL);
+ if (ret)
+ return ret;
+
mech_list->len++;
return 0;
}
+#if 0
static int
set_context_flags(OM_uint32 req_flags, ContextFlags *flags)
{
flags->integFlag = 1;
return 0;
}
+#endif
-OM_uint32 gss_init_sec_context_spnego(
+OM_uint32 KRB5_LIB_FUNCTION gss_init_sec_context_spnego(
OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
size_t buf_size;
size_t len;
int ret;
- unsigned krb5_oid_array[] =
- {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02};
- oid krb5_oid;
memset(&token_init, 0, sizeof(token_init));
- krb5_oid.length = sizeof(krb5_oid_array);
- krb5_oid.components = krb5_oid_array;
-
ALLOC(token_init.mechTypes);
if (token_init.mechTypes == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
- ret = add_mech(token_init.mechTypes, &krb5_oid);
+ ret = add_mech(token_init.mechTypes, GSS_KRB5_MECH);
if (ret) {
*minor_status = ret;
ret = GSS_S_FAILURE;
goto end;
}
+#if 0
ALLOC(token_init.reqFlags);
if (token_init.reqFlags == NULL) {
*minor_status = ENOMEM;
goto end;
}
set_context_flags(req_flags, token_init.reqFlags);
+#endif
major_status = gss_init_sec_context(minor_status,
initiator_cred_handle,
context_handle,
target_name,
- (gss_OID) &krb5_oid,
+ GSS_KRB5_MECH,
req_flags,
time_req,
input_chan_bindings,
/* The MS implementation of SPNEGO seems to not like the mechListMIC field,
* so we omit it (it's optional anyway) */
- ASN1_MALLOC_ENCODE(NegTokenInit, buf, buf_size, &token_init, &len, ret);
- if (ret || buf_size != len) {
- *minor_status = EINVAL; /* XXX */
- ret = GSS_S_FAILURE;
- goto end;
- }
+ buf_size = 1024;
+ buf = malloc(buf_size);
+
+ do {
+ ret = encode_NegTokenInit(buf + buf_size -1,
+ buf_size,
+ &token_init, &len);
+ if (ret == 0) {
+ size_t tmp;
+
+ ret = der_put_length_and_tag(buf + buf_size - len - 1,
+ buf_size - len,
+ len,
+ KERB_CTXT,
+ CONS,
+ 0,
+ &tmp);
+ if (ret == 0)
+ len += tmp;
+ }
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ goto end;
+ }
+ buf = tmp;
+ } else {
+ *minor_status = ret;
+ ret = GSS_S_FAILURE;
+ goto end;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ ret = gssapi_spnego_encapsulate(minor_status,
+ buf + buf_size - len, len,
+ output_token, GSS_SPNEGO_MECH);
- output_token->value = buf;
- output_token->length = buf_size;
- buf = NULL;
ret = major_status;
end: