int
GSI_SOCKET_delegation_accept(GSI_SOCKET *self,
			     unsigned char **delegated_credentials,
			     int *delegated_credentials_len,
			     char *passphrase)
{
    int			return_value = GSI_SOCKET_ERROR;
    SSL_CREDENTIALS	*creds = NULL;
    unsigned char	*output_buffer = NULL;
    int			output_buffer_len;
    unsigned char	*input_buffer = NULL;
    size_t		input_buffer_len;
    unsigned char	*fmsg;
    int                 i;
    
    if (self == NULL)
    {	
	return GSI_SOCKET_ERROR;
    }

    if ((delegated_credentials == NULL) ||
	(delegated_credentials_len == 0))
    {
	self->error_number = EINVAL;
	goto error;
    }
    
    if (self->gss_context == GSS_C_NO_CONTEXT)
    {
	GSI_SOCKET_set_error_string(self, "GSI_SOCKET not authenticated");
	return GSI_SOCKET_ERROR;
    }

    if (self->certreq) {

        creds = ssl_credentials_new();
        if (ssl_certreq_pem_to_der(self->certreq, &output_buffer,
                                   &output_buffer_len) == SSL_ERROR) {
            GSI_SOCKET_set_error_from_verror(self);
            goto error;
        }
        
    } else {

    /* Generate proxy certificate request and send */
    if (ssl_proxy_delegation_init(&creds, &output_buffer, &output_buffer_len,
				  0 /* default number of bits */,
				  NULL /* No callback */) == SSL_ERROR)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }
    
    }

    if (GSI_SOCKET_write_buffer(self, (const char *)output_buffer,
				output_buffer_len) == GSI_SOCKET_ERROR)
    {
	goto error;
    }
    
    /* Now read the signed certificate */
    if (GSI_SOCKET_read_token(self, &input_buffer,
			      &input_buffer_len) == GSI_SOCKET_ERROR)
    {
	goto error;
    }

    /* HACK: We may get just an error message rather than a cert... */
    if (strncmp((const char *)input_buffer, "VERSION",
                strlen("VERSION")) == 0) {
        myproxy_response_t *response;
        response = malloc(sizeof(*response));
        memset(response, 0, sizeof(*response));
        myproxy_handle_response((const char *)input_buffer, 
                                input_buffer_len,
                                response);
        myproxy_free(NULL, NULL, response);
        GSI_SOCKET_set_error_string(self,
                                    "server-side error: check server logs");
        goto error;
    }

    /* MAJOR HACK:
       We don't have application-level framing in our protocol.
       We can't separate the certificate chain easily from
       the final protocol message, so just discard it. */
    fmsg = input_buffer;
    for (i=0; i < input_buffer_len-strlen("VERSION"); i++, fmsg++) {
	if (strncmp((const char *)fmsg, "VERSION", strlen("VERSION")) == 0) {
	    input_buffer_len = fmsg-input_buffer;
	    break;
	}
    }
    
    if (ssl_proxy_delegation_finalize(creds, input_buffer,
				      input_buffer_len) == SSL_ERROR)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }
    
    if (passphrase && passphrase[0] == '\0') {
	passphrase = NULL;
    }
    if (ssl_proxy_to_pem(creds, delegated_credentials,
			 delegated_credentials_len, passphrase) == SSL_ERROR)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }
    
    /* Success */
    return_value = GSI_SOCKET_SUCCESS;
    
  error:
    if (creds != NULL)
    {
	ssl_credentials_destroy(creds);
    }
    
    if (input_buffer != NULL)
    {
	GSI_SOCKET_free_token(input_buffer);
    }
    
    if (output_buffer != NULL)
    {
	ssl_free_buffer(output_buffer);
    }

    return return_value;
}
예제 #2
0
CK_RV
get_myproxy_creds(char *server, char *username, char *password,
                  char **creds)
{
    myproxy_socket_attrs_t *socket_attrs = NULL;
    myproxy_request_t      *client_request = NULL;
    myproxy_response_t     *server_response = NULL;
    char *request_buffer = NULL;
    char creds_file[MAXPATHLEN];
    int ret, requestlen;

    verror_clear();

    socket_attrs = malloc(sizeof(*socket_attrs));
    if (socket_attrs == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto end;
    }
    memset(socket_attrs, 0, sizeof(*socket_attrs));

    client_request = malloc(sizeof(*client_request));
    if (client_request == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto end;
    }
    memset(client_request, 0, sizeof(*client_request));

    server_response = malloc(sizeof(*server_response));
    if (server_response == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto end;
    }
    memset(server_response, 0, sizeof(*server_response));

    socket_attrs->psport = MYPROXY_SERVER_PORT;
    socket_attrs->pshost = strdup(server);
    if (socket_attrs->pshost == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto end;
    }

    ret = myproxy_init_client(socket_attrs);
    if (ret < 0) {
	gpkcs11_log("Error contacting MyProxy server %s: %s\n",
		    socket_attrs->pshost, verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    GSI_SOCKET_allow_anonymous(socket_attrs->gsi_socket, 1);
    ret = myproxy_authenticate_init(socket_attrs, NULL);
    if (ret < 0) {
	gpkcs11_log("Error authenticating MyProxy server %s: %s\n",
		    socket_attrs->pshost, verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    client_request->version = strdup(MYPROXY_VERSION);
    client_request->command_type = MYPROXY_RETRIEVE_CERT;
    strncpy(client_request->passphrase, password, sizeof(client_request->passphrase));
    client_request->username = strdup(username);

    requestlen = myproxy_serialize_request_ex(client_request, &request_buffer);
    if (requestlen < 0) {
	gpkcs11_log("Error preparing MyProxy request: %s\n",
		    verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    ret = myproxy_send(socket_attrs, request_buffer, requestlen);
    free(request_buffer);
    if (ret < 0) {
	gpkcs11_log("Error sending MyProxy request: %s\n",
		    verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    ret = myproxy_recv_response_ex(socket_attrs, server_response,
				   client_request);
    if (ret != 0) {
	gpkcs11_log("Error receiving MyProxy response: %s\n",
		    verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    ret = myproxy_accept_credentials(socket_attrs, creds_file,
				     sizeof(creds_file));
    if (ret < 0) {
	gpkcs11_log("Error receiving credentials: %s\n",
		    verror_get_string());
	ret = CKR_GENERAL_ERROR;
	goto end;
    }

    *creds = strdup(creds_file);
    if (*creds == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto end;
    }

    ret = 0;

end:
    if (socket_attrs && socket_attrs->socket_fd)
	close(socket_attrs->socket_fd);
    myproxy_free(socket_attrs, client_request, server_response);
    verror_clear();

    return ret;
}
int GSI_SOCKET_delegation_init_ext(GSI_SOCKET *self,
				   const char *source_credentials,
				   int lifetime,
				   const char *passphrase)
{
    int				return_value = GSI_SOCKET_ERROR;
    SSL_CREDENTIALS		*creds = NULL;
    SSL_PROXY_RESTRICTIONS	*proxy_restrictions = NULL;
    unsigned char		*input_buffer = NULL;
    size_t			input_buffer_length;
    unsigned char		*output_buffer = NULL;
    int				output_buffer_length;
    

    if (self == NULL)
    {
	goto error;
    }

    if (self->gss_context == GSS_C_NO_CONTEXT)
    {
	GSI_SOCKET_set_error_string(self, "GSI_SOCKET not authenticated");
	goto error;
    }

    /*
     * Load proxy we are going to use to sign delegation
     */
    creds = ssl_credentials_new();
    
    if (creds == NULL)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }
    
    if (passphrase && passphrase[0] == '\0') {
	passphrase = NULL;
    }

    if (ssl_proxy_load_from_file(creds, source_credentials,
				 passphrase) == SSL_ERROR)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }

    /*
     * Read the certificate request from the client
     */
    if (GSI_SOCKET_read_token(self, &input_buffer,
			      &input_buffer_length) == GSI_SOCKET_ERROR)
    {
	goto error;
    }

    /* HACK: We may get an error message rather than a certreq... */
    if (strncmp((const char *)input_buffer, "VERSION",
                strlen("VERSION")) == 0) {
        myproxy_response_t *response;
        response = malloc(sizeof(*response));
        memset(response, 0, sizeof(*response));
        myproxy_handle_response((const char *)input_buffer, 
                                input_buffer_length,
                                response);
        myproxy_free(NULL, NULL, response);
        GSI_SOCKET_set_error_string(self, "server-side error: check server logs");
        goto error;
    }

    /*
     * Set up the restrictions on the proxy
     */
    proxy_restrictions = ssl_proxy_restrictions_new();
    
    if (proxy_restrictions == NULL)
    {
	goto error;
    }

    if (ssl_proxy_restrictions_set_lifetime(proxy_restrictions,
					    (long) lifetime) == SSL_ERROR)
    {
	goto error;
    }
   
    if (GSI_SOCKET_peer_used_limited_proxy(self)) {
        ssl_proxy_restrictions_set_limited(proxy_restrictions, 1);
    }

    /*
     * Sign the request
     */
    if (ssl_proxy_delegation_sign(creds,
				  proxy_restrictions,
				  input_buffer,
				  input_buffer_length,
				  &output_buffer,
				  &output_buffer_length) == SSL_ERROR)
    {
	GSI_SOCKET_set_error_from_verror(self);
	goto error;
    }

    /*
     * Write the proxy certificate back to user
     */
    if (GSI_SOCKET_write_buffer(self,
				(const char *)output_buffer,
				output_buffer_length) == GSI_SOCKET_ERROR)
    {
	goto error;
    }

    /* Success */
    return_value = GSI_SOCKET_SUCCESS;
    
  error:
    if (input_buffer != NULL)
    {
	GSI_SOCKET_free_token(input_buffer);
    }
    
    if (output_buffer != NULL)
    {
	ssl_free_buffer(output_buffer);
    }
    
    if (creds != NULL)
    {
	ssl_credentials_destroy(creds);
    }

    if (proxy_restrictions != NULL)
    {
	ssl_proxy_restrictions_destroy(proxy_restrictions);
    }
    
    return return_value;
}
예제 #4
0
int
main(int argc, char *argv[]) 
{    
    char *pshost = NULL;
    char *request_buffer = NULL;
    int requestlen;
    int return_value = 1;

    myproxy_socket_attrs_t *socket_attrs;
    myproxy_request_t      *client_request;
    myproxy_response_t     *server_response;
    
    /* check library version */
    if (myproxy_check_version()) {
	fprintf(stderr, "MyProxy library version mismatch.\n"
		"Expecting %s.  Found %s.\n",
		MYPROXY_VERSION_DATE, myproxy_version(0,0,0));
	exit(1);
    }

    myproxy_log_use_stream (stderr);

    socket_attrs = malloc(sizeof(*socket_attrs));
    memset(socket_attrs, 0, sizeof(*socket_attrs));

    client_request = malloc(sizeof(*client_request));
    memset(client_request, 0, sizeof(*client_request));

    server_response = malloc(sizeof(*server_response));
    memset(server_response, 0, sizeof(*server_response));

    /* setup defaults */
    client_request->version = malloc(strlen(MYPROXY_VERSION) + 1);
    strcpy(client_request->version, MYPROXY_VERSION);
    client_request->command_type = MYPROXY_DESTROY_PROXY;

    pshost = getenv("MYPROXY_SERVER");
    if (pshost != NULL) {
        socket_attrs->pshost = strdup(pshost);
    }

    client_request->proxy_lifetime = 0;
    
    if (getenv("MYPROXY_SERVER_PORT")) {
	socket_attrs->psport = atoi(getenv("MYPROXY_SERVER_PORT"));
    } else {
	socket_attrs->psport = MYPROXY_SERVER_PORT;
    }

    /* Initialize client arguments and create client request object */
    init_arguments(argc, argv, socket_attrs, client_request);

    /*
     * We don't need to send the real pass phrase to the server as it
     * will just use our identity to authenticate and authorize us.
     * But we need to send over a dummy pass phrase at least
     * MIN_PASS_PHASE_LEN (currently 6) characters long.
     */
    strncpy(client_request->passphrase, "DUMMY-PASSPHRASE",
	    sizeof(client_request->passphrase));
    
    /* Set up client socket attributes */
    if (myproxy_init_client(socket_attrs) < 0) {
	verror_print_error(stderr);
        goto cleanup;
    }

    /* Authenticate client to server */
    if (myproxy_authenticate_init(socket_attrs, NULL /* Default proxy */) < 0) {
	verror_print_error(stderr);
	goto cleanup;
    }

    if (client_request->username == NULL) { /* set default username */
	if (dn_as_username) {
	    if (ssl_get_base_subject_file(NULL,
					  &client_request->username)) {
		fprintf(stderr,
			"Cannot get subject name from your certificate\n");
		goto cleanup;
	    }
	} else {
	    char *username = NULL;
	    if (!(username = getenv("LOGNAME"))) {
		fprintf(stderr, "Please specify a username.\n");
		goto cleanup;
	    }
	    client_request->username = strdup(username);
	}
    }

    /* Serialize client request object */
    requestlen = myproxy_serialize_request_ex(client_request, 
					      &request_buffer);
    
    if (requestlen < 0) {
	verror_print_error(stderr);
        goto cleanup;
    }

    /* Send request to the myproxy-server */
    if (myproxy_send(socket_attrs, request_buffer, requestlen) < 0) {
	verror_print_error(stderr);
        goto cleanup;
    }
    free(request_buffer);
    request_buffer = NULL;

    /* Receive a response from the server */
    if (myproxy_recv_response_ex(socket_attrs, server_response,
				 client_request) < 0) {
	verror_print_error(stderr);
        goto cleanup;
    }

    /* Check response */
    switch(server_response->response_type) {
    case MYPROXY_ERROR_RESPONSE:
        fprintf(stderr, "Received error from server: %s\n",
		server_response->error_string);
	goto cleanup;
    case MYPROXY_OK_RESPONSE:
	if (client_request->credname) {
	    printf("MyProxy credential '%s' for user %s was successfully removed.\n",
		   client_request->credname, client_request->username); 
	} else {
	    printf("Default MyProxy credential for user %s was successfully removed.\n",
		   client_request->username); 
	}
        break;
    default:
        fprintf(stderr, "Invalid response type received.\n");
	goto cleanup;
    }
    
    return_value = 0;

 cleanup:
    /* free memory allocated */
    myproxy_free(socket_attrs, client_request, server_response);

    return return_value;
}