OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_cred (OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t value) { return gss_export_cred(minor_status, cred_handle, value); }
OM_uint32 _gss_spnego_export_cred (OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t value) { gssspnego_cred cred = (gssspnego_cred)cred_handle; return gss_export_cred(minor_status, cred->negotiated_cred_id, value); }
void mdsip_open_cb( globus_xio_handle_t xio_handle, globus_result_t result, void *user_arg) { globus_result_t res; mdsip_client_t *ctx; mdsip_options_t *options = (mdsip_options_t *)user_arg; gss_cred_id_t credential; ctx = mdsip_new_client(options); mdsip_test_result(xio_handle,result,ctx,"mdsip_open_cb"); if (options->port_name == NULL) { if (options->security_level > 0) { gss_buffer_desc buffer_desc = GSS_C_EMPTY_BUFFER; OM_uint32 minor_status; OM_uint32 major_status; res = globus_xio_handle_cntl(xio_handle,options->gsi_driver, GLOBUS_XIO_GSI_GET_DELEGATED_CRED,&credential); mdsip_test_result(xio_handle,res,ctx,"mdsip_open_cb,GET_DELEGATED_CRED"); major_status = gss_export_cred(&minor_status,credential,GSS_C_NO_OID,0,&buffer_desc); if(major_status != GSS_S_COMPLETE) { char *error_str; globus_gss_assist_display_status_str(&error_str, NULL, major_status, minor_status, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); } else { char cred_file_name[]="/tmp/x509pp_pXXXXXX"; int fd=mkstemp(cred_file_name); if (fd != -1) { fchmod(fd,00600); write(fd,buffer_desc.value,buffer_desc.length); fchmod(fd,00400); close(fd); setenv("X509_USER_PROXY",cred_file_name,1); } else perror("Error creating proxy credential file"); major_status = gss_release_buffer(&minor_status,&buffer_desc); } } } ctx->mdsip_read_cb=mdsip_authenticate_cb; res = globus_xio_register_read(xio_handle,(globus_byte_t *)&ctx->header, sizeof(mdsip_message_header_t), sizeof(mdsip_message_header_t),NULL,mdsip_read_header_cb,ctx); mdsip_test_result(xio_handle,res,ctx,"mdsip_open_cb,globus_xio_register_read"); }
/* Create a auth_session_info_transport from an auth_session_info. * * NOTE: Members of the auth_session_info_transport structure are * talloc_referenced() into this structure, and should not be changed. */ NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx, struct auth_session_info *session_info, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, struct auth_session_info_transport **transport_out) { struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport); if (!session_info_transport) { return NT_STATUS_NO_MEMORY; }; session_info_transport->session_info = talloc_reference(session_info_transport, session_info); if (!session_info_transport->session_info) { return NT_STATUS_NO_MEMORY; }; if (session_info->credentials) { struct gssapi_creds_container *gcc; OM_uint32 gret; OM_uint32 minor_status; gss_buffer_desc cred_token; const char *error_string; int ret; ret = cli_credentials_get_client_gss_creds(session_info->credentials, event_ctx, lp_ctx, &gcc, &error_string); if (ret != 0) { *transport_out = session_info_transport; return NT_STATUS_OK; } gret = gss_export_cred(&minor_status, gcc->creds, &cred_token); if (gret != GSS_S_COMPLETE) { return NT_STATUS_INTERNAL_ERROR; } if (cred_token.length) { session_info_transport->exported_gssapi_credentials = data_blob_talloc(session_info_transport, cred_token.value, cred_token.length); gss_release_buffer(&minor_status, &cred_token); NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data); } } *transport_out = session_info_transport; return NT_STATUS_OK; }
void export_import_cred(gss_cred_id_t *cred) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_export_cred(&minor, *cred, &buf); check_gsserr("gss_export_cred", major, minor); (void)gss_release_cred(&minor, cred); major = gss_import_cred(&minor, &buf, cred); check_gsserr("gss_import_cred", major, minor); (void)gss_release_buffer(&minor, &buf); }
OM_uint32 gssi_export_cred(OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t token) { struct gpp_cred_handle *cred; GSSI_TRACE(); cred = (struct gpp_cred_handle *)cred_handle; if (!cred) { return GSS_S_CALL_INACCESSIBLE_READ; } /* We do not support exporting creds via the proxy. * It's exclusively a local operation for now */ if (!cred->local) { return GSS_S_CRED_UNAVAIL; } return gss_export_cred(minor_status, cred->local, token); }
static pam_handle_t * perform_gssapi (void) { struct pam_conv conv = { pam_conv_func, }; OM_uint32 major, minor; gss_cred_id_t server = GSS_C_NO_CREDENTIAL; gss_cred_id_t client = GSS_C_NO_CREDENTIAL; gss_buffer_desc input = GSS_C_EMPTY_BUFFER; gss_buffer_desc output = GSS_C_EMPTY_BUFFER; gss_buffer_desc local = GSS_C_EMPTY_BUFFER; gss_buffer_desc display = GSS_C_EMPTY_BUFFER; gss_name_t name = GSS_C_NO_NAME; gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NO_OID; pam_handle_t *pamh = NULL; OM_uint32 flags = 0; char *str = NULL; OM_uint32 caps = 0; int res; server = GSS_C_NO_CREDENTIAL; res = PAM_AUTH_ERR; /* We shouldn't be writing to kerberos caches here */ setenv ("KRB5CCNAME", "FILE:/dev/null", 1); debug ("reading kerberos auth from cockpit-ws"); input.value = read_auth_until_eof (&input.length); major = gss_accept_sec_context (&minor, &context, server, &input, GSS_C_NO_CHANNEL_BINDINGS, &name, &mech_type, &output, &flags, &caps, &client); if (GSS_ERROR (major)) { warnx ("gssapi auth failed: %s", gssapi_strerror (major, minor)); goto out; } /* * In general gssapi mechanisms can require multiple challenge response * iterations keeping &context between each, however Kerberos doesn't * require this, so we don't care :O * * If we ever want this to work with something other than Kerberos, then * we'll have to have some sorta session that holds the context. */ if (major & GSS_S_CONTINUE_NEEDED) goto out; major = gss_localname (&minor, name, mech_type, &local); if (major == GSS_S_COMPLETE) { minor = 0; str = dup_string (local.value, local.length); debug ("mapped gssapi name to local user '%s'", str); if (getpwnam (str)) { res = pam_start ("cockpit", str, &conv, &pamh); } else { /* If the local user doesn't exist, pretend gss_localname() failed */ free (str); str = NULL; major = GSS_S_FAILURE; minor = KRB5_NO_LOCALNAME; } } if (major != GSS_S_COMPLETE) { if (minor == (OM_uint32)KRB5_NO_LOCALNAME || minor == (OM_uint32)KRB5_LNAME_NOTRANS) { major = gss_display_name (&minor, name, &display, NULL); if (GSS_ERROR (major)) { warnx ("couldn't get gssapi display name: %s", gssapi_strerror (major, minor)); goto out; } str = dup_string (display.value, display.length); debug ("no local user mapping for gssapi name '%s'", str); res = pam_start ("cockpit", str, &conv, &pamh); } else { warnx ("couldn't map gssapi name to local user: %s", gssapi_strerror (major, minor)); goto out; } } if (res != PAM_SUCCESS) errx (EX, "couldn't start pam: %s", pam_strerror (NULL, res)); if (pam_set_item (pamh, PAM_RHOST, rhost) != PAM_SUCCESS || pam_get_item (pamh, PAM_USER, (const void **)&user) != PAM_SUCCESS) errx (EX, "couldn't setup pam"); assert (user != NULL); res = open_session (pamh, user); out: write_auth_begin (res); if (user) write_auth_string ("user", user); if (output.value) write_auth_hex ("gssapi-output", output.value, output.length); if (output.value) gss_release_buffer (&minor, &output); output.value = NULL; output.length = 0; if (caps & GSS_C_DELEG_FLAG && client != GSS_C_NO_CREDENTIAL) { #ifdef HAVE_GSS_IMPORT_CRED major = gss_export_cred (&minor, client, &output); if (GSS_ERROR (major)) warnx ("couldn't export gssapi credentials: %s", gssapi_strerror (major, minor)); else if (output.value) write_auth_hex ("gssapi-creds", output.value, output.length); #else /* cockpit-ws will complain for us, if they're ever used */ write_auth_hex ("gssapi-creds", (void *)"", 0); #endif } write_auth_end (); if (display.value) gss_release_buffer (&minor, &display); if (output.value) gss_release_buffer (&minor, &output); if (local.value) gss_release_buffer (&minor, &local); if (client != GSS_C_NO_CREDENTIAL) gss_release_cred (&minor, &client); if (server != GSS_C_NO_CREDENTIAL) gss_release_cred (&minor, &server); if (name != GSS_C_NO_NAME) gss_release_name (&minor, &name); if (context != GSS_C_NO_CONTEXT) gss_delete_sec_context (&minor, &context, GSS_C_NO_BUFFER); free (input.value); free (str); unsetenv ("KRB5CCNAME"); if (res != PAM_SUCCESS) exit (5); return pamh; }
int main() { OM_uint32 init_maj_stat; OM_uint32 accept_maj_stat; OM_uint32 maj_stat; OM_uint32 min_stat; OM_uint32 ret_flags; OM_uint32 req_flags = 0; OM_uint32 time_rec; gss_buffer_desc send_tok; gss_buffer_desc recv_tok; gss_buffer_desc * token_ptr; gss_OID mech_type; gss_name_t target_name; gss_ctx_id_t init_context; gss_ctx_id_t accept_context; gss_ctx_id_t del_init_context; gss_ctx_id_t del_accept_context; gss_cred_id_t delegated_cred; gss_cred_id_t imported_cred; gss_cred_id_t cred_handle; char * error_str; globus_result_t result; globus_gsi_cert_utils_cert_type_t cert_type; int rc = EXIT_SUCCESS; printf("1..1\n"); /* Activate Modules */ globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE); /* Initialize variables */ token_ptr = GSS_C_NO_BUFFER; init_context = GSS_C_NO_CONTEXT; accept_context = GSS_C_NO_CONTEXT; del_init_context = GSS_C_NO_CONTEXT; del_accept_context = GSS_C_NO_CONTEXT; delegated_cred = GSS_C_NO_CREDENTIAL; accept_maj_stat = GSS_S_CONTINUE_NEEDED; ret_flags = 0; req_flags |= GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG; /* acquire the credential */ maj_stat = gss_acquire_cred(&min_stat, NULL, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_BOTH, &cred_handle, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } /* get the subject name */ maj_stat = gss_inquire_cred(&min_stat, cred_handle, &target_name, NULL, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } /* set up the first security context */ init_maj_stat = gss_init_sec_context(&min_stat, cred_handle, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { accept_maj_stat=gss_accept_sec_context(&min_stat, &accept_context, GSS_C_NO_CREDENTIAL, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, NULL, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, NULL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } } printf("# %s:%d: Successfully established initial security context\n", __FILE__, __LINE__); /* delegate our credential over the initial security context and * insert a restriction extension into the delegated credential. * This is a post GT 2.0 feature. */ init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, token_ptr, req_flags, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { accept_maj_stat=gss_accept_delegation(&min_stat, accept_context, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &send_tok, req_flags, 0, &time_rec, &delegated_cred, &mech_type, &recv_tok); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &recv_tok, req_flags, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } } printf("# %s:%d: Successfully delegated credential\n", __FILE__, __LINE__); /* export and import the delegated credential */ /* this can be done both to a buffer and to a file */ /* New in GT 2.0 */ maj_stat = gss_export_cred(&min_stat, delegated_cred, GSS_C_NO_OID, 0, &send_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } maj_stat = gss_import_cred(&min_stat, &imported_cred, GSS_C_NO_OID, 0, &send_tok, 0, &time_rec); if(maj_stat != GSS_S_COMPLETE) { globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } printf("# %s:%d: Successfully exported/imported the delegated credential\n", __FILE__, __LINE__); /* set up another security context using the delegated credential */ init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { accept_maj_stat=gss_accept_sec_context(&min_stat, &del_accept_context, imported_cred, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, NULL, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, NULL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat); rc = EXIT_FAILURE; goto fail; } } /* got sec context based on delegated cred now */ printf("# %s:%d: Successfully established security context with delegated credential\n", __FILE__, __LINE__); /* Verify that the delegated credential is a limited proxy */ result = globus_gsi_cred_get_cert_type( ((gss_cred_id_desc *)imported_cred)->cred_handle, &cert_type); if(result != GLOBUS_SUCCESS) { char * error_str; globus_object_t * error_obj; error_obj = globus_error_get(result); error_str = globus_error_print_chain(error_obj); fprintf(stderr, "%s", error_str); globus_libc_free(error_str); globus_object_free(error_obj); rc = EXIT_FAILURE; goto fail; } if (! GLOBUS_GSI_CERT_UTILS_IS_LIMITED_PROXY(cert_type)) { fprintf(stderr, "Invalid certificate type. Expected a limited proxy, got %d\n", (int) cert_type); rc = EXIT_FAILURE; goto fail; } fail: printf("%s gssapi_limited_delegation_test\n", (rc==EXIT_SUCCESS) ? "ok" : "not ok"); globus_module_deactivate_all(); exit(rc); }
uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall, gss_cred_id_t *in, gssx_cred *out) { uint32_t ret_maj; uint32_t ret_min; gss_name_t name = NULL; uint32_t lifetime; gss_cred_usage_t cred_usage; gss_OID_set mechanisms = NULL; uint32_t initiator_lifetime; uint32_t acceptor_lifetime; struct gssx_cred_element *el; int ret; int i, j; struct gp_creds_handle *handle = NULL; gss_buffer_desc token = GSS_C_EMPTY_BUFFER; ret_maj = gss_inquire_cred(&ret_min, *in, &name, &lifetime, &cred_usage, &mechanisms); if (ret_maj) { goto done; } ret_maj = gp_conv_name_to_gssx(&ret_min, name, &out->desired_name); if (ret_maj) { goto done; } gss_release_name(&ret_min, &name); name = NULL; out->elements.elements_len = mechanisms->count; out->elements.elements_val = calloc(out->elements.elements_len, sizeof(gssx_cred_element)); if (!out->elements.elements_val) { ret_maj = GSS_S_FAILURE; ret_min = ENOMEM; goto done; } for (i = 0, j = 0; i < mechanisms->count; i++, j++) { el = &out->elements.elements_val[j]; ret_maj = gss_inquire_cred_by_mech(&ret_min, *in, &mechanisms->elements[i], &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage); if (ret_maj) { gp_log_failure(&mechanisms->elements[i], ret_maj, ret_min); /* temporarily skip any offender */ out->elements.elements_len--; j--; continue; #if 0 ret = EINVAL; goto done; #endif } ret_maj = gp_conv_name_to_gssx(&ret_min, name, &el->MN); if (ret_maj) { goto done; } gss_release_name(&ret_min, &name); name = NULL; ret = gp_conv_oid_to_gssx(&mechanisms->elements[i], &el->mech); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } el->cred_usage = gp_conv_gssx_to_cred_usage(cred_usage); el->initiator_time_rec = initiator_lifetime; el->acceptor_time_rec = acceptor_lifetime; } handle = gp_service_get_creds_handle(gpcall->service); if (!handle) { ret_maj = GSS_S_FAILURE; ret_min = EINVAL; goto done; } ret_maj = gss_export_cred(&ret_min, *in, &token); if (ret_maj) { goto done; } ret = gp_encrypt_buffer(handle->context, &handle->key, token.length, token.value, &out->cred_handle_reference); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } out->needs_release = false; /* now we have serialized creds in the hands of the client. * we can safey free them here so that we can remain sateless and * not leak memory */ gss_release_cred(&ret_min, in); ret_maj = GSS_S_COMPLETE; ret_min = 0; done: *min = ret_min; gss_release_name(&ret_min, &name); gss_release_oid_set(&ret_min, &mechanisms); return ret_maj; }
int receive_delegated_proxy(char **s, gss_ctx_id_t gss_context, int sck) { char *buf; int return_status = BPR_RECEIVE_DELEGATED_PROXY_ERROR; int send_status; gss_buffer_desc input_token,output_token; gss_buffer_desc snd_token, rcv_token; gss_buffer_desc cred_token; gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL; OM_uint32 del_maj_stat, maj_stat, min_stat, time_rec; int conf_req_flag = 1; /* Non zero value to request confidentiality */ del_maj_stat = GSS_S_CONTINUE_NEEDED; if (gss_context != GSS_C_NO_CONTEXT) { while (del_maj_stat == GSS_S_CONTINUE_NEEDED) { /* get_token can return -1 on error or GLOBUS_GSS_ASSIST_TOKEN_EOF==3 */ if (get_token(&sck, &input_token.value, &input_token.length) != 0) break; maj_stat = gss_unwrap( &min_stat, gss_context, &input_token, &rcv_token, NULL, NULL); gss_release_buffer(&min_stat, &input_token); if (!GSS_ERROR(maj_stat)) { del_maj_stat=gss_accept_delegation(&min_stat, gss_context, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &rcv_token, GSS_C_GLOBUS_SSL_COMPATIBLE, 0, &time_rec, &delegated_cred, NULL, &snd_token); } else break; gss_release_buffer(&min_stat, &rcv_token); if (del_maj_stat != GSS_S_CONTINUE_NEEDED) break; maj_stat = gss_wrap( &min_stat, gss_context, conf_req_flag, GSS_C_QOP_DEFAULT, &snd_token, NULL, &output_token); gss_release_buffer(&min_stat, &snd_token); if (!GSS_ERROR(maj_stat)) { send_status = send_token((void*)&sck, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (send_status < 0) { break; } } else { break; } } } if (del_maj_stat == GSS_S_COMPLETE) { /* Export credential to a string */ maj_stat = gss_export_cred(&min_stat, delegated_cred, GSS_C_NO_OID, 0, &cred_token); if (maj_stat == GSS_S_COMPLETE) { if (s != NULL) { *s = (char *)malloc(cred_token.length + 1); if (*s != NULL) { memcpy(*s, cred_token.value, cred_token.length); (*s)[cred_token.length]='\000'; return_status = BPR_RECEIVE_DELEGATED_PROXY_OK; } } } gss_release_buffer(&min_stat, &cred_token); } return return_status; }
/* * Export GSI credentials to disk. */ static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client) { OM_uint32 major_status; OM_uint32 minor_status; gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER; char * p; if (!client || !client->creds) { return; } major_status = gss_export_cred(&minor_status, client->creds, GSS_C_NO_OID, 1, &export_cred); if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) { Gssctxt *ctx; ssh_gssapi_build_ctx(&ctx); ctx->major = major_status; ctx->minor = minor_status; ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid); ssh_gssapi_error(ctx); ssh_gssapi_delete_ctx(&ctx); return; } p = strchr((char *) export_cred.value, '='); if (p == NULL) { logit("Failed to parse exported credentials string '%.100s'", (char *)export_cred.value); gss_release_buffer(&minor_status, &export_cred); return; } *p++ = '\0'; if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { client->store.envvar = strdup("X509_USER_PROXY"); } else { client->store.envvar = strdup((char *)export_cred.value); } if (access(p, R_OK) == 0) { if (client->store.filename) { if (rename(p, client->store.filename) < 0) { logit("Failed to rename %s to %s: %s", p, client->store.filename, strerror(errno)); free(client->store.filename); client->store.filename = strdup(p); } else { p = client->store.filename; } } else { client->store.filename = strdup(p); } } client->store.envval = strdup(p); #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif gss_release_buffer(&minor_status, &export_cred); }
int main(int argc, char **argv) { int optind = 0; OM_uint32 min_stat, maj_stat; gss_ctx_id_t cctx, sctx; void *ctx; gss_OID nameoid, mechoid, actual_mech, actual_mech2; gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL, deleg_cred = GSS_C_NO_CREDENTIAL; gss_name_t cname = GSS_C_NO_NAME; gss_buffer_desc credential_data = GSS_C_EMPTY_BUFFER; setprogname(argv[0]); init_o2n(); if (krb5_init_context(&context)) errx(1, "krb5_init_context"); cctx = sctx = GSS_C_NO_CONTEXT; if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) usage(1); if (help_flag) usage (0); if(version_flag){ print_version(NULL); exit(0); } argc -= optind; argv += optind; if (argc != 1) usage(1); if (dns_canon_flag != -1) gsskrb5_set_dns_canonicalize(dns_canon_flag); if (type_string == NULL) nameoid = GSS_C_NT_HOSTBASED_SERVICE; else if (strcmp(type_string, "hostbased-service") == 0) nameoid = GSS_C_NT_HOSTBASED_SERVICE; else if (strcmp(type_string, "krb5-principal-name") == 0) nameoid = GSS_KRB5_NT_PRINCIPAL_NAME; else errx(1, "%s not suppported", type_string); if (mech_string == NULL) mechoid = GSS_KRB5_MECHANISM; else mechoid = string_to_oid(mech_string); if (gsskrb5_acceptor_identity) { maj_stat = gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity); if (maj_stat) errx(1, "gsskrb5_acceptor_identity: %s", gssapi_err(maj_stat, 0, GSS_C_NO_OID)); } if (client_password) { credential_data.value = client_password; credential_data.length = strlen(client_password); } if (client_name) { gss_buffer_desc cn; cn.value = client_name; cn.length = strlen(client_name); maj_stat = gss_import_name(&min_stat, &cn, GSS_C_NT_USER_NAME, &cname); if (maj_stat) errx(1, "gss_import_name: %s", gssapi_err(maj_stat, min_stat, GSS_C_NO_OID)); } if (client_password) { maj_stat = gss_acquire_cred_with_password(&min_stat, cname, &credential_data, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &client_cred, NULL, NULL); if (GSS_ERROR(maj_stat)) errx(1, "gss_acquire_cred_with_password: %s", gssapi_err(maj_stat, min_stat, GSS_C_NO_OID)); } else { maj_stat = gss_acquire_cred(&min_stat, cname, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &client_cred, NULL, NULL); if (GSS_ERROR(maj_stat)) errx(1, "gss_acquire_cred: %s", gssapi_err(maj_stat, min_stat, GSS_C_NO_OID)); } if (limit_enctype_string) { krb5_error_code ret; ret = krb5_string_to_enctype(context, limit_enctype_string, &limit_enctype); if (ret) krb5_err(context, 1, ret, "krb5_string_to_enctype"); } if (limit_enctype) { if (client_cred == NULL) errx(1, "client_cred missing"); maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, client_cred, 1, &limit_enctype); if (maj_stat) errx(1, "gss_krb5_set_allowable_enctypes: %s", gssapi_err(maj_stat, min_stat, GSS_C_NO_OID)); } loop(mechoid, nameoid, argv[0], client_cred, &sctx, &cctx, &actual_mech, &deleg_cred); if (verbose_flag) printf("resulting mech: %s\n", oid_to_string(actual_mech)); if (ret_mech_string) { gss_OID retoid; retoid = string_to_oid(ret_mech_string); if (gss_oid_equal(retoid, actual_mech) == 0) errx(1, "actual_mech mech is not the expected type %s", ret_mech_string); } /* XXX should be actual_mech */ if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) { time_t time; gss_buffer_desc authz_data; gss_buffer_desc in, out1, out2; krb5_keyblock *keyblock, *keyblock2; krb5_timestamp now; krb5_error_code ret; ret = krb5_timeofday(context, &now); if (ret) errx(1, "krb5_timeofday failed"); /* client */ maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, &cctx, 1, /* version */ &ctx); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_export_lucid_sec_context failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_free_lucid_sec_context failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); /* server */ maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, &sctx, 1, /* version */ &ctx); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_export_lucid_sec_context failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_free_lucid_sec_context failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, sctx, &time); if (maj_stat != GSS_S_COMPLETE) errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); if (time > now) errx(1, "gsskrb5_extract_authtime_from_sec_context failed: " "time authtime is before now: %ld %ld", (long)time, (long)now); maj_stat = gsskrb5_extract_service_keyblock(&min_stat, sctx, &keyblock); if (maj_stat != GSS_S_COMPLETE) errx(1, "gsskrb5_export_service_keyblock failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); krb5_free_keyblock(context, keyblock); maj_stat = gsskrb5_get_subkey(&min_stat, sctx, &keyblock); if (maj_stat != GSS_S_COMPLETE && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) errx(1, "gsskrb5_get_subkey server failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); if (maj_stat != GSS_S_COMPLETE) keyblock = NULL; else if (limit_enctype && keyblock->keytype != limit_enctype) errx(1, "gsskrb5_get_subkey wrong enctype"); maj_stat = gsskrb5_get_subkey(&min_stat, cctx, &keyblock2); if (maj_stat != GSS_S_COMPLETE && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) errx(1, "gsskrb5_get_subkey client failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); if (maj_stat != GSS_S_COMPLETE) keyblock2 = NULL; else if (limit_enctype && keyblock->keytype != limit_enctype) errx(1, "gsskrb5_get_subkey wrong enctype"); if (keyblock || keyblock2) { if (keyblock == NULL) errx(1, "server missing token keyblock"); if (keyblock2 == NULL) errx(1, "client missing token keyblock"); if (keyblock->keytype != keyblock2->keytype) errx(1, "enctype mismatch"); if (keyblock->keyvalue.length != keyblock2->keyvalue.length) errx(1, "key length mismatch"); if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data, keyblock2->keyvalue.length) != 0) errx(1, "key data mismatch"); } if (session_enctype_string) { krb5_enctype enctype; ret = krb5_string_to_enctype(context, session_enctype_string, &enctype); if (ret) krb5_err(context, 1, ret, "krb5_string_to_enctype"); if (enctype != keyblock->keytype) errx(1, "keytype is not the expected %d != %d", (int)enctype, (int)keyblock2->keytype); } if (keyblock) krb5_free_keyblock(context, keyblock); if (keyblock2) krb5_free_keyblock(context, keyblock2); maj_stat = gsskrb5_get_initiator_subkey(&min_stat, sctx, &keyblock); if (maj_stat != GSS_S_COMPLETE && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) errx(1, "gsskrb5_get_initiator_subkey failed: %s", gssapi_err(maj_stat, min_stat, actual_mech)); if (maj_stat == GSS_S_COMPLETE) { if (limit_enctype && keyblock->keytype != limit_enctype) errx(1, "gsskrb5_get_initiator_subkey wrong enctype"); krb5_free_keyblock(context, keyblock); } maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, sctx, 128, &authz_data); if (maj_stat == GSS_S_COMPLETE) gss_release_buffer(&min_stat, &authz_data); memset(&out1, 0, sizeof(out1)); memset(&out2, 0, sizeof(out2)); in.value = "foo"; in.length = 3; gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in, 100, &out1); gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in, 100, &out2); if (out1.length != out2.length) errx(1, "prf len mismatch"); if (memcmp(out1.value, out2.value, out1.length) != 0) errx(1, "prf data mismatch"); gss_release_buffer(&min_stat, &out1); gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in, 100, &out1); if (out1.length != out2.length) errx(1, "prf len mismatch"); if (memcmp(out1.value, out2.value, out1.length) != 0) errx(1, "prf data mismatch"); gss_release_buffer(&min_stat, &out1); gss_release_buffer(&min_stat, &out2); in.value = "bar"; in.length = 3; gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in, 100, &out1); gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in, 100, &out2); if (out1.length != out2.length) errx(1, "prf len mismatch"); if (memcmp(out1.value, out2.value, out1.length) != 0) errx(1, "prf data mismatch"); gss_release_buffer(&min_stat, &out1); gss_release_buffer(&min_stat, &out2); wrapunwrap_flag = 1; getverifymic_flag = 1; } if (wrapunwrap_flag) { wrapunwrap(cctx, sctx, 0, actual_mech); wrapunwrap(cctx, sctx, 1, actual_mech); wrapunwrap(sctx, cctx, 0, actual_mech); wrapunwrap(sctx, cctx, 1, actual_mech); } if (iov_flag) { wrapunwrap_iov(cctx, sctx, 0, actual_mech); wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|USE_SIGN_ONLY|FORCE_IOV, actual_mech); /* works */ wrapunwrap_iov(cctx, sctx, 0, actual_mech); wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech); wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech); } if (getverifymic_flag) { getverifymic(cctx, sctx, actual_mech); getverifymic(cctx, sctx, actual_mech); getverifymic(sctx, cctx, actual_mech); getverifymic(sctx, cctx, actual_mech); } gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); if (deleg_cred != GSS_C_NO_CREDENTIAL) { gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL; gss_buffer_desc cb; if (verbose_flag) printf("checking actual mech (%s) on delegated cred\n", oid_to_string(actual_mech)); loop(actual_mech, nameoid, argv[0], deleg_cred, &sctx, &cctx, &actual_mech2, &cred2); gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); gss_release_cred(&min_stat, &cred2); /* try again using SPNEGO */ if (verbose_flag) printf("checking spnego on delegated cred\n"); loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], deleg_cred, &sctx, &cctx, &actual_mech2, &cred2); gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); gss_release_cred(&min_stat, &cred2); /* check export/import */ if (ei_flag) { maj_stat = gss_export_cred(&min_stat, deleg_cred, &cb); if (maj_stat != GSS_S_COMPLETE) errx(1, "export failed: %s", gssapi_err(maj_stat, min_stat, NULL)); maj_stat = gss_import_cred(&min_stat, &cb, &cred2); if (maj_stat != GSS_S_COMPLETE) errx(1, "import failed: %s", gssapi_err(maj_stat, min_stat, NULL)); gss_release_buffer(&min_stat, &cb); gss_release_cred(&min_stat, &deleg_cred); if (verbose_flag) printf("checking actual mech (%s) on export/imported cred\n", oid_to_string(actual_mech)); loop(actual_mech, nameoid, argv[0], cred2, &sctx, &cctx, &actual_mech2, &deleg_cred); gss_release_cred(&min_stat, &deleg_cred); gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); /* try again using SPNEGO */ if (verbose_flag) printf("checking SPNEGO on export/imported cred\n"); loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], cred2, &sctx, &cctx, &actual_mech2, &deleg_cred); gss_release_cred(&min_stat, &deleg_cred); gss_delete_sec_context(&min_stat, &cctx, NULL); gss_delete_sec_context(&min_stat, &sctx, NULL); gss_release_cred(&min_stat, &cred2); } else { gss_release_cred(&min_stat, &deleg_cred); } } empty_release(); krb5_free_context(context); return 0; }
int main() { OM_uint32 init_maj_stat; OM_uint32 accept_maj_stat; OM_uint32 maj_stat; OM_uint32 min_stat; OM_uint32 ret_flags; OM_uint32 req_flags = 0; OM_uint32 time_rec; gss_buffer_desc send_tok; gss_buffer_desc recv_tok; gss_buffer_desc * token_ptr; gss_OID mech_type; gss_name_t target_name; gss_ctx_id_t init_context; gss_ctx_id_t accept_context; gss_ctx_id_t del_init_context; gss_ctx_id_t del_accept_context; gss_cred_id_t delegated_cred; gss_cred_id_t imported_cred; gss_cred_id_t cred_handle; char * error_str; int rc = EXIT_SUCCESS; printf("1..1\n"); /* Initialize variables */ token_ptr = GSS_C_NO_BUFFER; init_context = GSS_C_NO_CONTEXT; accept_context = GSS_C_NO_CONTEXT; del_init_context = GSS_C_NO_CONTEXT; del_accept_context = GSS_C_NO_CONTEXT; delegated_cred = GSS_C_NO_CREDENTIAL; accept_maj_stat = GSS_S_CONTINUE_NEEDED; ret_flags = 0; req_flags |= GSS_C_GLOBUS_SSL_COMPATIBLE; /* Activate Modules */ globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE); globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE); maj_stat = gss_acquire_cred(&min_stat, NULL, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_BOTH, &cred_handle, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } /* get the subject name */ maj_stat = gss_inquire_cred(&min_stat, cred_handle, &target_name, NULL, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } /* set up the first security context */ init_maj_stat = gss_init_sec_context(&min_stat, cred_handle, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { accept_maj_stat=gss_accept_sec_context(&min_stat, &accept_context, GSS_C_NO_CREDENTIAL, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, NULL, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, NULL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } } printf("# %s:%d: Successfully established initial security context\n", __FILE__, __LINE__); init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, token_ptr, req_flags, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&recv_tok); maj_stat = gss_wrap(&min_stat, init_context, 0, GSS_C_QOP_DEFAULT, &send_tok, NULL, &recv_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { internal_release_buffer(&send_tok); maj_stat = gss_unwrap(&min_stat, accept_context, &recv_tok, &send_tok, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&recv_tok); accept_maj_stat=gss_accept_delegation(&min_stat, accept_context, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &send_tok, req_flags, 0, &time_rec, &delegated_cred, &mech_type, &recv_tok); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } internal_release_buffer(&send_tok); maj_stat = gss_wrap(&min_stat, accept_context, 0, GSS_C_QOP_DEFAULT, &recv_tok, NULL, &send_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&recv_tok); maj_stat = gss_unwrap(&min_stat, init_context, &send_tok, &recv_tok, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&send_tok); init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &recv_tok, req_flags, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&recv_tok); maj_stat = gss_wrap(&min_stat, init_context, 0, GSS_C_QOP_DEFAULT, &send_tok, NULL, &recv_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } } printf("# %s:%d: Successfully delegated credential\n", __FILE__, __LINE__); /* export and import the delegated credential */ /* this can be done both to a buffer and to a file */ /* New in GT 2.0 */ internal_release_buffer(&send_tok); maj_stat = gss_export_cred(&min_stat, delegated_cred, GSS_C_NO_OID, 0, &send_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } maj_stat = gss_import_cred(&min_stat, &imported_cred, GSS_C_NO_OID, 0, &send_tok, 0, &time_rec); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } internal_release_buffer(&send_tok); printf("# %s:%d: Successfully exported/imported the delegated credential\n", __FILE__, __LINE__); /* set up another security context using the delegated credential */ init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } while(1) { internal_release_buffer(&recv_tok); accept_maj_stat=gss_accept_sec_context(&min_stat, &del_accept_context, imported_cred, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, &target_name, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, NULL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); fprintf(stderr, "\nLINE %d ERROR: %s\n\n", __LINE__, error_str); globus_print_error((globus_result_t) min_stat); rc = EXIT_FAILURE; goto fail; } } /* got sec context based on delegated cred now */ printf("# %s:%d: Successfully established security context with delegated credential\n", __FILE__, __LINE__); fail: printf("%s gssapi_delegation_compat_test\n", (rc == EXIT_SUCCESS) ? "ok" : "not ok"); globus_module_deactivate_all(); exit(rc); }
int main() { OM_uint32 init_maj_stat; OM_uint32 accept_maj_stat; OM_uint32 maj_stat; OM_uint32 min_stat; OM_uint32 ret_flags; OM_uint32 time_rec; gss_buffer_desc send_tok; gss_buffer_desc recv_tok; gss_buffer_desc * token_ptr; gss_buffer_desc oid_buffer; gss_buffer_set_desc oid_buffers; gss_buffer_set_t inquire_buffers; gss_OID name_type; gss_OID mech_type; gss_OID_set_desc oid_set; gss_name_t target_name; gss_ctx_id_t init_context; gss_ctx_id_t accept_context; gss_ctx_id_desc * init_context_handle; gss_ctx_id_t del_init_context; gss_ctx_id_t del_accept_context; gss_cred_id_t delegated_cred; gss_cred_id_t imported_cred; gss_cred_id_t cred_handle; char * subject = "/O=Grid/O=Globus/OU=mcs.anl.gov/CN=Samuel Meder"; char * error_str; char * buf; /* Initialize variables */ token_ptr = GSS_C_NO_BUFFER; init_context = GSS_C_NO_CONTEXT; accept_context = GSS_C_NO_CONTEXT; del_init_context = GSS_C_NO_CONTEXT; del_accept_context = GSS_C_NO_CONTEXT; name_type = GSS_C_NT_USER_NAME; delegated_cred = GSS_C_NO_CREDENTIAL; accept_maj_stat = GSS_S_CONTINUE_NEEDED; ret_flags = 0; oid_buffer.value = malloc(EXT_SIZE); oid_buffer.length = EXT_SIZE; buf = (char *) oid_buffer.value; memset(buf,'A',EXT_SIZE); buf[EXT_SIZE-1]='\0'; oid_buffers.count = 1; oid_buffers.elements = &oid_buffer; oid_set.count = 1; oid_set.elements = gss_restrictions_extension; send_tok.value = subject; send_tok.length = strlen(subject) + 1; /* acquire the credential */ maj_stat = gss_acquire_cred(&min_stat, NULL, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_BOTH, &cred_handle, NULL, NULL); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } /* import the subject name */ maj_stat = gss_import_name(&min_stat, &send_tok, name_type, &target_name); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } /* set up the first security context */ init_maj_stat = gss_init_sec_context(&min_stat, cred_handle, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } while(1) { accept_maj_stat=gss_accept_sec_context(&min_stat, &accept_context, GSS_C_NO_CREDENTIAL, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, NULL, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, GSS_C_NO_CREDENTIAL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } } printf("%s:%d: Successfully established initial security context\n", __FILE__, __LINE__); /* delegate our credential over the initial security context and * insert a restriction extension into the delegated credential. * This is a post GT 2.0 feature. */ init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, &oid_set, &oid_buffers, token_ptr, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } while(1) { accept_maj_stat=gss_accept_delegation(&min_stat, accept_context, GSS_C_NO_OID_SET, GSS_C_NO_BUFFER_SET, &send_tok, 0, &time_rec, &delegated_cred, &mech_type, &recv_tok); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_delegation(&min_stat, init_context, cred_handle, GSS_C_NO_OID, &oid_set, &oid_buffers, &recv_tok, 0, &send_tok); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } } printf("%s:%d: Successfully delegated credential\n", __FILE__, __LINE__); /* export and import the delegated credential */ /* this can be done both to a buffer and to a file */ /* New in GT 2.0 */ maj_stat = gss_export_cred(&min_stat, delegated_cred, GSS_C_NO_OID, 0, &send_tok); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } maj_stat = gss_import_cred(&min_stat, &imported_cred, GSS_C_NO_OID, 0, &send_tok, 0, &time_rec); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } printf("%s:%d: Successfully exported/imported the delegated credential\n", __FILE__, __LINE__); free(oid_buffer.value); oid_buffer.value = (void *) &oid_set; oid_buffer.length = 1; /* Tell the GSS that we will handle restriction extensions */ /* This is a post GT 2.0 feature */ maj_stat = gss_set_sec_context_option( &min_stat, &del_init_context, (gss_OID) GSS_APPLICATION_WILL_HANDLE_EXTENSIONS, &oid_buffer); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } maj_stat = gss_set_sec_context_option( &min_stat, &del_accept_context, (gss_OID) GSS_APPLICATION_WILL_HANDLE_EXTENSIONS, &oid_buffer); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } /* set up another security context using the delegated credential */ init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, token_ptr, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } while(1) { accept_maj_stat=gss_accept_sec_context(&min_stat, &del_accept_context, imported_cred, &send_tok, GSS_C_NO_CHANNEL_BINDINGS, &target_name, &mech_type, &recv_tok, &ret_flags, /* ignore time_rec */ NULL, GSS_C_NO_CREDENTIAL); if(accept_maj_stat != GSS_S_COMPLETE && accept_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } else if(accept_maj_stat == GSS_S_COMPLETE) { break; } init_maj_stat = gss_init_sec_context(&min_stat, imported_cred, &del_init_context, target_name, GSS_C_NULL_OID, 0, 0, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, NULL, NULL); if(init_maj_stat != GSS_S_COMPLETE && init_maj_stat != GSS_S_CONTINUE_NEEDED) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } } /* got sec context based on delegated cred now */ printf("%s:%d: Successfully established security context with delegated credential\n", __FILE__, __LINE__); /* Extract and print the restrictions extension from the security * context. * This is a post GT 2.0 feature. */ maj_stat = gss_inquire_sec_context_by_oid(&min_stat, del_accept_context, gss_restrictions_extension, &inquire_buffers); if(maj_stat != GSS_S_COMPLETE) { globus_gss_assist_display_status_str(&error_str, NULL, init_maj_stat, min_stat, 0); printf("\nLINE %d ERROR: %s\n\n", __LINE__, error_str); exit(1); } printf("%s:%d: Security context contains restriction extension %s\n", __FILE__, __LINE__, (char *) inquire_buffers->elements[0].value); }
gfarmExportedCredential * gfarmGssExportCredential(gss_cred_id_t cred, OM_uint32 *statPtr) { gfarmExportedCredential *exportedCred = NULL; OM_uint32 majStat = 0; OM_uint32 minStat = 0; gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; char *exported, *filename, *env; static char exported_name[] = "X509_USER_DELEG_PROXY="; static char env_name[] = "X509_USER_PROXY="; static char file_prefix[] = "FILE:"; majStat = gss_export_cred(&minStat, cred, GSS_C_NO_OID, 1, &buf); if (GSS_ERROR(majStat)) goto Done; exported = buf.value; for (filename = exported; *filename != '\0'; filename++) if (!isalnum(*(unsigned char *)filename) && *filename != '_') break; if (*filename != '=') { /* not an environment variable */ majStat = GSS_S_UNAVAILABLE; goto Done; } filename++; if (memcmp(exported, exported_name, sizeof(exported_name) - 1) == 0) { GFARM_MALLOC_ARRAY(env, sizeof(env_name) + strlen(filename)); if (env == NULL) { majStat = GSS_S_FAILURE; goto Done; } memcpy(env, env_name, sizeof(env_name) - 1); strcpy(env + sizeof(env_name) - 1, filename); filename = env + sizeof(env_name) - 1; } else { env = strdup(exported); if (env == NULL) { majStat = GSS_S_FAILURE; goto Done; } filename = env + (filename - exported); } if (memcmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0) filename += sizeof(file_prefix) - 1; GFARM_MALLOC(exportedCred); if (exportedCred == NULL) { free(env); majStat = GSS_S_FAILURE; goto Done; } exportedCred->env = env; exportedCred->filename = access(filename, R_OK) == 0 ? filename : NULL; Done: gss_release_buffer(&minStat, &buf); if (statPtr != NULL) *statPtr = majStat; if (GSS_ERROR(majStat)) { gflog_debug(GFARM_MSG_1000800, "failed to export credential (%u)(%u)", majStat, minStat); } return exportedCred; }