Beispiel #1
0
gss_ctx_id_t initiate_context(gss_cred_id_t credential_handle, const char *server_name, int sck)
{
	OM_uint32	major_status = 0;
	OM_uint32	minor_status = 0;
	int		token_status = 0;
	OM_uint32	ret_flags = 0;
	gss_ctx_id_t	context_handle = GSS_C_NO_CONTEXT;

	major_status = globus_gss_assist_init_sec_context(
			&minor_status,
      			credential_handle,
			&context_handle,
			(char *) server_name,
			GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG |
			GSS_C_GLOBUS_ACCEPT_PROXY_SIGNED_BY_LIMITED_PROXY_FLAG,
			&ret_flags,
			&token_status,
			get_token,
			(void *) &sck,
			send_token,
			(void *) &sck);

	if (major_status != GSS_S_COMPLETE)
	{
		globus_gss_assist_display_status(stderr,
				"GSS Authentication failure: client\n ",
				major_status,
				minor_status,
				token_status);
		return(GSS_C_NO_CONTEXT); /* fail somehow */
	}
	return(context_handle);
}
Beispiel #2
0
static int auth_globus_assert(struct link *link, time_t stoptime)
{
	int rc;
	gss_cred_id_t credential = GSS_C_NO_CREDENTIAL;
	gss_ctx_id_t context = GSS_C_NO_CONTEXT;
	OM_uint32 major, minor, flags = 0;
	int token;
	char *reason = NULL;

	globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);

	if(use_delegated_credential && delegated_credential != GSS_C_NO_CREDENTIAL) {
		debug(D_AUTH, "globus: using delegated credential");
		credential = delegated_credential;
		major = GSS_S_COMPLETE;
	} else {
		debug(D_AUTH, "globus: loading my credentials");
		major = globus_gss_assist_acquire_cred(&minor, GSS_C_INITIATE, &credential);
	}

	if(major == GSS_S_COMPLETE) {
		debug(D_AUTH, "globus: waiting for server to get ready");
		if(auth_barrier(link, "yes\n", stoptime) == 0) {
			debug(D_AUTH, "globus: authenticating with server");
			major = globus_gss_assist_init_sec_context(&minor, credential, &context, "GSI-NO-TARGET", 0, &flags, &token, read_token, link, write_token, link);
			if(major == GSS_S_COMPLETE) {
				debug(D_AUTH, "globus: credentials accepted!");
				gss_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
			} else {
				globus_gss_assist_display_status_str(&reason, "", major, minor, token);
				debug(D_AUTH, "globus: credentials rejected: %s", reason ? reason : "unknown reason");
				THROW_QUIET(EACCES);
			}
		} else {
			debug(D_AUTH, "globus: server couldn't load credentials");
			THROW_QUIET(EACCES);
		}
	} else {
		debug(D_AUTH, "globus: couldn't load my credentials; did you grid-proxy-init?");
		auth_barrier(link, "no\n", stoptime);
		THROW_QUIET(EACCES);
	}

	rc = 0;
	goto out;
out:
	if(!use_delegated_credential) {
		gss_release_cred(&major, &credential);
	}
	globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE);
	free(reason);
	return RCUNIX(rc);
}
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 main(int argc, char * argv[])
{
    gss_cred_id_t                       init_cred = GSS_C_NO_CREDENTIAL;
    OM_uint32                           major_status;
    OM_uint32                           minor_status;
    int                                 token_status;
    gss_ctx_id_t                        init_context = GSS_C_NO_CONTEXT;
    OM_uint32                           ret_flags;
    int                                 sock;
    FILE *                              infd;
    FILE *                              outfd;
    char *                              print_buffer = NULL;
    char *                              recv_buffer = NULL;
    size_t                              buffer_length;
    struct sockaddr_in                  sockaddr;
    struct hostent *                    hostname;
    char *                              verbose_env = NULL;

    globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);

    verbose_env = getenv("GSS_ASSIST_VERBOSE_TEST");

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        perror("opening stream socket");
        exit(1);
    }
    
    sockaddr.sin_family = AF_INET;

    hostname = gethostbyname(argv[1]);
    if(hostname == 0)
    {
        fprintf(stdout, "%s: uknown host", argv[1]);
        exit(2);
    }

    bcopy(hostname->h_addr, &sockaddr.sin_addr, hostname->h_length);
    sockaddr.sin_port = htons(atoi(argv[2]));

    if(connect(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr)) < 0)
    {
        perror("connecting stream socket");
        exit(1);
    }

    infd = fdopen(dup(sock), "r");
    setbuf(infd, NULL);

    outfd = fdopen(dup(sock), "w");
    setbuf(outfd, NULL);
    
    close(sock);

    /* INITIATOR PROCESS */
    
    major_status = globus_gss_assist_acquire_cred(&minor_status,
                                                  GSS_C_INITIATE,
                                                  &init_cred);
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't acquire initiator's credentials",
            major_status,
            minor_status,
            0);
        exit(1);
    }

    major_status = globus_gss_assist_init_sec_context(
        &minor_status,
        init_cred,
        &init_context,
        NULL,
        GSS_C_MUTUAL_FLAG|GSS_C_DELEG_FLAG,
        &ret_flags,
        &token_status,
        globus_gss_assist_token_get_fd,
        (void *) (infd),
        globus_gss_assist_token_send_fd,
        (void *) (outfd));
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't authenticate as initiator\n",
            major_status,
            minor_status,
            token_status);
        exit(1);
    }
    
    if(verbose_env)
    {
        fprintf(stdout, 
                "INITIATOR: "__FILE__":%d"
                ": Initiator successfully created context\n", __LINE__);
    }

    major_status = globus_gss_assist_wrap_send(
        &minor_status,
        init_context,
        init_message,
        sizeof(init_message),
        &token_status,
        globus_gss_assist_token_send_fd,
        (void *) (outfd),
        stdout);
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
            stdout,
            "INITATOR: Couldn't wrap and send message\n",
            major_status,
            minor_status,
            token_status);
        exit(1);
    }
    
    major_status = globus_gss_assist_get_unwrap(
        &minor_status,
        init_context,
        &recv_buffer,
        &buffer_length,
        &token_status,
        globus_gss_assist_token_get_fd,
        (void *) (infd),
        stdout);
    if(GSS_ERROR(major_status))
    {
        fprintf(stdout, "INITIATOR ERROR\n");
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't get encrypted message from initiator\n",
            major_status,
            minor_status,
            token_status);
        fprintf(stdout, "INITIATOR ERROR FINISHED\n");
        exit(1);
    }

    print_buffer = malloc(buffer_length + 1);
    globus_libc_snprintf(print_buffer, buffer_length + 1, "%s", recv_buffer);
    
    if(verbose_env)
    {
        fprintf(stdout,
                "INITIATOR: "__FILE__":%d"
                ": received: %s\n", __LINE__, print_buffer);
    }

    free(print_buffer);
    free(recv_buffer);

    major_status = globus_gss_assist_wrap_send(
        &minor_status,
        init_context,
        init_message,
        sizeof(init_message),
        &token_status,
        globus_gss_assist_token_send_fd,
        (void *) (outfd),
        stdout);
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
            stdout,
            "INITATOR: Couldn't wrap and send message\n",
            major_status,
            minor_status,
            token_status);
        exit(1);
    }

    major_status = globus_gss_assist_get_unwrap(
        &minor_status,
        init_context,
        &recv_buffer,
        &buffer_length,
        &token_status,
        globus_gss_assist_token_get_fd,
        (void *) (infd),
        stdout);
    if(GSS_ERROR(major_status))
    {
        fprintf(stdout, "INITIATOR ERROR\n");
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't get encrypted message from initiator\n",
            major_status,
            minor_status,
            token_status);
        fprintf(stdout, "INITIATOR ERROR FINISHED\n");
        exit(1);
    }
    
    print_buffer = malloc(buffer_length + 1);
    globus_libc_snprintf(print_buffer, buffer_length + 1, "%s", recv_buffer);
    
    if(verbose_env)
    {
        fprintf(stdout,
                "INITIATOR: "__FILE__":%d"
                ": received: %s\n", __LINE__, print_buffer);
    }

    free(print_buffer);
    free(recv_buffer);

    major_status = gss_delete_sec_context(&minor_status,
                                          &init_context,
                                          GSS_C_NO_BUFFER);
    if(major_status != GSS_S_COMPLETE)
    {
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't delete security context\n",
            major_status,
            minor_status,
            0);
        exit(1);
    }
            
    gss_release_cred(&minor_status,
                     &init_cred);
    if(major_status != GSS_S_COMPLETE)
    {
        globus_gss_assist_display_status(
            stdout,
            "INITIATOR: Couldn't delete security context\n",
            major_status,
            minor_status,
            0);
        exit(1);
    }

    if(fclose(infd) == EOF)
    {
        perror("closing stream socket");
        exit(1);
    }

    if(fclose(outfd) == EOF)
    {
        perror("closing stream socket");
        exit(1);
    }
    globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE);
    
    exit(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;
}
Beispiel #6
0
/**
 * Initialize GSI Authentication.
 * This method asks the server for authentication.
 * @param sock the socket descriptot
 * @return true on success, false otherwise.
 */
bool GSISocketClient::InitGSIAuthentication(int sock)
{
	OM_uint32                   major_status = 0;
	OM_uint32                   minor_status = 0;
	gss_cred_id_t               credential = GSS_C_NO_CREDENTIAL;
	OM_uint32                   req_flags  = 0;
	OM_uint32                   ret_flags  = 0;
	int                         token_status = 0;
	bool                        return_status = false;
	gss_name_t                  targ_name;
	gss_buffer_desc             name_buffer;
	char                        service[1024];
      
	//acquire our credentials 
	major_status = globus_gss_assist_acquire_cred(&minor_status,
                                                  GSS_C_BOTH,
                                                  &credential);
	if(major_status != GSS_S_COMPLETE) 
	{
		char buf[32];
		std::string msg(FAILED_ACQ_CRED);
		sprintf(buf, "%d", port);
		msg.append(host + ":" + std::string(buf));
		char *gssmsg = NULL;
		globus_gss_assist_display_status_str( &gssmsg,
					    NULL,
					    major_status,
					    minor_status,
					    token_status);
		std::string source(gssmsg);
		free(gssmsg);
		return false;
	}
    	//Request that remote peer authenticate tself
	req_flags = GSS_C_MUTUAL_FLAG;   
	if(_delegate_credentials) 
	{
		req_flags |= GSS_C_DELEG_FLAG; 
	} 
	snprintf(service, sizeof(service), "host@%s", host.c_str());
	//initialize the security context
    	// credential has to be fill in beforehand 
	std::pair<int,int> arg(sock, m_auth_timeout);
	major_status =
        	globus_gss_assist_init_sec_context(&minor_status,
                                           credential,
                                           &gss_context,
                                           _server_contact.empty() ? service :(char*) _server_contact.c_str(), 
                                           req_flags,
                                           &ret_flags,
                                           &token_status,
                                           get_token,
                                           (void *) &arg,
                                           send_token,
                                           (void *) &arg);
	gss_release_cred(&minor_status, &credential);
	if(major_status != GSS_S_COMPLETE)
	{
		char *gssmsg = NULL;
		globus_gss_assist_display_status_str(&gssmsg,
					   NULL,
					   major_status,
					   minor_status,
					   token_status);
		if(gss_context != GSS_C_NO_CONTEXT) 
		{
			gss_delete_sec_context(&minor_status, &gss_context, GSS_C_NO_BUFFER);
		}
		std::string source(gssmsg);
		free(gssmsg);
		return_status = false;		
	}
	else
	{
		major_status = gss_inquire_context(&minor_status,
					 gss_context,
					 NULL,
					 &targ_name,
					 NULL,
					 NULL,
					 NULL,
					 NULL,
					 NULL);
		return_status = (major_status == GSS_S_COMPLETE); 
		major_status = gss_display_name(&minor_status, targ_name, &name_buffer, NULL);
		gss_release_name(&minor_status, &targ_name);
	}
	if (return_status == false && gss_context != GSS_C_NO_CONTEXT) 
	{
		gss_delete_sec_context(&minor_status, &gss_context, GSS_C_NO_BUFFER);
	}
	if (return_status == false) 
	{
		char *gssmsg = NULL;
		globus_gss_assist_display_status_str( &gssmsg,
			NULL,
			major_status,
			minor_status,
			token_status);
		std::string source(gssmsg);
		free(gssmsg);
	}
	return return_status;
}