static OM_uint32 get_service_keyblock (OM_uint32 *minor_status, gsskrb5_ctx ctx, gss_buffer_set_t *data_set) { krb5_storage *sp = NULL; krb5_data data; OM_uint32 maj_stat = GSS_S_COMPLETE; krb5_error_code ret = EINVAL; sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); *minor_status = ENOMEM; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (ctx->service_keyblock == NULL) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context"); *minor_status = EINVAL; return GSS_S_FAILURE; } krb5_data_zero(&data); ret = krb5_store_keyblock(sp, *ctx->service_keyblock); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) goto out; ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc value; value.length = data.length; value.value = data.data; maj_stat = gss_add_buffer_set_member(minor_status, &value, data_set); } out: krb5_data_free(&data); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; maj_stat = GSS_S_FAILURE; } return maj_stat; }
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, const gss_OID desired_object, gss_buffer_set_t *data_set) { krb5_context context; gsskrb5_cred cred = (gsskrb5_cred)cred_handle; krb5_error_code ret; gss_buffer_desc buffer; char *str; GSSAPI_KRB5_INIT (&context); if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) { *minor_status = EINVAL; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); if (cred->ccache == NULL) { HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = EINVAL; return GSS_S_FAILURE; } ret = krb5_cc_get_full_name(context, cred->ccache, &str); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } buffer.value = str; buffer.length = strlen(str); ret = gss_add_buffer_set_member(minor_status, &buffer, data_set); if (ret != GSS_S_COMPLETE) _gsskrb5_clear_status (); free(str); *minor_status = 0; return GSS_S_COMPLETE; }
OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, krb5_context context, krb5_ccache id, krb5_principal principal, OM_uint32 *lifetime) { krb5_creds in_cred, out_cred; krb5_const_realm realm; krb5_error_code kret; memset(&in_cred, 0, sizeof(in_cred)); in_cred.client = principal; realm = krb5_principal_get_realm(context, principal); if (realm == NULL) { _gsskrb5_clear_status (); *minor_status = KRB5_PRINC_NOMATCH; /* XXX */ return GSS_S_FAILURE; } kret = krb5_make_principal(context, &in_cred.server, realm, KRB5_TGS_NAME, realm, NULL); if (kret) { *minor_status = kret; return GSS_S_FAILURE; } kret = krb5_cc_retrieve_cred(context, id, 0, &in_cred, &out_cred); krb5_free_principal(context, in_cred.server); if (kret) { *minor_status = 0; *lifetime = 0; return GSS_S_COMPLETE; } *lifetime = out_cred.times.endtime; krb5_free_cred_contents(context, &out_cred); return GSS_S_COMPLETE; }
OM_uint32 _gsskrb5_krb5_import_cred(OM_uint32 *minor_status, krb5_ccache id, krb5_principal keytab_principal, krb5_keytab keytab, gss_cred_id_t *cred) { krb5_context context; krb5_error_code kret; gsskrb5_cred handle; OM_uint32 ret; *cred = NULL; GSSAPI_KRB5_INIT (&context); handle = calloc(1, sizeof(*handle)); if (handle == NULL) { _gsskrb5_clear_status (); *minor_status = ENOMEM; return (GSS_S_FAILURE); } HEIMDAL_MUTEX_init(&handle->cred_id_mutex); handle->usage = 0; if (id) { char *str; handle->usage |= GSS_C_INITIATE; kret = krb5_cc_get_principal(context, id, &handle->principal); if (kret) { free(handle); *minor_status = kret; return GSS_S_FAILURE; } if (keytab_principal) { krb5_boolean match; match = krb5_principal_compare(context, handle->principal, keytab_principal); if (match == FALSE) { krb5_free_principal(context, handle->principal); free(handle); _gsskrb5_clear_status (); *minor_status = EINVAL; return GSS_S_FAILURE; } } ret = __gsskrb5_ccache_lifetime(minor_status, context, id, handle->principal, &handle->lifetime); if (ret != GSS_S_COMPLETE) { krb5_free_principal(context, handle->principal); free(handle); return ret; } kret = krb5_cc_get_full_name(context, id, &str); if (kret) goto out; kret = krb5_cc_resolve(context, str, &handle->ccache); free(str); if (kret) goto out; } if (keytab) { char *str; handle->usage |= GSS_C_ACCEPT; if (keytab_principal && handle->principal == NULL) { kret = krb5_copy_principal(context, keytab_principal, &handle->principal); if (kret) goto out; } kret = krb5_kt_get_full_name(context, keytab, &str); if (kret) goto out; kret = krb5_kt_resolve(context, str, &handle->keytab); free(str); if (kret) goto out; } if (id || keytab) { ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, &handle->mechanisms); if (ret != GSS_S_COMPLETE) { kret = *minor_status; goto out; } } *minor_status = 0; *cred = (gss_cred_id_t)handle; return GSS_S_COMPLETE; out: gss_release_oid_set(minor_status, &handle->mechanisms); if (handle->ccache) krb5_cc_close(context, handle->ccache); if (handle->keytab) krb5_kt_close(context, handle->keytab); if (handle->principal) krb5_free_principal(context, handle->principal); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); *minor_status = kret; return GSS_S_FAILURE; }
static OM_uint32 export_lucid_sec_context_v1(OM_uint32 *minor_status, gsskrb5_ctx context_handle, krb5_context context, gss_buffer_set_t *data_set) { krb5_storage *sp = NULL; OM_uint32 major_status = GSS_S_COMPLETE; krb5_error_code ret; krb5_keyblock *key = NULL; int32_t number; int is_cfx; krb5_data data; *minor_status = 0; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); _gsskrb5i_is_cfx(context_handle, &is_cfx); sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); ret = ENOMEM; goto out; } ret = krb5_store_int32(sp, 1); if (ret) goto out; ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0); if (ret) goto out; ret = krb5_store_int32(sp, context_handle->lifetime); if (ret) goto out; krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ if (ret) goto out; ret = krb5_store_uint32(sp, (uint32_t)number); if (ret) goto out; krb5_auth_getremoteseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ if (ret) goto out; ret = krb5_store_uint32(sp, (uint32_t)number); if (ret) goto out; ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); if (ret) goto out; ret = _gsskrb5i_get_token_key(context_handle, context, &key); if (ret) goto out; if (is_cfx == 0) { int sign_alg, seal_alg; switch (key->keytype) { case ETYPE_DES_CBC_CRC: case ETYPE_DES_CBC_MD4: case ETYPE_DES_CBC_MD5: sign_alg = 0; seal_alg = 0; break; case ETYPE_DES3_CBC_MD5: case ETYPE_DES3_CBC_SHA1: sign_alg = 4; seal_alg = 2; break; case ETYPE_ARCFOUR_HMAC_MD5: case ETYPE_ARCFOUR_HMAC_MD5_56: sign_alg = 17; seal_alg = 16; break; default: sign_alg = -1; seal_alg = -1; break; } ret = krb5_store_int32(sp, sign_alg); if (ret) goto out; ret = krb5_store_int32(sp, seal_alg); if (ret) goto out; /* ctx_key */ ret = krb5_store_keyblock(sp, *key); if (ret) goto out; } else { int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0; /* have_acceptor_subkey */ ret = krb5_store_int32(sp, subkey_p); if (ret) goto out; /* ctx_key */ ret = krb5_store_keyblock(sp, *key); if (ret) goto out; /* acceptor_subkey */ if (subkey_p) { ret = krb5_store_keyblock(sp, *key); if (ret) goto out; } } ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc ad_data; ad_data.value = data.data; ad_data.length = data.length; ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); krb5_data_free(&data); if (ret) goto out; } out: if (key) krb5_free_keyblock (context, key); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; major_status = GSS_S_FAILURE; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return major_status; }
static OM_uint32 inquire_sec_context_get_subkey (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, enum keytype keytype, gss_buffer_set_t *data_set) { krb5_keyblock *key = NULL; krb5_storage *sp = NULL; krb5_data data; OM_uint32 maj_stat = GSS_S_COMPLETE; krb5_error_code ret; krb5_data_zero(&data); sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); ret = ENOMEM; goto out; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); switch(keytype) { case ACCEPTOR_KEY: ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key); break; case INITIATOR_KEY: ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key); break; case TOKEN_KEY: ret = _gsskrb5i_get_token_key(context_handle, context, &key); break; default: _gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype); ret = EINVAL; break; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) goto out; if (key == NULL) { _gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype); ret = EINVAL; goto out; } ret = krb5_store_keyblock(sp, *key); krb5_free_keyblock (context, key); if (ret) goto out; ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc value; value.length = data.length; value.value = data.data; maj_stat = gss_add_buffer_set_member(minor_status, &value, data_set); } out: krb5_data_free(&data); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; maj_stat = GSS_S_FAILURE; } return maj_stat; }