From 776ed53425eed4c6c822d22bbda8fc0e35a18621 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 4 May 1996 00:17:55 +0000 Subject: [PATCH] * get_creds.c (krb5_get_credentials_core): new function. Common part of krb5_get_credentials and krb5_get_credentials_validate. Some formerly local variables are now arguments. (krb5_get_credentials): same as before, but calls _core to do some of the work. (krb5_get_credentials_validate): uses krb5_get_cred_from_kdc_validate and only stores the returned credential in the cache, instead of storing all of them. * gc_frm_kdc.c (krb5_get_cred_from_kdc_opt): new function. Same body as krb5_get_cred_from_kdc, but takes one new argument, kdcopts, and combines it with the other kdc options when calling krb5_get_cred_via_tkt. This is static and only called by (krb5_get_cred_from_kdc): a wrapper that provides the same function it did before, and (krb5_get_cred_from_kdc_validate): a wrapper that passes KDC_OPT_VALIDATE, so that kinit can use it. We'll probably need another one for renewing tickets as well. * rd_req_dec.c (krb5_rd_req_decoded_opt): new function. Same body as krb5_rd_req_decoded, but takes one new argument, check_valid_flag, to determine whether or not to check if the "invalid flag" is set in the ticket. Also made static, so that it is only called via: (krb5_rd_req_decoded): wrapper for krb5_rd_req_decoded_opt that specifies the "invalid flag" gets checked, and (krb5_rd_req_decoded_anyflag): wrapper for krb5_rd_req_decoded_opt that specifies that the "invalid flag" doesn't get checked. (This version is only called from kdc_util.c:kdc_process_tgs_req.) * str_conv.c (krb5_string_to_timestamp): double check that strptime at least parsed *some* of the string, avoid degenerate cases from GNU libc strptime. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7890 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/ChangeLog | 40 ++++++++++++++ src/lib/krb5/krb/gc_frm_kdc.c | 32 ++++++++++- src/lib/krb5/krb/get_creds.c | 100 +++++++++++++++++++++++++++------- src/lib/krb5/krb/rd_req_dec.c | 49 +++++++++++++++-- src/lib/krb5/krb/str_conv.c | 4 +- 5 files changed, 197 insertions(+), 28 deletions(-) diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 39b1ff601..9eece7a08 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,43 @@ +Fri May 3 00:15:18 1996 Mark Eichin + + * get_creds.c (krb5_get_credentials_core): new function. Common + part of krb5_get_credentials and krb5_get_credentials_validate. + Some formerly local variables are now arguments. + (krb5_get_credentials): same as before, but calls _core to do some + of the work. + (krb5_get_credentials_validate): uses + krb5_get_cred_from_kdc_validate and only stores the returned + credential in the cache, instead of storing all of them. + +Thu May 2 22:48:56 1996 Mark Eichin + + * gc_frm_kdc.c (krb5_get_cred_from_kdc_opt): new function. Same + body as krb5_get_cred_from_kdc, but takes one new argument, + kdcopts, and combines it with the other kdc options when calling + krb5_get_cred_via_tkt. This is static and only called by + (krb5_get_cred_from_kdc): a wrapper that provides the same + function it did before, and + (krb5_get_cred_from_kdc_validate): a wrapper that passes + KDC_OPT_VALIDATE, so that kinit can use it. + We'll probably need another one for renewing tickets as well. + + * rd_req_dec.c (krb5_rd_req_decoded_opt): new function. Same body + as krb5_rd_req_decoded, but takes one new argument, + check_valid_flag, to determine whether or not to check if the + "invalid flag" is set in the ticket. Also made static, so that it + is only called via: + (krb5_rd_req_decoded): wrapper for krb5_rd_req_decoded_opt that + specifies the "invalid flag" gets checked, and + (krb5_rd_req_decoded_anyflag): wrapper for krb5_rd_req_decoded_opt + that specifies that the "invalid flag" doesn't get checked. (This + version is only called from kdc_util.c:kdc_process_tgs_req.) + +Wed May 1 02:26:53 1996 Mark Eichin + + * str_conv.c (krb5_string_to_timestamp): double check that + strptime at least parsed *some* of the string, avoid degenerate + cases from GNU libc strptime. + Tue Apr 30 18:19:01 1996 Ken Raeburn * t_ser.c (stuff): New variable. diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index 2a157aa28..4b4120d14 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -59,13 +59,14 @@ #define FLAGS2OPTS(flags) (flags & KDC_TKT_COMMON_MASK) -krb5_error_code -krb5_get_cred_from_kdc(context, ccache, in_cred, out_cred, tgts) +static krb5_error_code +krb5_get_cred_from_kdc_opt(context, ccache, in_cred, out_cred, tgts, kdcopt) krb5_context context; krb5_ccache ccache; krb5_creds *in_cred; krb5_creds **out_cred; krb5_creds ***tgts; + int kdcopt; { krb5_creds **ret_tgts = NULL; int ntgts = 0; @@ -377,6 +378,7 @@ krb5_get_cred_from_kdc(context, ccache, in_cred, out_cred, tgts) } retval = krb5_get_cred_via_tkt(context, &tgt, FLAGS2OPTS(tgt.ticket_flags) | + kdcopt | (in_cred->second_ticket.length ? KDC_OPT_ENC_TKT_IN_SKEY : 0), tgt.addresses, in_cred, out_cred); @@ -396,3 +398,29 @@ cleanup: } return(retval); } + +krb5_error_code +krb5_get_cred_from_kdc(context, ccache, in_cred, out_cred, tgts) + krb5_context context; + krb5_ccache ccache; + krb5_creds *in_cred; + krb5_creds **out_cred; + krb5_creds ***tgts; +{ + + return krb5_get_cred_from_kdc_opt(context, ccache, in_cred, out_cred, tgts, + 0); +} + +krb5_error_code +krb5_get_cred_from_kdc_validate(context, ccache, in_cred, out_cred, tgts) + krb5_context context; + krb5_ccache ccache; + krb5_creds *in_cred; + krb5_creds **out_cred; + krb5_creds ***tgts; +{ + + return krb5_get_cred_from_kdc_opt(context, ccache, in_cred, out_cred, tgts, + KDC_OPT_VALIDATE); +} diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index c0b8912e7..3bc633c41 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -42,49 +42,71 @@ #include "k5-int.h" -krb5_error_code INTERFACE -krb5_get_credentials(context, options, ccache, in_creds, out_creds) +static krb5_error_code INTERFACE +krb5_get_credentials_core(context, options, ccache, in_creds, out_creds, + mcreds, fields) krb5_context context; const krb5_flags options; krb5_ccache ccache; krb5_creds *in_creds; krb5_creds **out_creds; + krb5_creds *mcreds; + krb5_flags *fields; { - krb5_error_code retval, rv2; - krb5_creds **tgts; - krb5_creds *ncreds; - krb5_creds mcreds; - krb5_flags fields; + krb5_error_code retval; if (!in_creds || !in_creds->server || !in_creds->client) return EINVAL; - memset((char *)&mcreds, 0, sizeof(krb5_creds)); - mcreds.magic = KV5M_CREDS; - mcreds.times.endtime = in_creds->times.endtime; + memset((char *)mcreds, 0, sizeof(krb5_creds)); + mcreds->magic = KV5M_CREDS; + mcreds->times.endtime = in_creds->times.endtime; #ifdef HAVE_C_STRUCTURE_ASSIGNMENT - mcreds.keyblock = in_creds->keyblock; + mcreds->keyblock = in_creds->keyblock; #else - memcpy(&mcreds.keyblock, &in_creds->keyblock, sizeof(krb5_keyblock)); + memcpy(&mcreds->keyblock, &in_creds->keyblock, sizeof(krb5_keyblock)); #endif - mcreds.authdata = in_creds->authdata; - mcreds.server = in_creds->server; - mcreds.client = in_creds->client; + mcreds->authdata = in_creds->authdata; + mcreds->server = in_creds->server; + mcreds->client = in_creds->client; - fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */ + *fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */ | KRB5_TC_MATCH_AUTHDATA ; - if (mcreds.keyblock.enctype) - fields |= KRB5_TC_MATCH_KTYPE; + if (mcreds->keyblock.enctype) + *fields |= KRB5_TC_MATCH_KTYPE; if (options & KRB5_GC_USER_USER) { /* also match on identical 2nd tkt and tkt encrypted in a session key */ - fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY; - mcreds.is_skey = TRUE; - mcreds.second_ticket = in_creds->second_ticket; + *fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY; + mcreds->is_skey = TRUE; + mcreds->second_ticket = in_creds->second_ticket; if (!in_creds->second_ticket.length) return KRB5_NO_2ND_TKT; } + return 0; +} + +krb5_error_code INTERFACE +krb5_get_credentials(context, options, ccache, in_creds, out_creds) + krb5_context context; + const krb5_flags options; + krb5_ccache ccache; + krb5_creds *in_creds; + krb5_creds **out_creds; +{ + krb5_error_code retval; + krb5_creds mcreds; + krb5_creds *ncreds; + krb5_creds **tgts; + krb5_flags fields; + + retval = krb5_get_credentials_core(context, options, ccache, + in_creds, out_creds, + &mcreds, &fields); + + if (retval) return retval; + if ((ncreds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) return ENOMEM; @@ -106,6 +128,7 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds) retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts); if (tgts) { register int i = 0; + krb5_error_code rv2; while (tgts[i]) { if ((rv2 = krb5_cc_store_cred(context, ccache, tgts[i]))) { retval = rv2; @@ -119,3 +142,38 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds) retval = krb5_cc_store_cred(context, ccache, *out_creds); return retval; } + +krb5_error_code INTERFACE +krb5_get_credentials_validate(context, options, ccache, in_creds, out_creds) + krb5_context context; + const krb5_flags options; + krb5_ccache ccache; + krb5_creds *in_creds; + krb5_creds **out_creds; +{ + krb5_error_code retval; + krb5_creds mcreds; + krb5_principal tmp; + krb5_creds **tgts = 0; + krb5_flags fields; + + retval = krb5_get_credentials_core(context, options, ccache, + in_creds, out_creds, + &mcreds, &fields); + + if (retval) return retval; + + retval = krb5_get_cred_from_kdc_validate(context, ccache, + in_creds, out_creds, &tgts); + if (retval) return retval; + if (tgts) krb5_free_tgt_creds(context, tgts); + + retval = krb5_cc_get_principal(context, ccache, &tmp); + if (retval) return retval; + + retval = krb5_cc_initialize(context, ccache, tmp); + if (retval) return retval; + + retval = krb5_cc_store_cred(context, ccache, *out_creds); + return retval; +} diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index 6585cb3ea..0c62c19df 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -86,9 +86,9 @@ krb5_rd_req_decrypt_tkt_part(context, req, keytab) return retval; } -krb5_error_code -krb5_rd_req_decoded(context, auth_context, req, server, keytab, - ap_req_options, ticket) +static krb5_error_code +krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab, + ap_req_options, ticket, check_valid_flag) krb5_context context; krb5_auth_context * auth_context; const krb5_ap_req * req; @@ -96,6 +96,7 @@ krb5_rd_req_decoded(context, auth_context, req, server, keytab, krb5_keytab keytab; krb5_flags * ap_req_options; krb5_ticket ** ticket; + int check_valid_flag; { krb5_error_code retval = 0; krb5_timestamp currenttime; @@ -235,9 +236,11 @@ krb5_rd_req_decoded(context, auth_context, req, server, keytab, goto cleanup; } - if (req->ticket->enc_part2->flags & TKT_FLG_INVALID) { + if (check_valid_flag) { + if (req->ticket->enc_part2->flags & TKT_FLG_INVALID) { retval = KRB5KRB_AP_ERR_TKT_INVALID; goto cleanup; + } } (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number; @@ -280,6 +283,44 @@ cleanup: return retval; } +krb5_error_code +krb5_rd_req_decoded(context, auth_context, req, server, keytab, + ap_req_options, ticket) + krb5_context context; + krb5_auth_context * auth_context; + const krb5_ap_req * req; + krb5_const_principal server; + krb5_keytab keytab; + krb5_flags * ap_req_options; + krb5_ticket ** ticket; +{ + krb5_error_code retval; + retval = krb5_rd_req_decoded_opt(context, auth_context, + req, server, keytab, + ap_req_options, ticket, + 1); /* check_valid_flag */ + return retval; +} + +krb5_error_code +krb5_rd_req_decoded_anyflag(context, auth_context, req, server, keytab, + ap_req_options, ticket) + krb5_context context; + krb5_auth_context * auth_context; + const krb5_ap_req * req; + krb5_const_principal server; + krb5_keytab keytab; + krb5_flags * ap_req_options; + krb5_ticket ** ticket; +{ + krb5_error_code retval; + retval = krb5_rd_req_decoded_opt(context, auth_context, + req, server, keytab, + ap_req_options, ticket, + 0); /* don't check_valid_flag */ + return retval; +} + static krb5_error_code decrypt_authenticator(context, request, authpp) krb5_context context; diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c index 854ac9189..987792726 100644 --- a/src/lib/krb5/krb/str_conv.c +++ b/src/lib/krb5/krb/str_conv.c @@ -426,11 +426,13 @@ krb5_string_to_timestamp(string, timestampp) int i; int found; struct tm timebuf; + char *s; found = 0; memset(&timebuf, 0, sizeof(timebuf)); for (i=0; i