static OM_uint32 get_local_def_creds(OM_uint32 *minor_status, struct gpp_name_handle *name, gss_cred_usage_t cred_usage, struct gpp_cred_handle *cred_handle) { gss_OID_set interposed_mechs = GSS_C_NO_OID_SET; gss_OID_set special_mechs = GSS_C_NO_OID_SET; OM_uint32 maj, min; maj = GSS_S_FAILURE; min = 0; interposed_mechs = gss_mech_interposer((gss_OID)&gssproxy_mech_interposer); if (interposed_mechs == GSS_C_NO_OID_SET) { goto done; } special_mechs = gpp_special_available_mechs(interposed_mechs); if (special_mechs == GSS_C_NO_OID_SET) { goto done; } maj = gss_acquire_cred(&min, name ? name->local : NULL, 0, special_mechs, cred_usage, &cred_handle->local, NULL, NULL); done: *minor_status = min; (void)gss_release_oid_set(&min, &special_mechs); (void)gss_release_oid_set(&min, &interposed_mechs); return maj; }
int attrs_for_mech(struct attrs_for_mech_options *opt, int argc, char **argv) { gss_OID_set mech_attr = NULL, known_mech_attrs = NULL; gss_OID mech = GSS_C_NO_OID; OM_uint32 major, minor; if (opt->mech_string) { mech = gss_name_to_oid(opt->mech_string); if (mech == NULL) errx(1, "mech %s is unknown", opt->mech_string); } major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attr, &known_mech_attrs); if (major) errx(1, "gss_inquire_attrs_for_mech"); if (mech) { print_mech_attr(opt->mech_string, mech, mech_attr); } if (opt->all_flag) { print_mech_attr("all mechs", NULL, known_mech_attrs); } gss_release_oid_set(&minor, &mech_attr); gss_release_oid_set(&minor, &known_mech_attrs); return 0; }
/* Privileged (called from ssh_gssapi_server_ctx) */ static OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx) { OM_uint32 status; char lname[NI_MAXHOST]; gss_OID_set oidset; gss_create_empty_oid_set(&status, &oidset); gss_add_oid_set_member(&status, ctx->oid, &oidset); if (gethostname(lname, sizeof(lname))) { gss_release_oid_set(&status, &oidset); return (-1); } if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); } if ((ctx->major = gss_acquire_cred(&ctx->minor, ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) ssh_gssapi_error(ctx); gss_release_oid_set(&status, &oidset); return (ctx->major); }
/* Privileged (called from ssh_gssapi_server_ctx) */ static OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx) { OM_uint32 status; char lname[NI_MAXHOST]; gss_OID_set oidset; if (options.gss_strict_acceptor) { gss_create_empty_oid_set(&status, &oidset); gss_add_oid_set_member(&status, ctx->oid, &oidset); if (gethostname(lname, MAXHOSTNAMELEN)) { gss_release_oid_set(&status, &oidset); return (-1); } if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); } if ((ctx->major = gss_acquire_cred(&ctx->minor, ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) ssh_gssapi_error(ctx); gss_release_oid_set(&status, &oidset); return (ctx->major); } else { ctx->name = GSS_C_NO_NAME; ctx->creds = GSS_C_NO_CREDENTIAL; } return GSS_S_COMPLETE; }
static OM_uint32 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) { OM_uint32 ret, junk; gss_OID_set m; size_t i; ret = gss_indicate_mechs(minor_status, &m); if (ret != GSS_S_COMPLETE) return ret; ret = gss_create_empty_oid_set(minor_status, mechs); if (ret != GSS_S_COMPLETE) { gss_release_oid_set(&junk, &m); return ret; } for (i = 0; i < m->count; i++) { if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM)) continue; ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs); if (ret) { gss_release_oid_set(&junk, &m); gss_release_oid_set(&junk, mechs); return ret; } } gss_release_oid_set(&junk, &m); return ret; }
OM_uint32 gss_indicate_mechs (OM_uint32 * minor_status, gss_OID_set * mech_set ) { OM_uint32 ret; ret = gss_create_empty_oid_set(minor_status, mech_set); if (ret) return ret; ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set); if (ret) { gss_release_oid_set(NULL, mech_set); return ret; } ret = gss_add_oid_set_member(minor_status, GSS_SPNEGO_MECHANISM, mech_set); if (ret) { gss_release_oid_set(NULL, mech_set); return ret; } *minor_status = 0; return GSS_S_COMPLETE; }
OM_uint32 gssEapDefaultMech(OM_uint32 *minor, gss_OID *oid) { gss_OID_set mechs; OM_uint32 major, tmpMinor; major = gssEapIndicateMechs(minor, &mechs); if (GSS_ERROR(major)) { return major; } if (mechs->count == 0) { gss_release_oid_set(&tmpMinor, &mechs); return GSS_S_BAD_MECH; } if (!internalizeOid(&mechs->elements[0], oid)) { /* don't double-free if we didn't internalize it */ mechs->elements[0].length = 0; mechs->elements[0].elements = NULL; } gss_release_oid_set(&tmpMinor, &mechs); *minor = 0; return GSS_S_COMPLETE; }
static OM_uint32 dumpMechAttrs(OM_uint32 *minor, gss_OID mech) { OM_uint32 major, tmpMinor; gss_OID_set mech_attrs = GSS_C_NO_OID_SET; gss_OID_set known_attrs = GSS_C_NO_OID_SET; size_t i; major = gss_inquire_attrs_for_mech(minor, mech, &mech_attrs, &known_attrs); if (GSS_ERROR(major)) { displayStatus("gss_inquire_attrs_for_mech", major, *minor); return major; } printf("Mech attrs: "); for (i = 0; i < mech_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(minor, &mech_attrs->elements[i], &name, &short_desc, &long_desc); if (GSS_ERROR(major)) { displayStatus("gss_display_mech_attr", major, *minor); continue; } printf("%.*s ", (int)name.length, (char *)name.value); gss_release_buffer(minor, &name); gss_release_buffer(minor, &short_desc); gss_release_buffer(minor, &long_desc); } printf("\n"); printf("Known attrs: "); for (i = 0; i < known_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(minor, &known_attrs->elements[i], &name, &short_desc, &long_desc); if (GSS_ERROR(major)) { displayStatus("gss_display_mech_attr", major, *minor); continue; } printf("%.*s ", (int)name.length, (char *)name.value); gss_release_buffer(minor, &name); gss_release_buffer(minor, &short_desc); gss_release_buffer(minor, &long_desc); } printf("\n"); gss_release_oid_set(&tmpMinor, &mech_attrs); gss_release_oid_set(&tmpMinor, &known_attrs); return GSS_S_COMPLETE; }
/* * Translate an OID_set from the local GSS-API library's ABI into the * ABI which SAP expects. This translation routine is only used within * this shim adapter, so it is appropriate for the this routine to release * the storage which was allocated by the GSS-API library (since that * storage will never be exposed to the application and will otherwise be * leaked). * * Returns 0 on success, errno on failure. */ static int gss_OID_set_loc_to_sap(gss_OID_set loc, sapgss_OID_set *sap) { sapgss_OID s; gss_OID e; size_t i; uint32_t dummy; if (sap == NULL) return 0; if (loc == NULL) { *sap = NULL; return 0; } *sap = calloc(1, sizeof(**sap)); if (*sap == NULL) return errno; (*sap)->elements = calloc(loc->count, sizeof(sapgss_OID_desc)); if ((*sap)->elements == NULL) { free(*sap); *sap = NULL; return ENOMEM; } for(i = 0; i < loc->count; ++i) { e = &loc->elements[i]; s = &(*sap)->elements[i]; s->elements = malloc(e->length); if (s->elements == NULL) goto looperr; memcpy(s->elements, e->elements, e->length); s->length = e->length; } (*sap)->count = loc->count; (void)gss_release_oid_set(&dummy, &loc); return 0; looperr: for(i = 0; i < loc->count; ++i) { s = &(*sap)->elements[i]; if (s->elements == NULL) break; free(s->elements); } free((*sap)->elements); free(*sap); *sap = NULL; (void)gss_release_oid_set(&dummy, &loc); return ENOMEM; }
/* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) { int i = 0; OM_uint32 min_status; int present; gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) return; while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, &supported_mechs[i]->oid, supported, &present))) present = 0; if (present) gss_add_oid_set_member(&min_status, &supported_mechs[i]->oid, oidset); i++; } gss_release_oid_set(&min_status, &supported); }
int listMechanisms(int argc, char* argv[]) { OM_uint32 major, minor; gss_OID_set mechanisms; int index,i; gss_OID currElem = NULL; printf("\tListing available mechanisms\n"); major = gss_indicate_mechs(&minor, &mechanisms); checkError(major, minor, "gss_indicate_mechs"); printf("\tFound %zu elements:\n", mechanisms->count); for(index = 0; index < mechanisms->count; index++) { currElem = &(mechanisms->elements[index]); printf("\t{ %d,", currElem->length); for(i = 0; i < currElem->length; i++) printf("\\x%x", ((char *)currElem->elements)[i]); printf("}\n"); printOid(currElem); } if (major != GSS_S_COMPLETE) { fprintf(stderr, "failed to get the mechanisms "); return 1; } printf("\tfreeing the oidset..\n"); major = gss_release_oid_set(&minor, &mechanisms); checkError(major, minor, "gss_release_oid_set"); return 0; }
static apr_status_t mag_oid_set_destroy(void *ptr) { uint32_t min; gss_OID_set set = (gss_OID_set)ptr; (void)gss_release_oid_set(&min, &set); return APR_SUCCESS; }
int supported_mechanisms(void *argptr, int argc, char **argv) { OM_uint32 maj_stat, min_stat; gss_OID_set mechs; rtbl_t ct; size_t i; maj_stat = gss_indicate_mechs(&min_stat, &mechs); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_indicate_mechs failed"); printf("Supported mechanisms:\n"); ct = rtbl_create(); if (ct == NULL) errx(1, "rtbl_create"); rtbl_set_separator(ct, " "); rtbl_add_column(ct, COL_OID, 0); rtbl_add_column(ct, COL_NAME, 0); rtbl_add_column(ct, COL_DESC, 0); rtbl_add_column(ct, COL_SASL, 0); for (i = 0; i < mechs->count; i++) { gss_buffer_desc str, sasl_name, mech_name, mech_desc; maj_stat = gss_oid_to_str(&min_stat, &mechs->elements[i], &str); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_oid_to_str failed"); rtbl_add_column_entryv(ct, COL_OID, "%.*s", (int)str.length, (char *)str.value); gss_release_buffer(&min_stat, &str); (void)gss_inquire_saslname_for_mech(&min_stat, &mechs->elements[i], &sasl_name, &mech_name, &mech_desc); rtbl_add_column_entryv(ct, COL_NAME, "%.*s", (int)mech_name.length, (char *)mech_name.value); rtbl_add_column_entryv(ct, COL_DESC, "%.*s", (int)mech_desc.length, (char *)mech_desc.value); rtbl_add_column_entryv(ct, COL_SASL, "%.*s", (int)sasl_name.length, (char *)sasl_name.value); gss_release_buffer(&min_stat, &mech_name); gss_release_buffer(&min_stat, &mech_desc); gss_release_buffer(&min_stat, &sasl_name); } gss_release_oid_set(&min_stat, &mechs); rtbl_format(ct, stdout); rtbl_destroy(ct); return 0; }
/* Return true if mech should be accepted with no acceptor credential. */ static int allow_mech_by_default(gss_OID mech) { OM_uint32 status, minor; gss_OID_set attrs; int reject = 0, p; /* Whether we accept an interposer mech depends on whether we accept the * mech it interposes. */ mech = gssint_get_public_oid(mech); if (mech == GSS_C_NO_OID) return 0; status = gss_inquire_attrs_for_mech(&minor, mech, &attrs, NULL); if (status) return 0; /* Check for each attribute which would cause us to exclude this mech from * the default credential. */ if (generic_gss_test_oid_set_member(&minor, GSS_C_MA_DEPRECATED, attrs, &p) != GSS_S_COMPLETE || p) reject = 1; else if (generic_gss_test_oid_set_member(&minor, GSS_C_MA_NOT_DFLT_MECH, attrs, &p) != GSS_S_COMPLETE || p) reject = 1; (void) gss_release_oid_set(&minor, &attrs); return !reject; }
OM_uint32 _gsskrb5_inquire_names_for_mech ( OM_uint32 * minor_status, const gss_OID mechanism, gss_OID_set * name_types ) { OM_uint32 ret; int i; *minor_status = 0; if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 && gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) { *name_types = GSS_C_NO_OID_SET; return GSS_S_BAD_MECH; } ret = gss_create_empty_oid_set(minor_status, name_types); if (ret != GSS_S_COMPLETE) return ret; for (i = 0; name_list[i] != NULL; i++) { ret = gss_add_oid_set_member(minor_status, *(name_list[i]), name_types); if (ret != GSS_S_COMPLETE) break; } if (ret != GSS_S_COMPLETE) gss_release_oid_set(NULL, name_types); return GSS_S_COMPLETE; }
OM_uint32 gss_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle ) { *minor_status = 0; if (*cred_handle == GSS_C_NO_CREDENTIAL) { return GSS_S_COMPLETE; } GSSAPI_KRB5_INIT (); HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex); if ((*cred_handle)->principal != NULL) krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); if ((*cred_handle)->keytab != NULL) krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab); if ((*cred_handle)->ccache != NULL) { const krb5_cc_ops *ops; ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache); if (ops == &krb5_mcc_ops) krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache); else krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); } gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex); HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex); memset(*cred_handle, 0, sizeof(**cred_handle)); free(*cred_handle); *cred_handle = GSS_C_NO_CREDENTIAL; return GSS_S_COMPLETE; }
OM_uint32 ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) { gss_buffer_desc gssbuf; gss_name_t gssname; OM_uint32 status; gss_OID_set oidset; gssbuf.value = (void *) name; gssbuf.length = strlen(gssbuf.value); gss_create_empty_oid_set(&status, &oidset); gss_add_oid_set_member(&status, ctx->oid, &oidset); ctx->major = gss_import_name(&ctx->minor, &gssbuf, GSS_C_NT_USER_NAME, &gssname); if (!ctx->major) ctx->major = gss_acquire_cred(&ctx->minor, gssname, 0, oidset, GSS_C_INITIATE, &ctx->client_creds, NULL, NULL); gss_release_name(&status, &gssname); gss_release_oid_set(&status, &oidset); if (ctx->major) ssh_gssapi_error(ctx); return(ctx->major); }
/** * Passes back the mech set of available mechs. * We only have one for now. * * @param minor_status * @param mech_set * * @return */ OM_uint32 GSS_CALLCONV gss_indicate_mechs( OM_uint32 * minor_status, gss_OID_set * mech_set) { OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 local_minor_status; gss_OID_set_desc * set; static char * _function_name_ = "gss_indicate_mechs"; GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER; if (minor_status == NULL || mech_set == NULL) { major_status = GSS_S_FAILURE; if (minor_status != NULL) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid parameter"))); } goto exit; } *minor_status = (OM_uint32) GLOBUS_SUCCESS; major_status = gss_create_empty_oid_set(&local_minor_status, &set); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_MECH); goto exit; } major_status = gss_add_oid_set_member( &local_minor_status, (const gss_OID) gss_mech_globus_gssapi_openssl, &set); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OID); gss_release_oid_set(&local_minor_status, &set); goto exit; } *mech_set = set; exit: GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT; return major_status; }
static OM_uint32 acceptor_approved(void *userptr, gss_name_t target_name, const gss_cred_id_t cred_handle, gss_OID mech) { OM_uint32 junk, ret; gss_OID_set oidset; if (cred_handle) { int present = 0; ret = gss_inquire_cred(&junk, cred_handle, NULL, NULL, NULL, &oidset); if (ret != GSS_S_COMPLETE) return ret; ret = gss_test_oid_set_member(&junk, mech, oidset, &present); gss_release_oid_set(&junk, &oidset); if (ret != GSS_S_COMPLETE || present == 0) return GSS_S_FAILURE; } else { gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; if (target_name == GSS_C_NO_NAME) return GSS_S_COMPLETE; gss_create_empty_oid_set(&junk, &oidset); gss_add_oid_set_member(&junk, mech, &oidset); ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset, GSS_C_ACCEPT, &cred, NULL, NULL); gss_release_oid_set(&junk, &oidset); if (ret != GSS_S_COMPLETE) return ret; gss_release_cred(&junk, &cred); } return GSS_S_COMPLETE; }
OM_uint32 GSSAPI_CALLCONV _gss_ntlm_inquire_cred (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, gss_name_t * name, OM_uint32 * lifetime, gss_cred_usage_t * cred_usage, gss_OID_set * mechanisms ) { OM_uint32 ret, junk; *minor_status = 0; if (cred_handle == NULL) return GSS_S_NO_CRED; if (name) { ntlm_name n = calloc(1, sizeof(*n)); ntlm_cred c = (ntlm_cred)cred_handle; if (n) { n->user = strdup(c->username); n->domain = strdup(c->domain); } if (n == NULL || n->user == NULL || n->domain == NULL) { if (n) free(n->user); *minor_status = ENOMEM; return GSS_S_FAILURE; } *name = (gss_name_t)n; } if (lifetime) *lifetime = GSS_C_INDEFINITE; if (cred_usage) *cred_usage = 0; if (mechanisms) *mechanisms = GSS_C_NO_OID_SET; if (cred_handle == GSS_C_NO_CREDENTIAL) return GSS_S_NO_CRED; if (mechanisms) { ret = gss_create_empty_oid_set(minor_status, mechanisms); if (ret) goto out; ret = gss_add_oid_set_member(minor_status, GSS_NTLM_MECHANISM, mechanisms); if (ret) goto out; } return GSS_S_COMPLETE; out: gss_release_oid_set(&junk, mechanisms); return ret; }
/** * Initialize a previously allocated error of type * GLOBUS_ERROR_TYPE_GSSAPI * @ingroup globus_gssapi_error_object * * @param error * The previously allocated error object. * @param base_source * Pointer to the originating module. * @param base_cause * The error object causing the error. If this is the original * error this paramater may be NULL. * @param major_status * The GSSAPI major status * @param minor_status * The GSSAPI minor status * @return * The resulting error object. You may have to call * globus_error_put() on this object before passing it on. */ globus_object_t * globus_error_initialize_gssapi_error( globus_object_t * error, globus_module_descriptor_t * base_source, globus_object_t * base_cause, const OM_uint32 major_status, const OM_uint32 minor_status) { globus_l_gssapi_error_data_t * instance_data; globus_object_t * minor_obj; gss_OID_set actual_mechs; OM_uint32 local_minor_status; extern gss_OID gss_mech_globus_gssapi_openssl; instance_data = (globus_l_gssapi_error_data_t *) malloc(sizeof(globus_l_gssapi_error_data_t)); instance_data->major_status = major_status; instance_data->minor_status = minor_status; instance_data->is_globus_gsi = GLOBUS_FALSE; if(gss_indicate_mechs( &local_minor_status, &actual_mechs) == GSS_S_COMPLETE) { int boolean; if(gss_test_oid_set_member( &local_minor_status, gss_mech_globus_gssapi_openssl, actual_mechs, &boolean) == GSS_S_COMPLETE && boolean) { instance_data->is_globus_gsi = GLOBUS_TRUE; } gss_release_oid_set(&local_minor_status, &actual_mechs); } if(instance_data->is_globus_gsi) { minor_obj = globus_error_get((globus_result_t) minor_status); if(!base_cause) { base_cause = minor_obj; } else if(minor_obj) { base_cause = globus_error_initialize_base( minor_obj, globus_error_get_source(base_cause), base_cause); } } globus_object_set_local_instance_data(error, instance_data); return globus_error_initialize_base(error, base_source, base_cause); }/* globus_error_initialize_gssapi_error() */
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_names_for_mech(OM_uint32 *minor_status, const gss_OID mechanism, gss_OID_set *name_types) { OM_uint32 major_status; gssapi_mech_interface m = __gss_get_mechanism(mechanism); *minor_status = 0; *name_types = GSS_C_NO_OID_SET; if (!m) return (GSS_S_BAD_MECH); /* * If the implementation can do it, ask it for a list of * names, otherwise fake it. */ if (m->gm_inquire_names_for_mech) { return (m->gm_inquire_names_for_mech(minor_status, mechanism, name_types)); } else { major_status = gss_create_empty_oid_set(minor_status, name_types); if (major_status) return (major_status); major_status = gss_add_oid_set_member(minor_status, GSS_C_NT_HOSTBASED_SERVICE, name_types); if (major_status) { OM_uint32 junk; gss_release_oid_set(&junk, name_types); return (major_status); } major_status = gss_add_oid_set_member(minor_status, GSS_C_NT_USER_NAME, name_types); if (major_status) { OM_uint32 junk; gss_release_oid_set(&junk, name_types); return (major_status); } } return (GSS_S_COMPLETE); }
OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech ( OM_uint32 * minor_status, const gss_OID mechanism, gss_OID_set * name_types ) { gss_OID_set mechs, names, n; OM_uint32 ret, junk; size_t i, j; *name_types = NULL; ret = spnego_supported_mechs(minor_status, &mechs); if (ret != GSS_S_COMPLETE) return ret; ret = gss_create_empty_oid_set(minor_status, &names); if (ret != GSS_S_COMPLETE) goto out; for (i = 0; i < mechs->count; i++) { ret = gss_inquire_names_for_mech(minor_status, &mechs->elements[i], &n); if (ret) continue; for (j = 0; j < n->count; j++) gss_add_oid_set_member(minor_status, &n->elements[j], &names); gss_release_oid_set(&junk, &n); } ret = GSS_S_COMPLETE; *name_types = names; out: gss_release_oid_set(&junk, &mechs); return ret; }
static void acquire_cred_complete(void *ctx, OM_uint32 maj, gss_status_id_t status __unused, gss_cred_id_t creds, gss_OID_set oids, OM_uint32 time_rec __unused) { uint32_t min; struct smb_gss_cred_ctx *aq_cred_ctx = ctx; gss_release_oid_set(&min, &oids); aq_cred_ctx->creds = creds; aq_cred_ctx->maj = maj; dispatch_semaphore_signal(aq_cred_ctx->sem); }
static int negotiate_init_context( http_auth_negotiate_context *ctx, const gitno_connection_data *connection_data) { OM_uint32 status_major, status_minor; gss_OID item, *oid; gss_OID_set mechanism_list; size_t i; /* Query supported mechanisms looking for SPNEGO) */ if (GSS_ERROR(status_major = gss_indicate_mechs(&status_minor, &mechanism_list))) { negotiate_err_set(status_major, status_minor, "could not query mechanisms"); return -1; } if (mechanism_list) { for (oid = negotiate_oids; *oid; oid++) { for (i = 0; i < mechanism_list->count; i++) { item = &mechanism_list->elements[i]; if (item->length == (*oid)->length && memcmp(item->elements, (*oid)->elements, item->length) == 0) { ctx->oid = *oid; break; } } if (ctx->oid) break; } } gss_release_oid_set(&status_minor, &mechanism_list); if (!ctx->oid) { giterr_set(GITERR_NET, "Negotiate authentication is not supported"); return -1; } git_buf_puts(&ctx->target, "HTTP@"); git_buf_puts(&ctx->target, connection_data->host); if (git_buf_oom(&ctx->target)) return -1; ctx->gss_context = GSS_C_NO_CONTEXT; ctx->configured = 1; return 0; }
static void empty_release(void) { gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_name_t name = GSS_C_NO_NAME; gss_OID_set oidset = GSS_C_NO_OID_SET; OM_uint32 junk; gss_delete_sec_context(&junk, &ctx, NULL); gss_release_cred(&junk, &cred); gss_release_name(&junk, &name); gss_release_oid_set(&junk, &oidset); }
int supported_mechanisms(void *argptr, int argc, char **argv) { OM_uint32 maj_stat, min_stat; gss_OID_set mechs; rtbl_t ct; size_t i; maj_stat = gss_indicate_mechs(&min_stat, &mechs); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_indicate_mechs failed"); printf("Supported mechanisms:\n"); ct = rtbl_create(); if (ct == NULL) errx(1, "rtbl_create"); rtbl_set_separator(ct, " "); rtbl_add_column(ct, COL_OID, 0); rtbl_add_column(ct, COL_NAME, 0); for (i = 0; i < mechs->count; i++) { gss_buffer_desc name; maj_stat = gss_oid_to_str(&min_stat, &mechs->elements[i], &name); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_oid_to_str failed"); rtbl_add_column_entryv(ct, COL_OID, "%.*s", (int)name.length, (char *)name.value); gss_release_buffer(&min_stat, &name); if (gss_oid_equal(&mechs->elements[i], GSS_KRB5_MECHANISM)) rtbl_add_column_entry(ct, COL_NAME, "Kerberos 5"); else if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM)) rtbl_add_column_entry(ct, COL_NAME, "SPNEGO"); else if (gss_oid_equal(&mechs->elements[i], GSS_NTLM_MECHANISM)) rtbl_add_column_entry(ct, COL_NAME, "NTLM"); } gss_release_oid_set(&min_stat, &mechs); rtbl_format(ct, stdout); rtbl_destroy(ct); return 0; }
static void ac_complete(void *ctx, OM_uint32 major, gss_status_id_t status, gss_cred_id_t cred, gss_OID_set oids, OM_uint32 time_rec) { OM_uint32 junk; if (major) { fprintf(stderr, "error: %d", (int)major); gss_release_cred(&junk, &cred); goto out; } client_cred = cred; out: gss_release_oid_set(&junk, &oids); }
gss_OID_set mag_filter_unwanted_mechs(gss_OID_set src) { gss_const_OID unwanted_mechs[] = { &gss_mech_spnego, gss_mech_krb5_old, gss_mech_krb5_wrong, gss_mech_iakerb, GSS_C_NO_OID }; gss_OID_set dst; uint32_t maj, min; int present = 0; if (src == GSS_C_NO_OID_SET) return GSS_C_NO_OID_SET; for (int i = 0; unwanted_mechs[i] != GSS_C_NO_OID; i++) { maj = gss_test_oid_set_member(&min, discard_const(unwanted_mechs[i]), src, &present); if (present) break; } if (present) { maj = gss_create_empty_oid_set(&min, &dst); if (maj != GSS_S_COMPLETE) { return GSS_C_NO_OID_SET; } for (int i = 0; i < src->count; i++) { present = 0; for (int j = 0; unwanted_mechs[j] != GSS_C_NO_OID; j++) { if (gss_oid_equal(&src->elements[i], unwanted_mechs[j])) { present = 1; break; } } if (present) continue; maj = gss_add_oid_set_member(&min, &src->elements[i], &dst); if (maj != GSS_S_COMPLETE) { gss_release_oid_set(&min, &dst); return GSS_C_NO_OID_SET; } } return dst; } return src; }
OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name ( OM_uint32 * minor_status, gss_const_name_t input_name, gss_OID_set * mech_types ) { OM_uint32 ret, junk; ret = gss_create_empty_oid_set(minor_status, mech_types); if (ret) return ret; ret = gss_add_oid_set_member(minor_status, GSS_SPNEGO_MECHANISM, mech_types); if (ret) gss_release_oid_set(&junk, mech_types); return ret; }