diff options
Diffstat (limited to 'kuser')
-rw-r--r-- | kuser/kgetcred.1 | 3 | ||||
-rw-r--r-- | kuser/kgetcred.c | 5 | ||||
-rw-r--r-- | kuser/kgetcred.cat1 | 6 | ||||
-rw-r--r-- | kuser/kimpersonate.c | 8 | ||||
-rw-r--r-- | kuser/kinit.1 | 12 | ||||
-rw-r--r-- | kuser/kinit.c | 94 | ||||
-rw-r--r-- | kuser/kinit.cat1 | 12 | ||||
-rw-r--r-- | kuser/klist.c | 10 |
8 files changed, 119 insertions, 31 deletions
diff --git a/kuser/kgetcred.1 b/kuser/kgetcred.1 index 5bc5762903fe..c8473ab99a5e 100644 --- a/kuser/kgetcred.1 +++ b/kuser/kgetcred.1 @@ -58,6 +58,7 @@ .Op Fl Fl no-transit-check .Op Fl Fl no-store .Op Fl Fl cached-only +.Op Fl n \*(Ba Fl Fl anonymous .Op Fl Fl version .Op Fl Fl help .Ar principal @@ -135,6 +136,8 @@ requests that the KDC doesn't do transit checking. do not store tickets in the ccache. .It Fl Fl cached-only do not talk the TGS, search only the ccache. +.It Fl Fl anonymous +obtain an anonymous service ticket. .It Fl Fl forwardable .It Fl Fl debug enables debug output to stderr. diff --git a/kuser/kgetcred.c b/kuser/kgetcred.c index b95bc9d05e2e..92eb770990c5 100644 --- a/kuser/kgetcred.c +++ b/kuser/kgetcred.c @@ -46,6 +46,7 @@ static char *impersonate_str; static char *nametype_str; static int store_flag = 1; static int cached_only_flag; +static int anonymous_flag; static int debug_flag; static int version_flag; static int help_flag; @@ -76,6 +77,8 @@ struct getargs args[] = { NP_("don't store the tickets obtained in the cache", ""), NULL }, { "cached-only", 0, arg_flag, &cached_only_flag, NP_("don't talk to the KDC, just search the cache", ""), NULL }, + { "anonymous", 'n', arg_flag, &anonymous_flag, + NP_("request an anonymous ticket", ""), NULL }, { "debug", 0, arg_flag, &debug_flag, NULL, NULL }, { "version", 0, arg_flag, &version_flag, NULL, NULL }, { "help", 0, arg_flag, &help_flag, NULL, NULL } @@ -176,6 +179,8 @@ main(int argc, char **argv) krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE); if (cached_only_flag) krb5_get_creds_opt_add_options(context, opt, KRB5_GC_CACHED); + if (anonymous_flag) + krb5_get_creds_opt_add_options(context, opt, KRB5_GC_ANONYMOUS); if (delegation_cred_str) { krb5_ccache id; diff --git a/kuser/kgetcred.cat1 b/kuser/kgetcred.cat1 index c1c6ea212e66..cab2045d7d66 100644 --- a/kuser/kgetcred.cat1 +++ b/kuser/kgetcred.cat1 @@ -8,7 +8,8 @@ SSYYNNOOPPSSIISS kkggeettccrreedd [----ccaannoonniiccaalliizzee] [----ccaannoonniiccaall] [--cc --ccaacchhee | ----ccaacchhee==_c_a_c_h_e] [--ee _e_n_c_t_y_p_e | ----eennccttyyppee==_e_n_c_t_y_p_e] [----ddeebbuugg] [--HH | ----hhoossttbbaasseedd] [----nnaammee--ttyyppee==_n_a_m_e_-_t_y_p_e] [----nnoo--ttrraannssiitt--cchheecckk] [----nnoo--ssttoorree] - [----ccaacchheedd--oonnllyy] [----vveerrssiioonn] [----hheellpp] _p_r_i_n_c_i_p_a_l + [----ccaacchheedd--oonnllyy] [--nn | ----aannoonnyymmoouuss] [----vveerrssiioonn] [----hheellpp] + _p_r_i_n_c_i_p_a_l kkggeettccrreedd [options] ----hhoossttbbaasseedd _p_r_i_n_c_i_p_a_l kkggeettccrreedd [options] ----hhoossttbbaasseedd _s_e_r_v_i_c_e _h_o_s_t_n_a_m_e _[_e_x_t_r_a_-_c_o_m_p_o_n_e_n_t_s_] @@ -76,6 +77,9 @@ DDEESSCCRRIIPPTTIIOONN ----ccaacchheedd--oonnllyy do not talk the TGS, search only the ccache. + ----aannoonnyymmoouuss + obtain an anonymous service ticket. + ----ffoorrwwaarrddaabbllee ----ddeebbuugg diff --git a/kuser/kimpersonate.c b/kuser/kimpersonate.c index d2a485b3f939..b1cefea0fd49 100644 --- a/kuser/kimpersonate.c +++ b/kuser/kimpersonate.c @@ -82,7 +82,9 @@ encode_ticket(krb5_context context, et.flags = cred->flags.b; et.key = cred->session; et.crealm = cred->client->realm; - copy_PrincipalName(&cred->client->name, &et.cname); + ret = copy_PrincipalName(&cred->client->name, &et.cname); + if (ret) + krb5_err(context, 1, ret, "copy_PrincipalName"); { krb5_data empty_string; @@ -127,7 +129,9 @@ encode_ticket(krb5_context context, ticket.tkt_vno = 5; ticket.realm = cred->server->realm; - copy_PrincipalName(&cred->server->name, &ticket.sname); + ret = copy_PrincipalName(&cred->server->name, &ticket.sname); + if (ret) + krb5_err(context, 1, ret, "copy_PrincipalName"); ASN1_MALLOC_ENCODE(Ticket, buf, len, &ticket, &size, ret); if(ret) diff --git a/kuser/kinit.1 b/kuser/kinit.1 index 697f61b0ae2c..65d733d96ee3 100644 --- a/kuser/kinit.1 +++ b/kuser/kinit.1 @@ -82,7 +82,7 @@ .Op Fl Fl password-file= Ns Ar filename .Op Fl Fl fcache-version= Ns Ar version-number .Op Fl A | Fl Fl no-addresses -.Op Fl Fl anonymous +.Op Fl n | Fl Fl anonymous .Op Fl Fl enterprise .Op Fl Fl version .Op Fl Fl help @@ -165,10 +165,12 @@ in .Xr krb5.conf 5 . .It Fl A , Fl Fl no-addresses Request a ticket with no addresses. -.It Fl Fl anonymous -Request an anonymous ticket (which means that the ticket will be -issued to an anonymous principal, typically -.Dq anonymous@REALM ) . +.It Fl n , Fl Fl anonymous +Request an anonymous ticket. If the principal is specified as @REALM, then +anonymous PKINIT will be used to acquire an unauthenticated anonymous ticket +and both the client name and realm in the returned ticket will be anonymized. +Otherwise, authentication proceeds as normal and the anonymous ticket will have +only the client name anonymized. .It Fl Fl enterprise Parse principal as a enterprise (KRB5-NT-ENTERPRISE) name. Enterprise names are email like principals that are stored in the name part of diff --git a/kuser/kinit.c b/kuser/kinit.c index 4e93c6905231..4a263511470e 100644 --- a/kuser/kinit.c +++ b/kuser/kinit.c @@ -155,7 +155,7 @@ static struct getargs args[] = { { "extra-addresses",'a', arg_strings, &extra_addresses, NP_("include these extra addresses", ""), "addresses" }, - { "anonymous", 0, arg_flag, &anonymous_flag, + { "anonymous", 'n', arg_flag, &anonymous_flag, NP_("request an anonymous ticket", ""), NULL }, { "request-pac", 0, arg_flag, &pac_flag, @@ -206,6 +206,9 @@ static struct getargs args[] = { { "help", 0, arg_flag, &help_flag, NULL, NULL } }; +static char * +get_default_realm(krb5_context context); + static void usage(int ret) { @@ -236,7 +239,7 @@ copy_configs(krb5_context context, krb5_principal start_ticket_server) { krb5_error_code ret; - const char *cfg_names[] = {"realm-config", "FriendlyName", NULL}; + const char *cfg_names[] = {"realm-config", "FriendlyName", "anon_pkinit_realm", NULL}; const char *cfg_names_w_pname[] = {"fast_avail", NULL}; krb5_data cfg_data; size_t i; @@ -277,6 +280,34 @@ copy_configs(krb5_context context, } static krb5_error_code +get_anon_pkinit_tgs_name(krb5_context context, + krb5_ccache ccache, + krb5_principal *tgs_name) +{ + krb5_error_code ret; + krb5_data data; + char *realm; + + ret = krb5_cc_get_config(context, ccache, NULL, "anon_pkinit_realm", &data); + if (ret == 0) + realm = strndup(data.data, data.length); + else + realm = get_default_realm(context); + + krb5_data_free(&data); + + if (realm == NULL) + return krb5_enomem(context); + + ret = krb5_make_principal(context, tgs_name, realm, + KRB5_TGS_NAME, realm, NULL); + + free(realm); + + return ret; +} + +static krb5_error_code renew_validate(krb5_context context, int renew, int validate, @@ -296,7 +327,13 @@ renew_validate(krb5_context context, krb5_warn(context, ret, "krb5_cc_get_principal"); return ret; } - ret = get_server(context, in.client, server, &in.server); + + if (server == NULL && + krb5_principal_is_anonymous(context, in.client, + KRB5_ANON_MATCH_UNAUTHENTICATED)) + ret = get_anon_pkinit_tgs_name(context, cache, &in.server); + else + ret = get_server(context, in.client, server, &in.server); if (ret) { krb5_warn(context, ret, "get_server"); goto out; @@ -383,7 +420,7 @@ renew_validate(krb5_context context, out: if (tempccache) - krb5_cc_close(context, tempccache); + krb5_cc_destroy(context, tempccache); if (out) krb5_free_creds(context, out); krb5_free_cred_contents(context, &in); @@ -430,7 +467,8 @@ get_new_tickets(krb5_context context, krb5_principal principal, krb5_ccache ccache, krb5_deltat ticket_life, - int interactive) + int interactive, + int anonymous_pkinit) { krb5_error_code ret; krb5_creds cred; @@ -528,15 +566,15 @@ get_new_tickets(krb5_context context, krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag) krb5_get_init_creds_opt_set_win2k(context, opt, TRUE); - if (pk_user_id || ent_user_id || anonymous_flag) { + if (pk_user_id || ent_user_id || anonymous_pkinit) { ret = krb5_get_init_creds_opt_set_pkinit(context, opt, principal, pk_user_id, pk_x509_anchors, NULL, NULL, - pk_use_enckey ? 2 : 0 | - anonymous_flag ? 4 : 0, + pk_use_enckey ? KRB5_GIC_OPT_PKINIT_USE_ENCKEY : 0 | + anonymous_pkinit ? KRB5_GIC_OPT_PKINIT_ANONYMOUS : 0, prompter, NULL, passwd); @@ -628,7 +666,8 @@ get_new_tickets(krb5_context context, krb5_warn(context, ret, "krb5_init_creds_set_keytab"); goto out; } - } else if (pk_user_id || ent_user_id || anonymous_flag) { + } else if (pk_user_id || ent_user_id || + krb5_principal_is_anonymous(context, principal, KRB5_ANON_MATCH_ANY)) { } else if (!interactive && passwd[0] == '\0') { static int already_warned = 0; @@ -676,7 +715,7 @@ get_new_tickets(krb5_context context, if (ntlm_domain && passwd[0]) heim_ntlm_nt_key(passwd, &ntlmkey); #endif - memset(passwd, 0, sizeof(passwd)); + memset_s(passwd, sizeof(passwd), 0, sizeof(passwd)); switch(ret){ case 0: @@ -774,12 +813,21 @@ get_new_tickets(krb5_context context, krb5_cc_set_config(context, ccache, NULL, "realm-config", &data); } + if (anonymous_pkinit) { + krb5_data data; + + data.length = strlen(principal->realm); + data.data = principal->realm; + + krb5_cc_set_config(context, ccache, NULL, "anon_pkinit_realm", &data); + } + out: krb5_get_init_creds_opt_free(context, opt); if (ctx) krb5_init_creds_free(context, ctx); if (tempccache) - krb5_cc_close(context, tempccache); + krb5_cc_destroy(context, tempccache); if (enctype) free(enctype); @@ -923,7 +971,7 @@ renew_func(void *ptr) server_str, ctx->ticket_life); } else { ret = get_new_tickets(ctx->context, ctx->principal, ctx->ccache, - ctx->ticket_life, 0); + ctx->ticket_life, 0, 0); } expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal, server_str, &renew_expire); @@ -1222,6 +1270,8 @@ main(int argc, char **argv) #ifdef HAVE_SIGACTION struct sigaction sa; #endif + krb5_boolean unique_ccache = FALSE; + int anonymous_pkinit = FALSE; setprogname(argv[0]); @@ -1271,15 +1321,16 @@ main(int argc, char **argv) pk_user_id = NULL; - } else if (anonymous_flag) { + } else if (anonymous_flag && argc && argv[0][0] == '@') { + /* If principal argument as @REALM, try anonymous PKINIT */ - ret = krb5_make_principal(context, &principal, argv[0], + ret = krb5_make_principal(context, &principal, &argv[0][1], KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL); if (ret) krb5_err(context, 1, ret, "krb5_make_principal"); krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN); - + anonymous_pkinit = TRUE; } else if (use_keytab || keytab_str) { get_princ_kt(context, &principal, argv[0]); } else { @@ -1311,6 +1362,7 @@ main(int argc, char **argv) krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache)); setenv("KRB5CCNAME", s, 1); + unique_ccache = TRUE; } else { ret = krb5_cc_cache_match(context, principal, &ccache); if (ret) { @@ -1330,6 +1382,8 @@ main(int argc, char **argv) krb5_cc_close(context, ccache); ret = get_switched_ccache(context, type, principal, &ccache); + if (ret == 0) + unique_ccache = TRUE; } } } @@ -1378,12 +1432,18 @@ main(int argc, char **argv) krb5_afslog(context, ccache, NULL, NULL); #endif + if (unique_ccache) + krb5_cc_destroy(context, ccache); exit(ret != 0); } - ret = get_new_tickets(context, principal, ccache, ticket_life, 1); - if (ret) + ret = get_new_tickets(context, principal, ccache, ticket_life, + 1, anonymous_pkinit); + if (ret) { + if (unique_ccache) + krb5_cc_destroy(context, ccache); exit(1); + } #ifndef NO_AFS if (ret == 0 && server_str == NULL && do_afslog && k_hasafs()) diff --git a/kuser/kinit.cat1 b/kuser/kinit.cat1 index 1a50d4ec462e..0cd20732b253 100644 --- a/kuser/kinit.cat1 +++ b/kuser/kinit.cat1 @@ -13,7 +13,7 @@ SSYYNNOOPPSSIISS [--kk | ----uussee--kkeeyyttaabb] [--vv | ----vvaalliiddaattee] [--ee _e_n_c_t_y_p_e_s | ----eennccttyyppeess==_e_n_c_t_y_p_e_s] [--aa _a_d_d_r_e_s_s_e_s | ----eexxttrraa--aaddddrreesssseess==_a_d_d_r_e_s_s_e_s] [----ppaasssswwoorrdd--ffiillee==_f_i_l_e_n_a_m_e] [----ffccaacchhee--vveerrssiioonn==_v_e_r_s_i_o_n_-_n_u_m_b_e_r] - [--AA | ----nnoo--aaddddrreesssseess] [----aannoonnyymmoouuss] [----eenntteerrpprriissee] [----vveerrssiioonn] + [--AA | ----nnoo--aaddddrreesssseess] [--nn | ----aannoonnyymmoouuss] [----eenntteerrpprriissee] [----vveerrssiioonn] [----hheellpp] [_p_r_i_n_c_i_p_a_l [_c_o_m_m_a_n_d]] DDEESSCCRRIIPPTTIIOONN @@ -90,9 +90,13 @@ DDEESSCCRRIIPPTTIIOONN --AA, ----nnoo--aaddddrreesssseess Request a ticket with no addresses. - ----aannoonnyymmoouuss - Request an anonymous ticket (which means that the ticket will be - issued to an anonymous principal, typically ``anonymous@REALM''). + --nn, ----aannoonnyymmoouuss + Request an anonymous ticket. If the principal is specified as + @REALM, then anonymous PKINIT will be used to acquire an unau- + thenticated anonymous ticket and both the client name and realm + in the returned ticket will be anonymized. Otherwise, authenti- + cation proceeds as normal and the anonymous ticket will have only + the client name anonymized. ----eenntteerrpprriissee Parse principal as a enterprise (KRB5-NT-ENTERPRISE) name. Enter- diff --git a/kuser/klist.c b/kuser/klist.c index e7fb8998b10e..02db225d3425 100644 --- a/kuser/klist.c +++ b/kuser/klist.c @@ -122,6 +122,12 @@ print_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags) *sp++ = 'A'; if(cred->flags.b.hw_authent) *sp++ = 'H'; + if(cred->flags.b.transited_policy_checked) + *sp++ = 'T'; + if(cred->flags.b.ok_as_delegate) + *sp++ = 'O'; + if(cred->flags.b.anonymous) + *sp++ = 'a'; *sp = '\0'; rtbl_add_column_entry(ct, COL_FLAGS, s); } @@ -403,7 +409,7 @@ display_tokens(int do_verbose) continue; t[min(parms.out_size,sizeof(t)-1)] = 0; memcpy(&size_secret_tok, r, sizeof(size_secret_tok)); - /* dont bother about the secret token */ + /* don't bother about the secret token */ r += size_secret_tok + sizeof(size_secret_tok); if (parms.out_size < (r - t) + sizeof(size_public_tok)) continue; @@ -413,7 +419,7 @@ display_tokens(int do_verbose) continue; memcpy(&ct, r, size_public_tok); r += size_public_tok; - /* there is a int32_t with length of cellname, but we dont read it */ + /* there is a int32_t with length of cellname, but we don't read it */ r += sizeof(int32_t); cell = r; |