Exemplo n.º 1
0
OM_uint32
gss_delete_sec_context(OM_uint32 *minor_status,
    gss_ctx_id_t *context_handle,
    gss_buffer_t output_token)
{
	OM_uint32 major_status;
	struct _gss_context *ctx = (struct _gss_context *) *context_handle;

	if (output_token)
		_gss_buffer_zero(output_token);

	*minor_status = 0;
	if (ctx) {
		/*
		 * If we have an implementation ctx, delete it,
		 * otherwise fake an empty token.
		 */
		if (ctx->gc_ctx) {
			major_status = ctx->gc_mech->gm_delete_sec_context(
				minor_status, &ctx->gc_ctx, output_token);
		}
		free(ctx);
		*context_handle = GSS_C_NO_CONTEXT;
	}

	return (GSS_S_COMPLETE);
}
Exemplo n.º 2
0
OM_uint32
gss_pseudo_random(OM_uint32 *minor_status,
		  gss_ctx_id_t context,
		  int prf_key,
		  const gss_buffer_t prf_in,
		  ssize_t desired_output_len,
		  gss_buffer_t prf_out)
{
    struct _gss_context *ctx = (struct _gss_context *) context;
    struct _gss_mech_switch *m = ctx->gc_mech;
    OM_uint32 major_status;

    _gss_buffer_zero(prf_out);
    *minor_status = 0;

    if (ctx == NULL) {
	*minor_status = 0;
	return GSS_S_NO_CONTEXT;
    }

    if (m->gm_pseudo_random == NULL)
	return GSS_S_UNAVAILABLE;
    
    major_status = (*m->gm_pseudo_random)(minor_status, ctx->gc_ctx,
					  prf_key, prf_in, desired_output_len,
					  prf_out);
    if (major_status != GSS_S_COMPLETE)
	    _gss_mg_error(m, major_status, *minor_status);

    return major_status;
}
Exemplo n.º 3
0
OM_uint32
gss_wrap(OM_uint32 *minor_status,
         const gss_ctx_id_t context_handle,
         int conf_req_flag,
         gss_qop_t qop_req,
         const gss_buffer_t input_message_buffer,
         int *conf_state,
         gss_buffer_t output_message_buffer)
{
    struct _gss_context *ctx = (struct _gss_context *) context_handle;
    struct _gss_mech_switch *m;

    if (conf_state)
        *conf_state = 0;
    _gss_buffer_zero(output_message_buffer);
    if (ctx == NULL) {
        *minor_status = 0;
        return (GSS_S_NO_CONTEXT);
    }
    m = ctx->gc_mech;

    return (m->gm_wrap(minor_status, ctx->gc_ctx,
                       conf_req_flag, qop_req, input_message_buffer,
                       conf_state, output_message_buffer));
}
OM_uint32
gss_export_sec_context(OM_uint32 *minor_status,
    gss_ctx_id_t *context_handle,
    gss_buffer_t interprocess_token)
{
	OM_uint32 major_status;
	struct _gss_context *ctx = (struct _gss_context *) *context_handle;
	struct _gss_mech_switch *m = ctx->gc_mech;
	gss_buffer_desc buf;

	_gss_buffer_zero(interprocess_token);

	major_status = m->gm_export_sec_context(minor_status,
	    &ctx->gc_ctx, &buf);
	
	if (major_status == GSS_S_COMPLETE) {
		unsigned char *p;

		free(ctx);
		*context_handle = GSS_C_NO_CONTEXT;
		interprocess_token->length = buf.length
			+ 2 + m->gm_mech_oid.length;
		interprocess_token->value = malloc(interprocess_token->length);
		if (!interprocess_token->value) {
			/*
			 * We are in trouble here - the context is
			 * already gone. This is allowed as long as we
			 * set the caller's context_handle to
			 * GSS_C_NO_CONTEXT, which we did above.
			 * Return GSS_S_FAILURE.
			 */
			_gss_buffer_zero(interprocess_token);
			*minor_status = ENOMEM;
			return (GSS_S_FAILURE);
		}
		p = interprocess_token->value;
		p[0] = m->gm_mech_oid.length >> 8;
		p[1] = m->gm_mech_oid.length;
		memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length);
		memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length);
		gss_release_buffer(minor_status, &buf);
	} else {
Exemplo n.º 5
0
OM_uint32
gss_release_buffer(OM_uint32 *minor_status,
		   gss_buffer_t buffer)
{

	*minor_status = 0;
	if (buffer->value)
		free(buffer->value);
	_gss_buffer_zero(buffer);

	return (GSS_S_COMPLETE);
}
Exemplo n.º 6
0
OM_uint32
gss_get_mic(OM_uint32 *minor_status,
    const gss_ctx_id_t context_handle,
    gss_qop_t qop_req,
    const gss_buffer_t message_buffer,
    gss_buffer_t message_token)
{
	struct _gss_context *ctx = (struct _gss_context *) context_handle;
	struct _gss_mech_switch *m;

	_gss_buffer_zero(message_token);
	if (ctx == NULL) {
		*minor_status = 0;
		return (GSS_S_NO_CONTEXT);
	}
	m = ctx->gc_mech;

	return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
		    message_buffer, message_token));
}
Exemplo n.º 7
0
OM_uint32
gss_export_name(OM_uint32 *minor_status,
    const gss_name_t input_name,
    gss_buffer_t exported_name)
{
	struct _gss_name *name = (struct _gss_name *) input_name;
	struct _gss_mechanism_name *mn;

	_gss_buffer_zero(exported_name);

	/*
	 * If this name already has any attached MNs, export the first
	 * one, otherwise export based on the first mechanism in our
	 * list.
	 */
	mn = SLIST_FIRST(&name->gn_mn);
	if (!mn) {
		*minor_status = 0;
		return (GSS_S_NAME_NOT_MN);
	}

	return mn->gmn_mech->gm_export_name(minor_status,
	    mn->gmn_name, exported_name);
}
OM_uint32
gss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid,
    gss_buffer_t output_token)
{
	unsigned char *p;
	size_t len, inside_len;
	size_t a, b;
	int i;

	_gss_buffer_zero(output_token);

	/*
	 * First time around, we calculate the size, second time, we
	 * encode the token.
	 */
	p = 0;
	for (i = 0; i < 2; i++) {
		len = 0;

		/*
		 * Token starts with [APPLICATION 0] SEQUENCE.
		 */
		if (p)
			*p++ = 0x60;
		len++;

		/*
		 * The length embedded in the token is the space
		 * needed for the encapsulated oid plus the length of
		 * the inner token.
		 */
		if (oid->length > 127)
			return (GSS_S_DEFECTIVE_TOKEN);

		inside_len = 2 + oid->length + input_token->length;

		/*
		 * Figure out how to encode the length
		 */
		if (inside_len < 128) {
			if (p)
				*p++ = inside_len;
			len++;
		} else {
			b = 1;
			if (inside_len >= 0x100)
				b++;
			if (inside_len >= 0x10000)
				b++;
			if (inside_len >= 0x1000000)
				b++;
			if (p)
				*p++ = b | 0x80;
			len++;
			a = inside_len << 8*(4 - b);
			while (b) {
				if (p)
					*p++ = (a >> 24);
				a <<= 8;
				len++;
				b--;
			}
		}

		/*
		 * Encode the OID for the mechanism. Simplify life by
		 * assuming that the OID length is less than 128 bytes.
		 */
		if (p)
			*p++ = 0x06;
		len++;
		if (p)
			*p++ = oid->length;
		len++;
		if (p) {
			memcpy(p, oid->elements, oid->length);
			p += oid->length;
		}
		len += oid->length;

		if (p) {
			memcpy(p, input_token->value, input_token->length);
			p += input_token->length;
		}
		len += input_token->length;

		if (i == 0) {
			output_token->length = len;
			output_token->value = malloc(len);
			if (!output_token->value)
				return (GSS_S_DEFECTIVE_TOKEN);
			p = output_token->value;
		}
	}

	return (GSS_S_COMPLETE);
}
OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
    gss_ctx_id_t *context_handle,
    const gss_cred_id_t acceptor_cred_handle,
    const gss_buffer_t input_token,
    const gss_channel_bindings_t input_chan_bindings,
    gss_name_t *src_name,
    gss_OID *mech_type,
    gss_buffer_t output_token,
    OM_uint32 *ret_flags,
    OM_uint32 *time_rec,
    gss_cred_id_t *delegated_cred_handle)
{
	OM_uint32 major_status, mech_ret_flags;
	struct _gss_mech_switch *m;
	struct _gss_context *ctx = (struct _gss_context *) *context_handle;
	struct _gss_cred *cred = (struct _gss_cred *) acceptor_cred_handle;
	struct _gss_mechanism_cred *mc;
	gss_cred_id_t acceptor_mc, delegated_mc;
	gss_name_t src_mn;

	*minor_status = 0;
	if (src_name)
		*src_name = GSS_C_NO_NAME;
	if (mech_type)
		*mech_type = GSS_C_NO_OID;
	if (ret_flags)
		*ret_flags = 0;
	if (time_rec)
		*time_rec = 0;
	if (delegated_cred_handle)
		*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
	_gss_buffer_zero(output_token);

	/*
	 * If this is the first call (*context_handle is NULL), we must
	 * parse the input token to figure out the mechanism to use.
	 */
	if (*context_handle == GSS_C_NO_CONTEXT) {
		gss_OID_desc mech_oid;

		major_status = choose_mech(input_token, &mech_oid);
		if (major_status != GSS_S_COMPLETE)
			return (major_status);

		/*
		 * Now that we have a mechanism, we can find the
		 * implementation.
		 */
		ctx = malloc(sizeof(struct _gss_context));
		if (!ctx) {
			*minor_status = ENOMEM;
			return (GSS_S_DEFECTIVE_TOKEN);
		}
		memset(ctx, 0, sizeof(struct _gss_context));
		m = ctx->gc_mech = _gss_find_mech_switch(&mech_oid);
		if (!m) {
			free(ctx);
			return (GSS_S_BAD_MECH);
		}
	} else
		m = ctx->gc_mech;

	if (cred) {
		SLIST_FOREACH(mc, &cred->gc_mc, gmc_link)
			if (mc->gmc_mech == m)
				break;
		if (!mc)
			return (GSS_S_BAD_MECH);
		acceptor_mc = mc->gmc_cred;
	} else {
Exemplo n.º 10
0
OM_uint32
gss_display_status(OM_uint32 *minor_status,
    OM_uint32 status_value,
    int status_type,
    const gss_OID mech_type,
    OM_uint32 *message_content,
    gss_buffer_t status_string)
{
	OM_uint32 major_status;

	_gss_buffer_zero(status_string);
	*message_content = 0;

	major_status = _gss_mg_get_error(mech_type, status_type,
					 status_value, status_string);
	if (major_status == GSS_S_COMPLETE) {

		*message_content = 0;
		*minor_status = 0;
		return (GSS_S_COMPLETE);
	}

	*minor_status = 0;
	switch (status_type) {
	case GSS_C_GSS_CODE: {
		char *buf;

		if (GSS_SUPPLEMENTARY_INFO(status_value))
		    asprintf(&buf, "%s", supplementary_error(
		        GSS_SUPPLEMENTARY_INFO(status_value)));
		else
		    asprintf (&buf, "%s %s",
		        calling_error(GSS_CALLING_ERROR(status_value)),
			routine_error(GSS_ROUTINE_ERROR(status_value)));

		if (buf == NULL)
			break;

		status_string->length = strlen(buf);
		status_string->value  = buf;

		return (GSS_S_COMPLETE);
	}
	case GSS_C_MECH_CODE: {
		OM_uint32 maj_junk, min_junk;
		gss_buffer_desc oid;
		char *buf;

		maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid);
		if (maj_junk != GSS_S_COMPLETE) {
			oid.value = strdup("unknown");
			oid.length = 7;
		}

		asprintf (&buf, "unknown mech-code %lu for mech %.*s",
			  (unsigned long)status_value,
			  (int)oid.length, (char *)oid.value);
		if (maj_junk == GSS_S_COMPLETE)
			gss_release_buffer(&min_junk, &oid);

		if (buf == NULL)
		    break;

		status_string->length = strlen(buf);
		status_string->value  = buf;

		return (GSS_S_COMPLETE);
	}
	}
	_gss_buffer_zero(status_string);
	return (GSS_S_BAD_STATUS);
}