#include <CoreServices/CoreServices.h>
-#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 <Kerberos/KerberosLoginPrivate.h>
+#include <KerberosLoginPrivate.h>
#endif /* USE_LOGIN_LIBRARY */
-#include <Kerberos/CredentialsCache.h>
+#include <CredentialsCache.h>
#include <string.h>
#include <stdlib.h>
-
-#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
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;
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;
*
* 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)
/*
* Credentials file -> name, instance, realm mapping
*/
-int INTERFACE
+int KRB5_CALLCONV
krb_get_tf_fullname (
const char* ticket_file,
char* name,
/*
* Retrieval from credentials cache
*/
-int INTERFACE
+int KRB5_CALLCONV
krb_get_cred (
char* service,
char* instance,
/*
* Getting name of default credentials cache
*/
-const char* INTERFACE
+const char* KRB5_CALLCONV
tkt_string (void)
{
if (gDefaultCacheName == NULL) {
*
* Implementation in dest_tkt.c
*/
-int INTERFACE
+int KRB5_CALLCONV
dest_tkt (void)
{
cc_int32 cc_err = ccNoError;
/*
* Number of credentials in credentials cache
*/
-int INTERFACE
+int KRB5_CALLCONV
krb_get_num_cred (void)
{
cc_credentials_t theCreds = NULL;
* 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,
/*
* Deletion from credentials file
*/
-int INTERFACE
+int KRB5_CALLCONV
krb_delete_cred (
char* sname,
char* sinstance,
*
* Implementation in memcache.c
*/
-int INTERFACE
+int KRB5_CALLCONV
dest_all_tkts (void)
{
int count = 0;
+2003-02-10 Alexandra Ellwood <lxs@mit.edu>
+ 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 <tlyu@mit.edu>
* Makefile.in: Add rules to generate krb_err_txt.c.
#if TARGET_OS_MAC && defined(__FILES__)
-#include <Kerberos/KerberosFullPath.h>
+#include <CoreServices/CoreServices.h>
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(
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;
}
}
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;
}
}
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
#include "krb4int.h"
#include "port-sockets.h"
-#if USE_CCAPI
-#include <Kerberos/CredentialsCache.h>
+#ifdef USE_CCAPI
+#include <CredentialsCache.h>
#endif
#define KRB5_PRIVATE 1
return result;
}
-#if USE_CCAPI
+#ifdef USE_CCAPI
/*
* Realm -> string_to_key mapping
*/
#include <string.h>
#include <stdlib.h>
-#if TARGET_OS_MAC /* XXX */
-#include <Kerberos/CredentialsCache.h>
-#endif
#include "krb.h"
#include "krb4int.h"
#include "kadm.h"
#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
#include "krb4int.h"
#include "prot.h"
+#include "port-sockets.h"
#include <string.h>
/* Define a couple of function types including parameters. These
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
#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;
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,
#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
{
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);
}
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
/* 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);
#include <string.h>
#include <stdlib.h>
-#if TARGET_OS_MAC
-#include <Kerberos/CredentialsCache.h>
+#ifdef USE_CCAPI
+#include <CredentialsCache.h>
#endif
#include "krb.h"
#include "krb4int.h"
* 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;
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);
}