From 5a2fb0d6ee3d6db893fbe34c4097c019f8a4027d Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Mon, 10 Feb 2003 22:11:35 +0000 Subject: [PATCH] Note: these checkins are partial progress for Tom Yu. They probably don't build; Tom is expecting that. *** CCache-glue.c: Removed copying of the string_to_key type in krb_save_credentials. Saving the string_to_key type is unnecessary and was just for display purposes. Will be removed for KfM 5.0. Updated to use KRB5_CALLCONV instead of INTERFACE and include the krb5's krb4 headers instead of the KfM ones. *** change-password.c: Removed include of CredentialsCache.h and code that switches between string to key types. This doesn't make sense for password changing because the krb4 protocol for password changing implemented here only supports mit's string to key. Bug was in KfM and got ported forward. Should the code call mit_password_to_key for all platforms? *** FSp-glue.c: Removed dependency on MoreFiles and replaced it with code to use FSRefs now that we are Carbon-only. *** g_in_tkt.c: Added loop which calls password to key functions trying each one. This technique was imported from KTH-KRB into KfM. This code still needs to have the TARGET_OS_MAC code made more Unix friendly for Darwin builds. The behavior differences (store the address or not) should be deferred until the very last moment to avoid excessive #ifdefs. *** g_pw_in_tkt.c: Added loop which calls password to key functions trying each one. This technique was imported from KTH-KRB into KfM. *** krb4int.h: Added password-to-key.c functions so they can be used by g_in_tkt.c and g_pw_in_tkt.c. *** password-to-key.c: Removed dependence on the CCAPI so this code can be used on all platforms to implement looping over the password to key functions. *** RealmsConfig-glue.c: Changed to use #ifdef USE_CCAPI like is used elsewhere in the krb5 sources. This is just for consistency in krb5 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15172 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb4/CCache-glue.c | 52 ++++++++---------- src/lib/krb4/ChangeLog | 40 ++++++++++++++ src/lib/krb4/FSp-glue.c | 40 ++++++++++++-- src/lib/krb4/RealmsConfig-glue.c | 6 +- src/lib/krb4/change_password.c | 22 +------- src/lib/krb4/g_in_tkt.c | 27 +++++---- src/lib/krb4/g_pw_in_tkt.c | 38 +++++++------ src/lib/krb4/krb4int.h | 9 +++ src/lib/krb4/password_to_key.c | 94 +++++++++++++------------------- 9 files changed, 186 insertions(+), 142 deletions(-) diff --git a/src/lib/krb4/CCache-glue.c b/src/lib/krb4/CCache-glue.c index 8d1c402e0..27204c438 100644 --- a/src/lib/krb4/CCache-glue.c +++ b/src/lib/krb4/CCache-glue.c @@ -9,29 +9,24 @@ #include -#include "kerberos.h" +#include "krb.h" +#include "krb4int.h" +#include "prot.h" + +#if !defined (USE_CCAPI) || !USE_CCAPI +#error "Cannot use CCache glue without the CCAPI!" +#endif #ifdef USE_LOGIN_LIBRARY -#include +#include #endif /* USE_LOGIN_LIBRARY */ -#include +#include #include #include - -#include "Kerberos4Private.h" - -/* - * Psycho krb4 sources don't compile with these options on, so I use them just for this file - */ -#pragma require_prototypes on -#pragma mpwc_relax off - -int INTERFACE -krb_get_tf_realm ( - const char* ticket_file, - char* realm); +void +UpdateDefaultCache (void); /* * The way Kerberos v4 normally works is that at any given point in time there is a @@ -125,11 +120,8 @@ krb_save_credentials ( int kvno, KTEXT ticket, long issue_date, - KRB_UINT32 local_address, - KRB_UINT32 stk_type) + KRB_UINT32 local_address) { -#pragma unused (realm) - cc_int32 cc_err = ccNoError; int kerr = KSUCCESS; cc_credentials_v4_t v4creds; @@ -163,7 +155,7 @@ krb_save_credentials ( strncpy (v4creds.realm, realm, REALM_SZ); memmove (v4creds.session_key, session, sizeof (C_Block)); v4creds.kvno = kvno; - v4creds.string_to_key_type = stk_type; + v4creds.string_to_key_type = cc_v4_stk_unknown; v4creds.issue_date = issue_date; v4creds.address = local_address; v4creds.lifetime = lifetime; @@ -194,7 +186,7 @@ krb_save_credentials ( * * Determine the realm by opening the named cache and parsing realm from the principal */ -int INTERFACE +int KRB5_CALLCONV krb_get_tf_realm ( const char* ticket_file, char* realm) @@ -245,7 +237,7 @@ krb_get_tf_realm ( /* * Credentials file -> name, instance, realm mapping */ -int INTERFACE +int KRB5_CALLCONV krb_get_tf_fullname ( const char* ticket_file, char* name, @@ -292,7 +284,7 @@ krb_get_tf_fullname ( /* * Retrieval from credentials cache */ -int INTERFACE +int KRB5_CALLCONV krb_get_cred ( char* service, char* instance, @@ -429,7 +421,7 @@ krb_get_cred ( /* * Getting name of default credentials cache */ -const char* INTERFACE +const char* KRB5_CALLCONV tkt_string (void) { if (gDefaultCacheName == NULL) { @@ -490,7 +482,7 @@ krb_set_tkt_string ( * * Implementation in dest_tkt.c */ -int INTERFACE +int KRB5_CALLCONV dest_tkt (void) { cc_int32 cc_err = ccNoError; @@ -528,7 +520,7 @@ dest_tkt (void) /* * Number of credentials in credentials cache */ -int INTERFACE +int KRB5_CALLCONV krb_get_num_cred (void) { cc_credentials_t theCreds = NULL; @@ -581,7 +573,7 @@ krb_get_num_cred (void) * This function is _not_!! well-defined under CCache API, because * there is no guarantee about order of credentials remaining the same. */ -int INTERFACE +int KRB5_CALLCONV krb_get_nth_cred ( char* sname, char* sinstance, @@ -648,7 +640,7 @@ krb_get_nth_cred ( /* * Deletion from credentials file */ -int INTERFACE +int KRB5_CALLCONV krb_delete_cred ( char* sname, char* sinstance, @@ -711,7 +703,7 @@ krb_delete_cred ( * * Implementation in memcache.c */ -int INTERFACE +int KRB5_CALLCONV dest_all_tkts (void) { int count = 0; diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 0ba4774f0..b798a560f 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,43 @@ +2003-02-10 Alexandra Ellwood + Note: these checkins are partial progress for Tom Yu. + They probably don't build; Tom is expecting that. + + * CCache-glue.c: Removed copying of the string_to_key type in + krb_save_credentials. Saving the string_to_key type is unnecessary + and was just for display purposes. Will be removed for KfM 5.0. + Updated to use KRB5_CALLCONV instead of INTERFACE and include the + krb5's krb4 headers instead of the KfM ones. + + * change-password.c: Removed include of CredentialsCache.h and + code that switches between string to key types. This doesn't make + sense for password changing because the krb4 protocol for password + changing implemented here only supports mit's string to key. Bug + was in KfM and got ported forward. Should the code call + mit_password_to_key for all platforms? + + * FSp-glue.c: Removed dependency on MoreFiles and replaced it with + code to use FSRefs now that we are Carbon-only. + + * g_in_tkt.c: Added loop which calls password to key functions + trying each one. This technique was imported from KTH-KRB into + KfM. This code still needs to have the TARGET_OS_MAC code made more + Unix friendly for Darwin builds. The behavior differences (store + the address or not) should be deferred until the very last moment to + avoid excessive #ifdefs. + + * g_pw_in_tkt.c: Added loop which calls password to key functions + trying each one. This technique was imported from KTH-KRB into KfM. + + * krb4int.h: Added password-to-key.c functions so they can be used by + g_in_tkt.c and g_pw_in_tkt.c. + + * password-to-key.c: Removed dependence on the CCAPI so this code can + be used on all platforms to implement looping over the password to + key functions. + + * RealmsConfig-glue.c: Changed to use #ifdef USE_CCAPI like is used + elsewhere in the krb5 sources. This is just for consistency in krb5. + 2003-02-07 Tom Yu * Makefile.in: Add rules to generate krb_err_txt.c. diff --git a/src/lib/krb4/FSp-glue.c b/src/lib/krb4/FSp-glue.c index a3b35dc2b..f8d6be13d 100644 --- a/src/lib/krb4/FSp-glue.c +++ b/src/lib/krb4/FSp-glue.c @@ -33,9 +33,10 @@ #if TARGET_OS_MAC && defined(__FILES__) -#include +#include static int FSp_srvtab_to_key(char *, char *, char *, char *, C_Block); +static OSStatus FSSpec2Path (FSSpec *spec, char **path, int pathLen); int KRB5_CALLCONV FSp_read_service_key( @@ -47,9 +48,9 @@ FSp_read_service_key( char *key) /* Pointer to key to be filled in */ { int retval = KFAILURE; - char *file = NULL; + char file [MAXPATHLEN]; if (filespec != NULL) { - if (FSpGetFullPOSIXPath (filespec, &file) != noErr) { + if (FSSpec2Path (filespec, &file, sizeof(file)) != noErr) { return retval; } } @@ -70,9 +71,10 @@ FSp_put_svc_key( char *key) { int retval = KFAILURE; - char *sfile = NULL; + char sfile[MAXPATHLEN]; + if (sfilespec != NULL) { - if (FSpGetFullPOSIXPath (sfilespec, &sfile) != noErr) { + if (FSSpec2Path (sfilespec, &sfile, sizeof(sfile)) != noErr) { return retval; } } @@ -102,4 +104,32 @@ static int FSp_srvtab_to_key(char *user, char *instance, char *realm, return FSp_read_service_key(user, instance, realm, 0, (FSSpec *)srvtab, (char *)key); } + +static OSStatus FSSpec2Path (FSSpec *spec, char **path, int pathLen) +{ + OSStatus err = noErr; + FSRef ref; + + /* check parameters */ + if (path == NULL) err = paramErr; + + /* convert the FSSpec to an FSRef */ + if (err == noErr) { + FSRefParam pb; + + pb.ioVRefNum = spec->vRefNum; + pb.ioDirID = spec->parID; + pb.ioNamePtr = (StringPtr) spec->name; + pb.newRef = &ref; + err = PBMakeFSRefSync(&pb); + } + + /* and then convert the FSRef to a path */ + if (err == noErr) { + err = FSRefMakePath (&ref, path, pathLen); + } + + return err; +} + #endif diff --git a/src/lib/krb4/RealmsConfig-glue.c b/src/lib/krb4/RealmsConfig-glue.c index 9c5a54349..fe2c01bff 100644 --- a/src/lib/krb4/RealmsConfig-glue.c +++ b/src/lib/krb4/RealmsConfig-glue.c @@ -42,8 +42,8 @@ #include "krb4int.h" #include "port-sockets.h" -#if USE_CCAPI -#include +#ifdef USE_CCAPI +#include #endif #define KRB5_PRIVATE 1 @@ -478,7 +478,7 @@ krb_get_krbhst( return result; } -#if USE_CCAPI +#ifdef USE_CCAPI /* * Realm -> string_to_key mapping */ diff --git a/src/lib/krb4/change_password.c b/src/lib/krb4/change_password.c index c3d5ad82c..44882eaac 100644 --- a/src/lib/krb4/change_password.c +++ b/src/lib/krb4/change_password.c @@ -27,9 +27,6 @@ #include #include -#if TARGET_OS_MAC /* XXX */ -#include -#endif #include "krb.h" #include "krb4int.h" #include "kadm.h" @@ -69,24 +66,7 @@ krb_change_password(char *principal, char *instance, char *realm, #if TARGET_OS_MAC /* Now create the key to send to the server */ - switch (client_parm.creds.stk_type) { - case cc_v4_stk_des: - mit_passwd_to_key(principal, instance, realm, newPassword, key); - break; - case cc_v4_stk_afs: - afs_passwd_to_key(principal, instance, realm, newPassword, key); - break; - case cc_v4_stk_krb5: - krb5_passwd_to_key(principal, instance, realm, newPassword, key); - break; - default: - /* - * Okay, actually afs_string_to_key sites can't use this - * protocol to change passwords - */ - mit_passwd_to_key(principal, instance, realm, newPassword, key); - break; - } + mit_passwd_to_key(principal, instance, realm, newPassword, key); #else des_string_to_key(newPassword, key); /* XXX check this! */ #endif diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c index e2b89552e..bebdd009c 100644 --- a/src/lib/krb4/g_in_tkt.c +++ b/src/lib/krb4/g_in_tkt.c @@ -29,6 +29,7 @@ #include "krb4int.h" #include "prot.h" +#include "port-sockets.h" #include /* Define a couple of function types including parameters. These @@ -414,6 +415,8 @@ krb_get_in_tkt_preauth_creds(user, instance, realm, service, sinstance, life, KTEXT cip = &cip_st; /* Returned Ciphertext */ int kerror; int byteorder; + key_proc_type *keyprocs = krb_get_keyprocs (key_proc); + int i = 0; #if TARGET_OS_MAC struct sockaddr_in local_addr; #endif @@ -431,15 +434,19 @@ krb_get_in_tkt_preauth_creds(user, instance, realm, service, sinstance, life, #endif if (kerror) return kerror; - /* Attempt to decrypt the reply. */ - if (decrypt_proc == NULL) - decrypt_tkt (user, instance, realm, arg, key_proc, &cip); - else - (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip); - - kerror = krb_parse_in_tkt_creds(user, instance, realm, - service, sinstance, - life, cip, byteorder, creds); + + /* Attempt to decrypt the reply. Loop trying password_to_key algorithms + until we succeed or we get an error other than "bad password" */ + do { + if (decrypt_proc == NULL) { + decrypt_tkt (user, instance, realm, arg, keyprocs[i], &cip); + } else { + (*decrypt_proc)(user, instance, realm, arg, keyprocs[i], &cip); + } + kerror = krb_parse_in_tkt_creds(user, instance, realm, + service, sinstance, life, cip, byteorder, creds); + } while ((keyprocs [++i] != NULL) && (kerror == INTK_BADPW)) + #if TARGET_OS_MAC /* Do this here to avoid OS dependency in parse_in_tkt prototype. */ creds->address = local_addr->sin_addr.s_addr; @@ -504,7 +511,7 @@ krb_get_in_tkt_preauth(user, instance, realm, service, sinstance, life, creds.realm, creds.session, creds.lifetime, creds.kvno, &creds.ticket_st, creds.issue_date, - creds.address, creds.stk_type); + creds.address); #else retval = krb_save_credentials(creds.service, creds.instance, creds.realm, creds.session, diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c index 1aa22783f..fc3f70c55 100644 --- a/src/lib/krb4/g_pw_in_tkt.c +++ b/src/lib/krb4/g_pw_in_tkt.c @@ -127,8 +127,8 @@ krb_get_pw_in_tkt(user,instance,realm,service,sinstance,life,password) #endif return(krb_get_in_tkt(user,instance,realm,service,sinstance,life, - (key_proc_type)passwd_to_key, - (decrypt_tkt_type)NULL, password)); + (key_proc_type)NULL, /* krb_get_in_tkt will try them all */ + (decrypt_tkt_type)NULL, password)); } int KRB5_CALLCONV @@ -138,7 +138,7 @@ krb_get_pw_in_tkt_creds( { return krb_get_in_tkt_creds(user, instance, realm, service, sinstance, life, - (key_proc_type)passwd_to_key, + (key_proc_type)NULL, /* krb_get_in_tkt_creds will try them all */ NULL, password, creds); } @@ -166,26 +166,32 @@ krb_get_pw_in_tkt_preauth(user,instance,realm,service,sinstance,life,password) int life; char *password; { - char *preauth_p; - int preauth_len; - int ret_st; - -#if defined(_WIN32) || defined(macintosh) + char *preauth_p; + int preauth_len; + int ret_st; + key_proc_type *keyprocs = krb_get_keyprocs (NULL); + int i = 0; + +#if defined(_WIN32) || USE_LOGIN_LIBRARY /* On non-Unix systems, we can't handle a null password, because passwd_to_key can't handle prompting for the password. */ - if (password == 0) - return INTK_PW_NULL; + if (password == 0) + return INTK_PW_NULL; #endif - krb_mk_preauth(&preauth_p, &preauth_len, (key_proc_type)passwd_to_key, - user, instance, realm, password, old_key); - ret_st = krb_get_in_tkt_preauth(user,instance,realm,service,sinstance,life, + /* Loop trying all the key_proc types */ + do { + krb_mk_preauth(&preauth_p, &preauth_len, keyprocs[i], + user, instance, realm, password, old_key); + ret_st = krb_get_in_tkt_preauth(user,instance,realm,service,sinstance,life, (key_proc_type) stub_key, (decrypt_tkt_type) NULL, password, preauth_p, preauth_len); - - krb_free_preauth(preauth_p, preauth_len); - return ret_st; + + krb_free_preauth(preauth_p, preauth_len); + } while ((keyprocs[++i] != NULL) && (ret_st == INTK_BADPW)); + + return ret_st; } /* FIXME! This routine belongs in the krb library and should simply diff --git a/src/lib/krb4/krb4int.h b/src/lib/krb4/krb4int.h index 1c7ab9f79..0b0c19b99 100644 --- a/src/lib/krb4/krb4int.h +++ b/src/lib/krb4/krb4int.h @@ -67,6 +67,15 @@ void krb_set_logfile(char *); /* month_sname.c */ const char * month_sname(int); +/* password_to_key.c */ +key_proc_type *krb_get_keyprocs (key_proc_type keyproc); +int mit_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key); +int krb5_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key); +int afs_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key); + /* rd_preauth.c */ #ifdef KRB_DB_DEFS int krb_rd_preauth(KTEXT, char *, int, Principal *, des_cblock); diff --git a/src/lib/krb4/password_to_key.c b/src/lib/krb4/password_to_key.c index e488eb238..b4b4d00b3 100644 --- a/src/lib/krb4/password_to_key.c +++ b/src/lib/krb4/password_to_key.c @@ -29,8 +29,8 @@ #include #include -#if TARGET_OS_MAC -#include +#ifdef USE_CCAPI +#include #endif #include "krb.h" #include "krb4int.h" @@ -53,68 +53,47 @@ * and 0 is returned. */ -#if TARGET_OS_MAC -/*ARGSUSED */ -int -krb_get_keyprocs(KRB_UINT32 stkType, - key_proc_array kps, key_proc_type_array sts) -{ - /* generates the list of key procs */ - /* always try them all, but try the specified one first */ - switch (stkType) { - case cc_v4_stk_afs: - kps[0] = afs_passwd_to_key; - sts[0] = cc_v4_stk_afs; - - kps[1] = mit_passwd_to_key; - sts[1] = cc_v4_stk_des; - - kps[2] = krb5_passwd_to_key; - sts[2] = cc_v4_stk_krb5; - - kps[3] = NULL; - break; - case cc_v4_stk_des: - case cc_v4_stk_unknown: - default: - kps[0] = mit_passwd_to_key; - sts[0] = cc_v4_stk_des; - - kps[1] = afs_passwd_to_key; - sts[1] = cc_v4_stk_afs; - kps[2] = krb5_passwd_to_key; - sts[2] = cc_v4_stk_krb5; - - kps[3] = NULL; - break; +key_proc_type *krb_get_keyprocs (key_proc_type keyproc) +{ + static key_proc_type default_keyprocs[4] = { mit_passwd_to_key, + afs_passwd_to_key, + krb5_passwd_to_key, + NULL }; + + static key_proc_type user_keyprocs[2] = { NULL, NULL }; + + /* generate the list of key procs */ + if (key_proc == NULL) { + return default_keyprocs; /* use the default */ + } else { + user_keyprocs[0] = keyproc; + return user_keyprocs; /* use the caller provided keyprocs */ } - return KSUCCESS; } -#endif -int -mit_passwd_to_key(char *user, char *instance, char *realm, - char *passwd, C_Block key) +int mit_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key) { #pragma unused(user) #pragma unused(instance) #pragma unused(realm) - if (passwd) + if (passwd) { mit_string_to_key(passwd, key); -#if !(defined(_WIN32) || defined(macintosh)) - else { - des_read_password((C_Block *)key, "Password: ", 0); + } else { +#if !(defined(_WIN32) || defined(USE_LOGIN_LIBRARY)) + des_read_password((des_cblock *)key, "Password: ", 0); +#else + return (-1); +#endif } -#endif /* unix */ return (0); } /* So we can use a v4 kinit against a v5 kdc with no krb4 salted key */ -int -krb5_passwd_to_key(char *user, char *instance, char *realm, - char *passwd, C_Block key) +int krb5_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key) { if (user && instance && realm && passwd) { unsigned int len = MAX_K_NAME_SZ + strlen(passwd) + 1; @@ -130,19 +109,20 @@ krb5_passwd_to_key(char *user, char *instance, char *realm, return -1; } -int -afs_passwd_to_key(char *user, char *instance, char *realm, - char *passwd, C_Block key) +int afs_passwd_to_key(char *user, char *instance, char *realm, + char *passwd, C_Block key) { #pragma unused(user) #pragma unused(instance) - if (passwd) + if (passwd) { afs_string_to_key(passwd, realm, key); -#if !(defined(_WIN32) || defined(macintosh)) - else { - des_read_password((C_Block *)key, "Password: ", 0); + } else { +#if !(defined(_WIN32) || defined(USE_LOGIN_LIBRARY)) + des_read_password((des_cblock *)key, "Password: ", 0); +#else + return (-1); +#endif } -#endif /* unix */ return (0); } -- 2.26.2