From: Danilo Almeida Date: Thu, 16 Mar 2000 00:47:21 +0000 (+0000) Subject: Add krb5_get_prompt_types() functionality X-Git-Tag: krb5-1.2-beta1~8 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a14e6157d20cbf91c313762965ff32bc55b6eea8;p=krb5.git Add krb5_get_prompt_types() functionality git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12118 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/clients/kinit/ChangeLog b/src/clients/kinit/ChangeLog index e6637351b..b4a79a002 100644 --- a/src/clients/kinit/ChangeLog +++ b/src/clients/kinit/ChangeLog @@ -1,3 +1,7 @@ +2000-03-15 Danilo Almeida + + * kinit.c: Add support for krb5_get_prompt_types. + 2000-03-07 Danilo Almeida * kinit.c: Add support for using both -4 and -5. Default to krb5 diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c index 4587cb838..a78be21bb 100644 --- a/src/clients/kinit/kinit.c +++ b/src/clients/kinit/kinit.c @@ -240,9 +240,9 @@ fprintf(stderr, USAGE_OPT_FMT, indent, col1, col2) fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4)); fprintf(stderr, "\t (Default behavior is to try %s%s%s%s)\n", default_k5?"Kerberos 5":"", - (default_k5 && default_k4)?" and ":"", + (default_k5 && default_k4)?" and ":"", default_k4?"Kerberos 4":"", - (!default_k5 && !default_k4)?"neither":""); + (!default_k5 && !default_k4)?"neither":""); ULINE("\t", "-V verbose", OPTTYPE_EITHER); ULINE("\t", "-l lifetime", OPTTYPE_EITHER); ULINE("\t", "-s start time", OPTTYPE_KRB5); @@ -679,11 +679,40 @@ k4_end(k4) memset(k4, 0, sizeof(*k4)); } +static char stash_password[1024]; +static int got_password = 0; + +krb5_error_code +KRB5_CALLCONV +kinit_prompter( + krb5_context ctx, + void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[] + ) +{ + int i; + krb5_prompt_type *types; + krb5_error_code rc = + krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts); + if (!rc && (types = krb5_get_prompt_types(ctx))) + for (i = 0; i < num_prompts; i++) + if ((types[i] == KRB5_PROMPT_TYPE_PASSWORD) || + (types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN)) + { + strncpy(stash_password, prompts[i].reply->data, + sizeof(stash_password)); + got_password = 1; + } + return rc; +} + int -k5_kinit(opts, k5, password) +k5_kinit(opts, k5) struct k_opts* opts; struct k5_data* k5; - char* password; { char* progname = progname_v5; int notix = 1; @@ -742,7 +771,7 @@ k5_kinit(opts, k5, password) switch (opts->action) { case INIT_PW: code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, - password, krb5_prompter_posix, 0, + 0, kinit_prompter, 0, opts->starttime, opts->service_name, &options); @@ -823,10 +852,10 @@ k5_kinit(opts, k5, password) } int -k4_kinit(opts, k4, password) +k4_kinit(opts, k4, ctx) struct k_opts* opts; struct k4_data* k4; - char* password; + krb5_context ctx; { char* progname = progname_v4; int k_errno = 0; @@ -852,17 +881,37 @@ k4_kinit(opts, k4, password) switch (opts->action) { case INIT_PW: + if (!got_password) { + int pwsize = sizeof(stash_password); + krb5_error_code code; + + sprintf(prompt, "Password for %s: ", opts.principal_name); + password[0] = 0; + /* + Note: krb5_read_password does not actually look at the + context, so we're ok even if we don't have a context. If + we cannot dynamically load krb5, we can substitute any + decent read password function instead of the krb5 one. + */ + code = krb5_read_password(ctx, prompt, 0, stash_password, &pwsize); + if (code || pwsize == 0) + { + fprintf(stderr, "Error while reading password for '%s'\n", + opts.principal_name); + memset(stash_password, 0, sizeof(stash_password)); + return 0; + } + got_password = 1; + } k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt", - k4->realm, k4->lifetime, password); + k4->realm, k4->lifetime, stash_password); if (k_errno) { -#ifndef HAVE_KRB524 fprintf(stderr, "%s: %s\n", progname, krb_get_err_text(k_errno)); if (authed_k5) fprintf(stderr, "Maybe your KDC does not support v4. " "Try the -5 option next time.\n"); -#endif return 0; } return 1; @@ -994,7 +1043,6 @@ main(argc, argv) struct k_opts opts; struct k5_data k5; struct k4_data k4; - char password[255]; progname = GET_PROGNAME(argv[0]); progname_v5 = getvprogname("5"); @@ -1029,38 +1077,14 @@ main(argc, argv) got_k5 = k5_begin(&opts, &k5, &k4); got_k4 = k4_begin(&opts, &k4); - if (opts.action == INIT_PW) - { - char prompt[255]; - int pwsize = sizeof(password); - krb5_error_code code; - - sprintf(prompt, "Password for %s: ", opts.principal_name); - password[0] = 0; - /* - Note: krb5_read_password does not actually look at the - context, so we're ok even if we don't have a context. If - we cannot dynamically load krb5, we can substitute any - decent read password function instead of the krb5 one. - */ - code = krb5_read_password(k5.ctx, prompt, 0, password, &pwsize); - if (code || pwsize == 0) - { - fprintf(stderr, "Error while reading password for '%s'\n", - opts.principal_name); - memset(password, 0, sizeof(password)); - exit(1); - } - } - - authed_k5 = k5_kinit(&opts, &k5, password); - authed_k4 = k4_kinit(&opts, &k4, password); - memset(password, 0, sizeof(password)); - + authed_k5 = k5_kinit(&opts, &k5); #ifdef HAVE_KRB524 - if (!authed_k4 && authed_k5) + if (authed_k5) authed_k4 = try_convert524(&k5); #endif + if (!authed_k4) + authed_k4 = k4_kinit(&opts, &k4, k5.ctx); + memset(stash_password, 0, sizeof(stash_password)); if (authed_k5 && opts.verbose) fprintf(stderr, "Authenticated to Kerberos v5\n"); diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 6ef98ebcc..928ecb1fc 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,8 @@ +2000-03-15 Danilo Almeida + + * krb5.hin: Add krb5_get_prompt_types() and related defs.. + * k5-int.h: Add krb5int_set_prompt_types(). + 2000-03-13 Tom Yu * k5-int.h: Update prototype to sync with changes in preauth2.c. diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 26a9c73d6..1c4880997 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -943,7 +943,6 @@ void krb5_free_etype_info * End "preauth.h" */ - typedef krb5_error_code (*krb5_gic_get_as_key_fct) KRB5_NPROTOTYPE((krb5_context, krb5_principal, @@ -1022,6 +1021,7 @@ struct _krb5_context { krb5_boolean profile_secure; int fcc_default_format; int scc_default_format; + krb5_prompt_type *prompt_types; #ifdef KRB5_DNS_LOOKUP krb5_boolean profile_in_memory; #endif /* KRB5_DNS_LOOKUP */ @@ -1511,6 +1511,9 @@ krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred_default KRB5_PROTOTYPE((krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *)); +void krb5int_set_prompt_types + KRB5_PROTOTYPE((krb5_context, krb5_prompt_type *)); + #if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) #pragma import reset #endif diff --git a/src/include/krb5.hin b/src/include/krb5.hin index b66d2d3e5..ea8f93e87 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -2400,6 +2400,20 @@ KRB5_DLLIMP void KRB5_CALLCONV krb5_realm_iterator_free KRB5_DLLIMP void KRB5_CALLCONV krb5_free_realm_string KRB5_PROTOTYPE((krb5_context context, char *str)); +/* + * Prompter enhancements + */ + +#define KRB5_PROMPT_TYPE_PASSWORD 0x1 +#define KRB5_PROMPT_TYPE_NEW_PASSWORD 0x2 +#define KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN 0x3 +#define KRB5_PROMPT_TYPE_PREAUTH 0x4 + +typedef krb5_int32 krb5_prompt_type; + +KRB5_DLLIMP krb5_prompt_type* KRB5_CALLCONV krb5_get_prompt_types + KRB5_PROTOTYPE((krb5_context context)); + #ifdef __cplusplus } #endif diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog index bbc0f8e59..b5abe94b8 100644 --- a/src/lib/ChangeLog +++ b/src/lib/ChangeLog @@ -1,3 +1,7 @@ +2000-03-15 Danilo Almeida + + * krb5_32.def: Add krb5_get_prompt_types. + 2000-02-01 Danilo Almeida * krb5_32.def: Replace decode_krb5_ticket with krb5_decode_ticket. diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 97265206f..59d8765aa 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,9 @@ +2000-03-15 Danilo Almeida + + * init_ctx.c (init_common), gic_pwd.c (krb5_get_as_key_password, + krb5_get_init_creds_password), preauth2.c (pa_sam): Add support + for krb5_get_prompt_types(). + 2000-03-13 Ken Raeburn * preauth2.c (pa_function): Called function now takes new diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index c2ee423cc..7ca43430e 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -19,6 +19,7 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, char *clientstr; char promptstr[1024]; krb5_prompt prompt; + krb5_prompt_type prompt_type; password = (krb5_data *) gak_data; @@ -53,10 +54,16 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, prompt.prompt = promptstr; prompt.hidden = 1; prompt.reply = password; + prompt_type = KRB5_PROMPT_TYPE_PASSWORD; + /* PROMPTER_INVOCATION */ + krb5int_set_prompt_types(context, &prompt_type); if (ret = (((*prompter)(context, prompter_data, NULL, NULL, - 1, &prompt)))) + 1, &prompt)))) { + krb5int_set_prompt_types(context, 0); return(ret); + } + krb5int_set_prompt_types(context, 0); } if ((salt->length == -1) && (salt->data == NULL)) { @@ -98,6 +105,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, krb5_data pw0, pw1; char banner[1024], pw0array[1024], pw1array[1024]; krb5_prompt prompt[2]; + krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])]; master = 0; as_reply = NULL; @@ -193,10 +201,12 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, prompt[0].prompt = "Enter new password"; prompt[0].hidden = 1; prompt[0].reply = &pw0; + prompt_types[0] = KRB5_PROMPT_TYPE_NEW_PASSWORD; prompt[1].prompt = "Enter it again"; prompt[1].hidden = 1; prompt[1].reply = &pw1; + prompt_types[1] = KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN; strcpy(banner, "Password expired. You must change it now."); @@ -204,9 +214,13 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, pw0.length = sizeof(pw0array); pw1.length = sizeof(pw1array); + /* PROMPTER_INVOCATION */ + krb5int_set_prompt_types(context, prompt_types); if (ret = ((*prompter)(context, data, 0, banner, sizeof(prompt)/sizeof(prompt[0]), prompt))) goto cleanup; + krb5int_set_prompt_types(context, 0); + if (strcmp(pw0.data, pw1.data) != 0) { ret = KRB5_LIBOS_BADPWDMATCH; @@ -271,6 +285,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, &master, &as_reply); cleanup: + krb5int_set_prompt_types(context, 0); /* if getting the password was successful, then check to see if the password is about to expire, and warn if so */ @@ -300,6 +315,7 @@ cleanup: hours/24); /* ignore an error here */ + /* PROMPTER_INVOCATION */ (*prompter)(context, data, 0, banner, 0, 0); } } diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index 9159a3717..e2eccc402 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -196,7 +196,7 @@ init_common (context, secure) 0, DEFAULT_CCACHE_TYPE, &tmp); ctx->fcc_default_format = tmp + 0x0500; ctx->scc_default_format = tmp + 0x0500; - + ctx->prompt_types = 0; *context = ctx; return 0; diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index ec80c6520..5ea61c9dc 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -247,6 +247,7 @@ krb5_error_code pa_sam(krb5_context context, char prompt[100], response[100]; krb5_data response_data; krb5_prompt kprompt; + krb5_prompt_type prompt_type; krb5_data defsalt; krb5_sam_challenge *sam_challenge = 0; krb5_sam_response sam_response; @@ -287,12 +288,17 @@ krb5_error_code pa_sam(krb5_context context, kprompt.prompt = prompt; kprompt.hidden = sam_challenge->sam_challenge.length?0:1; kprompt.reply = &response_data; + prompt_type = KRB5_PROMPT_TYPE_PREAUTH; + /* PROMPTER_INVOCATION */ + krb5int_set_prompt_types(context, &prompt_type); if (ret = ((*prompter)(context, prompter_data, name, banner, 1, &kprompt))) { krb5_xfree(sam_challenge); + krb5int_set_prompt_types(context, 0); return(ret); } + krb5int_set_prompt_types(context, 0); enc_sam_response_enc.sam_nonce = sam_challenge->sam_nonce; if (sam_challenge->sam_nonce == 0) { diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index ded442bda..8f8c01821 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,8 @@ +2000-03-15 Danilo Almeida + + * prompter.c: Add krb5int_set_prompt_types() and + krb5_get_prompt_types(). + 2000-03-14 Ken Raeburn * init_os_ctx.c (os_get_default_config_files): Remove unused diff --git a/src/lib/krb5/os/prompter.c b/src/lib/krb5/os/prompter.c index 800377f78..933ff2cea 100644 --- a/src/lib/krb5/os/prompter.c +++ b/src/lib/krb5/os/prompter.c @@ -229,3 +229,20 @@ krb5_prompter_posix(krb5_context context, } #endif /* !_WIN32 */ #endif /* !MSDOS */ + +void +krb5int_set_prompt_types(context, types) + krb5_context context; + krb5_prompt_type *types; +{ + context->prompt_types = 0; +} + +KRB5_DLLIMP +krb5_prompt_type* +KRB5_CALLCONV +krb5_get_prompt_types(context) + krb5_context context; +{ + return context->prompt_types; +} diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index df5209df0..4c5f271b2 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -110,6 +110,7 @@ EXPORTS krb5_parse_name krb5_principal_compare krb5_prompter_posix + krb5_get_prompt_types krb5_rd_cred krb5_rd_error krb5_rd_priv