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; }
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; }
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; }