/* * Equality based local login authorization. */ static OM_uint32 compare_names_authorize_localname(OM_uint32 *minor, const gss_union_name_t unionName, const gss_name_t user) { OM_uint32 status, tmpMinor; gss_name_t canonName; int match = 0; status = gss_canonicalize_name(minor, user, unionName->mech_type, &canonName); if (status != GSS_S_COMPLETE) return (status); status = gss_compare_name(minor, (gss_name_t)unionName, canonName, &match); if (status == GSS_S_COMPLETE && match == 0) status = GSS_S_UNAUTHORIZED; (void) gss_release_name(&tmpMinor, &canonName); return (status); }
uint32_t sapgss_compare_name( uint32_t *minor_status, gss_name_t name1, gss_name_t name2, int *name_equal) { return gss_compare_name(minor_status, name1, name2, name_equal); }
int ssh_gssapi_credentials_updated(Gssctxt *ctxt) { static gss_name_t saved_name = GSS_C_NO_NAME; static OM_uint32 saved_lifetime = 0; static gss_OID saved_mech = GSS_C_NO_OID; static gss_name_t name; static OM_uint32 last_call = 0; OM_uint32 lifetime, now, major, minor; int equal; gss_cred_usage_t usage = GSS_C_INITIATE; now = time(NULL); if (ctxt) { debug("Rekey has happened - updating saved versions"); if (saved_name != GSS_C_NO_NAME) gss_release_name(&minor, &saved_name); major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, &saved_name, &saved_lifetime, NULL, NULL); if (!GSS_ERROR(major)) { saved_mech = ctxt->oid; saved_lifetime+= now; } else { /* Handle the error */ } return 0; } if (now - last_call < 10) return 0; last_call = now; if (saved_mech == GSS_C_NO_OID) return 0; major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, &name, &lifetime, NULL, NULL); if (major == GSS_S_CREDENTIALS_EXPIRED) return 0; else if (GSS_ERROR(major)) return 0; major = gss_compare_name(&minor, saved_name, name, &equal); gss_release_name(&minor, &name); if (GSS_ERROR(major)) return 0; if (equal && (saved_lifetime < lifetime + now - 10)) return 1; return 0; }
static OM_uint32 compare_names(OM_uint32 *minor, const gss_OID mech_type, const gss_name_t name, const char *user, int *user_ok) { OM_uint32 status, tmpMinor; gss_name_t imported_name; gss_name_t canon_name; gss_buffer_desc gss_user; int match = 0; *user_ok = 0; gss_user.value = (void *)user; if (!gss_user.value || !name || !mech_type) return (GSS_S_BAD_NAME); gss_user.length = strlen(gss_user.value); status = gss_import_name(minor, &gss_user, GSS_C_NT_USER_NAME, &imported_name); if (status != GSS_S_COMPLETE) { goto out; } status = gss_canonicalize_name(minor, imported_name, mech_type, &canon_name); if (status != GSS_S_COMPLETE) { (void) gss_release_name(&tmpMinor, &imported_name); goto out; } status = gss_compare_name(minor, canon_name, name, &match); (void) gss_release_name(&tmpMinor, &canon_name); (void) gss_release_name(&tmpMinor, &imported_name); if (status == GSS_S_COMPLETE) { if (match) *user_ok = 1; /* remote user is a-ok */ } out: return (status); }
/*ARGSUSED*/ OM_uint32 ntlm_gss_compare_name( OM_uint32 *minor_status, const gss_name_t name1, const gss_name_t name2, int *name_equal) { OM_uint32 status = GSS_S_COMPLETE; dsyslog("Entering compare_name\n"); status = gss_compare_name(minor_status, name1, name2, name_equal); dsyslog("Leaving compare_name\n"); return (status); }
/** * @brief Compares two RPC creds * * @param[in] cred1 First RPC cred * @param[in] cred2 Second RPC cred * * @return true if same, false otherwise */ bool nfs_compare_clientcred(nfs_client_cred_t *cred1, nfs_client_cred_t *cred2) { #ifdef _HAVE_GSSAPI gss_name_t cred1_cred_name; gss_name_t cred2_cred_name; OM_uint32 maj_stat, min_stat; int status; #endif if (cred1 == NULL) return false; if (cred2 == NULL) return false; if (cred1->flavor != cred2->flavor) return false; switch (cred1->flavor) { case AUTH_UNIX: if (cred1->auth_union.auth_unix.aup_uid != cred2->auth_union.auth_unix.aup_uid) return false; if (cred1->auth_union.auth_unix.aup_gid != cred2->auth_union.auth_unix.aup_gid) return false; break; #ifdef _HAVE_GSSAPI case RPCSEC_GSS: maj_stat = gss_inquire_context(&min_stat, cred1->auth_union.auth_gss.gss_context_id, &cred1_cred_name, NULL, NULL, NULL, NULL, NULL, NULL); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTEXT_EXPIRED) return false; maj_stat = gss_inquire_context(&min_stat, cred2->auth_union.auth_gss.gss_context_id, &cred2_cred_name, NULL, NULL, NULL, NULL, NULL, NULL); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTEXT_EXPIRED) return false; maj_stat = gss_compare_name(&min_stat, cred1_cred_name, cred2_cred_name, &status); if (maj_stat != GSS_S_COMPLETE) return false; if (status == 0) return false; break; #endif default: if (memcmp (&cred1->auth_union, &cred2->auth_union, cred1->length)) return false; break; } /* If this point is reached, structures are the same */ return true; }
/** * @brief Init Sec Context * @ingroup globus_gsi_gssapi */ OM_uint32 GSS_CALLCONV gss_init_sec_context( OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t * context_handle_P, const gss_name_t target_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) { gss_ctx_id_desc * context = NULL; OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 local_minor_status; OM_uint32 local_major_status; globus_result_t local_result; int rc; char cbuf[1]; globus_gsi_cert_utils_cert_type_t cert_type; GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER; *minor_status = (OM_uint32) GLOBUS_SUCCESS; output_token->length = 0; context = *context_handle_P; /* module activation if not already done by calling * globus_module_activate */ globus_thread_once( &once_control, globus_l_gsi_gssapi_activate_once); globus_mutex_lock(&globus_i_gssapi_activate_mutex); if (!globus_i_gssapi_active) { globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE); } globus_mutex_unlock(&globus_i_gssapi_activate_mutex); if(req_flags & GSS_C_ANON_FLAG && req_flags & GSS_C_DELEG_FLAG) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Can't initialize a context to be both anonymous and " "provide delegation"))); goto error_exit; } if(req_flags & GSS_C_GLOBUS_SSL_COMPATIBLE && req_flags & GSS_C_DELEG_FLAG) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Can't initialize a context to both use SSL compatible " "context establishment and provide delegation"))); goto error_exit; } if(req_flags & GSS_C_DELEG_FLAG && target_name == GSS_C_NO_NAME) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Need a target name for authorization prior " "to doing delegation"))); goto error_exit; } if ((context == (gss_ctx_id_t) GSS_C_NO_CONTEXT) || !(context->ctx_flags & GSS_I_CTX_INITIALIZED)) { GLOBUS_I_GSI_GSSAPI_DEBUG_FPRINTF( 2, (globus_i_gsi_gssapi_debug_fstream, "Creating context w/ %s.\n", (initiator_cred_handle == GSS_C_NO_CREDENTIAL) ? "GSS_C_NO_CREDENTIAL" : "Credentials provided")); major_status = globus_i_gsi_gss_create_and_fill_context(&local_minor_status, &context, initiator_cred_handle, GSS_C_INITIATE, req_flags); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT); goto error_exit; } *context_handle_P = context; if (actual_mech_type != NULL) { *actual_mech_type = (gss_OID) gss_mech_globus_gssapi_openssl; } if (ret_flags != NULL) { *ret_flags = 0 ; } } else { /* first time there is no input token, but after that * there will always be one */ major_status = globus_i_gsi_gss_put_token(&local_minor_status, context, NULL, input_token); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_TOKEN_FAIL); goto error_exit; } } switch (context->gss_state) { case(GSS_CON_ST_HANDSHAKE): /* do the handshake work */ major_status = globus_i_gsi_gss_handshake(&local_minor_status, context); if (major_status == GSS_S_CONTINUE_NEEDED) { break; } if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_HANDSHAKE); context->gss_state = GSS_CON_ST_DONE; break; } /* make sure we are talking to the correct server */ major_status = globus_i_gsi_gss_retrieve_peer(&local_minor_status, context, GSS_C_INITIATE); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT); context->gss_state = GSS_CON_ST_DONE; break; } local_result = globus_gsi_callback_get_cert_type( context->callback_data, &cert_type); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA); major_status = GSS_S_FAILURE; goto error_exit; } /* * Need to check if the server is using a limited proxy. * And if that is acceptable here. * Caller tells us if it is not acceptable to * use a limited proxy. */ if ((context->req_flags & GSS_C_GLOBUS_DONT_ACCEPT_LIMITED_PROXY_FLAG) && GLOBUS_GSI_CERT_UTILS_IS_LIMITED_PROXY(cert_type)) { major_status = GSS_S_UNAUTHORIZED; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_PROXY_VIOLATION, (_GGSL("Function set to not accept limited proxies"))); context->gss_state = GSS_CON_ST_DONE; break; } /* this is the mutual authentication test */ if (target_name != NULL) { major_status = gss_compare_name(&local_minor_status, context->peer_cred_handle->globusid, target_name, &rc); if (GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_NAME); context->gss_state = GSS_CON_ST_DONE; break; } else if(rc == GSS_NAMES_NOT_EQUAL) { char * expected_name; char * actual_name; if(g_OID_equal(((gss_name_desc*) target_name)->name_oid, GSS_C_NT_HOSTBASED_SERVICE)) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_AUTHZ_DENIED, (_GGSL("The expected name for the remote host (%s%s%s) does not match the authenticated " "name of the remote host (%s%s%s). This happens when the name in the host certificate does not match the information obtained from DNS and is often a DNS configuration problem."), target_name->service_name ? target_name->service_name : "", target_name->service_name ? "@" : "", target_name->host_name ? target_name->host_name : "unknown", context->peer_cred_handle->globusid->service_name ? context->peer_cred_handle->globusid->service_name : "", context->peer_cred_handle->globusid->service_name ? "@" : "", context->peer_cred_handle->globusid->host_name ? context->peer_cred_handle->globusid->host_name : "unknown")); } else { expected_name = ((gss_name_desc*) target_name)->x509n_oneline; actual_name = ((gss_name_desc*) context->peer_cred_handle->globusid)->x509n_oneline; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_AUTHZ_DENIED, (_GGSL("The name of the remote entity (%s), and the expected " "name for the remote entity (%s) do not match"), actual_name, expected_name)); } major_status = GSS_S_UNAUTHORIZED; context->gss_state = GSS_CON_ST_DONE; break; } } context->ret_flags |= GSS_C_MUTUAL_FLAG; context->ret_flags |= GSS_C_PROT_READY_FLAG; context->ret_flags |= GSS_C_INTEG_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_ANON_FLAG | GSS_C_DELEG_FLAG; if (GLOBUS_GSI_CERT_UTILS_IS_LIMITED_PROXY(cert_type)) { context->ret_flags |= GSS_C_GLOBUS_RECEIVED_LIMITED_PROXY_FLAG; } # if LINK_WITH_INTERNAL_OPENSSL_API context->ret_flags |= GSS_C_TRANS_FLAG; # endif /* * IF we are talking to a real SSL server, * we don't want to do delegation, so we are done */ if (context->req_flags & GSS_C_GLOBUS_SSL_COMPATIBLE) { context->gss_state = GSS_CON_ST_DONE; break; } /* * If we have completed the handshake, but don't * have any more data to send, we can send the flag * now. i.e. fall through without break, * Otherwise, we will wait for the null byte * to get back in sync which we will ignore */ if (output_token->length != 0) { context->gss_state=GSS_CON_ST_FLAGS; break; } case(GSS_CON_ST_FLAGS): if (input_token->length > 0) { BIO_read(context->gss_sslbio, cbuf, 1); } /* send D if we want delegation, 0 otherwise */ if (context->req_flags & GSS_C_DELEG_FLAG) { BIO_write(context->gss_sslbio, "D", 1); context->gss_state = GSS_CON_ST_REQ; } else { BIO_write(context->gss_sslbio, "0", 1); context->gss_state = GSS_CON_ST_DONE; } break; case(GSS_CON_ST_REQ): local_result = globus_gsi_proxy_inquire_req( context->proxy_handle, context->gss_sslbio); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_PROXY_NOT_RECEIVED); major_status = GSS_S_FAILURE; context->gss_state = GSS_CON_ST_DONE; goto error_exit; } local_result = globus_gsi_cred_get_cert_type( context->cred_handle->cred_handle, &cert_type); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSI_CREDENTIAL); major_status = GSS_S_FAILURE; context->gss_state = GSS_CON_ST_DONE; goto error_exit; } local_result = globus_gsi_proxy_handle_set_type( context->proxy_handle, (context->req_flags & GSS_C_GLOBUS_DELEGATE_LIMITED_PROXY_FLAG) ? GLOBUS_GSI_CERT_UTILS_TYPE_LIMITED_PROXY : GLOBUS_GSI_CERT_UTILS_TYPE_IMPERSONATION_PROXY); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSI_PROXY); major_status = GSS_S_FAILURE; context->gss_state = GSS_CON_ST_DONE; goto exit; } local_result = globus_gsi_proxy_sign_req( context->proxy_handle, context->cred_handle->cred_handle, context->gss_sslbio); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSI_PROXY); major_status = GSS_S_FAILURE; context->gss_state = GSS_CON_ST_DONE; goto error_exit; } context->gss_state = GSS_CON_ST_DONE; break; case(GSS_CON_ST_CERT): ; case(GSS_CON_ST_DONE): ; } /* end of switch for gss_con_st */ local_major_status = globus_i_gsi_gss_get_token(&local_minor_status, context, NULL, output_token); if(GSS_ERROR(local_major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_TOKEN_FAIL); major_status = GSS_S_FAILURE; context->gss_state = GSS_CON_ST_DONE; goto error_exit; } /* some error occurred during switch */ if(GSS_ERROR(major_status)) { goto error_exit; } if (context->gss_state != GSS_CON_ST_DONE) { major_status |= GSS_S_CONTINUE_NEEDED; } else if(time_rec != NULL) { time_t lifetime; time_t current_time; major_status = globus_i_gsi_gss_get_context_goodtill( &local_minor_status, context, &lifetime); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT); goto exit; } current_time = time(NULL); if(current_time > lifetime) { *time_rec = 0; } else { *time_rec = (OM_uint32) (lifetime - current_time); } } if (ret_flags != NULL) { *ret_flags = context->ret_flags; } GLOBUS_I_GSI_GSSAPI_DEBUG_FPRINTF( 2, (globus_i_gsi_gssapi_debug_fstream, "init_sec_context:major_status:%08x" ":gss_state:%d req_flags=%08x:ret_flags=%08x\n", (unsigned int) major_status, context->gss_state, (unsigned int) req_flags, (unsigned int) context->ret_flags)); goto exit; error_exit: gss_delete_sec_context(&local_minor_status, (gss_ctx_id_t *) &context, output_token); *context_handle_P = (gss_ctx_id_t) context; exit: GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT; return major_status; }
int GSI_SOCKET_authentication_init(GSI_SOCKET *self, char *accepted_peer_names[]) { int token_status; gss_cred_id_t creds = GSS_C_NO_CREDENTIAL; gss_name_t server_gss_name = GSS_C_NO_NAME; OM_uint32 req_flags = 0, ret_flags = 0; int return_value = GSI_SOCKET_ERROR; gss_buffer_desc gss_buffer = { 0 }, tmp_gss_buffer = { 0 }; gss_name_t target_name = GSS_C_NO_NAME; gss_OID target_name_type = GSS_C_NO_OID; int i, rc=0, sock; FILE *fp = NULL; char *cert_dir = NULL; globus_result_t res; if (self == NULL) { return GSI_SOCKET_ERROR; } if (accepted_peer_names == NULL || accepted_peer_names[0] == NULL) { return GSI_SOCKET_ERROR; } if (self->gss_context != GSS_C_NO_CONTEXT) { GSI_SOCKET_set_error_string(self, "GSI_SOCKET already authenticated"); goto error; } res = GLOBUS_GSI_SYSCONFIG_GET_CERT_DIR(&cert_dir); if (res == GLOBUS_SUCCESS) { myproxy_debug("using trusted certificates directory %s", cert_dir); } else { verror_put_string("error getting trusted certificates directory"); globus_error_to_verror(res); goto error; } self->major_status = globus_gss_assist_acquire_cred(&self->minor_status, GSS_C_INITIATE, &creds); if (self->major_status != GSS_S_COMPLETE) { if (self->allow_anonymous) { req_flags |= GSS_C_ANON_FLAG; myproxy_debug("no valid credentials found -- " "performing anonymous authentication"); } else { goto error; } } req_flags |= GSS_C_REPLAY_FLAG; req_flags |= GSS_C_MUTUAL_FLAG; req_flags |= GSS_C_CONF_FLAG; req_flags |= GSS_C_INTEG_FLAG; if ((sock = dup(self->sock)) < 0) { GSI_SOCKET_set_error_string(self, "dup() of socket fd failed"); self->error_number = errno; goto error; } if ((fp = fdopen(sock, "r")) == NULL) { GSI_SOCKET_set_error_string(self, "fdopen() of socket failed"); self->error_number = errno; goto error; } if (setvbuf(fp, NULL, _IONBF, 0) != 0) { GSI_SOCKET_set_error_string(self, "setvbuf() for socket failed"); self->error_number = errno; goto error; } self->major_status = globus_gss_assist_init_sec_context(&self->minor_status, creds, &self->gss_context, "GSI-NO-TARGET", req_flags, &ret_flags, &token_status, globus_gss_assist_token_get_fd, (void *)fp, assist_write_token, (void *)&self->sock); if (self->major_status != GSS_S_COMPLETE) { goto error; } /* Verify that all service requests were honored. */ req_flags &= ~(GSS_C_ANON_FLAG); /* GSI GSSAPI doesn't set this flag */ if ((req_flags & ret_flags) != req_flags) { GSI_SOCKET_set_error_string(self, "requested GSSAPI service not supported"); goto error; } if (ret_flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG) { self->limited_proxy = 1; } /* Check the authenticated identity of the server. */ self->major_status = gss_inquire_context(&self->minor_status, self->gss_context, NULL, &server_gss_name, NULL, NULL, NULL, NULL, NULL); if (self->major_status != GSS_S_COMPLETE) { GSI_SOCKET_set_error_string(self, "gss_inquire_context() failed"); goto error; } self->major_status = gss_display_name(&self->minor_status, server_gss_name, &gss_buffer, NULL); if (self->major_status != GSS_S_COMPLETE) { GSI_SOCKET_set_error_string(self, "gss_display_name() failed"); goto error; } self->peer_name = strdup(gss_buffer.value); myproxy_debug("server name: %s", self->peer_name); myproxy_debug("checking that server name is acceptable..."); /* We told gss_assist_init_sec_context() not to check the server name so we can check it manually here. */ for (i=0; accepted_peer_names[i] != NULL; i++) { tmp_gss_buffer.value = (void *)accepted_peer_names[i]; tmp_gss_buffer.length = strlen(accepted_peer_names[i]); if (strchr(accepted_peer_names[i],'@') && !strstr(accepted_peer_names[i],"CN=")) { target_name_type = GSS_C_NT_HOSTBASED_SERVICE; } else { target_name_type = GSS_C_NO_OID; } self->major_status = gss_import_name(&self->minor_status, &tmp_gss_buffer, target_name_type, &target_name); if (self->major_status != GSS_S_COMPLETE) { char error_string[550]; sprintf(error_string, "failed to import GSS name \"%.500s\"", accepted_peer_names[i]); GSI_SOCKET_set_error_string(self, error_string); goto error; } self->major_status = gss_compare_name(&self->minor_status, server_gss_name, target_name, &rc); gss_release_name(&self->minor_status, &target_name); if (self->major_status != GSS_S_COMPLETE) { char error_string[1050]; sprintf(error_string, "gss_compare_name(\"%.500s\",\"%.500s\") failed", self->peer_name, accepted_peer_names[i]); GSI_SOCKET_set_error_string(self, error_string); goto error; } if (rc) { myproxy_debug("server name matches \"%s\"", accepted_peer_names[i]); break; } else { myproxy_debug("server name does not match \"%s\"", accepted_peer_names[i]); } } if (!rc) { /* no match with acceptable target names */ GSI_SOCKET_set_error_string(self, "authenticated peer name does not match"); return_value = GSI_SOCKET_UNAUTHORIZED; goto error; } myproxy_debug("authenticated server name is acceptable"); /* Success */ return_value = GSI_SOCKET_SUCCESS; error: { OM_uint32 minor_status; gss_release_cred(&minor_status, &creds); gss_release_buffer(&minor_status, &gss_buffer); gss_release_name(&minor_status, &server_gss_name); } if (cert_dir) free(cert_dir); if (fp) fclose(fp); return return_value; }
int gsslib_put_credentials(gss_cred_id_t server_creds, gss_buffer_desc *cred, char *username) { gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_buffer_desc client_name; OM_uint32 maj_stat, min_stat; GSSAPI_INT ret_flags; gss_buffer_desc send_tok; gss_name_t client = NULL; gss_OID doid; int cc=0; gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL; gsslib_reset_error(); send_tok.length = 0; client_name.length = 0; if (cred->length <= 0) { gsslib_print_error(MSG_GSS_PRINTERROR_CREDENTIALBUFFERLENGTHISZERO ); cc = -1; goto error; } /* * establish and forward client credentials */ maj_stat = gss_accept_sec_context(&min_stat, &context, server_creds, cred, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &send_tok, &ret_flags, NULL, /* ignore time_rec */ &delegated_cred); /* ignore del_cred_handle */ if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_ACCEPTINGCONTEXT, maj_stat, min_stat); cc = -1; goto error; } if (send_tok.length != 0) { fprintf(stderr, "%s\n", MSG_GSS_ACCEPTSECCONTEXTREQUIRESTOKENTOBESENTBACK ); /* cc = -1; goto error; */ } maj_stat = gss_display_name(&min_stat, client, &client_name, &doid); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_DISPLAYINGNAME, maj_stat, min_stat); cc = -1; goto error; } #ifdef KRBGSS #ifdef KRB5_EXPORTVAR /* this is required for later Kerberos versions */ /* check for delegated credential */ if (delegated_cred == GSS_C_NO_CREDENTIAL) { fprintf(stderr, "WARNING: Credentials were not forwarded\n"); #ifdef REQUIRE_FORWARDED_CREDENTIALS cc = 3; goto error; #endif } if (username && (ret_flags & GSS_C_DELEG_FLAG)) { char *principal = malloc(client_name.length + 1); strncpy(principal, client_name.value, client_name.length); principal[client_name.length] = 0; put_creds_in_ccache(principal, delegated_cred); free(principal); } #endif #endif /* display the flags */ if (verbose) gsslib_display_ctx_flags(ret_flags); if (verbose) printf("client: \"%.*s\"\n", (int) client_name.length, (char *) client_name.value); if (username) { gss_buffer_desc tok; gss_name_t user_name; int str_equal; tok.value = username; tok.length = strlen(tok.value)+1; maj_stat = gss_import_name(&min_stat, &tok, GSS_C_NULL_OID, &user_name); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_PARSINGNAME, maj_stat, min_stat); cc = -1; goto error; } maj_stat = gss_compare_name(&min_stat, client, user_name, &str_equal); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status( MSG_GSS_DISPLAYSTATUS_DISPLAYINGNAME, maj_stat, min_stat); cc = 6; goto error; } #ifdef KRBGSS if (!str_equal) { krb5_context context; maj_stat = krb5_init_context(&context); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_GETTINGKRB5CONTEXT, maj_stat, GSS_S_COMPLETE); cc = -1; goto error; } /* see if this user is authorized by the krb5 client */ if (krb5_kuserok(context, (krb5_principal)client, username)) str_equal = 1; } /* Users from Kerberos cross-authenticated realms will not match, so we manually compare the user names */ if (!str_equal) { char *s; if ((s=strchr((char *)client_name.value, '@'))) str_equal = !strncmp(username, (char *)client_name.value, s-(char *)client_name.value); } #endif if (!str_equal) { char buf[1024]; snprintf(buf, sizeof(buf), MSG_GSS_CLIENTNAMEXDOESNOTMATCHUNAMEY_SS, (int)client_name.length, (char *)client_name.value, username); gsslib_print_error(buf); cc = 5; goto error; } } #ifdef DCE while (delegated_cred) { sec_login_handle_t login_context; error_status_t st; dce_error_string_t err_string; int lst; sec_login_auth_src_t auth_src=NULL; boolean32 reset_passwd=0; char errbuf[1024]; unsigned32 num_groups=0; signed32 *groups=NULL; unsigned32 flags; maj_stat = gssdce_set_cred_context_ownership(&min_stat, delegated_cred, GSSDCE_C_OWNERSHIP_APPLICATION); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_GSSDCESETCREDCONTEXTOWNERSHIP, maj_stat, min_stat); break; } #if 0 gsslib_print_error(MSG_GSS_PRINTERROR_CREDENTIALDUMP); gsslib_print_error(dump_cred(delegated_cred)); #endif maj_stat = gssdce_cred_to_login_context(&min_stat, delegated_cred, &login_context); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_GSSDCECREDTOLOGINCONTEXT, maj_stat, min_stat); break; } #ifdef TURN_OFF_DELEGATION { sec_login_handle_t *new_login_context; new_login_context = sec_login_disable_delegation(login_context, &st); if (st != error_status_ok) { dce_error_inq_text(st, err_string, &lst); snprintf(errbuf, sizeof errbuf, MSG_GSS_PRINTERROR_COULDNOTDISABLEDELEGATIONX_S, err_string); gsslib_print_error(errbuf); } else { login_context = *new_login_context; } } #endif flags = sec_login_get_context_flags(login_context, &st); sec_login_set_context_flags(login_context, flags & ~sec_login_credentials_private, &st); if (!sec_login_certify_identity(login_context, &st)) { dce_error_inq_text(st, err_string, &lst); snprintf(errbuf, sizeof errbuf, MSG_GSS_PRINTERROR_COULDNOTCERTIFYIDENTITYX_S, err_string); gsslib_print_error(errbuf); break; } sec_login_set_context(login_context, &st); if (st != error_status_ok) { dce_error_inq_text(st, err_string, &lst); snprintf(errbuf, sizeof errbuf, MSG_GSS_PRINTERROR_COULDNOTSETUPLOGINCONTEXTX_S, err_string); gsslib_print_error(errbuf); break; } { char *cp; cp = getenv("KRB5CCNAME"); if (cp) { snprintf(errbuf, sizeof errbuf, MSG_GSS_PRINTERROR_NEWKRB5CCNAMEISX_S , cp); gsslib_print_error(errbuf); } else { gsslib_print_error(MSG_GSS_PRINTERROR_KRB5CCNAMENOTFOUND ); } } break; } #endif /* DCE */ error: if (client) { maj_stat = gss_release_name(&min_stat, &client); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_DISPLAYSTATUS_RELEASINGNAME, maj_stat, min_stat); cc = -1; } } if (send_tok.length) (void) gss_release_buffer(&min_stat, &send_tok); if (client_name.length) (void) gss_release_buffer(&min_stat, &client_name); return cc; }
static void copy_import(void) { gss_cred_id_t cred1, cred2; OM_uint32 maj_stat, min_stat; gss_name_t name1, name2; OM_uint32 lifetime1, lifetime2; gss_cred_usage_t usage1, usage2; gss_OID_set mechs1, mechs2; krb5_ccache id; krb5_error_code ret; krb5_context context; int equal; maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred1, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_acquire_cred"); maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1, &usage1, &mechs1); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); ret = krb5_init_context(&context); if (ret) errx(1, "krb5_init_context"); ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); if (ret) krb5_err(context, 1, ret, "krb5_cc_new_unique"); maj_stat = gss_krb5_copy_ccache(&min_stat, cred1, id); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_copy_ccache"); maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_import_cred"); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred 2"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); if (usage1 != usage2) { /* as long any of them is both are everything it ok */ if (usage1 != GSS_C_BOTH && usage2 != GSS_C_BOTH) errx(1, "usages disjoined"); } gss_release_name(&min_stat, &name2); gss_release_oid_set(&min_stat, &mechs2); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); gss_release_cred(&min_stat, &cred1); gss_release_cred(&min_stat, &cred2); gss_release_name(&min_stat, &name1); gss_release_name(&min_stat, &name2); #if 0 compare(mechs1, mechs2); #endif gss_release_oid_set(&min_stat, &mechs1); gss_release_oid_set(&min_stat, &mechs2); krb5_cc_destroy(context, id); krb5_free_context(context); }
int main(int argc, char * argv[]) { int rc = 0, c = 0, failed = 0; OM_uint32 major_status, minor_status; int name_equal; globus_list_t *i; compare_name_test_case_t * test_case; globus_module_descriptor_t *modules[] = { GLOBUS_COMMON_MODULE, GLOBUS_GSI_GSSAPI_MODULE, GLOBUS_GSI_CREDENTIAL_MODULE, NULL }, *failed_module = NULL; if (argc != 2) { fprintf(stderr, "%s test-case-file\n", argv[0]); exit(-1); } rc = globus_module_activate_array(modules, &failed_module); if (rc != 0) { exit(-1); } globus_l_gss_read_test_cases(argv[1]); import_names(); printf("1..%d\n", globus_list_size(test_cases)); for (i = test_cases; !globus_list_empty(i); i = globus_list_rest(i)) { test_case = globus_list_first(i); if ((!gss_l_host_ip_support) && (test_case->name_type1 == GSS_L_HOST_IP || test_case->name_type2 == GSS_L_HOST_IP)) { printf("ok %d # skip !gss_l_host_ip_support\n", ++c); fflush(stdout); continue; } if ((!gss_l_x509_support) && (test_case->name_type1 == GSS_L_X509 || test_case->name_type2 == GSS_L_X509)) { printf("ok %d # skip !gss_l_x509_support\n", ++c); fflush(stdout); continue; } rc = 0; major_status = gss_compare_name( &minor_status, test_case->name1, test_case->name2, &name_equal); if (GSS_ERROR(major_status)) { globus_gsi_gssapi_test_print_error( stderr, major_status, minor_status); rc = 1; } else if (name_equal != test_case->expectation) { globus_l_gss_test_print_name_error( stderr, test_case->name1, test_case->name_type1, test_case->name2, test_case->name_type2, test_case->expectation); rc = 2; } major_status = gss_compare_name( &minor_status, test_case->name2, test_case->name1, &name_equal); if (GSS_ERROR(major_status)) { globus_gsi_gssapi_test_print_error( stderr, major_status, minor_status); rc = 3; } else if (name_equal != test_case->expectation) { globus_l_gss_test_print_name_error( stderr, test_case->name2, test_case->name_type2, test_case->name1, test_case->name_type1, test_case->expectation); rc = 4; } c++; if (rc == 0) { printf("ok %s\n", test_case->test_name); } else { failed++; printf("not ok %d %s\n", c, test_case->test_name); } fflush(stdout); } globus_l_gss_free_test_cases(); return failed; }
bool Condor_Auth_X509::CheckServerName(char const *fqh,char const *ip,ReliSock *sock,CondorError *errstack) { if( param_boolean("GSI_SKIP_HOST_CHECK",false) ) { return true; } char const *server_dn = getAuthenticatedName(); if( !server_dn ) { std::string msg; formatstr(msg,"Failed to find certificate DN for server on GSI connection to %s",ip); errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str()); return false; } std::string skip_check_pattern; if( param(skip_check_pattern,"GSI_SKIP_HOST_CHECK_CERT_REGEX") ) { Regex re; const char *errptr=NULL; int erroffset=0; std::string full_pattern; formatstr(full_pattern,"^(%s)$",skip_check_pattern.c_str()); if( !re.compile(full_pattern.c_str(),&errptr,&erroffset) ) { dprintf(D_ALWAYS,"GSI_SKIP_HOST_CHECK_CERT_REGEX is not a valid regular expression: %s\n",skip_check_pattern.c_str()); return false; } if( re.match(server_dn,NULL) ) { return true; } } ASSERT( errstack ); ASSERT( m_gss_server_name ); ASSERT( ip ); if( !fqh || !fqh[0] ) { std::string msg; formatstr(msg,"Failed to look up server host address for GSI connection to server with IP %s and DN %s. Is DNS correctly configured? This server name check can be bypassed by making GSI_SKIP_HOST_CHECK_CERT_REGEX match the DN, or by disabling all hostname checks by setting GSI_SKIP_HOST_CHECK=true or defining GSI_DAEMON_NAME.",ip,server_dn); errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str()); return false; } std::string connect_name; gss_buffer_desc gss_connect_name_buf; gss_name_t gss_connect_name; OM_uint32 major_status = 0; OM_uint32 minor_status = 0; char const *connect_addr = sock->get_connect_addr(); std::string alias_buf; if( connect_addr ) { Sinful s(connect_addr); char const *alias = s.getAlias(); if( alias ) { dprintf(D_FULLDEBUG,"GSI host check: using host alias %s for %s %s\n",alias,fqh,sock->peer_ip_str()); alias_buf = alias; fqh = alias_buf.c_str(); } } formatstr(connect_name,"%s/%s",fqh,sock->peer_ip_str()); gss_connect_name_buf.value = strdup(connect_name.c_str()); gss_connect_name_buf.length = connect_name.size()+1; major_status = gss_import_name(&minor_status, &gss_connect_name_buf, GLOBUS_GSS_C_NT_HOST_IP, &gss_connect_name); free( gss_connect_name_buf.value ); if( major_status != GSS_S_COMPLETE ) { std::string comment; formatstr(comment,"Failed to create gss connection name data structure for %s.\n",connect_name.c_str()); print_log( major_status, minor_status, 0, comment.c_str() ); return false; } int name_equal = 0; major_status = gss_compare_name( &minor_status, m_gss_server_name, gss_connect_name, &name_equal ); gss_release_name( &major_status, &gss_connect_name ); if( !name_equal ) { std::string msg; formatstr(msg,"We are trying to connect to a daemon with certificate DN (%s), but the host name in the certificate does not match any DNS name associated with the host to which we are connecting (host name is '%s', IP is '%s', Condor connection address is '%s'). Check that DNS is correctly configured. If the certificate is for a DNS alias, configure HOST_ALIAS in the daemon's configuration. If you wish to use a daemon certificate that does not match the daemon's host name, make GSI_SKIP_HOST_CHECK_CERT_REGEX match the DN, or disable all host name checks by setting GSI_SKIP_HOST_CHECK=true or by defining GSI_DAEMON_NAME.\n", server_dn, fqh, ip, connect_addr ? connect_addr : sock->peer_description() ); errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str()); } return name_equal != 0; }
/* Privileged (called from accept_secure_ctx) */ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; int equal = 0; gss_name_t new_name = GSS_C_NO_NAME; gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; if (options.gss_store_rekey && client->used && ctx->client_creds) { if (client->mech->oid.length != ctx->oid->length || (memcmp(client->mech->oid.elements, ctx->oid->elements, ctx->oid->length) !=0)) { debug("Rekeyed credentials have different mechanism"); return GSS_S_COMPLETE; } if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ctx->client_creds, ctx->oid, &new_name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } ctx->major = gss_compare_name(&ctx->minor, client->name, new_name, &equal); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx); return (ctx->major); } if (!equal) { debug("Rekeyed credentials have different name"); return GSS_S_COMPLETE; } debug("Marking rekeyed credentials for export"); gss_release_name(&ctx->minor, &client->name); gss_release_cred(&ctx->minor, &client->creds); client->name = new_name; client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; return GSS_S_COMPLETE; } client->mech = NULL; while (supported_mechs[i]->name != NULL) { if (supported_mechs[i]->oid.length == ctx->oid->length && (memcmp(supported_mechs[i]->oid.elements, ctx->oid->elements, ctx->oid->length) == 0)) client->mech = supported_mechs[i]; i++; } if (client->mech == NULL) return GSS_S_FAILURE; if (ctx->client_creds && (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, &ename))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, &client->exportedname))) { return (ctx->major); } gss_release_buffer(&ctx->minor, &ename); /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; return (ctx->major); }
int main(int argc, char **argv) { gss_buffer_desc name_buffer; OM_uint32 maj_stat, min_stat; gss_name_t name, MNname, MNname2; int optidx = 0; char *str; int len, equal; setprogname(argv[0]); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag){ print_version(NULL); exit(0); } argc -= optidx; argv += optidx; gsskrb5_set_default_realm("MIT.EDU"); /* * test import/export */ str = NULL; len = asprintf(&str, "*****@*****.**"); if (len < 0 || str == NULL) errx(1, "asprintf"); name_buffer.value = str; name_buffer.length = len; maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_HOSTBASED_SERVICE, &name); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import name error"); free(str); maj_stat = gss_canonicalize_name (&min_stat, name, GSS_KRB5_MECHANISM, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "canonicalize name error"); maj_stat = gss_export_name(&min_stat, MNname, &name_buffer); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "export name error (KRB5)"); /* * Import the exported name and compare */ maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_EXPORT_NAME, &MNname2); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import name error (exported KRB5 name)"); maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); gss_release_name(&min_stat, &MNname2); gss_release_buffer(&min_stat, &name_buffer); gss_release_name(&min_stat, &MNname); gss_release_name(&min_stat, &name); /* * Import oid less name and compare to mech name. * Dovecot SASL lib does this. */ str = NULL; len = asprintf(&str, "lha"); if (len < 0 || str == NULL) errx(1, "asprintf"); name_buffer.value = str; name_buffer.length = len; maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NO_OID, &name); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import (no oid) name error"); maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_KRB5_NT_USER_NAME, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import (krb5 mn) name error"); free(str); maj_stat = gss_compare_name(&min_stat, name, MNname, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); gss_release_name(&min_stat, &MNname); gss_release_name(&min_stat, &name); #if 0 maj_stat = gss_canonicalize_name (&min_stat, name, GSS_SPNEGO_MECHANISM, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "canonicalize name error"); maj_stat = gss_export_name(&maj_stat, MNname, &name_buffer); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "export name error (SPNEGO)"); gss_release_name(&min_stat, &MNname); gss_release_buffer(&min_stat, &name_buffer); #endif return 0; }
int gfarmGssAcquireCredential(gss_cred_id_t *credPtr, const gss_name_t desiredName, gss_cred_usage_t credUsage, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr, gss_name_t *credNamePtr) { OM_uint32 majStat = 0; OM_uint32 minStat = 0; int ret = -1; gss_cred_id_t cred; *credPtr = GSS_C_NO_CREDENTIAL; majStat = gss_acquire_cred(&minStat, desiredName, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, credUsage, &cred, NULL, NULL); #if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS if (majStat != GSS_S_COMPLETE) { OM_uint32 majStat2, majStat3; OM_uint32 minStat2, minStat3; /* * to workaround a problem that any proxy credential cannot be * acquired by using "/C=.../O=.../CN=John Smith" as its name. * Globus requires "/C=.../O=.../CN=John Smith/CN=proxy". */ majStat2 = gss_acquire_cred(&minStat2, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, credUsage, &cred, NULL, NULL); if (majStat2 == GSS_S_COMPLETE) { gss_name_t credName; if (gfarmGssNewCredentialName(&credName, cred, NULL, NULL) > 0) { int equal; majStat3 = gss_compare_name(&minStat3, desiredName, credName, &equal); if (majStat3 == GSS_S_COMPLETE && equal) { majStat = majStat2; minStat = minStat2; } gfarmGssDeleteName(&credName, NULL, NULL); } if (majStat != GSS_S_COMPLETE) { gfarmGssDeleteCredential(&cred, NULL, NULL); } } } #endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */ /* * Check validness. */ if (majStat == GSS_S_COMPLETE) { if (credNamePtr == NULL) { ret = 1; } else if (gfarmGssNewCredentialName(credNamePtr, cred, &majStat, &minStat) > 0) { /* Only valid when the name is got. */ ret = 1; } if (ret > 0 && credPtr != NULL) { *credPtr = cred; } else { gfarmGssDeleteCredential(&cred, NULL, NULL); } } if (majStatPtr != NULL) { *majStatPtr = majStat; } if (minStatPtr != NULL) { *minStatPtr = minStat; } if (ret == -1) { gflog_debug(GFARM_MSG_1000790, "failed to acquire credential (%u)(%u)", majStat, minStat); } return ret; }
main(int argc,char *argv[]) { gss_name_t n1, n2, n3; gss_buffer_desc buf1, buf2, buf3; gss_buffer_t bp1, bp2, bp3; char s1[STRBUFSIZE], s2[STRBUFSIZE], s3[STRBUFSIZE]; gss_OID result_oid; OM_uint32 retcode,minor_status; int cmp_val; /* import all three names */ printf("test 1: gss_import_name():\n"); buf1.length=sizeof(NSTR1); buf1.value=NSTR1; retcode=gss_import_name(&minor_status,&buf1,NAMESPACE,&n1); ERRCHK(retcode,minor_status); printf("test 1: passed.\n\n"); printf("test 2: gss_import_name():\n"); buf2.length=sizeof(NSTR2); buf2.value=NSTR2; retcode=gss_import_name(&minor_status,&buf2,NAMESPACE,&n2); ERRCHK(retcode,minor_status); printf("test 2: passed.\n\n"); buf3.length=sizeof(NSTR3); buf3.value=NSTR3; retcode=gss_import_name(&minor_status,&buf3,NAMESPACE,&n3); ERRCHK(retcode,minor_status); printf("test 3: gss_display_name():\n"); buf1.length=STRBUFSIZE; buf1.value=s1; retcode=gss_display_name(&minor_status,n1,&buf1,&result_oid); ERRCHK(retcode,minor_status); printf("original name: [%s]\n\tcanonical name: [%s]\n", NSTR1,buf1.value); printf("test 3: passed.\n\n"); printf("test 4: gss_display_name():\n"); buf2.length=STRBUFSIZE; buf2.value=s2; retcode=gss_display_name(&minor_status,n2,&buf2,&result_oid); ERRCHK(retcode,minor_status); printf("original name: [%s]\n\tcanonical name: [%s]\n", NSTR2,buf2.value); printf("test 4: passed.\n\n"); printf("test 5: gss_display_name():\n"); buf3.length=STRBUFSIZE; buf3.value=s3; retcode=gss_display_name(&minor_status,n3,&buf3,&result_oid); ERRCHK(retcode,minor_status); printf("original name: [%s]\n\tcanonical name: [%s]\n", NSTR3,buf3.value); printf("test 5: passed.\n\n"); printf("test 6: gss_compare_name(): equality test:\n"); retcode=gss_compare_name(&minor_status,n1,n2,&cmp_val); ERRCHK(retcode,minor_status); if (!cmp_val) { printf("test 6: names should have compared equal, but didn't!\n"); exit(1); } printf("test 6: passed.\n\n"); printf("test 7: gss_compare_name(): inequality test:\n"); retcode=gss_compare_name(&minor_status,n1,n3,&cmp_val); ERRCHK(retcode,minor_status); if (cmp_val) { printf("test 7: gss_compare_name() returned TRUE for non-equivalent names!\n"); exit(1); } printf("test 7: passed.\n\n"); printf("%s: all tests passed.\n",argv[0]); return 0; }