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); }
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; }
/** * 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; }