static krb5_error_code find_cred(krb5_context context, krb5_ccache id, krb5_principal server, krb5_creds **tgts, krb5_creds *out_creds) { krb5_error_code ret; krb5_creds mcreds; krb5_cc_clear_mcred(&mcreds); mcreds.server = server; ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, &mcreds, out_creds); if(ret == 0) return 0; while(tgts && *tgts){ if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, &mcreds, *tgts)){ ret = krb5_copy_creds_contents(context, *tgts, out_creds); return ret; } tgts++; } return not_found(context, server, KRB5_CC_NOTFOUND); }
static krb5_error_code mcc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_mcache *m = MCACHE(id); krb5_error_code ret; struct link *l; if (MISDEAD(m)) return ENOENT; l = malloc (sizeof(*l)); if (l == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return KRB5_CC_NOMEM; } l->next = m->creds; m->creds = l; memset (&l->cred, 0, sizeof(l->cred)); ret = krb5_copy_creds_contents (context, creds, &l->cred); if (ret) { m->creds = l->next; free (l); return ret; } return 0; }
krb5_error_code kcm_ccache_store_cred_internal(krb5_context context, kcm_ccache ccache, krb5_creds *creds, int copy, krb5_creds **credp) { struct kcm_creds **c; krb5_error_code ret; for (c = &ccache->creds; *c != NULL; c = &(*c)->next) ; *c = (struct kcm_creds *)calloc(1, sizeof(**c)); if (*c == NULL) return KRB5_CC_NOMEM; RAND_bytes((*c)->uuid, sizeof((*c)->uuid)); *credp = &(*c)->cred; if (copy) { ret = krb5_copy_creds_contents(context, creds, *credp); if (ret) { free(*c); *c = NULL; } } else { **credp = *creds; ret = 0; } return ret; }
krb5_error_code KRB5_LIB_FUNCTION krb5_init_creds_get_creds(krb5_context context, krb5_init_creds_context ctx, krb5_creds *cred) { return krb5_copy_creds_contents(context, &ctx->cred, cred); }
/* * Obtain renewed credentials for the given service using the existing * credentials in the provided ticket cache. */ krb5_error_code krb5_get_renewed_creds(krb5_context ctx, krb5_creds *creds, krb5_const_principal client, krb5_ccache ccache, const char *in_tkt_service) { krb5_kdc_flags flags; krb5_creds in, *old = NULL, *out = NULL; krb5_error_code code; flags.i = 0; flags.b.renewable = 1; flags.b.renew = 1; memset(&in, 0, sizeof(in)); code = krb5_copy_principal(ctx, client, &in.client); if (code != 0) goto done; if (in_tkt_service == NULL) { const char *realm; realm = krb5_principal_get_realm(ctx, client); if (realm == NULL) { code = KRB5_CONFIG_NODEFREALM; goto done; } code = krb5_build_principal(ctx, &in.server, strlen(realm), realm, "krbtgt", realm, (const char *) NULL); if (code != 0) goto done; } else { code = krb5_parse_name(ctx, in_tkt_service, &in.server); if (code != 0) goto done; } code = krb5_get_credentials(ctx, 0, ccache, &in, &old); if (code != 0) goto done; flags.b.forwardable = old->flags.b.forwardable; flags.b.proxiable = old->flags.b.proxiable; code = krb5_get_kdc_cred(ctx, ccache, flags, NULL, NULL, old, &out); if (code != 0) goto done; #ifdef HAVE_KRB5_COPY_CREDS_CONTENTS code = krb5_copy_creds_contents(ctx, out, creds); krb5_free_creds(ctx, out); #else /* No good alternative -- hope this works. */ *creds = *out; free(out); #endif done: krb5_free_cred_contents(ctx, &in); if (old != NULL) krb5_free_creds(ctx, old); return code; }
krb5_error_code KRB5_LIB_FUNCTION krb5_copy_creds (krb5_context context, const krb5_creds *incred, krb5_creds **outcred) { krb5_creds *c; c = malloc (sizeof (*c)); if (c == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } memset (c, 0, sizeof(*c)); *outcred = c; return krb5_copy_creds_contents (context, incred, c); }
static krb5_error_code mcc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_mcache *m = MCACHE(id); struct link *l; if (MISDEAD(m)) return ENOENT; l = *cursor; if (l != NULL) { *cursor = l->next; return krb5_copy_creds_contents (context, &l->cred, creds); } else return KRB5_CC_END; }
static krb5_error_code kcmss_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code ret; kcm_ccache c = KCMCACHE(id); KCM_ASSERT_VALID(c); ret = krb5_copy_creds_contents(context, &((struct kcm_creds *)cursor)->cred, creds); if (ret) return ret; *cursor = ((struct kcm_creds *)cursor)->next; if (*cursor == 0) ret = KRB5_CC_END; return ret; }
static krb5_error_code kcmss_retrieve(krb5_context context, krb5_ccache id, krb5_flags which, const krb5_creds *mcred, krb5_creds *creds) { krb5_error_code ret; kcm_ccache c = KCMCACHE(id); krb5_creds *credp; KCM_ASSERT_VALID(c); ret = kcm_ccache_retrieve_cred_internal(context, c, which, mcred, &credp); if (ret) return ret; ret = krb5_copy_creds_contents(context, credp, creds); if (ret) return ret; return 0; }
int main(int argc, char **argv) { int log_level = 0; char *data_str; char *ap_req_str = NULL; unsigned char *data; size_t data_len; /* krb5 */ krb5_error_code ret; krb5_context context; krb5_auth_context auth_context; char *princ_str_tn = "kink/tn.example.com"; krb5_principal princ_tn; char *princ_str_nut = "kink/nut.example.com"; krb5_principal princ_nut; char *princ_str_krbtgt = "krbtgt/EXAMPLE.COM"; krb5_principal princ_krbtgt; krb5_ccache ccache; krb5_keytab keytab; krb5_creds creds_tgt; krb5_data ap_req; prog = (const char *) basename(argv[0]); if (prog == NULL) { fprintf(stderr, "basename: %s -- %s\n", strerror(errno), argv[0]); return(0); /* NOTREACHED */ } { int ch = 0; while ((ch = getopt(argc, argv, "dq:")) != -1) { switch (ch) { case 'd': log_level++; break; case 'q': ap_req_str = optarg; break; default: usage(); /* NOTREACHED */ break; } } argc -= optind; argv += optind; } if (!argc) { usage(); /* NOTREACHED */ } data_str = argv[0]; { printf("dbg: %s starts arg(%s)\n", prog, data_str); } { { /* stdout */ printf("std:data:%s\n", data_str); } data_len = strlen(data_str); data_len = data_len/2 + data_len%2; data = (unsigned char *)malloc(data_len); memset(data, 0, data_len); data = hex2data(data_str, data); } if (ap_req_str != NULL) { hex2krb5data(ap_req_str, &ap_req); if (log_level) { dump_krb5_data(&ap_req); } { /* stdout */ int i = 0; unsigned char *p; p = (unsigned char *)ap_req.data; printf("std:ap_req:"); for (i = 0; i < ap_req.length; i++) { printf("%02x", *p++); } printf("\n"); } } /* prepare krb5 context */ { /** init context */ ret = krb5_init_context(&context); if (ret != 0) { printf("ERR:krb5_init_context:%s\n", krb5_get_err_text(context, ret)); return(ret); } /** setup principals */ ret = krb5_parse_name(context, princ_str_tn, &princ_tn); if (ret != 0) { printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret)); return(ret); } ret = krb5_parse_name(context, princ_str_nut, &princ_nut); if (ret != 0) { printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret)); return(ret); } ret = krb5_parse_name(context, princ_str_krbtgt, &princ_krbtgt); if (ret != 0) { printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret)); return(ret); } /** prepare credential cache */ ret = krb5_cc_default(context, &ccache); if (ret != 0) { printf("ERR:krb5_cc_default:%s\n", krb5_get_err_text(context, ret)); return(ret); } /** prepare keytab */ /*ret = krb5_kt_resolve(context, "/usr/local/var/krb5kdc/kadm5.keytab", &keytab);*/ ret = krb5_kt_default(context, &keytab); if (ret != 0) { /* printf("ERR:krb5_kt_default:%s", krb5_get_err_text(context, ret)); */ printf("ERR:krb5_kt_resolve:%s", krb5_get_err_text(context, ret)); return(ret); } } /* get TGT */ { krb5_creds mcreds; memset(&mcreds, 0, sizeof(mcreds)); mcreds.client = princ_tn; mcreds.server = princ_krbtgt; ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &creds_tgt); if (ret != 0) { printf("ERR:krb5_cc_retrieve_cred:%s\n", krb5_get_err_text(context, ret)); return(ret); } } /* prepare authentiation context */ { ret = krb5_auth_con_init(context, &auth_context); if (ret != 0) { printf("ERR:krb5_auth_con_init:%s\n", krb5_get_err_text(context, ret)); return(ret); } ret = krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if (ret != 0) { printf("ERR:krb5_auth_con_setflags:%s\n", krb5_get_err_text(context, ret)); return(ret); } /* if USE_SKEY */ /* ret = krb5_auth_con_setuserkey(context, auth_context, &creds_tgt.session); if (ret != 0) { printf("ERR:krb5_auth_con_setuseruserkey:%s\n", krb5_get_err_text(context, ret)); return(ret); } */ } /* set keyblock in auth_context */ if (ap_req_str != NULL) { krb5_ticket *ticket; krb5_flags ap_req_options; ap_req_options = AP_OPTS_MUTUAL_REQUIRED; ticket = NULL; ret = krb5_rd_req(context, &auth_context, &ap_req, NULL, keytab, &ap_req_options, &ticket); if (log_level) { printf("info: ticket.ticket.key is SKEYID_d\n"); /*dump_krb5_ticket(context, *ticket);*/ } if (log_level) { printf("ap_req_opt (%d)\n", ap_req_options); } if (ret != 0) { printf("ERR:krb5_rd_req:%s\n", krb5_get_err_text(context, ret)); return(ret); } if (log_level) { dump_krb5_keyblock(auth_context->keyblock); } krb5_free_ticket(context, ticket); } else { krb5_creds mcreds; krb5_creds *cred; krb5_creds cred_copy; memset(&mcreds, 0, sizeof(mcreds)); mcreds.client = princ_tn; mcreds.server = princ_nut; ret = krb5_get_credentials(context, KRB5_GC_CACHED, ccache, &mcreds, &cred); if (ret != 0) { printf("ERR:krb5_get_credentials:%s\n", krb5_get_err_text(context, ret)); return(ret); } /* mk_req_extends reallocate cred, so use a copy */ ret = krb5_copy_creds_contents(context, (const krb5_creds *)cred, &cred_copy); if (ret != 0) { printf("ERR:krb5_copy_creds_contents:%s\n", krb5_get_err_text(context, ret)); return(ret); } /* * If auth_con == NULL, one is allocated. * This is used later. (keyblock is used to decrypt AP_REP) */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_MUTUAL_REQUIRED, NULL /* in_data */, &cred_copy, &ap_req); if (ret != 0) { printf("ERR:krb5_mk_req_extended:%s\n", krb5_get_err_text(context, ret)); return(ret); } } /* create checksum */ { krb5_crypto crypto; krb5_checksum cksum; ret = krb5_crypto_init(context, auth_context->keyblock, auth_context->keyblock->keytype, &crypto); if (ret != 0) { printf("ERR:krb5_crypto_init:%s\n", krb5_get_err_text(context, ret)); return(ret); } if (0) { dump_krb5_keyblock(auth_context->keyblock); } ret = krb5_create_checksum(context, crypto, 40, 0 /* krb5_cksumtype type */, data, data_len, &cksum); if (ret != 0) { printf("ERR:krb5_create_checksum:%s\n", krb5_get_err_text(context, ret)); return(ret); } if (log_level) { dump_krb5_checksum(cksum); } { /* stdout */ int i = 0; unsigned char *p; p = (unsigned char *)cksum.checksum.data; printf("std:cksum:"); for (i = 0; i < cksum.checksum.length; i++) { printf("%02x", *p++); } printf("\n"); } krb5_crypto_destroy(context, crypto); } /* clenaup */ { /*free(data);*/ /*krb5_data_free(&ap_req);*/ krb5_free_cred_contents(context, &creds_tgt); ret = krb5_kt_close(context, keytab); if (ret != 0) { printf("ERR:krb5_kt_close:%s\n", krb5_get_err_text(context, ret)); return(ret); } ret = krb5_cc_close(context, ccache); if (ret != 0) { printf("ERR:krb5_cc_close:%s\n", krb5_get_err_text(context, ret)); return(ret); } krb5_free_principal(context, princ_krbtgt); krb5_free_principal(context, princ_nut); krb5_free_principal(context, princ_tn); krb5_free_context(context); } return(0); }