📄 myproxy_server.c
字号:
/* * myproxy-server * * program to store user's delegated credentials for later retrieval */#include "myproxy_common.h" /* all needed headers included here */#ifndef MIN#define MIN(x,y) ((x) < (y) ? (x) : (y))#endifstatic char usage[] = \"\n"\"Syntax: myproxy-server [-p|-port #] [-c config-file] [-s storage-dir] ...\n"\" myproxy-server [-h|-help] [-version]\n"\"\n"\" Options\n"\" -h | --help Displays usage\n"\" -u | --usage \n"\" \n"\" -v | --verbose Display debugging messages\n"\" -V | --version Displays version\n"\" -d | --debug Run in debug mode (don't fork)\n"\" -c | --config Specifies configuration file to use\n"\" -p | --port <portnumber> Specifies the port to run on\n"\" -P | --pidfile <path> Specifies a file to write the pid to\n"\" -s | --storage <directory> Specifies the credential storage directory\n"\"\n";struct option long_options[] ={ {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"port", required_argument, NULL, 'p'}, {"pidfile", required_argument, NULL, 'P'}, {"config", required_argument, NULL, 'c'}, {"storage", required_argument, NULL, 's'}, {"usage", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0}};static char short_options[] = "dhc:p:P:s:vVuD:";static char version[] ="myproxy-server version " MYPROXY_VERSION " (" MYPROXY_VERSION_DATE ") " "\n";/* Signal handling */typedef void Sigfunc(int); Sigfunc *my_signal(int signo, Sigfunc *func);void sig_exit(int signo);void sig_chld(int signo);void sig_ign(int signo);/* Function declarations */int init_arguments(int argc, char *argv[], myproxy_socket_attrs_t *server_attrs, myproxy_server_context_t *server_context);int myproxy_init_server(myproxy_socket_attrs_t *server_attrs);int handle_client(myproxy_socket_attrs_t *server_attrs, myproxy_server_context_t *server_context);void respond_with_error_and_die(myproxy_socket_attrs_t *attrs, const char *error);void send_response(myproxy_socket_attrs_t *server_attrs, myproxy_response_t *response, char *client_name);void get_proxy(myproxy_socket_attrs_t *server_attrs, myproxy_creds_t *creds, myproxy_request_t *request, myproxy_response_t *response, int max_proxy_lifetime);void put_proxy(myproxy_socket_attrs_t *server_attrs, myproxy_creds_t *creds, myproxy_response_t *response);void info_proxy(myproxy_creds_t *creds, myproxy_response_t *response);void destroy_proxy(myproxy_creds_t *creds, myproxy_response_t *response);void change_passwd(myproxy_creds_t *creds, char *new_passphrase, myproxy_response_t *response);static void failure(const char *failure_message); static void my_failure(const char *failure_message);static char *timestamp(void);static int become_daemon(myproxy_server_context_t *server_context);static void write_pidfile(const char path[]);static int myproxy_authorize_accept(myproxy_server_context_t *context, myproxy_socket_attrs_t *attrs, myproxy_request_t *client_request, char *client_name);/* returns 1 if passphrase matches, 0 otherwise */static intverify_passphrase(struct myproxy_creds *creds, myproxy_request_t *client_request, char *client_name, myproxy_server_context_t* config);/* returns 0 if authentication failed, 1 if authentication succeeded, 2 if certificate-based (renewal) authentication succeeded */static int authenticate_client(myproxy_socket_attrs_t *attrs, struct myproxy_creds *creds, myproxy_request_t *client_request, char *client_name, myproxy_server_context_t* config, int already_authenticated);/* Delegate requested credentials to the client */void get_credentials(myproxy_socket_attrs_t *attrs, myproxy_creds_t *creds, myproxy_request_t *request, myproxy_response_t *response, int max_proxy_lifetime);/* Accept end-entity credentials from client */void put_credentials(myproxy_socket_attrs_t *attrs, myproxy_creds_t *creds, myproxy_response_t *response);static int debug = 0;intmain(int argc, char *argv[]) { int listenfd; pid_t childpid; struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); myproxy_socket_attrs_t *socket_attrs; myproxy_server_context_t *server_context; /* 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); } socket_attrs = malloc(sizeof(*socket_attrs)); memset(socket_attrs, 0, sizeof(*socket_attrs)); server_context = malloc(sizeof(*server_context)); memset(server_context, 0, sizeof(*server_context)); /* Set context defaults */ server_context->run_as_daemon = 1; if (init_arguments(argc, argv, socket_attrs, server_context) < 0) { fprintf(stderr, usage); exit(1); } /* * Test to see if we're run out of inetd * If so, then stdin will be connected to a socket, * so getpeername() will succeed. */ if (getpeername(fileno(stdin), (struct sockaddr *) &client_addr, &client_addr_len) < 0) { server_context->run_as_daemon = 1; if (!debug) { if (become_daemon(server_context) < 0) { fprintf(stderr, "Error starting daemon\n"); exit(1); } } } else { server_context->run_as_daemon = 0; close(1); (void) open("/dev/null",O_WRONLY); } /* Initialize Logging */ if (debug) { myproxy_debug_set_level(1); myproxy_log_use_stream(stderr); } else { myproxy_log_use_syslog(LOG_DAEMON, server_context->my_name); } /* * Logging initialized: For here on use myproxy_log functions * instead of fprintf() and ilk. */ myproxy_log("myproxy-server %s starting at %s", myproxy_version(0,0,0), timestamp()); /* Set up signal handling to deal with zombie processes left over */ my_signal(SIGCHLD, sig_chld); /* If process is killed or Ctrl-C */ my_signal(SIGTERM, sig_exit); my_signal(SIGINT, sig_exit); /* Read my configuration */ if (myproxy_server_config_read(server_context) == -1) { verror_print_error(stderr); exit(1); } /* * set up gridmap file if explicitly defined. * if not, default to the usual place, but do not over write * the env var if previously defined. */ if ( server_context->certificate_mapfile != NULL ) { setenv( "GRIDMAP", server_context->certificate_mapfile, 1 ); } else { setenv( "GRIDMAP", "/etc/grid-security/grid-mapfile", 0 ); } /* setup certificate_issuer from certificate_issuer_cert if desired */ if ( ( server_context->certificate_issuer_cert != NULL) && ( server_context->certificate_issuer == NULL) ) { ssl_get_base_subject_file(server_context->certificate_issuer_cert, &server_context->certificate_issuer); } /* Make sure all's well with the storage directory. */ if (myproxy_check_storage_dir() == -1) { myproxy_log_verror(); myproxy_log("Exiting. Please fix errors with storage directory and restart."); exit(1); } if (!server_context->run_as_daemon) { myproxy_log("Connection from %s", inet_ntoa(client_addr.sin_addr)); socket_attrs->socket_fd = fileno(stdin); if (handle_client(socket_attrs, server_context) < 0) { my_failure("error in handle_client()"); } } else { /* Run as a daemon */ listenfd = myproxy_init_server(socket_attrs); if (server_context->pidfile) write_pidfile(server_context->pidfile); /* Set up concurrent server */ while (1) { socket_attrs->socket_fd = accept(listenfd, (struct sockaddr *) &client_addr, &client_addr_len); myproxy_log("Connection from %s", inet_ntoa(client_addr.sin_addr)); if (socket_attrs->socket_fd < 0) { if (errno == EINTR) { continue; } else { myproxy_log_perror("Error in accept()"); } } if (!debug) { childpid = fork(); if (childpid < 0) { /* check for error */ myproxy_log_perror("Error in fork"); close(socket_attrs->socket_fd); } else if (childpid != 0) { /* Parent */ /* parent closes connected socket */ close(socket_attrs->socket_fd); continue; /* while(1) */ } /* child process */ close(0); close(1); if (!debug) { close(2); } close(listenfd); } my_signal(SIGCHLD, SIG_DFL); if (handle_client(socket_attrs, server_context) < 0) { my_failure("error in handle_client()"); } _exit(0); } } return 0;} inthandle_client(myproxy_socket_attrs_t *attrs, myproxy_server_context_t *context) { char client_name[1024]; char *client_buffer = NULL; char *userdn = NULL; int requestlen; int use_ca_callout = 0; time_t now; myproxy_creds_t *client_creds; myproxy_request_t *client_request; myproxy_response_t *server_response; client_creds = malloc(sizeof(*client_creds)); memset(client_creds, 0, sizeof(*client_creds)); 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)); /* Create a new gsi socket */ attrs->gsi_socket = GSI_SOCKET_new(attrs->socket_fd); if (attrs->gsi_socket == NULL) { myproxy_log_perror("GSI_SOCKET_new()"); return -1; } /* Authenticate server to client and get DN of client */ if (myproxy_authenticate_accept(attrs, client_name, sizeof(client_name)) < 0) { /* Client_name may not be set on error so don't use it. */ myproxy_log_verror(); respond_with_error_and_die(attrs, "authentication failed"); } /* Log client name */ myproxy_log("Authenticated client %s", client_name); /* Receive client request */ requestlen = myproxy_recv_ex(attrs, &client_buffer); if (requestlen <= 0) { myproxy_log_verror(); respond_with_error_and_die(attrs, "Error in myproxy_recv_ex()"); } /* Deserialize client request */ if (myproxy_deserialize_request(client_buffer, requestlen, client_request) < 0) { myproxy_log_verror(); respond_with_error_and_die(attrs, "error parsing request"); } free(client_buffer); client_buffer = NULL; /* Check client version */ if (strcmp(client_request->version, MYPROXY_VERSION) != 0) { myproxy_log("client %s Invalid version number (%s) received", client_name, client_request->version); respond_with_error_and_die(attrs, "Invalid version number received.\n"); } /* Check client username and pass phrase */ if ((client_request->username == NULL) || (strlen(client_request->username) == 0)) { myproxy_log("client %s Invalid username (%s) received", client_name, (client_request->username == NULL ? "<NULL>" : client_request->username)); respond_with_error_and_die(attrs, "Invalid username received.\n"); } /* All authorization policies are enforced in this function. */ if (myproxy_authorize_accept(context, attrs, client_request, client_name) < 0) { myproxy_log("authorization failed"); respond_with_error_and_die(attrs, verror_get_string()); } /* Fill in client_creds with info from the request that describes the credentials the request applies to. */ client_creds->owner_name = strdup(client_name); client_creds->username = strdup(client_request->username); client_creds->passphrase = strdup(client_request->passphrase); client_creds->lifetime = client_request->proxy_lifetime; if (client_request->retrievers != NULL) client_creds->retrievers = strdup(client_request->retrievers); if (client_request->keyretrieve != NULL) client_creds->keyretrieve = strdup(client_request->keyretrieve); if (client_request->trusted_retrievers != NULL) client_creds->trusted_retrievers = strdup(client_request->trusted_retrievers); if (client_request->renewers != NULL) client_creds->renewers = strdup(client_request->renewers); if (client_request->credname != NULL) client_creds->credname = strdup (client_request->credname); if (client_request->creddesc != NULL) client_creds->creddesc = strdup (client_request->creddesc); /* Set response OK unless error... */ server_response->response_type = MYPROXY_OK_RESPONSE; /* Handle client request */ switch (client_request->command_type) { case MYPROXY_GET_PROXY: /* if it appears that we need to use the ca callouts because * of no stored creds, we should check if the ca is configured
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -