Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}