Ejemplo n.º 1
0
OM_uint32
gss_import_sec_context (
    OM_uint32 * minor_status,
    const gss_buffer_t interprocess_token,
    gss_ctx_id_t * context_handle
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_error_code kret;
    krb5_storage *sp;
    krb5_auth_context ac;
    krb5_address local, remote;
    krb5_address *localp, *remotep;
    krb5_data data;
    gss_buffer_desc buffer;
    krb5_keyblock keyblock;
    int32_t tmp;
    int32_t flags;
    OM_uint32 minor;
    int is_cfx = 0;

    GSSAPI_KRB5_INIT ();

    localp = remotep = NULL;

    sp = krb5_storage_from_mem (interprocess_token->value,
				interprocess_token->length);
    if (sp == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    *context_handle = malloc(sizeof(**context_handle));
    if (*context_handle == NULL) {
	*minor_status = ENOMEM;
	krb5_storage_free (sp);
	return GSS_S_FAILURE;
    }
    memset (*context_handle, 0, sizeof(**context_handle));
    HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);

    kret = krb5_auth_con_init (gssapi_krb5_context,
			       &(*context_handle)->auth_context);
    if (kret) {
	gssapi_krb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    /* flags */

    *minor_status = 0;

    if (krb5_ret_int32 (sp, &flags) != 0)
	goto failure;

    /* retrieve the auth context */

    ac = (*context_handle)->auth_context;
    krb5_ret_int32 (sp, &ac->flags);
    if (flags & SC_LOCAL_ADDRESS) {
	if (krb5_ret_address (sp, localp = &local) != 0)
	    goto failure;
    }

    if (flags & SC_REMOTE_ADDRESS) {
	if (krb5_ret_address (sp, remotep = &remote) != 0)
	    goto failure;
    }

    krb5_auth_con_setaddrs (gssapi_krb5_context, ac, localp, remotep);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    localp = remotep = NULL;

    if (krb5_ret_int16 (sp, &ac->local_port) != 0)
	goto failure;

    if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
	goto failure;
    if (flags & SC_KEYBLOCK) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_LOCAL_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setlocalsubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_REMOTE_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setremotesubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (krb5_ret_int32 (sp, &ac->local_seqnumber))
	goto failure;
    if (krb5_ret_int32 (sp, &ac->remote_seqnumber))
	goto failure;

    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->keytype = tmp;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->cksumtype = tmp;

    /* names */

    if (krb5_ret_data (sp, &data))
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->source);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->source);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    krb5_data_free (&data);

    if (krb5_ret_data (sp, &data) != 0)
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->target);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->target);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }    
    krb5_data_free (&data);

    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->more_flags = tmp;
    if (krb5_ret_int32 (sp, &tmp) == 0)
	(*context_handle)->lifetime = tmp;
    else
	(*context_handle)->lifetime = GSS_C_INDEFINITE;

    gsskrb5_is_cfx(*context_handle, &is_cfx);

    ret = _gssapi_msg_order_create(minor_status,
				   &(*context_handle)->order,
				   _gssapi_msg_order_f((*context_handle)->flags),
				   0, 0, is_cfx);
    if (ret)
	goto failure;

    krb5_storage_free (sp);
    return GSS_S_COMPLETE;

failure:
    krb5_auth_con_free (gssapi_krb5_context,
			(*context_handle)->auth_context);
    if ((*context_handle)->source != NULL)
	gss_release_name(&minor, &(*context_handle)->source);
    if ((*context_handle)->target != NULL)
	gss_release_name(&minor, &(*context_handle)->target);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    if((*context_handle)->order)
	_gssapi_msg_order_destroy(&(*context_handle)->order);
    HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
    krb5_storage_free (sp);
    free (*context_handle);
    *context_handle = GSS_C_NO_CONTEXT;
    return ret;
}
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_import_sec_context (
    OM_uint32 * minor_status,
    const gss_buffer_t interprocess_token,
    gss_ctx_id_t * context_handle
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_context context;
    krb5_error_code kret;
    krb5_storage *sp;
    krb5_auth_context ac;
    krb5_address local, remote;
    krb5_address *localp, *remotep;
    krb5_data data;
    gss_buffer_desc buffer;
    krb5_keyblock keyblock;
    int32_t flags, tmp;
    gsskrb5_ctx ctx;
    gss_name_t name;

    GSSAPI_KRB5_INIT (&context);

    *context_handle = GSS_C_NO_CONTEXT;

    localp = remotep = NULL;

    sp = krb5_storage_from_mem (interprocess_token->value,
				interprocess_token->length);
    if (sp == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    ctx = calloc(1, sizeof(*ctx));
    if (ctx == NULL) {
	*minor_status = ENOMEM;
	krb5_storage_free (sp);
	return GSS_S_FAILURE;
    }
    HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);

    kret = krb5_auth_con_init (context,
			       &ctx->auth_context);
    if (kret) {
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    /* flags */

    *minor_status = 0;

    if (krb5_ret_int32 (sp, &flags) != 0)
	goto failure;

    /* retrieve the auth context */

    ac = ctx->auth_context;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->flags = tmp;
    if (flags & SC_LOCAL_ADDRESS) {
	if (krb5_ret_address (sp, localp = &local) != 0)
	    goto failure;
    }

    if (flags & SC_REMOTE_ADDRESS) {
	if (krb5_ret_address (sp, remotep = &remote) != 0)
	    goto failure;
    }

    krb5_auth_con_setaddrs (context, ac, localp, remotep);
    if (localp)
	krb5_free_address (context, localp);
    if (remotep)
	krb5_free_address (context, remotep);
    localp = remotep = NULL;

    if (krb5_ret_int16 (sp, &ac->local_port) != 0)
	goto failure;

    if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
	goto failure;
    if (flags & SC_KEYBLOCK) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (flags & SC_LOCAL_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (flags & SC_REMOTE_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setremotesubkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
	goto failure;
    if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
	goto failure;

    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->keytype = tmp;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->cksumtype = tmp;

    /* names */

    if (krb5_ret_data (sp, &data))
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
				&name);
    if (ret) {
	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
				    &name);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    ctx->source = (krb5_principal)name;
    krb5_data_free (&data);

    if (krb5_ret_data (sp, &data) != 0)
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
				&name);
    if (ret) {
	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
				    &name);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    ctx->target = (krb5_principal)name;
    krb5_data_free (&data);

    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->more_flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->endtime = tmp;

    ret = _gssapi_msg_order_import(minor_status, sp, &ctx->gk5c.order);
    if (ret)
        goto failure;

    krb5_storage_free (sp);

    _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);

    *context_handle = (gss_ctx_id_t)ctx;

    return GSS_S_COMPLETE;

failure:
    krb5_auth_con_free (context,
			ctx->auth_context);
    if (ctx->source != NULL)
	krb5_free_principal(context, ctx->source);
    if (ctx->target != NULL)
	krb5_free_principal(context, ctx->target);
    if (localp)
	krb5_free_address (context, localp);
    if (remotep)
	krb5_free_address (context, remotep);
    if(ctx->gk5c.order)
	_gssapi_msg_order_destroy(&ctx->gk5c.order);
    HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
    krb5_storage_free (sp);
    free (ctx);
    *context_handle = GSS_C_NO_CONTEXT;
    return ret;
}
Ejemplo n.º 3
0
static OM_uint32
init_auth
(OM_uint32 * minor_status,
 gsskrb5_cred initiator_cred_handle,
 gsskrb5_ctx ctx,
 krb5_const_principal name,
 const gss_OID mech_type,
 OM_uint32 req_flags,
 OM_uint32 time_req,
 const gss_channel_bindings_t input_chan_bindings,
 const gss_buffer_t input_token,
 gss_OID * actual_mech_type,
 gss_buffer_t output_token,
 OM_uint32 * ret_flags,
 OM_uint32 * time_rec
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_error_code kret;
    krb5_flags ap_options;
    krb5_creds *cred = NULL;
    krb5_data outbuf;
    krb5_ccache ccache = NULL;
    uint32_t flags;
    krb5_data authenticator;
    Checksum cksum;
    krb5_enctype enctype;
    krb5_data fwd_data;
    OM_uint32 lifetime_rec;

    krb5_data_zero(&outbuf);
    krb5_data_zero(&fwd_data);

    *minor_status = 0;

    if (actual_mech_type)
	*actual_mech_type = GSS_KRB5_MECHANISM;

    if (initiator_cred_handle == NULL) {
	kret = krb5_cc_default (_gsskrb5_context, &ccache);
	if (kret) {
	    _gsskrb5_set_error_string ();
	    *minor_status = kret;
	    ret = GSS_S_FAILURE;
	    goto failure;
	}
    } else
	ccache = initiator_cred_handle->ccache;

    kret = krb5_cc_get_principal (_gsskrb5_context, ccache, &ctx->source);
    if (kret) {
	_gsskrb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    kret = krb5_copy_principal (_gsskrb5_context, name, &ctx->target);
    if (kret) {
	_gsskrb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    ret = _gss_DES3_get_mic_compat(minor_status, ctx);
    if (ret)
	goto failure;


    ret = gsskrb5_get_creds(minor_status,
			    ccache,
			    ctx,
			    ctx->target,
			    time_req,
			    time_rec,
			    &cred);
    if (ret)
	goto failure;

    ctx->lifetime = cred->times.endtime;

    ret = _gsskrb5_lifetime_left(minor_status,
			       ctx->lifetime,
			       &lifetime_rec);
    if (ret) {
	goto failure;
    }

    if (lifetime_rec == 0) {
	*minor_status = 0;
	ret = GSS_S_CONTEXT_EXPIRED;
	goto failure;
    }

    krb5_auth_con_setkey(_gsskrb5_context, 
			 ctx->auth_context, 
			 &cred->session);

    kret = krb5_auth_con_generatelocalsubkey(_gsskrb5_context, 
					     ctx->auth_context,
					     &cred->session);
    if(kret) {
	_gsskrb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }
    
    /* 
     * If the credential doesn't have ok-as-delegate, check what local
     * policy say about ok-as-delegate, default is FALSE that makes
     * code ignore the KDC setting and follow what the application
     * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the
     * KDC doesn't set ok-as-delegate.
     */
    if (!cred->flags.b.ok_as_delegate) {
	krb5_boolean delegate;
    
	krb5_appdefault_boolean(_gsskrb5_context,
				"gssapi", name->realm,
				"ok-as-delegate", FALSE, &delegate);
	if (delegate)
	    req_flags &= ~GSS_C_DELEG_FLAG;
    }

    flags = 0;
    ap_options = 0;
    if (req_flags & GSS_C_DELEG_FLAG)
	do_delegation (ctx->auth_context,
		       ccache, cred, name, &fwd_data, &flags);
    
    if (req_flags & GSS_C_MUTUAL_FLAG) {
	flags |= GSS_C_MUTUAL_FLAG;
	ap_options |= AP_OPTS_MUTUAL_REQUIRED;
    }
    
    if (req_flags & GSS_C_REPLAY_FLAG)
	flags |= GSS_C_REPLAY_FLAG;
    if (req_flags & GSS_C_SEQUENCE_FLAG)
	flags |= GSS_C_SEQUENCE_FLAG;
    if (req_flags & GSS_C_ANON_FLAG)
	;                               /* XXX */
    if (req_flags & GSS_C_DCE_STYLE) {
	/* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
	flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
	ap_options |= AP_OPTS_MUTUAL_REQUIRED;
    }
    if (req_flags & GSS_C_IDENTIFY_FLAG)
	flags |= GSS_C_IDENTIFY_FLAG;
    if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
	flags |= GSS_C_EXTENDED_ERROR_FLAG;

    flags |= GSS_C_CONF_FLAG;
    flags |= GSS_C_INTEG_FLAG;
    flags |= GSS_C_TRANS_FLAG;
    
    if (ret_flags)
	*ret_flags = flags;
    ctx->flags = flags;
    ctx->more_flags |= LOCAL;
    
    ret = _gsskrb5_create_8003_checksum (minor_status,
					 input_chan_bindings,
					 flags,
					 &fwd_data,
					 &cksum);
    krb5_data_free (&fwd_data);
    if (ret)
	goto failure;

    enctype = ctx->auth_context->keyblock->keytype;

    kret = krb5_build_authenticator (_gsskrb5_context,
				     ctx->auth_context,
				     enctype,
				     cred,
				     &cksum,
				     NULL,
				     &authenticator,
				     KRB5_KU_AP_REQ_AUTH);

    if (kret) {
	_gsskrb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    kret = krb5_build_ap_req (_gsskrb5_context,
			      enctype,
			      cred,
			      ap_options,
			      authenticator,
			      &outbuf);

    if (kret) {
	_gsskrb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,
				   (u_char *)"\x01\x00", GSS_KRB5_MECHANISM);
    if (ret)
	goto failure;

    krb5_data_free (&outbuf);
    krb5_free_creds(_gsskrb5_context, cred);
    free_Checksum(&cksum);
    if (initiator_cred_handle == NULL)
	krb5_cc_close(_gsskrb5_context, ccache);

    if (flags & GSS_C_MUTUAL_FLAG) {
	ctx->state = INITIATOR_WAIT_FOR_MUTAL;
	return GSS_S_CONTINUE_NEEDED;
    }

    return gsskrb5_initiator_ready(minor_status, ctx);
failure:
    if(cred)
	krb5_free_creds(_gsskrb5_context, cred);
    if (ccache && initiator_cred_handle == NULL)
	krb5_cc_close(_gsskrb5_context, ccache);

    return ret;

}
Ejemplo n.º 4
0
 krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context,
					krb5_auth_context auth_context,
					krb5_keyblock *keyblock)
{
	return krb5_auth_con_setkey(context, auth_context, keyblock);
}