int Condor_Auth_X509::authenticate_client_gss(CondorError* errstack) { OM_uint32 major_status = 0; OM_uint32 minor_status = 0; int status = 0; priv_state priv = PRIV_UNKNOWN; if (isDaemon()) { priv = set_root_priv(); } char target_str[] = "GSI-NO-TARGET"; major_status = globus_gss_assist_init_sec_context(&minor_status, credential_handle, &context_handle, target_str, GSS_C_MUTUAL_FLAG, &ret_flags, &token_status, relisock_gsi_get, (void *) mySock_, relisock_gsi_put, (void *) mySock_ ); if (isDaemon()) { set_priv(priv); } if (major_status != GSS_S_COMPLETE) { if (major_status == 655360 && minor_status == 6) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u). " "This indicates that it was unable to find the issuer " "certificate for your credential", (unsigned)major_status, (unsigned)minor_status); } else if (major_status == 655360 && minor_status == 9) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u). " "This indicates that it was unable to verify the server's " "credential", (unsigned)major_status, (unsigned)minor_status); } else if (major_status == 655360 && minor_status == 11) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u). " "This indicates that it was unable verify the server's " "credentials because a signing policy file was not found or " "could not be read.", (unsigned)major_status, (unsigned)minor_status); } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } print_log(major_status,minor_status,token_status, "Condor GSI authentication failure"); // Following four lines of code is added to temporarily // resolve a bug (I belive so) in Globus's GSI code. // basically, if client calls init_sec_context with // mutual authentication and it returns with a mismatched // target principal, init_sec_context will return without // sending the server any token. The sever, therefore, // hangs on waiting for the token (or until the timeout // occurs). This code will force the server to break out // the loop. status = 0; mySock_->encode(); mySock_->code(status); mySock_->end_of_message(); } else { // Now, wait for final signal mySock_->decode(); if (!mySock_->code(status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with server. Unable to receive server status"); dprintf(D_SECURITY, "Unable to receive final confirmation for GSI Authentication!\n"); } if (status == 0) { errstack->push("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to get authorization from server. Either the server " "does not trust your certificate, or you are not in the server's " "authorization file (grid-mapfile)"); dprintf(D_SECURITY, "Server is unable to authorize my user name. Check the GRIDMAP file on the server side.\n"); goto clear; } char * server = get_server_info(); // store the raw subject name for later mapping setAuthenticatedName(server); // Default to user name "gsi@unmapped". // Later on, if configured, we will invoke the callout in nameGssToLocal. setRemoteUser("gsi"); setRemoteDomain( UNMAPPED_DOMAIN ); // extract and store VOMS attributes if (param_boolean("USE_VOMS_ATTRIBUTES", true)) { // get the voms attributes from the peer globus_gsi_cred_handle_t peer_cred = context_handle->peer_cred_handle->cred_handle; char * voms_fqan = NULL; int voms_err = extract_VOMS_info(peer_cred, 1, NULL, NULL, &voms_fqan); if (!voms_err) { setFQAN(voms_fqan); free(voms_fqan); } else { // complain! dprintf(D_SECURITY, "ZKM: VOMS FQAN not present (error %i), ignoring.\n", voms_err); } } std::string fqh = get_full_hostname(mySock_->peer_addr()); StringList * daemonNames = getDaemonList("GSI_DAEMON_NAME",fqh.c_str()); // Now, let's see if the name is in the list, I am not using // anycase here, so if the host name and what we are looking for // are in different cases, then we will run into problems. if( daemonNames ) { status = daemonNames->contains_withwildcard(server) == TRUE? 1 : 0; if( !status ) { errstack->pushf("GSI", GSI_ERR_UNAUTHORIZED_SERVER, "Failed to authenticate because the subject '%s' is not currently trusted by you. " "If it should be, add it to GSI_DAEMON_NAME or undefine GSI_DAEMON_NAME.", server); dprintf(D_SECURITY, "GSI_DAEMON_NAME is defined and the server %s is not specified in the GSI_DAEMON_NAME parameter\n", server); } } else { status = CheckServerName(fqh.c_str(),mySock_->peer_ip_str(),mySock_,errstack); } if (status) { dprintf(D_SECURITY, "valid GSS connection established to %s\n", server); } mySock_->encode(); if (!mySock_->code(status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with server. Unable to send status"); dprintf(D_SECURITY, "Unable to mutually authenticate with server!\n"); status = 0; } delete [] server; delete daemonNames; } clear: return (status == 0) ? FALSE : TRUE; }
int Condor_Auth_X509::authenticate_server_gss(CondorError* errstack) { char * GSSClientname; int status = 0; OM_uint32 major_status = 0; OM_uint32 minor_status = 0; priv_state priv; priv = set_root_priv(); major_status = globus_gss_assist_accept_sec_context(&minor_status, &context_handle, credential_handle, &GSSClientname, &ret_flags, NULL, /* don't need user_to_user */ &token_status, NULL, /* don't delegate credential */ relisock_gsi_get, (void *) mySock_, relisock_gsi_put, (void *) mySock_ ); set_priv(priv); if ( (major_status != GSS_S_COMPLETE)) { if (major_status == 655360) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "COMMON Failed to authenticate (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } print_log(major_status,minor_status,token_status, "Condor GSI authentication failure" ); } else { // store the raw subject name for later mapping setAuthenticatedName(GSSClientname); setRemoteUser("gsi"); setRemoteDomain( UNMAPPED_DOMAIN ); if (param_boolean("USE_VOMS_ATTRIBUTES", true)) { // get the voms attributes from the peer globus_gsi_cred_handle_t peer_cred = context_handle->peer_cred_handle->cred_handle; char * voms_fqan = NULL; int voms_err = extract_VOMS_info(peer_cred, 1, NULL, NULL, &voms_fqan); if (!voms_err) { setFQAN(voms_fqan); free(voms_fqan); } else { // complain! dprintf(D_SECURITY, "ZKM: VOMS FQAN not present (error %i), ignoring.\n", voms_err); } } // XXX FIXME ZKM // i am making failure to be mapped a non-fatal error at this point. status = 1; mySock_->encode(); if (!mySock_->code(status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with client. Unable to send status"); dprintf(D_SECURITY, "Unable to send final confirmation\n"); status = 0; } if (status != 0) { // Now, see if client likes me or not mySock_->decode(); if (!mySock_->code(status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with client. Unable to receive status"); dprintf(D_SECURITY, "Unable to receive client confirmation.\n"); status = 0; } else { if (status == 0) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with client. Client does not trust our certificate. " "You may want to check the GSI_DAEMON_NAME in the condor_config"); dprintf(D_SECURITY, "Client rejected my certificate. Please check the GSI_DAEMON_NAME parameter in Condor's config file.\n"); } } } if (GSSClientname) { free(GSSClientname); } } return (status == 0) ? FALSE : TRUE; }
Condor_Auth_X509::CondorAuthX509Retval Condor_Auth_X509::authenticate_server_gss(CondorError* errstack, bool non_blocking) { OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 minor_status = 0; OM_uint32 time_req; gss_buffer_desc output_token_desc = GSS_C_EMPTY_BUFFER; gss_buffer_t output_token = &output_token_desc; gss_buffer_desc input_token_desc; gss_buffer_t input_token; if ( !m_globusActivated ) { errstack->push("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to load Globus libraries."); return Fail; } m_state = GSSAuth; do { if (non_blocking && !mySock_->readReady()) { dprintf(D_NETWORK, "Returning to DC as read would block.\n"); return WouldBlock; } input_token_desc.length = 0; input_token_desc.value = NULL; input_token = &input_token_desc; if ((token_status = relisock_gsi_get( mySock_, &input_token->value, &input_token->length)) != 0) { major_status = GSS_S_DEFECTIVE_TOKEN | GSS_S_CALL_INACCESSIBLE_READ; break; } dprintf(D_NETWORK, "gss_assist_accept_sec_context(1):inlen:%lu\n", static_cast<unsigned long>(input_token->length)); major_status = (*gss_accept_sec_context_ptr)( &minor_status, &context_handle, credential_handle, input_token, GSS_C_NO_CHANNEL_BINDINGS, &m_client_name, NULL, output_token, &ret_flags, &time_req, NULL); dprintf(D_NETWORK, "gss_assist_accept_sec_context(2)" "maj:%8.8x:min:%8.8x:ret:%8.8x " "outlen:%lu:context:%p\n", (unsigned int) major_status, (unsigned int) minor_status, (unsigned int) ret_flags, output_token->length, context_handle); if (output_token->length != 0) { if ((token_status = relisock_gsi_put( mySock_, output_token->value, output_token->length)) != 0) { major_status = GSS_S_DEFECTIVE_TOKEN | GSS_S_CALL_INACCESSIBLE_WRITE; } (*gss_release_buffer_ptr)(&minor_status, output_token); } if (GSS_ERROR(major_status)) { if (context_handle != GSS_C_NO_CONTEXT) { (*gss_delete_sec_context_ptr)(&minor_status, &context_handle, GSS_C_NO_BUFFER); } break; } if (input_token->length >0) { free(input_token->value); input_token->length = 0; } } while (major_status & GSS_S_CONTINUE_NEEDED); if (input_token->length >0) { free(input_token->value); input_token->length = 0; } m_status = 0; if ( (major_status != GSS_S_COMPLETE)) { if (major_status == 655360) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "COMMON Failed to authenticate (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } print_log(major_status,minor_status,token_status, "Condor GSI authentication failure" ); } else { gss_buffer_desc tmp_buffer_desc = GSS_C_EMPTY_BUFFER; gss_buffer_t tmp_buffer = &tmp_buffer_desc; char * gss_name = NULL; major_status = (*gss_display_name_ptr)(&minor_status, m_client_name, tmp_buffer, NULL); if (major_status == GSS_S_COMPLETE) { gss_name = (char *)malloc(tmp_buffer->length+1); if (gss_name) { memcpy(gss_name, tmp_buffer->value, tmp_buffer->length); gss_name[tmp_buffer->length] = '\0'; } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Unable to allocate buffer"); major_status = GSS_S_FAILURE; } } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Unable to determine remote client name. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } (*gss_release_buffer_ptr)(&minor_status, tmp_buffer); // store the raw subject name for later mapping if (gss_name) { setAuthenticatedName(gss_name); free(gss_name); } setRemoteUser("gsi"); setRemoteDomain( UNMAPPED_DOMAIN ); if (param_boolean("USE_VOMS_ATTRIBUTES", true)) { // get the voms attributes from the peer globus_gsi_cred_handle_t peer_cred = context_handle->peer_cred_handle->cred_handle; char * voms_fqan = NULL; int voms_err = extract_VOMS_info(peer_cred, 1, NULL, NULL, &voms_fqan); if (!voms_err) { setFQAN(voms_fqan); free(voms_fqan); } else { // complain! dprintf(D_SECURITY, "ZKM: VOMS FQAN not present (error %i), ignoring.\n", voms_err); } } // XXX FIXME ZKM // i am making failure to be mapped a non-fatal error at this point. m_status = (major_status == GSS_S_COMPLETE); mySock_->encode(); if (!mySock_->code(m_status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with client. Unable to send status"); dprintf(D_SECURITY, "Unable to send final confirmation\n"); m_status = 0; } } m_state = GetClientPost; return (m_status == 0) ? Fail : Continue; }