int GSI_SOCKET_check_creds(GSI_SOCKET *self) { gss_cred_id_t creds = GSS_C_NO_CREDENTIAL; int return_value = GSI_SOCKET_ERROR; if (self == NULL) { return GSI_SOCKET_ERROR; } self->major_status = globus_gss_assist_acquire_cred(&self->minor_status, GSS_C_BOTH, &creds); if (self->major_status != GSS_S_COMPLETE) { goto error; } /* Success */ return_value = GSI_SOCKET_SUCCESS; error: if (creds != GSS_C_NO_CREDENTIAL) { OM_uint32 minor_status; gss_release_cred(&minor_status, &creds); } return return_value; }
gss_cred_id_t acquire_cred(const gss_cred_usage_t cred_usage) { OM_uint32 major_status = 0; OM_uint32 minor_status = 0; gss_cred_id_t credential_handle = GSS_C_NO_CREDENTIAL; /* Acquire GSS credential */ major_status = globus_gss_assist_acquire_cred( &minor_status, cred_usage, &credential_handle); if (major_status != GSS_S_COMPLETE) { globus_gss_assist_display_status( stderr, "Error acquiring credentials", major_status, minor_status, 0); return(GSS_C_NO_CREDENTIAL); } return(credential_handle); }
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); }
static int auth_globus_accept(struct link *link, char **subject, time_t stoptime) { 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; int success = 0; globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE); *subject = 0; debug(D_AUTH, "globus: loading my credentials"); major = globus_gss_assist_acquire_cred(&minor, GSS_C_ACCEPT, &credential); if(major == GSS_S_COMPLETE) { debug(D_AUTH, "globus: waiting for client to get ready"); if(auth_barrier(link, "yes\n", stoptime) == 0) { delegated_credential = GSS_C_NO_CREDENTIAL; debug(D_AUTH, "globus: authenticating client"); major = globus_gss_assist_accept_sec_context(&minor, &context, credential, subject, &flags, 0, &token, &delegated_credential, read_token, link, write_token, link); if(major == GSS_S_COMPLETE) { debug(D_AUTH, "globus: accepted client %s", *subject); if(delegated_credential != GSS_C_NO_CREDENTIAL) { debug(D_AUTH, "globus: client delegated its credentials"); } success = 1; gss_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); } else { char *reason; globus_gss_assist_display_status_str(&reason, "", major, minor, token); if(!reason) reason = xxstrdup("unknown reason"); debug(D_AUTH, "globus: couldn't authenticate client: %s", reason); if(reason) free(reason); } } else { debug(D_AUTH, "globus: client couldn't load credentials"); } gss_release_cred(&major, &credential); } else { debug(D_AUTH, "globus: couldn't load my credentials: did you run grid-proxy-init?"); auth_barrier(link, "no\n", stoptime); } globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE); return success; }
gss_cred_id_t make_cred(char *proxyname) { static gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; OM_uint32 major_status; OM_uint32 minor_status; setenv("X509_USER_PROXY",proxyname,1); major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_INITIATE, /* or GSS_C_ACCEPT */ &delegated_cred_handle); if (major_status != GSS_S_COMPLETE) { globus_gss_assist_display_status(stderr, "Some failure message here", major_status, minor_status, 0); exit(1); } return delegated_cred_handle; }
int GSI_SOCKET_authentication_accept(GSI_SOCKET *self) { gss_cred_id_t creds = GSS_C_NO_CREDENTIAL; int token_status; int return_value = GSI_SOCKET_ERROR; OM_uint32 gss_flags = 0; int sock; FILE *fp = NULL; char *cert_dir = NULL; globus_result_t res; if (self == 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_ACCEPT, &creds); if (self->major_status != GSS_S_COMPLETE) { goto error; } /* These are supposed to be return flags only, according to RFC 2774, but GSI helpfully uses them as request flags too. */ gss_flags |= GSS_C_REPLAY_FLAG; gss_flags |= GSS_C_MUTUAL_FLAG; gss_flags |= GSS_C_CONF_FLAG; gss_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_accept_sec_context(&self->minor_status, &self->gss_context, creds, &self->peer_name, &gss_flags, NULL, /* u2u flag */ &token_status, NULL, /* Delegated creds * added in Globus 1.1.3 */ globus_gss_assist_token_get_fd, (void *)fp, assist_write_token, (void *)&self->sock); if (self->major_status != GSS_S_COMPLETE) { goto error; } if (!(gss_flags & GSS_C_CONF_FLAG)) { GSI_SOCKET_set_error_string(self, "requested confidentiality GSSAPI service" " but it is not available"); goto error; } if (gss_flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG) { self->limited_proxy = 1; } /* Success */ return_value = GSI_SOCKET_SUCCESS; error: if (creds != GSS_C_NO_CREDENTIAL) { OM_uint32 minor_status; gss_release_cred(&minor_status, &creds); } if (cert_dir) free(cert_dir); if (fp) fclose(fp); return return_value; }
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 main( int argc, char ** argv) { int rc; globus_gram_job_manager_config_t config; globus_gram_job_manager_t manager; char * sleeptime_str; long sleeptime = 0; globus_bool_t debug_mode_service = GLOBUS_FALSE; globus_bool_t located_active_jm = GLOBUS_FALSE; int http_body_fd = -1; int context_fd = -1; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; OM_uint32 major_status, minor_status; pid_t forked_starter = 0; globus_bool_t cgi_invoked = GLOBUS_FALSE; int lock_tries_left = 10; if ((sleeptime_str = getenv("GLOBUS_JOB_MANAGER_SLEEP"))) { sleeptime = atoi(sleeptime_str); sleep(sleeptime); } if (getenv("GATEWAY_INTERFACE")) { cgi_invoked = GLOBUS_TRUE; } /* * Stdin and stdout point at socket to client * Make sure no buffering. * stderr may also, depending on the option in the grid-services */ setbuf(stdout,NULL); /* Don't export these to the perl scripts */ fcntl(STDIN_FILENO, F_SETFD, (int) 1); fcntl(STDOUT_FILENO, F_SETFD, (int) 1); fcntl(STDERR_FILENO, F_SETFD, (int) 1); /* * At least have minimal POSIX path for job environment via extra * environment values */ if(getenv("PATH") == NULL) { char * path; char default_path[] = "/usr/bin:/bin"; size_t pathlen; pathlen = confstr(_CS_PATH, NULL, (size_t) 0); if (pathlen < sizeof(default_path)) { pathlen = sizeof(default_path); } path = malloc(pathlen); path[0] = 0; (void) confstr(_CS_PATH, path, pathlen); if (path[0] == 0) { strncpy(path, default_path, pathlen); } setenv("PATH", path, 1); } /* Force non-threaded execution for now */ globus_thread_set_model(GLOBUS_THREAD_MODEL_NONE); /* Activate a common before parsing command-line so that * things work. Note that we can't activate everything yet because we might * set the GLOBUS_TCP_PORT_RANGE after parsing command-line args and we * need that set before activating XIO. */ rc = globus_module_activate(GLOBUS_COMMON_MODULE); if (rc != GLOBUS_SUCCESS) { fprintf(stderr, "Error activating GLOBUS_COMMON_MODULE\n"); exit(1); } /* Parse command line options to get jobmanager configuration */ rc = globus_gram_job_manager_config_init(&config, argc, argv); if (rc != GLOBUS_SUCCESS) { reply_and_exit(NULL, rc, NULL); } globus_thread_key_create( &globus_i_gram_request_key, NULL); rc = globus_gram_job_manager_logging_init(&config); if (rc != GLOBUS_SUCCESS) { exit(1); } if (getenv("GRID_SECURITY_HTTP_BODY_FD") == NULL && !cgi_invoked) { debug_mode_service = GLOBUS_TRUE; } /* Set environment variables from configuration */ if(config.globus_location != NULL) { globus_libc_setenv("GLOBUS_LOCATION", config.globus_location, GLOBUS_TRUE); } if(config.tcp_port_range != NULL) { globus_libc_setenv("GLOBUS_TCP_PORT_RANGE", config.tcp_port_range, GLOBUS_TRUE); } if(config.tcp_source_range != NULL) { globus_libc_setenv("GLOBUS_TCP_SOURCE_RANGE", config.tcp_source_range, GLOBUS_TRUE); } /* Activate all of the modules we will be using */ rc = globus_l_gram_job_manager_activate(); if(rc != GLOBUS_SUCCESS) { exit(1); } /* * Get the delegated credential (or the default credential if we are * run without a client. Don't care about errors in the latter case. */ major_status = globus_gss_assist_acquire_cred( &minor_status, GSS_C_BOTH, &cred); if ((!debug_mode_service) && GSS_ERROR(major_status)) { globus_gss_assist_display_status( stderr, "Error acquiring security credential\n", major_status, minor_status, 0); exit(1); } if (cred != GSS_C_NO_CREDENTIAL) { unsigned long hash; char * newtag; rc = globus_gram_gsi_get_dn_hash( cred, &hash); if (rc == GLOBUS_SUCCESS) { newtag = globus_common_create_string("%s%s%lx", strcmp(config.service_tag, "untagged") == 0 ? "" : config.service_tag, strcmp(config.service_tag, "untagged") == 0 ? "" : ".", hash); free(config.service_tag); config.service_tag = newtag; } } /* * Remove delegated proxy from disk. */ if ((!debug_mode_service) && getenv("X509_USER_PROXY") != NULL) { remove(getenv("X509_USER_PROXY")); unsetenv("X509_USER_PROXY"); } /* Set up LRM-specific state based on our configuration. This will create * the job contact listener, start the SEG if needed, and open the log * file if needed. */ rc = globus_gram_job_manager_init(&manager, cred, &config); if(rc != GLOBUS_SUCCESS) { reply_and_exit(NULL, rc, manager.gt3_failure_message); } /* * Pull out file descriptor numbers for security context and job request * from the environment (set by the gatekeeper) */ if (cgi_invoked) { http_body_fd = 0; context_fd = -1; } else if (!debug_mode_service) { char * fd_env = getenv("GRID_SECURITY_HTTP_BODY_FD"); rc = sscanf(fd_env ? fd_env : "-1", "%d", &http_body_fd); if (rc != 1 || http_body_fd < 0) { fprintf(stderr, "Error locating http body fd\n"); exit(1); } fcntl(http_body_fd, F_SETFD, 1); fd_env = getenv("GRID_SECURITY_CONTEXT_FD"); rc = sscanf(fd_env ? fd_env : "-1", "%d", &context_fd); if (rc != 1 || context_fd < 0) { fprintf(stderr, "Error locating security context fd\n"); exit(1); } fcntl(context_fd, F_SETFD, 1); } /* Redirect stdin from /dev/null, we'll handle stdout after the reply is * sent */ if (!cgi_invoked) { freopen("/dev/null", "r", stdin); } /* Here we'll either become the active job manager to process all * jobs for this user/host/lrm combination, or we'll hand off the * file descriptors containing the info to the active job manager */ while (!located_active_jm) { /* We'll try to get the lock file associated with being the * active job manager here. If we get the OLD_JM_ALIVE error * somebody else has it */ rc = globus_gram_job_manager_startup_lock( &manager, &manager.lock_fd); if (rc == GLOBUS_SUCCESS) { /* We've acquired the lock. We will fork a new process to act like * all other job managers which don't have the lock, and continue * on in this process managing jobs for this LRM. Note that the * child process does not inherit the lock */ if (!debug_mode_service) { int save_errno = 0; /* We've acquired the manager lock */ forked_starter = fork(); save_errno = errno; if (forked_starter < 0) { if (sleeptime != 0) { sleep(sleeptime); } fprintf(stderr, "fork failed: %s", strerror(save_errno)); exit(1); } else if (forked_starter == 0) { /* We are the child process. We'll close our reference to * the lock and let the other process deal with jobs */ close(manager.lock_fd); manager.lock_fd = -1; } globus_logging_update_pid(); if (sleeptime != 0) { sleep(sleeptime); } } if (manager.lock_fd >= 0) { /* We hold the manager lock, so we'll store our credential, and * then, try to accept socket connections. If the socket * connections fail, we'll exit, and another process * will be forked to handle them. */ rc = globus_gram_job_manager_gsi_write_credential( NULL, cred, manager.cred_path); if (rc != GLOBUS_SUCCESS) { fprintf(stderr, "write cred failed\n"); exit(1); } if (!debug_mode_service) { close(http_body_fd); http_body_fd = -1; } rc = globus_gram_job_manager_startup_socket_init( &manager, &manager.active_job_manager_handle, &manager.socket_fd); if (rc != GLOBUS_SUCCESS) { /* This releases our lock. Either the child process will * attempt to acquire the lock again or some another job * manager will acquire the lock */ exit(0); } assert(manager.socket_fd != -1); } } else if (rc != GLOBUS_GRAM_PROTOCOL_ERROR_OLD_JM_ALIVE) { /* Some system error. Try again */ if (--lock_tries_left == 0) { reply_and_exit(NULL, rc, "Unable to create lock file"); } sleep(1); continue; } /* If manager.socket_fd != -1 then we are the main job manager for this * LRM. * We will restart all existing jobs and then allow the startup * socket to accept new jobs from other job managers. */ if (manager.socket_fd != -1) { /* Look up cputype/manufacturer if not known yet */ globus_l_gram_cputype_and_manufacturer(manager.config); GlobusTimeAbstimeGetCurrent(manager.usagetracker->jm_start_time); globus_i_gram_usage_stats_init(&manager); globus_i_gram_usage_start_session_stats(&manager); located_active_jm = GLOBUS_TRUE; /* Load existing jobs. The show must go on if this fails, unless it * fails with a misconfiguration error */ rc = globus_gram_job_manager_request_load_all( &manager); if (rc == GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED) { if (forked_starter > 0) { kill(forked_starter, SIGTERM); forked_starter = 0; } reply_and_exit(NULL, rc, manager.gt3_failure_message); } if (context_fd != -1) { close(context_fd); context_fd = -1; } freopen("/dev/null", "a", stdout); /* At this point, seg_last_timestamp is the earliest last timestamp * for any pre-existing jobs. If that is 0, then we don't have any * existing jobs so we'll just ignore seg events prior to now. */ if (manager.seg_last_timestamp == 0) { manager.seg_last_timestamp = time(NULL); } /* Start off the SEG if we need it. */ if (config.seg_module != NULL || strcmp(config.jobmanager_type, "fork") == 0 || strcmp(config.jobmanager_type, "condor") == 0) { rc = globus_gram_job_manager_init_seg(&manager); /* TODO: If SEG load fails and load_all added some to the * job_id hash, they will need to be pushed into the state * machine so that polling fallback can happen. */ if (rc != GLOBUS_SUCCESS) { config.seg_module = NULL; } } /* GRAM-128: * Register a periodic event to process the GRAM jobs that were * reloaded from their job state files at job manager start time. * This will acquire and then release a reference to each job, * which, behind the scenes, will kick of the state machine * for that job if needed. */ if (!globus_list_empty(manager.pending_restarts)) { globus_reltime_t restart_period; GlobusTimeReltimeSet(restart_period, 1, 0); rc = globus_callback_register_periodic( &manager.pending_restart_handle, NULL, &restart_period, globus_l_gram_process_pending_restarts, &manager); } { globus_reltime_t expire_period; GlobusTimeReltimeSet(expire_period, 1, 0); rc = globus_callback_register_periodic( &manager.expiration_handle, NULL, &expire_period, globus_gram_job_manager_expire_old_jobs, &manager); } { globus_reltime_t lockcheck_period; GlobusTimeReltimeSet(lockcheck_period, 60, 0); rc = globus_callback_register_periodic( &manager.lockcheck_handle, NULL, &lockcheck_period, globus_l_gram_lockcheck, &manager); } { globus_reltime_t idlescript_period; GlobusTimeReltimeSet(idlescript_period, 60, 0); rc = globus_callback_register_periodic( &manager.idle_script_handle, NULL, &idlescript_period, globus_gram_script_close_idle, &manager); } } else if (http_body_fd >= 0) { /* If manager.socket_fd == -1 then we are either the child from the * fork or another process started somehow (either command-line * invocation or via a job submit). If we have a client, then we'll * send our fds to the job manager with the lock and let it process * the job. * * If this succeeds, we set located_active_jm and leave the loop. * Otherwise, we try again. */ if (context_fd >= 0) { rc = globus_gram_job_manager_starter_send( &manager, http_body_fd, context_fd, fileno(stdout), cred); } else { rc = globus_gram_job_manager_starter_send_v2( &manager, cred); } if (rc == GLOBUS_SUCCESS) { located_active_jm = GLOBUS_TRUE; close(http_body_fd); if (context_fd >= 0) { close(context_fd); } manager.done = GLOBUS_TRUE; } else { globus_libc_usleep(250000); } } else { /* We were started by hand, but another process is currently the * main job manager */ unsigned long realpid = 0; FILE * pidin = fopen(manager.pid_path, "r"); fscanf(pidin, "%lu", &realpid); fclose(pidin); fprintf(stderr, "Other job manager process with pid %lu running and processing jobs\n", realpid); exit(0); } } /* Ignore SIGCHILD, and automatically reap child processes. Because of the * fork() above to delegate to another job manager process, and the use of * sub-processes to invoke the perl modules, we create some other * processes. We don't care too much how they exit, so we'll just make sure * we don't create zombies out of them. */ { struct sigaction act; act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGCHLD); #ifdef SA_NOCLDWAIT act.sa_flags = SA_NOCLDWAIT; #else /* This may leave zombies running on non-POSIX systems like Hurd */ act.sa_flags = 0; #endif sigaction(SIGCHLD, &act, NULL); } /* Enable log rotation via SIGUSR1 */ { struct sigaction act; act.sa_handler = globus_i_job_manager_log_rotate; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGUSR1); act.sa_flags = 0; sigaction(SIGUSR1, &act, NULL); } GlobusGramJobManagerLock(&manager); if (manager.socket_fd != -1 && globus_hashtable_empty(&manager.request_hash) && manager.grace_period_timer == GLOBUS_NULL_HANDLE) { globus_gram_job_manager_set_grace_period_timer(&manager); } /* For the active job manager, this will block until all jobs have * terminated. For any other job manager, the monitor.done is set to * GLOBUS_TRUE and this falls right through. */ while (! manager.done) { GlobusGramJobManagerWait(&manager); } if (manager.expiration_handle != GLOBUS_NULL_HANDLE) { globus_callback_unregister(manager.expiration_handle, NULL, NULL, NULL); } if (manager.lockcheck_handle != GLOBUS_NULL_HANDLE) { globus_callback_unregister(manager.lockcheck_handle, NULL, NULL, NULL); } if (manager.idle_script_handle != GLOBUS_NULL_HANDLE) { globus_callback_unregister(manager.idle_script_handle, NULL, NULL, NULL); } GlobusGramJobManagerUnlock(&manager); globus_gram_job_manager_log( &manager, GLOBUS_GRAM_JOB_MANAGER_LOG_DEBUG, "event=gram.end " "level=DEBUG " "\n"); /* Clean-up to do if we are the active job manager only */ if (manager.socket_fd != -1) { globus_gram_job_manager_script_close_all(&manager); globus_i_gram_usage_end_session_stats(&manager); globus_i_gram_usage_stats_destroy(&manager); remove(manager.pid_path); remove(manager.cred_path); remove(manager.socket_path); remove(manager.lock_path); } globus_gram_job_manager_logging_destroy(); globus_gram_job_manager_destroy(&manager); globus_gram_job_manager_config_destroy(&config); rc = globus_l_gram_deactivate(); if (rc != GLOBUS_SUCCESS) { fprintf(stderr, "deactivation failed with rc=%d\n", rc); exit(1); } /* { const char * gk_jm_id_var = "GATEKEEPER_JM_ID"; const char * gk_jm_id = globus_libc_getenv(gk_jm_id_var); globus_gram_job_manager_request_acct( request, "%s %s JM exiting\n", gk_jm_id_var, gk_jm_id ? gk_jm_id : "none"); } */ return(0); }
int gw_em_mad_check_credentials(char *info) { int rc; gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; OM_uint32 major_status; OM_uint32 minor_status; OM_uint32 lifetime; time_t goodtill; static time_t last_goodtill = 0; char goodtill_str[26]; info[0] = '\0'; /* (Re)adquire credentials */ major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_INITIATE, &gss_cred); if (major_status != GSS_S_COMPLETE) { sprintf(info, "Error loading credentials"); return 1; } gss_inquire_cred(&minor_status, gss_cred, NULL, &lifetime, NULL, NULL); goodtill = time(NULL) + lifetime; #ifdef GWSOLARIS ctime_r(&(goodtill), goodtill_str, sizeof(char)*26); #else ctime_r(&(goodtill), goodtill_str); #endif goodtill_str[24]='\0'; printf("TIMER - SUCCESS Credential is valid until %s\n", goodtill_str); if (last_goodtill == 0) { last_goodtill = goodtill; } else if (goodtill > last_goodtill) { rc = globus_gram_client_set_credentials(gss_cred); if (rc != 0) { sprintf(info, "Error setting credentials"); return 1; } printf("TIMER - SUCCESS Refreshing credentials until %s\n", goodtill_str); last_goodtill = goodtill; rc = gw_em_mad_refresh(gss_cred, info); if (rc != 0) { return 1; } } return 0; }
int main(int argc, char * argv[]) { gss_cred_id_t accept_cred = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_init_cred = GSS_C_NO_CREDENTIAL; OM_uint32 major_status; OM_uint32 minor_status; int token_status; gss_ctx_id_t accept_context = GSS_C_NO_CONTEXT; OM_uint32 ret_flags = 0; int sock, connect_sock; FILE * infd; FILE * outfd; char * print_buffer = NULL; char * recv_buffer = NULL; size_t buffer_length; struct sockaddr_in sockaddr; socklen_t length; char * init_name; char * verbose_env = NULL; globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE); verbose_env = getenv("GSS_ASSIST_VERBOSE_TEST"); setbuf(stdout, NULL); sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("opening stream socket"); exit(1); } sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = INADDR_ANY; sockaddr.sin_port = 0; if(bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) { perror("binding stream socket"); exit(1); } length = sizeof(sockaddr); if(getsockname(sock, (struct sockaddr *) &sockaddr, &length)) { perror("getting socket name"); exit(1); } /* Start accepting connection */ listen(sock, 1); fprintf(stdout, "Socket has port #%d\n", ntohs(sockaddr.sin_port)); connect_sock = accept(sock, 0, 0); if(connect_sock == -1) { perror("accept"); exit(1); } if(close(sock) < 0) { perror("Couldn't close listening socket"); exit(1); } infd = fdopen(dup(connect_sock), "r"); setbuf(infd, NULL); outfd = fdopen(dup(connect_sock), "w"); setbuf(outfd, NULL); close(connect_sock); /* ACCEPTOR PROCESS */ major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_ACCEPT, &accept_cred); if(GSS_ERROR(major_status)) { globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't acquire acceptor's credentials", major_status, minor_status, 0); exit(1); } major_status = globus_gss_assist_accept_sec_context( &minor_status, &accept_context, accept_cred, &init_name, &ret_flags, NULL, &token_status, &delegated_init_cred, 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, "ACCEPTOR: Couldn't authenticate as acceptor\n", major_status, minor_status, token_status); exit(1); } if(verbose_env) { fprintf(stdout, "ACCEPTOR: "__FILE__":%d" ": Acceptor successfully created context" " for initiator: %s\n", __LINE__, init_name); } /* major_status = globus_gss_assist_get_unwrap( &minor_status, accept_context, &recv_buffer, &buffer_length, &token_status, globus_gss_assist_token_get_fd, (void *) (infd), stdout); if(GSS_ERROR(major_status)) { fprintf(stdout, "ACCEPTOR ERROR\n"); globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't get encrypted message from initiator\n", major_status, minor_status, token_status); fprintf(stdout, "ACCEPTOR 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, "ACCEPTOR: "__FILE__":%d" ": received: %s\n", __LINE__, print_buffer); } free(print_buffer); free(recv_buffer); */ major_status = globus_gss_assist_get_unwrap( &minor_status, accept_context, &recv_buffer, &buffer_length, &token_status, globus_gss_assist_token_get_fd, (void *) (infd), stdout); if(GSS_ERROR(major_status)) { fprintf(stdout, "ACCEPTOR ERROR\n"); globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't get encrypted message from initiator\n", major_status, minor_status, token_status); fprintf(stdout, "ACCEPTOR 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, "ACCEPTOR: "__FILE__":%d" ": received: %s\n", __LINE__, print_buffer); } free(print_buffer); free(recv_buffer); major_status = globus_gss_assist_wrap_send( &minor_status, accept_context, accept_message, sizeof(accept_message), &token_status, globus_gss_assist_token_send_fd, (void *) (outfd), stdout); if(GSS_ERROR(major_status)) { globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't encrypt and send message\n", major_status, minor_status, token_status); exit(1); } major_status = globus_gss_assist_get_unwrap( &minor_status, accept_context, &recv_buffer, &buffer_length, &token_status, globus_gss_assist_token_get_fd, (void *) (infd), stdout); if(GSS_ERROR(major_status)) { fprintf(stdout, "ACCEPTOR ERROR\n"); globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't get encrypted message from initiator\n", major_status, minor_status, token_status); fprintf(stdout, "ACCEPTOR 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, "ACCEPTOR: "__FILE__":%d" ": received: %s\n", __LINE__, print_buffer); } free(print_buffer); free(recv_buffer); major_status = globus_gss_assist_wrap_send( &minor_status, accept_context, accept_message, sizeof(accept_message), &token_status, globus_gss_assist_token_send_fd, (void *) (outfd), stdout); if(GSS_ERROR(major_status)) { globus_gss_assist_display_status( stdout, "ACCEPTOR: Couldn't encrypt and send message\n", major_status, minor_status, token_status); exit(1); } major_status = gss_delete_sec_context(&minor_status, &accept_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, &accept_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_self_gss(CondorError* errstack) { OM_uint32 major_status; OM_uint32 minor_status; char comment[1024]; if ( credential_handle != GSS_C_NO_CREDENTIAL ) { // user already auth'd dprintf( D_FULLDEBUG, "This process has a valid certificate & key\n" ); return TRUE; } // ensure all env vars are in place, acquire cred will fail otherwise //use gss-assist to verify user (not connection) //this method will prompt for password if private key is encrypted! int time = mySock_->timeout(60 * 5); //allow user 5 min to type passwd priv_state priv = PRIV_UNKNOWN; //if ((!mySock_->isClient() && { if (isDaemon()) { priv = set_root_priv(); } major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_BOTH, &credential_handle); if (major_status != GSS_S_COMPLETE) { major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_BOTH, &credential_handle); } //if (!mySock_->isClient() || isDaemon()) { if (isDaemon()) { set_priv(priv); } mySock_->timeout(time); //put it back to what it was before if (major_status != GSS_S_COMPLETE) { if (major_status == 851968 && minor_status == 20) { errstack->pushf("GSI", GSI_ERR_NO_VALID_PROXY, "Failed to authenticate. Globus is reporting error (%u:%u). " "This indicates that you do not have a valid user proxy. " "Run grid-proxy-init.", (unsigned)major_status, (unsigned)minor_status); } else if (major_status == 851968 && minor_status == 12) { errstack->pushf("GSI", GSI_ERR_NO_VALID_PROXY, "Failed to authenticate. Globus is reporting error (%u:%u). " "This indicates that your user proxy has expired. " "Run grid-proxy-init.", (unsigned)major_status, (unsigned)minor_status); } else { errstack->pushf("GSI", GSI_ERR_ACQUIRING_SELF_CREDINTIAL_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u). There is probably a problem with your credentials. (Did you run grid-proxy-init?)", (unsigned)major_status, (unsigned)minor_status); } sprintf(comment,"authenticate_self_gss: acquiring self credentials failed. Please check your Condor configuration file if this is a server process. Or the user environment variable if this is a user process. \n"); print_log( major_status,minor_status,0,comment); credential_handle = GSS_C_NO_CREDENTIAL; return FALSE; } dprintf( D_FULLDEBUG, "This process has a valid certificate & key\n" ); return TRUE; }
/** * 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; }