Пример #1
0
static int
add_mech_type(gss_OID mech_type,
	      int includeMSCompatOID,
	      MechTypeList *mechtypelist)
{
    MechType mech;
    int ret;

    if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM))
	return 0;

    if (includeMSCompatOID &&
	gss_oid_equal(mech_type, &_gss_spnego_krb5_mechanism_oid_desc)) {
	ret = der_get_oid(_gss_spnego_mskrb_mechanism_oid_desc.elements,
			  _gss_spnego_mskrb_mechanism_oid_desc.length,
			  &mech,
			  NULL);
	if (ret)
	    return ret;
	ret = add_MechTypeList(mechtypelist, &mech);
	free_MechType(&mech);
	if (ret)
	    return ret;
    }
    ret = der_get_oid(mech_type->elements, mech_type->length, &mech, NULL);
    if (ret)
	return ret;
    ret = add_MechTypeList(mechtypelist, &mech);
    free_MechType(&mech);
    return ret;
}
Пример #2
0
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
{
    int ret;
    size_t size;
    heim_oid o;
    char *p;

    _mg_buffer_zero(oid_str);

    if (oid == GSS_C_NULL_OID)
	return GSS_S_FAILURE;

    ret = der_get_oid (oid->elements, oid->length, &o, &size);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ret = der_print_heim_oid(&o, ' ', &p);
    der_free_oid(&o);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    oid_str->value = p;
    oid_str->length = strlen(p);

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #3
0
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_encapsulate_token(gss_const_buffer_t input_token,
		      gss_const_OID oid,
		      gss_buffer_t output_token)
{
    GSSAPIContextToken ct;
    int ret;
    size_t size;

    ret = der_get_oid (oid->elements, oid->length, &ct.thisMech, &size);
    if (ret) {
	_mg_buffer_zero(output_token);
	return GSS_S_FAILURE;
    }

    ct.innerContextToken.data = input_token->value;
    ct.innerContextToken.length = input_token->length;

    ASN1_MALLOC_ENCODE(GSSAPIContextToken,
		       output_token->value, output_token->length,
		       &ct, &size, ret);
    der_free_oid(&ct.thisMech);
    if (ret) {
	_mg_buffer_zero(output_token);
	return GSS_S_FAILURE;
    }
    if (output_token->length != size)
	abort();

    return GSS_S_COMPLETE;
}
Пример #4
0
static OM_uint32
send_accept (OM_uint32 *minor_status,
	     gss_buffer_t output_token,
	     gss_buffer_t mech_token)
{
    NegTokenTarg targ;
    OM_uint32 ret;
    unsigned char *value = NULL;
    size_t length = 0;

    memset(&targ, 0, sizeof(targ));
    targ.negResult = malloc(sizeof(*targ.negResult));
    if (targ.negResult == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }
    *(targ.negResult) = accept_completed;

    targ.supportedMech = malloc(sizeof(*targ.supportedMech));
    if (targ.supportedMech == NULL) {
	free_NegTokenTarg(&targ);
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    ret = der_get_oid(GSS_KRB5_MECH->elements,
		      GSS_KRB5_MECH->length,
		      targ.supportedMech,
		      NULL);
    if (ret) {
	free_NegTokenTarg(&targ);
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    if (mech_token != NULL && mech_token->length != 0) {
        targ.responseToken = malloc(sizeof(*targ.responseToken));
        if (targ.responseToken == NULL) {
            free_NegTokenTarg(&targ);
            *minor_status = ENOMEM;
            return GSS_S_FAILURE;
        }
        targ.responseToken->length = mech_token->length;
        targ.responseToken->data   = mech_token->value;
        mech_token->length = 0;
        mech_token->value  = NULL;
    } else {
        targ.responseToken = NULL;
    }

    ret = code_NegTokenArg (minor_status, &targ, &value, &length);
    output_token->value = value;
    output_token->length = length;
    free_NegTokenTarg(&targ);
    if (ret)
        return ret;

    return GSS_S_COMPLETE;
}
Пример #5
0
static int
oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
{
    int ret;
    heim_oid oid;
    heim_oid prefix;

    *suffix = 0;

    ret = der_get_oid(oid_enc->elements, oid_enc->length,
		      &oid, NULL);
    if (ret) {
	return 0;
    }

    ret = der_get_oid(prefix_enc->elements, prefix_enc->length,
		      &prefix, NULL);
    if (ret) {
	der_free_oid(&oid);
	return 0;
    }

    ret = 0;

    if (oid.length - 1 == prefix.length) {
	*suffix = oid.components[oid.length - 1];
	oid.length--;
	ret = (der_heim_oid_cmp(&oid, &prefix) == 0);
	oid.length++;
    }

    der_free_oid(&oid);
    der_free_oid(&prefix);

    return ret;
}
Пример #6
0
static int
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;

   ret = der_get_oid(mech->elements, mech->length,
	             &mech_list->val[mech_list->len], NULL);
   if (ret)
     return ret;

   mech_list->len++;
   return 0;
}
Пример #7
0
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_decapsulate_token(gss_const_buffer_t input_token,
		      gss_const_OID oid,
		      gss_buffer_t output_token)
{
    GSSAPIContextToken ct;
    heim_oid o;
    OM_uint32 status;
    int ret;
    size_t size;

    _mg_buffer_zero(output_token);

    ret = der_get_oid (oid->elements, oid->length, &o, &size);
    if (ret)
	return GSS_S_FAILURE;

    ret = decode_GSSAPIContextToken(input_token->value, input_token->length,
				    &ct, NULL);
    if (ret) {
	der_free_oid(&o);
	return GSS_S_FAILURE;
    }

    if (der_heim_oid_cmp(&ct.thisMech, &o) == 0) {
	status = GSS_S_COMPLETE;
	output_token->value = ct.innerContextToken.data;
	output_token->length = ct.innerContextToken.length;
	der_free_oid(&ct.thisMech);
    } else {
	free_GSSAPIContextToken(&ct);
 	status = GSS_S_FAILURE;
    }
    der_free_oid(&o);

    return status;
}
Пример #8
0
OM_uint32
gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
					    gss_ctx_id_t context_handle,
					    int ad_type,
					    gss_buffer_t ad_data)
{
    gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
    OM_uint32 maj_stat;
    gss_OID_desc oid_flat;
    heim_oid baseoid, oid;
    size_t size;

    if (context_handle == GSS_C_NO_CONTEXT) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    /* All this to append an integer to an oid... */

    if (der_get_oid(GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->elements,
		    GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->length,
		    &baseoid, NULL) != 0) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }
    
    oid.length = baseoid.length + 1;
    oid.components = calloc(oid.length, sizeof(*oid.components));
    if (oid.components == NULL) {
	der_free_oid(&baseoid);

	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    memcpy(oid.components, baseoid.components, 
	   baseoid.length * sizeof(*baseoid.components));
    
    der_free_oid(&baseoid);

    oid.components[oid.length - 1] = ad_type;

    oid_flat.length = der_length_oid(&oid);
    oid_flat.elements = malloc(oid_flat.length);
    if (oid_flat.elements == NULL) {
	free(oid.components);
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    if (der_put_oid((unsigned char *)oid_flat.elements + oid_flat.length - 1, 
		    oid_flat.length, &oid, &size) != 0) {
	free(oid.components);
	free(oid_flat.elements);
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }
    if (oid_flat.length != size)
	abort();

    free(oid.components);

    /* FINALLY, we have the OID */

    maj_stat = gss_inquire_sec_context_by_oid (minor_status,
					       context_handle,
					       &oid_flat,
					       &data_set);

    free(oid_flat.elements);

    if (maj_stat)
	return maj_stat;
    
    if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) {
	gss_release_buffer_set(minor_status, &data_set);
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    ad_data->value = malloc(data_set->elements[0].length);
    if (ad_data->value == NULL) {
	gss_release_buffer_set(minor_status, &data_set);
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    ad_data->length = data_set->elements[0].length;
    memcpy(ad_data->value, data_set->elements[0].value, ad_data->length);
    gss_release_buffer_set(minor_status, &data_set);
    
    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #9
0
static OM_uint32
send_accept (OM_uint32 *minor_status,
	     gssspnego_ctx context_handle,
	     gss_buffer_t mech_token,
	     int initial_response,
	     gss_buffer_t mech_buf,
	     gss_buffer_t output_token)
{
    NegotiationToken nt;
    OM_uint32 ret;
    gss_buffer_desc mech_mic_buf;
    size_t size;

    memset(&nt, 0, sizeof(nt));

    nt.element = choice_NegotiationToken_negTokenResp;

    ALLOC(nt.u.negTokenResp.negResult, 1);
    if (nt.u.negTokenResp.negResult == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    if (context_handle->open) {
	if (mech_token != GSS_C_NO_BUFFER
	    && mech_token->length != 0
	    && mech_buf != GSS_C_NO_BUFFER)
	    *(nt.u.negTokenResp.negResult)  = accept_incomplete;
	else
	    *(nt.u.negTokenResp.negResult)  = accept_completed;
    } else {
	if (initial_response && context_handle->require_mic)
	    *(nt.u.negTokenResp.negResult)  = request_mic;
	else
	    *(nt.u.negTokenResp.negResult)  = accept_incomplete;
    }

    if (initial_response) {
	ALLOC(nt.u.negTokenResp.supportedMech, 1);
	if (nt.u.negTokenResp.supportedMech == NULL) {
	    free_NegotiationToken(&nt);
	    *minor_status = ENOMEM;
	    return GSS_S_FAILURE;
	}

	ret = der_get_oid(context_handle->preferred_mech_type->elements,
			  context_handle->preferred_mech_type->length,
			  nt.u.negTokenResp.supportedMech,
			  NULL);
	if (ret) {
	    free_NegotiationToken(&nt);
	    *minor_status = ENOMEM;
	    return GSS_S_FAILURE;
	}
    } else {
	nt.u.negTokenResp.supportedMech = NULL;
    }

    if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) {
	ALLOC(nt.u.negTokenResp.responseToken, 1);
	if (nt.u.negTokenResp.responseToken == NULL) {
	    free_NegotiationToken(&nt);
	    *minor_status = ENOMEM;
	    return GSS_S_FAILURE;
	}
	nt.u.negTokenResp.responseToken->length = mech_token->length;
	nt.u.negTokenResp.responseToken->data   = mech_token->value;
	mech_token->length = 0;
	mech_token->value  = NULL;
    } else {
	nt.u.negTokenResp.responseToken = NULL;
    }

    if (mech_buf != GSS_C_NO_BUFFER) {
	ret = gss_get_mic(minor_status,
			  context_handle->negotiated_ctx_id,
			  0,
			  mech_buf,
			  &mech_mic_buf);
	if (ret == GSS_S_COMPLETE) {
	    ALLOC(nt.u.negTokenResp.mechListMIC, 1);
	    if (nt.u.negTokenResp.mechListMIC == NULL) {
		gss_release_buffer(minor_status, &mech_mic_buf);
		free_NegotiationToken(&nt);
		*minor_status = ENOMEM;
		return GSS_S_FAILURE;
	    }
	    nt.u.negTokenResp.mechListMIC->length = mech_mic_buf.length;
	    nt.u.negTokenResp.mechListMIC->data   = mech_mic_buf.value;
	} else if (ret == GSS_S_UNAVAILABLE) {
	    nt.u.negTokenResp.mechListMIC = NULL;
	} else {
	    free_NegotiationToken(&nt);
	    return ret;
	}

    } else
	nt.u.negTokenResp.mechListMIC = NULL;

    ASN1_MALLOC_ENCODE(NegotiationToken,
		       output_token->value, output_token->length,
		       &nt, &size, ret);
    if (ret) {
	free_NegotiationToken(&nt);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    /*
     * The response should not be encapsulated, because
     * it is a SubsequentContextToken (note though RFC 1964
     * specifies encapsulation for all _Kerberos_ tokens).
     */

    if (*(nt.u.negTokenResp.negResult) == accept_completed)
	ret = GSS_S_COMPLETE;
    else
	ret = GSS_S_CONTINUE_NEEDED;
    free_NegotiationToken(&nt);
    return ret;
}