From: Michal Voců Date: Wed, 8 Aug 2012 15:26:46 +0000 (+0000) Subject: add krb5 counterpart for acquire_cred X-Git-Tag: glite-lbjp-common-gss_R_3_2_4_1~23 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=a44558635ac8607d916c8d7d3a4c1e23b631e739;p=jra1mw.git add krb5 counterpart for acquire_cred --- diff --git a/org.glite.lbjp-common.gss/interface/glite_gss.h b/org.glite.lbjp-common.gss/interface/glite_gss.h index caa66cb..672990b 100644 --- a/org.glite.lbjp-common.gss/interface/glite_gss.h +++ b/org.glite.lbjp-common.gss/interface/glite_gss.h @@ -87,6 +87,11 @@ edg_wll_gss_acquire_cred_gsi(const char *cert_file, edg_wll_GssStatus* gss_code); int +edg_wll_gss_acquire_cred_krb5(const char *cert_file, + edg_wll_GssCred *cred, + edg_wll_GssStatus* gss_code); + +int edg_wll_gss_release_cred(edg_wll_GssCred *cred, edg_wll_GssStatus* gss_code); diff --git a/org.glite.lbjp-common.gss/src/glite_gss.c b/org.glite.lbjp-common.gss/src/glite_gss.c index 038f539..f272501 100644 --- a/org.glite.lbjp-common.gss/src/glite_gss.c +++ b/org.glite.lbjp-common.gss/src/glite_gss.c @@ -840,6 +840,111 @@ end: return ret; } + + +int +edg_wll_gss_acquire_cred_krb5(const char *cert_file, edg_wll_GssCred *cred, + edg_wll_GssStatus* gss_code) +{ + OM_uint32 major_status = 0, minor_status, minor_status2; + gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; + gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER; + gss_name_t gss_name = GSS_C_NO_NAME; + gss_OID_set_desc mechs; + gss_OID_set avail_mechs = NULL; + OM_uint32 lifetime; + char *proxy_file = NULL; + char *name = NULL; + int ret, mech_available; + + *cred = NULL; + + major_status = gss_indicate_mechs(&minor_status, &avail_mechs); + /* ignore error */ + + major_status = gss_test_oid_set_member(&minor_status, get_oid("krb5"), + avail_mechs, &mech_available); + if (!GSS_ERROR(major_status) && !mech_available) { + ret = 0; + lifetime = 0; + goto end1; + } + + mechs.count = 1; + mechs.elements = get_oid("krb5"); + + major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0, + &mechs, GSS_C_BOTH, + &gss_cred, NULL, NULL); + if (GSS_ERROR(major_status)) { + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + + /* gss_import_cred() doesn't check validity of credential loaded, so let's + * verify it now */ + major_status = gss_inquire_cred(&minor_status, gss_cred, &gss_name, + &lifetime, NULL, NULL); + if (GSS_ERROR(major_status)) { + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + + /* Must cast to time_t since OM_uint32 is unsinged and hence we couldn't + * detect negative values. */ + if ((time_t) lifetime <= 0) { + major_status = GSS_S_CREDENTIALS_EXPIRED; + minor_status = 0; /* XXX */ + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + + major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL); + if (GSS_ERROR(major_status)) { + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + name = buffer.value; + memset(&buffer, 0, sizeof(buffer)); + +end1: + + *cred = calloc(1, sizeof(**cred)); + if (*cred == NULL) { + ret = EDG_WLL_GSS_ERROR_ERRNO; + free(name); + goto end; + } + + (*cred)->gss_cred = gss_cred; + gss_cred = GSS_C_NO_CREDENTIAL; + (*cred)->lifetime = lifetime; + (*cred)->name = name; + + ret = 0; + +end: + if (gss_name != GSS_C_NO_NAME) + gss_release_name(&minor_status2, &gss_name); + + if (gss_cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&minor_status2, &gss_cred); + + if (avail_mechs) + gss_release_oid_set(&minor_status2, &avail_mechs); + + if (GSS_ERROR(major_status)) { + if (gss_code) { + gss_code->major_status = major_status; + gss_code->minor_status = minor_status; + } + ret = EDG_WLL_GSS_ERROR_GSS; + } + + return ret; +} + + /* XXX XXX This is black magic. "Sometimes" server refuses the client with SSL * alert "certificate expired" even if it is not true. In this case the server * slave terminates (which helps, usually), and we can reconnect transparently.