gss_krb5.c

来自「samba最新软件」· C语言 代码 · 共 866 行 · 第 1/2 页

C
866
字号
    OM_uint32 maj_status;    gss_buffer_desc buffer;    krb5_storage *sp;    krb5_data data;    int i;    sp = krb5_storage_emem();    if (sp == NULL) {	*minor_status = ENOMEM;	maj_status = GSS_S_FAILURE;	goto out;    }    for (i = 0; i < num_enctypes; i++) {	ret = krb5_store_int32(sp, enctypes[i]);	if (ret) {	    *minor_status = ret;	    maj_status = GSS_S_FAILURE;	    goto out;	}    }    ret = krb5_storage_to_data(sp, &data);    if (ret) {	*minor_status = ret;	maj_status = GSS_S_FAILURE;	goto out;    }    buffer.value = data.data;    buffer.length = data.length;    maj_status = gss_set_cred_option(minor_status,				     &cred,				     GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X,				     &buffer);    krb5_data_free(&data);out:    if (sp)	krb5_storage_free(sp);    return maj_status;}/* * */OM_uint32gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c){    struct _gss_mech_switch *m;    gss_buffer_desc buffer;    OM_uint32 junk;    _gss_load_mech();    if (c) {	buffer.value = c;	buffer.length = sizeof(*c);    } else {	buffer.value = NULL;	buffer.length = 0;    }    SLIST_FOREACH(m, &_gss_mechs, gm_link) {	if (m->gm_mech.gm_set_sec_context_option == NULL)	    continue;	m->gm_mech.gm_set_sec_context_option(&junk, NULL,	    GSS_KRB5_SEND_TO_KDC_X, &buffer);    }    return (GSS_S_COMPLETE);}/* * */OM_uint32gss_krb5_ccache_name(OM_uint32 *minor_status, 		     const char *name,		     const char **out_name){    struct _gss_mech_switch *m;    gss_buffer_desc buffer;    OM_uint32 junk;    _gss_load_mech();    if (out_name)	*out_name = NULL;    buffer.value = rk_UNCONST(name);    buffer.length = strlen(name);    SLIST_FOREACH(m, &_gss_mechs, gm_link) {	if (m->gm_mech.gm_set_sec_context_option == NULL)	    continue;	m->gm_mech.gm_set_sec_context_option(&junk, NULL,	    GSS_KRB5_CCACHE_NAME_X, &buffer);    }    return (GSS_S_COMPLETE);}/* * */OM_uint32gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,					  gss_ctx_id_t context_handle,					  time_t *authtime){    gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;    OM_uint32 maj_stat;    if (context_handle == GSS_C_NO_CONTEXT) {	*minor_status = EINVAL;	return GSS_S_FAILURE;    }        maj_stat =	gss_inquire_sec_context_by_oid (minor_status,					context_handle,					GSS_KRB5_GET_AUTHTIME_X,					&data_set);    if (maj_stat)	return maj_stat;        if (data_set == GSS_C_NO_BUFFER_SET) {	gss_release_buffer_set(minor_status, &data_set);	*minor_status = EINVAL;	return GSS_S_FAILURE;    }    if (data_set->count != 1) {	gss_release_buffer_set(minor_status, &data_set);	*minor_status = EINVAL;	return GSS_S_FAILURE;    }    if (data_set->elements[0].length != 4) {	gss_release_buffer_set(minor_status, &data_set);	*minor_status = EINVAL;	return GSS_S_FAILURE;    }    {	unsigned char *buf = data_set->elements[0].value;	*authtime = (buf[3] <<24) | (buf[2] << 16) | 	    (buf[1] << 8) | (buf[0] << 0);    }    gss_release_buffer_set(minor_status, &data_set);    *minor_status = 0;    return GSS_S_COMPLETE;}/* * */OM_uint32gsskrb5_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;}/* * */static OM_uint32gsskrb5_extract_key(OM_uint32 *minor_status,		    gss_ctx_id_t context_handle,		    const gss_OID oid, 		    krb5_keyblock **keyblock){    krb5_error_code ret;    gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;    OM_uint32 major_status;    krb5_context context = NULL;    krb5_storage *sp = NULL;    if (context_handle == GSS_C_NO_CONTEXT) {	ret = EINVAL;	return GSS_S_FAILURE;    }        ret = krb5_init_context(&context);    if(ret) {	*minor_status = ret;	return GSS_S_FAILURE;    }    major_status =	gss_inquire_sec_context_by_oid (minor_status,					context_handle,					oid,					&data_set);    if (major_status)	return major_status;        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;    }    sp = krb5_storage_from_mem(data_set->elements[0].value,			       data_set->elements[0].length);    if (sp == NULL) {	ret = ENOMEM;	goto out;    }        *keyblock = calloc(1, sizeof(**keyblock));    if (keyblock == NULL) {	ret = ENOMEM;	goto out;    }    ret = krb5_ret_keyblock(sp, *keyblock);out:     gss_release_buffer_set(minor_status, &data_set);    if (sp)	krb5_storage_free(sp);    if (ret && keyblock) {	krb5_free_keyblock(context, *keyblock);	*keyblock = NULL;    }    if (context)	krb5_free_context(context);    *minor_status = ret;    if (ret)	return GSS_S_FAILURE;    return GSS_S_COMPLETE;}/* * */OM_uint32gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,				 gss_ctx_id_t context_handle,				 krb5_keyblock **keyblock){    return gsskrb5_extract_key(minor_status,			       context_handle,			       GSS_KRB5_GET_SERVICE_KEYBLOCK_X,			       keyblock);}OM_uint32gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,			     gss_ctx_id_t context_handle,			     krb5_keyblock **keyblock){    return gsskrb5_extract_key(minor_status,			       context_handle,			       GSS_KRB5_GET_INITIATOR_SUBKEY_X,			       keyblock);}OM_uint32gsskrb5_get_subkey(OM_uint32 *minor_status,		   gss_ctx_id_t context_handle,		   krb5_keyblock **keyblock){    return gsskrb5_extract_key(minor_status,			       context_handle,			       GSS_KRB5_GET_SUBKEY_X,			       keyblock);}OM_uint32gsskrb5_set_default_realm(const char *realm){        struct _gss_mech_switch	*m;	gss_buffer_desc buffer;	OM_uint32 junk;	_gss_load_mech();	buffer.value = rk_UNCONST(realm);	buffer.length = strlen(realm);	SLIST_FOREACH(m, &_gss_mechs, gm_link) {		if (m->gm_mech.gm_set_sec_context_option == NULL)			continue;		m->gm_mech.gm_set_sec_context_option(&junk, NULL,		    GSS_KRB5_SET_DEFAULT_REALM_X, &buffer);	}	return (GSS_S_COMPLETE);}OM_uint32gss_krb5_get_tkt_flags(OM_uint32 *minor_status,		       gss_ctx_id_t context_handle,		       OM_uint32 *tkt_flags){    OM_uint32 major_status;    gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;    if (context_handle == GSS_C_NO_CONTEXT) {	*minor_status = EINVAL;	return GSS_S_FAILURE;    }        major_status =	gss_inquire_sec_context_by_oid (minor_status,					context_handle,					GSS_KRB5_GET_TKT_FLAGS_X,					&data_set);    if (major_status)	return major_status;        if (data_set == GSS_C_NO_BUFFER_SET || 	data_set->count != 1 ||	data_set->elements[0].length < 4) {	gss_release_buffer_set(minor_status, &data_set);	*minor_status = EINVAL;	return GSS_S_FAILURE;    }    {	const u_char *p = data_set->elements[0].value;	*tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);    }    gss_release_buffer_set(minor_status, &data_set);    return GSS_S_COMPLETE;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?