static void mag_store_deleg_creds(request_rec *req, char *dir, char *clientname, gss_cred_id_t delegated_cred, char **ccachefile) { gss_key_value_element_desc element; gss_key_value_set_desc store; char *value; uint32_t maj, min; value = apr_psprintf(req->pool, "FILE:%s/%s", dir, clientname); if (!value) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL, "OOM storing delegated credentials"); return; } element.key = "ccache"; element.value = value; store.elements = &element; store.count = 1; maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE, GSS_C_NULL_OID, 1, 1, &store, NULL, NULL); if (GSS_ERROR(maj)) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req, "%s", mag_error(req, "failed to store delegated creds", maj, min)); } *ccachefile = value; }
static void check_ticket_count(gss_cred_id_t cred, int expected) { krb5_error_code ret; krb5_context context = NULL; krb5_creds kcred; krb5_cc_cursor cur; krb5_ccache ccache; int count = 0; gss_key_value_set_desc store; gss_key_value_element_desc elem; OM_uint32 major, minor; const char *ccname = "MEMORY:count"; store.count = 1; store.elements = &elem; elem.key = "ccache"; elem.value = ccname; major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, &mech_krb5, 1, 0, &store, NULL, NULL); check_gsserr("gss_store_cred_into", major, minor); ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_cc_resolve(context, ccname, &ccache); check_k5err(context, "krb5_cc_resolve", ret); ret = krb5_cc_start_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_start_seq_get", ret); while (!krb5_cc_next_cred(context, ccache, &cur, &kcred)) { if (!krb5_is_config_principal(context, kcred.server)) count++; krb5_free_cred_contents(context, &kcred); } ret = krb5_cc_end_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_end_seq_get", ret); if (expected != count) { printf("Expected %d tickets but got %d\n", expected, count); exit(1); } krb5_cc_destroy(context, ccache); krb5_free_context(context); }
static void mag_store_deleg_creds(request_rec *req, const char *ccname, gss_cred_id_t delegated_cred) { gss_key_value_element_desc element; gss_key_value_set_desc store; uint32_t maj, min; element.key = "ccache"; store.elements = &element; store.count = 1; element.value = apr_psprintf(req->pool, "FILE:%s", ccname); maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE, GSS_C_NULL_OID, 1, 1, &store, NULL, NULL); if (GSS_ERROR(maj)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", mag_error(req, "failed to store delegated creds", maj, min)); } }
static int read_one_token(gss_name_t service, const char *ccname, int negotiate) { gss_cred_id_t cred = NULL; gss_cred_id_t deleg_creds = NULL; gss_name_t client; gss_OID mech_oid; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_buffer_desc in, out, dname; krb5_context kctx = NULL; krb5_ccache ccache = NULL; krb5_error_code kret; OM_uint32 maj, min; char *inbuf = NULL; char *tmp; char buf[65536]; int ret = 0; if (service) { maj = gss_acquire_cred(&min, service, 0, NULL, GSS_C_ACCEPT, &cred, NULL, NULL); GBAIL("gss_acquire_cred", maj, min); } inbuf = read_buffer(stdin); if (!inbuf) /* Just a couple of \n's in a row or EOF, not an error. */ return 0; tmp = inbuf; if (negotiate) { if (strncasecmp("Negotiate ", inbuf, 10)) { fprintf(stderr, "Token doesn't begin with " "\"Negotiate \"\n"); return -1; } tmp += 10; } in.length = base64_decode((uint8_t *)tmp, strlen(tmp), (uint8_t *)buf, sizeof(buf)); in.value = buf; out.length = 0; out.value = 0; maj = gss_accept_sec_context(&min, &ctx, cred, &in, GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_oid, &out, NULL, NULL, &deleg_creds); GBAIL("gss_accept_sec_context", maj, min); /* * XXXrcd: not bothering to clean up because we're about to exit. * Probably should fix this in case the code is used as * an example by someone. */ maj = gss_display_name(&min, client, &dname, NULL); GBAIL("gss_display_name", maj, min); if (!nflag) printf("Authenticated: %.*s\n", (int)dname.length, (char *)dname.value); if (ccname) { #ifdef HAVE_GSS_STORE_CRED_INTO gss_key_value_set_desc store; gss_key_value_element_desc elem; int overwrite_cred = 1; int default_cred = 0; elem.key = "ccache"; elem.value = ccname; store.count = 1; store.elements = &elem; maj = gss_store_cred_into(&min, deleg_creds, GSS_C_INITIATE, GSS_C_NO_OID, overwrite_cred, default_cred, &store, NULL, NULL); GBAIL("gss_store_cred_into", maj, min); #else K5BAIL(krb5_init_context(&kctx)); K5BAIL(krb5_cc_resolve(kctx, ccname, &ccache)); maj = gss_krb5_copy_ccache(&min, deleg_creds, ccache); GBAIL("gss_krb5_copy_ccache", maj, min); #endif } bail: if (kctx) krb5_free_context(kctx); if (ccache) krb5_cc_close(kctx, ccache); if (cred) gss_release_cred(&min, &cred); if (deleg_creds) gss_release_cred(&min, &deleg_creds); free(inbuf); return ret; }
int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_key_value_set_desc store; gss_buffer_desc buf; gss_name_t service = GSS_C_NO_NAME; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; int i, e; if (argc < 2 || ((argc - 3) % 2)) { usage(argv[0]); exit(1); } store.count = (argc - 3) / 2; store.elements = calloc(store.count, sizeof(struct gss_key_value_element_struct)); if (!store.elements) { fprintf(stderr, "OOM\n"); exit(1); } if (argc > 2) { if (strcmp(argv[2], "--cred_store") != 0) { usage(argv[0]); exit(1); } for (i = 3, e = 0; i < argc; i += 2, e++) { store.elements[e].key = argv[i]; store.elements[e].value = argv[i + 1]; continue; } } /* First acquire default creds and try to store them in the cred store. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred, NULL, NULL); if (major) { print_status("gss_acquire_cred(default user creds) failed", major, minor); goto out; } major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, GSS_C_NO_OID, 1, 0, &store, NULL, NULL); if (major) { print_status("gss_store_cred_in_store(default user creds) failed", major, minor); goto out; } gss_release_cred(&minor, &cred); /* Then try to acquire creds from store. */ buf.value = argv[1]; buf.length = strlen(argv[1]); major = gss_import_name(&minor, &buf, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &service); if (major) { print_status("gss_import_name(principal) failed", major, minor); goto out; } major = gss_acquire_cred_from(&minor, service, 0, GSS_C_NO_OID_SET, GSS_C_BOTH, &store, &cred, NULL, NULL); if (major) { print_status("gss_acquire_cred_from_store(principal) failed", major, minor); goto out; } fprintf(stdout, "Cred Store Success\n"); major = 0; out: gss_release_name(&minor, &service); gss_release_cred(&minor, &cred); free(store.elements); return major; }