void krb5_deleteprinc(krb5_context ctx, kadm5_handle hndl, char *in) { krb5_principal princ = NULL; kadm5_ret_t ret; char croakstr[2048] = ""; K5BAIL(krb5_parse_name(ctx, in, &princ)); K5BAIL(kadm5_delete_principal(hndl, princ)); done: /* XXXrcd: free the princ. */ if (ret) croak("%s", croakstr); }
char * krb5_createprinc(krb5_context ctx, kadm5_handle hndl, kadm5_principal_ent_rec p, long mask, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, char *passwd) { kadm5_ret_t ret; char croakstr[2048] = ""; if (passwd) passwd = strdup(passwd); else passwd = random_passwd(ctx, HUMAN_PASSWD_SIZE); if (!passwd) croak("Out of memory."); mask |= KADM5_PRINCIPAL; K5BAIL(kadm5_create_principal_3(hndl, &p, mask, n_ks_tuple, ks_tuple, passwd)); done: if (ret) { free(passwd); croak("%s", croakstr); } return passwd; }
kadm5_handle krb5_get_kadm5_hndl(krb5_context ctx, char *dbname, const char *princstr) { kadm5_config_params params; kadm5_ret_t ret; kadm5_handle hndl; char croakstr[2048] = ""; memset((char *) ¶ms, 0, sizeof(params)); if (dbname) { params.mask = KADM5_CONFIG_DBNAME; params.dbname = dbname; } if (!princstr) princstr = "root"; K5BAIL(KADM5_INIT_WITH_PASSWORD(ctx, (char *)princstr, ¶ms, &hndl)); done: if (ret) croak("%s", croakstr); return hndl; }
void krb5_modprinc(krb5_context ctx, kadm5_handle hndl, kadm5_principal_ent_rec p, long mask) { kadm5_ret_t ret; char croakstr[256] = ""; K5BAIL(kadm5_modify_principal(hndl, &p, mask)); done: if (ret) croak("%s", croakstr); }
kadm5_principal_ent_rec krb5_query_princ(krb5_context ctx, kadm5_handle hndl, char *in) { kadm5_principal_ent_rec dprinc; krb5_principal princ = NULL; kadm5_ret_t ret; char croakstr[2048] = ""; memset(&dprinc, 0, sizeof(dprinc)); K5BAIL(krb5_parse_name(ctx, in, &princ)); K5BAIL(kadm5_get_principal(hndl, princ, &dprinc, KADM5_PRINCIPAL_NORMAL_MASK)); done: if (princ) krb5_free_principal(ctx, princ); /* XXXrcd: free dprinc */ if (ret) croak("%s", croakstr); return dprinc; }
static int k5ping(krb5_context ctx, const char *host, int socktype, krb5_principal princ, int use_kt, const char *passwd, krb5_principal sprinc) { K5BAIL_DECLS; krb5_error_code kerr; krb5_ccache ccache = NULL; krb5_keytab kt; krb5_creds creds; krb5_get_init_creds_opt *opt = NULL; VERBOSE(1, (stderr, "initiating kerberos5/%s ping to %s\n", socktype == SOCK_DGRAM ? "udp" : "tcp", host)); parse_kdc(host); current_socktype = socktype; K5BAIL(krb5_cc_resolve(ctx, "MEMORY:k5ping", &ccache)); K5BAIL(krb5_get_init_creds_opt_alloc(ctx, &opt)); krb5_get_init_creds_opt_set_tkt_life(opt, 15 * 60); if (use_kt) { K5BAIL(krb5_kt_default(ctx, &kt)); K5BAIL(krb5_get_init_creds_keytab(ctx, &creds, princ, kt, 0, NULL, opt)); } else { K5BAIL(krb5_get_init_creds_password(ctx, &creds, princ, passwd, krb5_prompter_posix, NULL, 0, NULL, opt)); } K5BAIL(krb5_cc_store_cred(ctx, ccache, &creds)); kret = kvno5(ctx, host, socktype, princ, sprinc, ccache); done: if (ccache) krb5_cc_destroy(ctx, ccache); /* XXXrcd: free a few more things here... */ /* opt. creds. */ if (croakstr[0]) fail_msg("kerberos5", socktype, host, croakstr); return kret; }
static char * random_passwd(krb5_context ctx, int len) { krb5_keyblock key; krb5_error_code ret; char croakstr[2048] = ""; char *passwd = NULL; unsigned char *tmp; int i; passwd = malloc(len + 1); if (!passwd) { snprintf(croakstr, sizeof(croakstr), "Out of memory"); ret = errno; goto done; } /* We lamely convert a key into a string for the passwd */ K5BAIL(krb5_c_make_random_key(ctx, 18, &key)); /* * We are contructing what we presume to be a relatively good * passwd here. First, we select a single character from each * of three character classes. We do this up front to ensure * that all passwds contain at least 3 character classes. We * could generate and then test, but we don't. We looking to * weight things a little away from the symbols and towards * simplicity. So, let's say that lower or upper case characters * have about 4.5 bits of strength given that we've selected * 23 of them. The numbers have about 2.2 or so. Our c_all[] * is also a little skewed. We have 79 possible characters but * we're skewing towards lower case to make it easier to type. * So, we're not really getting over 6 bits out of it. Still, * let's say that we're getting 5.5, then our 10 char passwd * is: * * 2.2 + 4.5 + 4.5 + 7 * 5.5 = 49 bits. * * XXXrcd: * Also note that because of our use of simple modulo arith, * we're slightly biasing results towards the fronts of each * of these character classes... * * Good enough. Certainly better than the users will choose for * themselves. */ tmp = KEYBLOCK_CONTENTS(key); passwd[0] = c_low[tmp[0] % (sizeof(c_low) - 1)]; passwd[1] = c_cap[tmp[1] % (sizeof(c_cap) - 1)]; passwd[2] = c_num[tmp[2] % (sizeof(c_num) - 1)]; for (i=3; i < len; i++) passwd[i] = c_all[tmp[i] % (sizeof(c_all) - 1)]; krb5_free_keyblock_contents(ctx, &key); passwd[i] = '\0'; done: if (ret) { free(passwd); croak("%s", croakstr); } return passwd; }
int main(int argc, char **argv) { K5BAIL_DECLS; krb5_context ctx; krb5_principal princ; krb5_principal sprinc; int ch; int ret; int do_tcp = 0; int do_udp = 0; int do_v4 = 0; int do_v5 = 0; int do_524 = 0; int times = 1; int use_kt = 0; char v4_ticket_file[128]; char *passwd = NULL; char *tprinc = NULL; char *tsprinc = NULL; progname = strrchr(argv[0], '/'); if (progname) progname++; else progname = argv[0]; while ((ch = getopt(argc, argv, "459P:S:kn:p:tuv")) != -1) switch (ch) { case '4': do_v4 = 1; break; case '5': do_v5 = 1; break; case '9': do_524 = 1; break; case 'P': free(passwd); passwd = strdup(optarg); break; case 'S': free(tsprinc); tsprinc = strdup(optarg); break; case 'k': use_kt = 1; break; case 'n': times = atoi(optarg); break; case 'p': free(tprinc); tprinc = strdup(optarg); break; case 't': do_tcp = 1; break; case 'u': do_udp = 1; break; case 'v': verbose++; break; default: usage(); } argc -= optind; argv += optind; /* Check sanity */ if (passwd && use_kt) { fprintf(stderr, "Cannot use both passwd and keytab.\n"); exit(1); } #ifdef HAVE_KRB4 if (do_v4 && use_kt) { fprintf(stderr, "Cannot use keytab with Kerberos IV.\n"); exit(1); } #endif #ifndef HAVE_KRB4 if (do_v4 || do_524) { fprintf(stderr, "Kerberos IV unsupported in this " "implementation.\n"); exit(1); } #endif /* Fill in default values */ if (!tprinc) tprinc = strdup(PING_PRINC); if (!tsprinc) tsprinc = strdup(PING_SPRINC); if (!use_kt && !passwd) passwd = strdup(PING_PASSWD); if (!use_kt && !*passwd) { /* on empty passwds we prompt for it */ passwd = getpass("Password:"******"/tmp/k5ping_tkt4_%d_%d", getpid(), getuid()); k_set_default_cache_k4(ctx, v4_ticket_file); #endif VERBOSE(1, (stderr, "princ: %s\nsprinc: %s\n", tprinc, tsprinc)); while (times-- > 0) { int i; ret = 0; for (i=0; argv[i]; i++) { if (do_v5 && do_tcp && k5ping(ctx, argv[i], SOCK_STREAM, princ, use_kt, passwd, sprinc)) { ret++; continue; } if (do_v5 && do_udp && k5ping(ctx, argv[i], SOCK_DGRAM, princ, use_kt, passwd, sprinc)) { ret++; continue; } #ifdef HAVE_KRB4 if (do_524 && k524ping(ctx, argv[i], tsprinc)) { ret++; continue; } if (do_v4 && k4ping(ctx, argv[i], princ, passwd, sprinc)) { ret++; continue; } #endif if (times == 0) printf("k5ping(%s): successful\n", argv[i]); } } done: if (croakstr[0]) fprintf(stderr, "FATAL: %s\n", croakstr); exit(ret); }
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; }