From: Tom Yu Date: Sat, 19 Sep 1998 02:32:21 +0000 (+0000) Subject: merge of tlyu-3des-k4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa92c95777d0cede4d8bb4a10e90dc988b44fd9f;p=thirdparty%2Fkrb5.git merge of tlyu-3des-k4 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/marc-3des@10922 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/ChangeLog b/src/ChangeLog index 3e225822a5..92eea4d3f4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +Wed Aug 19 20:14:31 1998 Tom Yu + + * aclocal.m4 (KRB5_LIB_AUX): Back out Sam's change to reorder the + "force_static" logic, as it would cause problems where a + forced-static library is built in the same directory as a + program, due to explicit setting of CC_LINK, etc. + +Mon Aug 17 18:10:29 1998 Tom Yu + + * aclocal.m4: Fix Sam's fixes (variable capitalization). + Wed Jul 8 01:10:44 1998 Matthew D Hancher * aclocal.m4: Allow shared libraries to build properly under Irix diff --git a/src/aclocal.m4 b/src/aclocal.m4 index 00b0d418fe..e789b59db2 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -888,10 +888,6 @@ AC_ARG_ENABLE([shared], *) if test "$krb5_force_static" = "yes"; then AC_MSG_RESULT([Forcing static libraries.]) - SHLIBEXT=.so-nobuild - SHLIBVEXT=.so.v-nobuild - CC_LINK="$CC_LINK_STATIC" - SHLIBSEXT=.so.s-nobuild else AC_MSG_RESULT([Enabling shared libraries.]) LIBLIST="$LIBLIST "'lib$(LIB)$(SHLIBEXT)' @@ -907,13 +903,13 @@ AC_ARG_ENABLE([shared], ;; esac OBJLISTS="$OBJLISTS OBJS.SH" + fi DEPLIBEXT=$SHLIBEXT CC_LINK="$CC_LINK_SHARED" if test "$STLIBEXT" = "$SHLIBEXT" ; then STLIBEXT=".a-no-build" LIBINSTLIST="install-shared" #don't install static fi -fi ;; esac else @@ -1022,7 +1018,7 @@ mips-sgi-irix6.3) # This is a Kludge; see below SHLIBEXT=.so SHOBJEXT=.o # Kludge follows: (gcc makes n32 object files but ld expects o32, so we reeducate ld) - if test "$KRB5_CV_PROG_GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then LDCOMBINE='ld -n32 -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname lib$(LIB)$(SHLIBSEXT)' else LDCOMBINE='ld -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname lib$(LIB)$(SHLIBSEXT)' @@ -1051,7 +1047,7 @@ mips-sgi-irix*) # untested... mips-sni-sysv4) - if test "$KRB5_CV_PROG_GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then PICFLAGS=-fpic LDCOMBINE='$(CC) -G -Wl,-h -Wl,lib$(LIB)$(SHLIBSEXT)' else @@ -1118,7 +1114,7 @@ mips-*-netbsd*) ;; *-*-solaris*) - if test "$KRB5_CV_PROG_GCC" = yes; then + if test "$krb5_cv_prog_gcc" = yes; then PICFLAGS=-fpic LDCOMBINE='$(CC) -shared -h lib$(LIB)$(SHLIBSEXT)' else diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index e25c6652a6..53213697ef 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,7 @@ +Tue Aug 18 16:48:02 1998 Tom Yu + + * krlogin.c: Add for FIONREAD. + Sun Jul 26 23:46:36 1998 Sam Hartman * login.c (main): Allow krb524 conversion for forwarded tickets diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index ae875f15cd..6471f2b00b 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -61,6 +61,11 @@ char copyright[] = #include #include +#ifdef HAVE_SYS_FILIO_H +/* Solaris needs for FIONREAD */ +#include +#endif + #ifdef HAVE_STDLIB_H #include #endif diff --git a/src/clients/ChangeLog b/src/clients/ChangeLog index fc6d07275c..5e97d0fa67 100644 --- a/src/clients/ChangeLog +++ b/src/clients/ChangeLog @@ -1,3 +1,9 @@ +Thu Aug 13 19:05:43 1998 Tom Yu + + * configure.in: Remove kvno for now. + + * Makefile.in (LOCAL_SUBDIRS): Remove kvno for now. + Sat Jul 25 15:00:26 1998 Sam Hartman * Makefile.in (LOCAL_SUBDIRS): add kvno diff --git a/src/clients/Makefile.in b/src/clients/Makefile.in index e772cf6b86..b793c04303 100644 --- a/src/clients/Makefile.in +++ b/src/clients/Makefile.in @@ -1,7 +1,7 @@ thisconfigdir=. BUILDTOP=$(REL)$(U) -LOCAL_SUBDIRS= klist kinit kdestroy kpasswd ksu kvno +LOCAL_SUBDIRS= klist kinit kdestroy kpasswd ksu ##WIN32##all-windows:: ##WIN32## @echo Making all in clients\klist diff --git a/src/clients/configure.in b/src/clients/configure.in index db30b09c31..578f48751d 100644 --- a/src/clients/configure.in +++ b/src/clients/configure.in @@ -8,7 +8,7 @@ AC_CHECK_HEADERS(unistd.h pwd.h) K5_GEN_MAKEFILE(.) K5_GEN_MAKEFILE(klist) K5_GEN_MAKEFILE(kinit) -K5_GEN_MAKEFILE(kvno) +dnl K5_GEN_MAKEFILE(kvno) K5_GEN_MAKEFILE(kdestroy) K5_GEN_MAKEFILE(kpasswd) K5_GEN_MAKEFILE(ksu) diff --git a/src/include/ChangeLog b/src/include/ChangeLog index b3c8848e00..0f5ee7119e 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,9 @@ +Tue Sep 1 19:32:33 1998 Tom Yu + + * krb5.hin: Add ENCTYPE_LOCAL_DES3_HMAC_SHA1, in order to deal + with marc's current des3 cryptosystem until we figure out what + we're actually going to use for a standardized cryptosystem. + Wed Jul 1 19:14:25 1998 Theodore Y. Ts'o * win-mac.h: Make size_t to be an unsigned long instead of diff --git a/src/include/kerberosIV/ChangeLog b/src/include/kerberosIV/ChangeLog index 85f624b066..0ecf2b09e7 100644 --- a/src/include/kerberosIV/ChangeLog +++ b/src/include/kerberosIV/ChangeLog @@ -1,3 +1,9 @@ +Thu Sep 17 18:23:26 1998 Tom Yu + + * krb_db.h: ifdef out the declarations for kerb_get_* and + kerb_db_* to avoid problems with krb4 compat code in the kdc, + which declares some of these static. + Wed Feb 18 15:51:41 1998 Tom Yu * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/include/kerberosIV/krb_db.h b/src/include/kerberosIV/krb_db.h index 4925137c43..dc2265d960 100644 --- a/src/include/kerberosIV/krb_db.h +++ b/src/include/kerberosIV/krb_db.h @@ -104,11 +104,13 @@ typedef struct { } Dba; +#if 0 extern int kerb_get_principal(); extern int kerb_put_principal(); extern int kerb_db_get_stat(); extern int kerb_db_put_stat(); extern int kerb_get_dba(); extern int kerb_db_get_dba(); +#endif #endif /* KRB_DB_DEFS */ diff --git a/src/include/krb5.hin b/src/include/krb5.hin index a8a15fee81..2442b4a083 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -132,11 +132,11 @@ typedef unsigned int krb5_boolean; typedef unsigned int krb5_msgtype; typedef unsigned int krb5_kvno; -typedef unsigned int krb5_addrtype; -typedef unsigned int krb5_enctype; -typedef unsigned int krb5_cksumtype; -typedef unsigned int krb5_authdatatype; -typedef unsigned int krb5_keyusage; +typedef krb5_int32 krb5_addrtype; +typedef krb5_int32 krb5_enctype; +typedef krb5_int32 krb5_cksumtype; +typedef krb5_int32 krb5_authdatatype; +typedef krb5_int32 krb5_keyusage; typedef krb5_int32 krb5_preauthtype; /* This may change, later on */ typedef krb5_int32 krb5_flags; @@ -325,6 +325,9 @@ typedef struct _krb5_enc_data { #define ENCTYPE_DES3_HMAC_SHA1 0x0007 #define ENCTYPE_DES_HMAC_SHA1 0x0008 #define ENCTYPE_UNKNOWN 0x01ff +/* local crud */ +/* marc's DES-3 with 32-bit length */ +#define ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007 #define CKSUMTYPE_CRC32 0x0001 #define CKSUMTYPE_RSA_MD4 0x0002 diff --git a/src/kadmin/dbutil/ChangeLog b/src/kadmin/dbutil/ChangeLog index 3ab92e90e3..6cae35b0cf 100644 --- a/src/kadmin/dbutil/ChangeLog +++ b/src/kadmin/dbutil/ChangeLog @@ -1,3 +1,15 @@ +Thu Aug 20 16:50:00 1998 Tom Yu + + * kdb5_util.c (add_random_key): Fixes to deal with absence of "-e" + flag. + +Wed Aug 19 14:52:40 1998 Tom Yu + + * kdb5_util.c (add_random_key): New function to create a new + random key for a principal while retaining the previous kvno's + keys. This is only temporary until a reasonable kadm5 interface + is made. + 1998-05-06 Theodore Ts'o * kdb5_stash.c (argv): diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c index 775d83ad96..d99b0c08b9 100644 --- a/src/kadmin/dbutil/kdb5_util.c +++ b/src/kadmin/dbutil/kdb5_util.c @@ -60,7 +60,8 @@ usage() "\tdump [-old] [-ov] [-b6] [-verbose] [filename [princs...]]\n" "\tload [-old] [-ov] [-b6] [-verbose] [-update] filename\n" "\tdump_v4 [filename]\n" - "\tload_v4 [-t] [-n] [-v] [-K] [-s stashfile] inputfile\n"); + "\tload_v4 [-t] [-n] [-v] [-K] [-s stashfile] inputfile\n" + "\tark [-e etype_list] principal\n"); exit(1); } @@ -82,6 +83,7 @@ int load_db(int, char **); int dump_v4db(int, char **); int load_v4db(int, char **); int open_db_and_mkey(); +int add_random_key(int, char **); typedef int (*cmd_func)(int, char **); @@ -97,6 +99,7 @@ struct _cmd_table { "load", load_db, 0, "dump_v4", dump_v4db, 1, "load_v4", load_v4db, 0, + "ark", add_random_key, 1, NULL, NULL, 0, }; @@ -413,3 +416,104 @@ quit() } return 0; } + +int +add_random_key(argc, argv) + int argc; + char **argv; +{ + krb5_error_code ret; + krb5_principal princ; + krb5_db_entry dbent; + int n, i; + krb5_boolean more; + krb5_timestamp now; + + krb5_key_salt_tuple *keysalts = NULL; + krb5_int32 num_keysalts = 0; + + int free_keysalts; + char *me = argv[0]; + char *ks_str = NULL; + char *pr_str; + + if (argc < 2) + usage(); + for (argv++, argc--; *argv; argv++, argc--) { + if (!strcmp(*argv, "-e")) { + argv++; argc--; + ks_str = *argv; + continue; + } else + break; + } + if (argc < 1) + usage(); + pr_str = *argv; + ret = krb5_parse_name(util_context, pr_str, &princ); + if (ret) { + com_err(me, ret, "while parsing principal name %s", pr_str); + return 1; + } + n = 1; + ret = krb5_db_get_principal(util_context, princ, &dbent, + &n, &more); + if (ret) { + com_err(me, ret, "while fetching principal %s", pr_str); + return 1; + } + if (n != 1) { + fprintf(stderr, "principal %s not found\n", pr_str); + return 1; + } + if (more) { + fprintf(stderr, "principal %s not unique\n", pr_str); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_string_to_keysalts(ks_str, + ", \t", ":.-", 0, + &keysalts, + &num_keysalts); + if (ret) { + com_err(me, ret, "while parsing keysalts %s", ks_str); + return 1; + } + if (!num_keysalts || keysalts == NULL) { + num_keysalts = global_params.num_keysalts; + keysalts = global_params.keysalts; + free_keysalts = 0; + } else + free_keysalts = 1; + ret = krb5_dbe_ark(util_context, &master_keyblock, + keysalts, num_keysalts, + &dbent); + if (free_keysalts) + free(keysalts); + if (ret) { + com_err(me, ret, "while randomizing principal %s", pr_str); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + dbent.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; + ret = krb5_timeofday(util_context, &now); + if (ret) { + com_err(me, ret, "while getting time"); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_dbe_update_last_pwd_change(util_context, &dbent, now); + if (ret) { + com_err(me, ret, "while setting changetime"); + krb5_dbe_free_contents(util_context, &dbent); + return 1; + } + ret = krb5_db_put_principal(util_context, &dbent, &n); + krb5_dbe_free_contents(util_context, &dbent); + if (ret) { + com_err(me, ret, "while saving principal %s", pr_str); + return 1; + } + printf("%s changed\n", pr_str); + return 0; +} diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index 6b9617d4ec..4bdf99afd2 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,46 @@ +Thu Sep 17 18:21:51 1998 Tom Yu + + * kdc_util.c (kdc_get_server_key): Fix to not use cached tgs key + to prevent lossage when it might be out of date by always fetching + the correct kvno for the ticket out of the database. + +Tue Sep 1 19:34:30 1998 Tom Yu + + * kerberos_v4.c (compat_decrypt_key): Add + ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list of keytypes to bash. + (kerb_get_principal): Add ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list + of searched enctypes. + +Wed Aug 19 13:37:00 1998 Tom Yu + + * kerberos_v4.c (set_tgtkey): Add kvno arg to fetch an explicit + kvno. Also compare kvno as well as realm when caching the TGT + key. Declare as static. + (kerb_get_principal): Add kvno argument to permit searching for + an explicit kvno. + (kerberos_v4): Extract the kvno directly out of the krb_req, since + we know what the format is. + +Wed Aug 12 18:40:08 1998 Tom Yu + + * kerberos_v4.c: Add macro K4KDC_ENCTYPE_OK to determine whether a + given enctype is compatible with single-DES krb4. + (compat_decrypt_key): Declare as static. Change call signature to + include an output krb5_keyblock as well as an input to determine + whether the principal should be treated as a service principal. + Bash the enctype of the keyblock to raw des3 if it's full-blown + des3. + (kerb_get_principal): Add k5key and issrv arguments as in + compat_decrypt_key, mostly to pass them on there. Hardcode a + search order that includes des3 for looking up service keys. + (kerberos_v4): Call krb_create_ticket or krb_cr_tkt_krb5 as + appropriate to the key type. While we're at it, s/ktbtgt/krbtgt/ + just to avoid confusing people. + (check_princ): Add k5key and issrv args for as in + compat_decrypt_key. Fix up null key detection to only operate if + it's a single-des key. + (set_tgtkey): Call krb_set_key_krb5 if appropriate. + Wed Jul 15 18:32:07 1998 Tom Yu * configure.in: Add CHECK_SIGNALS so that POSIX_SIGNALS gets diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 110e56884c..51d4d7807e 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -335,12 +335,15 @@ cleanup: /* XXX This function should no longer be necessary. * The KDC should take the keytab associated with the realm and pass that to * the krb5_rd_req_decode(). --proven + * + * It's actually still used by do_tgs_req() for u2u auth, and not too + * much else. -- tlyu */ krb5_error_code kdc_get_server_key(ticket, key, kvno) krb5_ticket * ticket; krb5_keyblock ** key; - krb5_kvno * kvno; + krb5_kvno * kvno; /* XXX nothing uses this */ { krb5_error_code retval; krb5_db_entry server; @@ -349,64 +352,46 @@ kdc_get_server_key(ticket, key, kvno) krb5_key_data * server_key; int i; - if (krb5_principal_compare(kdc_context, tgs_server, ticket->server)) { - retval = krb5_copy_keyblock(kdc_context, &tgs_key, key); - *kvno = tgs_kvno; - return retval; - } else { - nprincs = 1; + nprincs = 1; - if ((retval = krb5_db_get_principal(kdc_context, ticket->server, - &server, &nprincs, - &more))) { - return(retval); - } - if (more) { - krb5_db_free_principal(kdc_context, &server, nprincs); - return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); - } else if (nprincs != 1) { - char *sname; - - krb5_db_free_principal(kdc_context, &server, nprincs); - if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) { - krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'", - sname); - free(sname); - } - return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); - } - /* - * Get the latest version of the server key_data and - * convert the key into a real key (it may be encrypted in the database) - * - * Search the key list in the order specified by the key/salt list. - */ - server_key = (krb5_key_data *) NULL; - for (i=0; irealm_nkstypes; i++) { - krb5_key_salt_tuple *kslist; - - kslist = (krb5_key_salt_tuple *) kdc_active_realm->realm_kstypes; - if (!krb5_dbe_find_enctype(kdc_context, - &server, - kslist[i].ks_enctype, - -1, - -1, - &server_key)) - break; - } - if (!server_key) - return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); - - *kvno = server_key->key_data_kvno; - if ((*key = (krb5_keyblock *)malloc(sizeof **key))) { - retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, - server_key, - *key, NULL); - } else - retval = ENOMEM; + if ((retval = krb5_db_get_principal(kdc_context, ticket->server, + &server, &nprincs, + &more))) { + return(retval); + } + if (more) { krb5_db_free_principal(kdc_context, &server, nprincs); - return retval; + return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + } else if (nprincs != 1) { + char *sname; + + krb5_db_free_principal(kdc_context, &server, nprincs); + if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) { + krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'", + sname); + free(sname); + } + return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); + } + retval = krb5_dbe_find_enctype(kdc_context, &server, + ticket->enc_part.enctype, -1, + ticket->enc_part.kvno, &server_key); + if (retval) + goto errout; + if (!server_key) { + retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; + goto errout; } + *kvno = server_key->key_data_kvno; + if ((*key = (krb5_keyblock *)malloc(sizeof **key))) { + retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, + server_key, + *key, NULL); + } else + retval = ENOMEM; +errout: + krb5_db_free_principal(kdc_context, &server, nprincs); + return retval; } /* This probably wants to be updated if you support last_req stuff */ diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c index 57e2704b5e..2bc3e8ced5 100644 --- a/src/kdc/kerberos_v4.c +++ b/src/kdc/kerberos_v4.c @@ -65,10 +65,12 @@ extern int errno; -int compat_decrypt_key PROTOTYPE((krb5_key_data *, C_Block)); -int kerb_get_principal PROTOTYPE((char *, char *, Principal *, int, - int *)); -int check_princ PROTOTYPE((char *, char *, unsigned, Principal *)); +static int compat_decrypt_key PROTOTYPE((krb5_key_data *, C_Block, + krb5_keyblock *, int)); +static int kerb_get_principal PROTOTYPE((char *, char *, Principal *, int, + int *, krb5_keyblock *, krb5_kvno, int)); +static int check_princ PROTOTYPE((char *, char *, unsigned, Principal *, + krb5_keyblock *, int)); #ifdef HAVE_STDARG_H char * v4_klog KRB5_PROTOTYPE((int, const char *, ...)); @@ -144,8 +146,8 @@ static krb5_data *response; void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); -int set_tgtkey PROTOTYPE((char *)); - +static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); + /* Attributes converted from V5 to V4 - internal representation */ #define V4_KDB_REQUIRES_PREAUTH 0x1 #define V4_KDB_DISALLOW_ALL_TIX 0x2 @@ -334,36 +336,59 @@ hang() } #define kdb_encrypt_key( in, out, mk, mks, e_d_flag) #define LONGLEN 4 +#define K4KDC_ENCTYPE_OK(e) \ +((e) == ENCTYPE_DES_CBC_CRC \ + || (e) == ENCTYPE_DES_CBC_MD4 \ + || (e) == ENCTYPE_DES_CBC_MD5 \ + || (e) == ENCTYPE_DES_CBC_RAW) /* take a v5 keyblock, masquerading as a v4 key, * decrypt it, and convert the resulting v5 keyblock * to a real v4 key. * this is ugly, but it saves changing more v4 code. + * + * Also, keep old krb5_keyblock around in case we want to use it later. */ -int compat_decrypt_key (in5, out4) - krb5_key_data *in5; - C_Block out4; +static int +compat_decrypt_key (in5, out4, out5, issrv) + krb5_key_data *in5; + C_Block out4; + krb5_keyblock *out5; + int issrv; /* whether it's a server key */ { - krb5_keyblock out5; - int retval = -1; + krb5_error_code retval; - out5.contents = NULL; - if (krb5_dbekd_decrypt_key_data(kdc_context,&master_keyblock,in5,&out5,NULL)){ + out5->contents = NULL; + memset(out4, 0, sizeof(out4)); + retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock, + in5, out5, NULL); + if (retval) { lt = klog(L_DEATH_REQ, "KDC can't decrypt principal's key."); + out5->contents = NULL; return(retval); } - if (out5.length != KRB5_MIT_DES_KEYSIZE) - lt = klog(L_DEATH_REQ, "internal keysize error in kdc"); - else if ((out5.enctype != ENCTYPE_DES_CBC_CRC) && - (out5.enctype != ENCTYPE_DES_CBC_MD4) && - (out5.enctype != ENCTYPE_DES_CBC_MD5) && - (out5.enctype != ENCTYPE_DES_CBC_RAW)) - lt = klog(L_DEATH_REQ, "incompatible principal key type."); - else { - memcpy(out4, out5.contents, out5.length); - retval = 0; + if (K4KDC_ENCTYPE_OK(out5->enctype)) { + if (out5->length == KRB5_MIT_DES_KEYSIZE) + memcpy(out4, out5->contents, out5->length); + else { + lt = klog(L_DEATH_REQ, "internal keysize error in kdc"); + krb5_free_keyblock_contents(kdc_context, out5); + out5->contents = NULL; + retval = -1; + } + } else { + if (!issrv) { + lt = klog(L_DEATH_REQ, "incompatible principal key type."); + krb5_free_keyblock_contents(kdc_context, out5); + out5->contents = NULL; + retval = -1; + } else { + /* KLUDGE! If it's a non-raw des3 key, bash its enctype */ + if (out5->enctype == ENCTYPE_DES3_HMAC_SHA1 || + out5->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) + out5->enctype = ENCTYPE_DES3_CBC_RAW; + } } - krb5_free_keyblock_contents(kdc_context, &out5); return(retval); } @@ -372,13 +397,16 @@ int compat_decrypt_key (in5, out4) #define MIN5 300 #define HR21 255 -int -kerb_get_principal(name, inst, principal, maxn, more) +static int +kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) char *name; /* could have wild card */ char *inst; /* could have wild card */ Principal *principal; int maxn; /* max number of name structs to return */ int *more; /* more tuples than room for */ + krb5_keyblock *k5key; + krb5_kvno kvno; + int issrv; /* true if retrieving a service key */ { /* Note that this structure should not be passed to the krb5_free* functions, because the pointers within it point @@ -430,27 +458,52 @@ kerb_get_principal(name, inst, principal, maxn, more) return(nprinc); } - if (krb5_dbe_find_enctype(kdc_context, - &entries, - ENCTYPE_DES_CBC_CRC, - KRB5_KDB_SALTTYPE_V4, - -1, - &pkey) && - krb5_dbe_find_enctype(kdc_context, - &entries, - ENCTYPE_DES_CBC_CRC, - -1, - -1, - &pkey)) - { - lt = klog(L_KRB_PERR, "KDC V4: principal %s.%s isn't V4 compatible", - name, inst); - krb5_db_free_principal(kdc_context, &entries, nprinc); - return(0); + if (!issrv) { + if (krb5_dbe_find_enctype(kdc_context, + &entries, + ENCTYPE_DES_CBC_CRC, + KRB5_KDB_SALTTYPE_V4, + kvno, + &pkey) && + krb5_dbe_find_enctype(kdc_context, + &entries, + ENCTYPE_DES_CBC_CRC, + -1, + kvno, + &pkey)) { + lt = klog(L_KRB_PERR, + "KDC V4: principal %s.%s isn't V4 compatible", + name, inst); + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } + } else { + /* XXX yes I know this is a hardcoded search order */ + if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_LOCAL_DES3_HMAC_SHA1, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_HMAC_SHA1, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES_CBC_CRC, + KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES_CBC_CRC, + -1, kvno, &pkey)) { + lt = klog(L_KRB_PERR, + "KDC V4: failed to find key for %s.%s", + name, inst); + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } } - if (! compat_decrypt_key( pkey, k)) { - memcpy( &principal->key_low, k, LONGLEN); + if (!compat_decrypt_key(pkey, k, k5key, issrv)) { + memcpy( &principal->key_low, k, LONGLEN); memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); } /* convert v5's entries struct to v4's Principal struct: @@ -550,7 +603,11 @@ kerberos_v4(client, pkt) Key_schedule key_s; char *ptr; + krb5_keyblock k5key; + krb5_kvno kvno; + + k5key.contents = NULL; /* in case we have to free it */ ciph->length = 0; @@ -639,11 +696,14 @@ kerberos_v4(client, pkt) inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); if ((i = check_princ(req_name_ptr, req_inst_ptr, 0, - &a_name_data))) { + &a_name_data, &k5key, 0))) { kerb_err_reply(client, pkt, i, lt); a_name_data.key_low = a_name_data.key_high = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } + /* don't use k5key for client */ + krb5_free_keyblock_contents(kdc_context, &k5key); tk->length = 0; /* init */ if (strcmp(service, "krbtgt")) klog(L_NTGT_INTK, @@ -651,10 +711,11 @@ kerberos_v4(client, pkt) req_inst_ptr, service, instance, 0); /* this does all the checking */ if ((i = check_princ(service, instance, lifetime, - &s_name_data))) { + &s_name_data, &k5key, 1))) { kerb_err_reply(client, pkt, i, lt); a_name_data.key_high = a_name_data.key_low = 0; s_name_data.key_high = s_name_data.key_low = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } /* Bound requested lifetime with service and user */ @@ -675,10 +736,22 @@ kerberos_v4(client, pkt) kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); /* construct and seal the ticket */ - krb_create_ticket(tk, k_flags, a_name_data.name, - a_name_data.instance, local_realm, - client_host.s_addr, (char *) session_key, lifetime, kerb_time.tv_sec, - s_name_data.name, s_name_data.instance, key); + if (K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_create_ticket(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, (char *) session_key, + lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + key); + } else { + krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, + a_name_data.instance, local_realm, + client_host.s_addr, (char *) session_key, + lifetime, kerb_time.tv_sec, + s_name_data.name, s_name_data.instance, + &k5key); + } + krb5_free_keyblock_contents(kdc_context, &k5key); memset(key, 0, sizeof(key)); memset(key_s, 0, sizeof(key_s)); @@ -737,14 +810,15 @@ kerberos_v4(client, pkt) memcpy(auth->dat, pkt->dat, auth->length); strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ); - if (set_tgtkey(tktrlm)) { + kvno = (krb5_kvno)auth->dat[2]; + if (set_tgtkey(tktrlm, kvno)) { lt = klog(L_ERR_UNK, - "FAILED realm %s unknown. Host: %s ", - tktrlm, inet_ntoa(client_host)); + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); kerb_err_reply(client, pkt, kerno, lt); return; } - kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, ad, 0); if (kerno) { @@ -784,9 +858,11 @@ kerberos_v4(client, pkt) return; } kerno = check_princ(service, instance, req_life, - &s_name_data); + &s_name_data, &k5key, 1); if (kerno) { kerb_err_reply(client, pkt, kerno, lt); + s_name_data.key_high = s_name_data.key_low = 0; + krb5_free_keyblock_contents(kdc_context, &k5key); return; } /* Bound requested lifetime with service and user */ @@ -910,18 +986,21 @@ static char *krb4_stime(t) return st; } -int check_princ(p_name, instance, lifetime, p) +static int +check_princ(p_name, instance, lifetime, p, k5key, issrv) char *p_name; char *instance; unsigned lifetime; Principal *p; + krb5_keyblock *k5key; + int issrv; /* whether this is a server key */ { static int n; static int more; /* long trans; */ - n = kerb_get_principal(p_name, instance, p, 1, &more); + n = kerb_get_principal(p_name, instance, p, 1, &more, k5key, 0, issrv); klog(L_ALL_REQ, "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", p_name, instance, lifetime, n, 0); @@ -987,10 +1066,12 @@ int check_princ(p_name, instance, lifetime, p) /* If the user's key is null, we want to return an error */ if ((p->key_low == 0) && (p->key_high == 0)) { - /* User has a null key */ - lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, - instance, 0); - return KERB_ERR_NULL_KEY; + if (k5key->contents != NULL && K4KDC_ENCTYPE_OK(k5key->enctype)) { + /* User has a null key */ + lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, + instance, 0); + return KERB_ERR_NULL_KEY; + } } /* make sure the service hasn't expired */ if (((u_long) p->exp_date != 0)&& @@ -1007,31 +1088,44 @@ int check_princ(p_name, instance, lifetime, p) /* Set the key for krb_rd_req so we can check tgt */ -int set_tgtkey(r) +static int +set_tgtkey(r, kvno) char *r; /* Realm for desired key */ + krb5_kvno kvno; { int n; static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; Principal p_st; Principal *p = &p_st; C_Block key; + krb5_keyblock k5key; - if (!strcmp(lastrealm, r)) + k5key.contents = NULL; + if (!strcmp(lastrealm, r) && last_kvno == kvno) return (KSUCCESS); /* log("Getting key for %s", r); */ - n = kerb_get_principal("krbtgt", r, p, 1, &more); + n = kerb_get_principal("krbtgt", r, p, 1, &more, &k5key, kvno, 1); if (n == 0) return (KFAILURE); - /* unseal tgt key from master key */ - memcpy(key, &p->key_low, 4); - memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4); - kdb_encrypt_key(key, key, master_key, - master_key_schedule, DECRYPT); - krb_set_key((char *) key, 0); - strcpy(lastrealm, r); + if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strcpy(lastrealm, r); + last_kvno = kvno; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); + memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4); + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + krb_set_key((char *) key, 0); + strcpy(lastrealm, r); + last_kvno = kvno; + } + krb5_free_keyblock_contents(kdc_context, &k5key); return (KSUCCESS); } diff --git a/src/krb524/ChangeLog b/src/krb524/ChangeLog index 28f0adb800..9bc1d60e27 100644 --- a/src/krb524/ChangeLog +++ b/src/krb524/ChangeLog @@ -1,3 +1,26 @@ +Tue Sep 1 19:35:44 1998 Tom Yu + + * cnv_tkt_skey.c (krb524_convert_tkt_skey): Add + ENCTYPE_LOCAL_DES3_HMAC_SHA1 to the list of enctypes to bash. + + * krb524d.c (do_connection): Add ENCTYPE_LOCAL_DES3_HMAC_SHA1 to + the list of enctypes to search. + +Wed Aug 19 13:40:28 1998 Tom Yu + + * cnv_tkt_skey.c (krb524_convert_tkt_skey): Call krb_cr_tkt_krb5 + if necessary, depending on th enctype. Force enctype to be raw + DES3 if it's another DES3 type. + + * krb524d.c (kdc_get_server_key): Add integer kvno argument, + rename previous kvno arg as kvnop, to distinguish returned (found) + kvno from the input kvno. + (lookup_service_key): Add kvnop argument to allow for returned + kvno. + (do_connection): Search for DES3 keys as well as DES. Get the + found kvno as well, and use that instead of the kvno of the + incoming ticket. + Sat Jul 18 22:10:29 1998 Geoffrey King * krb524d.c (main): Remove the variable use_other_realm. diff --git a/src/krb524/cnv_tkt_skey.c b/src/krb524/cnv_tkt_skey.c index df270776ab..4c51b6777f 100644 --- a/src/krb524/cnv_tkt_skey.c +++ b/src/krb524/cnv_tkt_skey.c @@ -154,19 +154,39 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey, (long) lifetime); /* XXX are there V5 flags we should map to V4 equivalents? */ - ret = krb_create_ticket(v4tkt, - 0, /* flags */ - pname, - pinst, - prealm, - *((unsigned long *)kaddr.contents), - (char *) v5etkt->session->contents, - lifetime, - /* issue_data */ - server_time, - sname, - sinst, - v4_skey->contents); + if (v4_skey->enctype == ENCTYPE_DES_CBC_CRC) { + ret = krb_create_ticket(v4tkt, + 0, /* flags */ + pname, + pinst, + prealm, + *((unsigned long *)kaddr.contents), + (char *) v5etkt->session->contents, + lifetime, + /* issue_data */ + server_time, + sname, + sinst, + v4_skey->contents); + } else { + /* Force enctype to be raw if using DES3. */ + if (v4_skey->enctype == ENCTYPE_DES3_HMAC_SHA1 || + v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) + v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; + ret = krb_cr_tkt_krb5(v4tkt, + 0, /* flags */ + pname, + pinst, + prealm, + *((unsigned long *)kaddr.contents), + (char *) v5etkt->session->contents, + lifetime, + /* issue_data */ + server_time, + sname, + sinst, + v4_skey); + } krb5_free_enc_tkt_part(context, v5etkt); v5tkt->enc_part2 = NULL; diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c index e9ab662d15..85a196e7e0 100644 --- a/src/krb524/krb524d.c +++ b/src/krb524/krb524d.c @@ -247,6 +247,7 @@ krb5_error_code do_connection(s, context) krb5_data msgdata, tktdata; char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p; int n, ret, saddrlen; + krb5_kvno v4kvno; /* Clear out keyblock contents so we don't accidentally free the stack.*/ v5_service_key.contents = v4_service_key.contents = 0; @@ -286,14 +287,28 @@ krb5_error_code do_connection(s, context) printf("V5 ticket decoded\n"); if ((ret = lookup_service_key(context, v5tkt->server, - v5tkt->enc_part.enctype, - &v5_service_key))) + v5tkt->enc_part.enctype, + v5tkt->enc_part.kvno, + &v5_service_key, NULL))) goto error; if ((ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES3_CBC_RAW, + 0, /* highest kvno */ + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_LOCAL_DES3_HMAC_SHA1, + 0, + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES3_HMAC_SHA1, + 0, + &v4_service_key, &v4kvno)) && + (ret = lookup_service_key(context, v5tkt->server, ENCTYPE_DES_CBC_CRC, - &v4_service_key))) - goto error; + 0, + &v4_service_key, &v4kvno))) + goto error; if (debug) printf("service key retrieved\n"); @@ -328,7 +343,7 @@ error: if (ret) goto write_msg; - n = htonl(v5tkt->enc_part.kvno); + n = htonl(v4kvno); memcpy(p, (char *) &n, sizeof(int)); p += sizeof(int); msgdata.length += sizeof(int); @@ -357,32 +372,35 @@ write_msg: return ret; } -krb5_error_code lookup_service_key(context, p, ktype, key) +krb5_error_code lookup_service_key(context, p, ktype, kvno, key, kvnop) krb5_context context; krb5_principal p; krb5_enctype ktype; + krb5_kvno kvno; krb5_keyblock *key; + krb5_kvno *kvnop; { int ret; krb5_keytab_entry entry; if (use_keytab) { - if ((ret = krb5_kt_get_entry(context, kt, p, 0, ktype, &entry))) + if ((ret = krb5_kt_get_entry(context, kt, p, kvno, ktype, &entry))) return ret; memcpy(key, (char *) &entry.key, sizeof(krb5_keyblock)); return 0; } else if (use_master) { - return kdc_get_server_key(context, p, key, NULL, ktype); + return kdc_get_server_key(context, p, key, kvnop, ktype, kvno); } return 0; } -krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype) +krb5_error_code kdc_get_server_key(context, service, key, kvnop, ktype, kvno) krb5_context context; krb5_principal service; krb5_keyblock *key; - krb5_kvno *kvno; + krb5_kvno *kvnop; krb5_enctype ktype; + krb5_kvno kvno; { krb5_error_code ret; kadm5_principal_ent_rec server; @@ -403,14 +421,14 @@ krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype) ktype, (ktype == ENCTYPE_DES_CBC_CRC) ? KRB5_KDB_SALTTYPE_V4 : -1, - -1, - key, NULL, kvno)) && + kvno, + key, NULL, kvnop)) && (ret = kadm5_decrypt_key(handle, &server, ktype, -1, - -1, - key, NULL, kvno))) { + kvno, + key, NULL, kvnop))) { kadm5_free_principal_ent(handle, &server); return (KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); } diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index dd0e7b5611..9e93dbe884 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,21 @@ +Mon Sep 14 23:21:17 1998 Tom Yu + + * old/decrypt.c (krb5_old_decrypt): Fix memory leak. + +Tue Sep 1 19:33:38 1998 Tom Yu + + * etypes.c: Add ETYPE_LOCAL_DES3_HMAC_SHA1 to deal with marc's + des3 code. ETYPE_DES3_HMAC_SHA1 remains the same for now. + +Mon Aug 17 23:40:11 1998 Tom Yu + + * keyhash_provider/k5_md4des.c (k5_md4des_verify): Add + compatibility for krb5-beta5 checksums. + + * keyhash_provider/k5_md5des.c (k5_md5des_verify): Add + compatibility for krb5-beta5 checksums. Fix typos similar to + those corrected in k5_md4des.c. + Wed Apr 15 18:02:44 1998 Tom Yu * Makefile.in (LIB): Rename to k5crypto. diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c index 0897bf3750..b47841b12d 100644 --- a/src/lib/crypto/etypes.c +++ b/src/lib/crypto/etypes.c @@ -40,8 +40,13 @@ struct krb5_keytypes krb5_enctypes_list[] = { krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, krb5_dk_string_to_key }, + { ENCTYPE_LOCAL_DES3_HMAC_SHA1, + "des3-marc-hmac-sha1", "Triple DES with HMAC/sha1 (marc's code)", + &krb5_enc_des3, &krb5_hash_sha1, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5_dk_string_to_key }, { ENCTYPE_DES3_HMAC_SHA1, - "des3-hmac-sha1", "Triple DES with HMAC/sha1", + "des3-hmac-sha1", "Triple DES with HMAC/sha1 (as yet unspecified code)", &krb5_enc_des3, &krb5_hash_sha1, krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, krb5_dk_string_to_key }, diff --git a/src/lib/crypto/keyhash_provider/k5_md4des.c b/src/lib/crypto/keyhash_provider/k5_md4des.c index 4d4a9baff8..e338cfaf9c 100644 --- a/src/lib/crypto/keyhash_provider/k5_md4des.c +++ b/src/lib/crypto/keyhash_provider/k5_md4des.c @@ -5,6 +5,9 @@ #define CONFLENGTH 8 +/* Force acceptance of krb5-beta5 md4des checksum for now. */ +#define KRB5_MD4DES_BETA5_COMPAT + static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; static void @@ -91,19 +94,31 @@ k5_md4des_verify(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, unsigned char xorkey[8]; int i; mit_des_key_schedule schedule; + int compathash = 0; if (key->length != 8) return(KRB5_BAD_KEYSIZE); if (ivec) return(KRB5_CRYPTO_INTERNAL); - if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) + if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { +#ifdef KRB5_MD4DES_BETA5_COMPAT + if (hash->length != RSA_MD4_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else + return(KRB5_CRYPTO_INTERNAL); +#endif return(KRB5_CRYPTO_INTERNAL); + } /* create and schedule the encryption key */ memcpy(xorkey, key->contents, sizeof(xorkey)); - for (i=0; idata, - (krb5_pointer) plaintext, sizeof(plaintext), - schedule, (char *) mit_des_zeroblock, 0); + if (!compathash) { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, (char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } /* hash the confounder, then the input data */ krb5_MD4Init(&ctx); - krb5_MD4Update(&ctx, plaintext, CONFLENGTH); + if (!compathash) { + krb5_MD4Update(&ctx, plaintext, CONFLENGTH); + } krb5_MD4Update(&ctx, input->data, input->length); krb5_MD4Final(&ctx); /* compare the decrypted hash to the computed one */ - *valid = - (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH) == 0); + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD4_CKSUM_LENGTH) == 0); + } memset(plaintext, 0, sizeof(plaintext)); diff --git a/src/lib/crypto/keyhash_provider/k5_md5des.c b/src/lib/crypto/keyhash_provider/k5_md5des.c index 23a6c2d573..9bdf5f4c33 100644 --- a/src/lib/crypto/keyhash_provider/k5_md5des.c +++ b/src/lib/crypto/keyhash_provider/k5_md5des.c @@ -5,6 +5,9 @@ #define CONFLENGTH 8 +/* Force acceptance of krb5-beta5 md5des checksum for now. */ +#define KRB5_MD5DES_BETA5_COMPAT + static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; static void @@ -32,8 +35,6 @@ k5_md5des_hash(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, if (key->length != 8) return(KRB5_BAD_KEYSIZE); - if ((input->length%8) != 0) - return(KRB5_BAD_MSIZE); if (ivec) return(KRB5_CRYPTO_INTERNAL); if (output->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) @@ -48,7 +49,7 @@ k5_md5des_hash(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, /* create and schedule the encryption key */ - memcpy(xorkey, key->contents, sizeof(key->length)); + memcpy(xorkey, key->contents, sizeof(xorkey)); for (i=0; ilength != 8) return(KRB5_BAD_KEYSIZE); - if ((input->length%8) != 0) - return(KRB5_BAD_MSIZE); if (ivec) return(KRB5_CRYPTO_INTERNAL); - if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) + if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) { +#ifdef KRB5_MD5DES_BETA5_COMPAT + if (hash->length != RSA_MD5_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else return(KRB5_CRYPTO_INTERNAL); +#endif + } /* create and schedule the encryption key */ - memcpy(xorkey, key->contents, sizeof(key->length)); - for (i=0; icontents, sizeof(xorkey)); + if (!compathash) { + for (i=0; idata, - (krb5_pointer) plaintext, sizeof(plaintext), - schedule, (char *) mit_des_zeroblock, 0); + if (!compathash) { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, (char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } /* hash the confounder, then the input data */ krb5_MD5Init(&ctx); - krb5_MD5Update(&ctx, plaintext, CONFLENGTH); + if (!compathash) { + krb5_MD5Update(&ctx, plaintext, CONFLENGTH); + } krb5_MD5Update(&ctx, input->data, input->length); krb5_MD5Final(&ctx); /* compare the decrypted hash to the computed one */ - *valid = - (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH) == 0); - + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD5_CKSUM_LENGTH) == 0); + } memset(plaintext, 0, sizeof(plaintext)); return(0); diff --git a/src/lib/crypto/old/decrypt.c b/src/lib/crypto/old/decrypt.c index 8bbc044393..d84eadfa41 100644 --- a/src/lib/crypto/old/decrypt.c +++ b/src/lib/crypto/old/decrypt.c @@ -86,7 +86,7 @@ cleanup: } memset(cksumdata, 0, hashsize); - + free(cksumdata); return(ret); } diff --git a/src/lib/des425/Makefile.in b/src/lib/des425/Makefile.in index f19fc2bd31..e96e03f999 100644 --- a/src/lib/des425/Makefile.in +++ b/src/lib/des425/Makefile.in @@ -27,7 +27,6 @@ SHLIB_RDIRS=$(KRB5_LIBDIR) STOBJLISTS=OBJS.ST STLIBOBJS=cksum.o \ - des.o \ enc_dec.o \ key_parity.o \ key_sched.o \ @@ -44,7 +43,6 @@ STLIBOBJS=cksum.o \ OBJS= cksum.$(OBJEXT) \ - des.$(OBJEXT) \ enc_dec.$(OBJEXT) \ key_parity.$(OBJEXT) \ key_sched.$(OBJEXT) \ @@ -60,7 +58,6 @@ OBJS= cksum.$(OBJEXT) \ k4_glue.$(OBJEXT) SRCS= $(srcdir)/cksum.c \ - $(srcdir)/des.c \ $(srcdir)/enc_dec.c \ $(srcdir)/key_parity.c \ $(srcdir)/key_sched.c \ diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index bc5c578755..a852fe0015 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,9 @@ +Thu Sep 3 19:35:44 1998 Tom Yu + + * accept_sec_context.c (krb5_gss_accept_sec_context): Fix typo; + bash the enctype in ctx->subkey->enctype rather than just + "enctype", which nothing checks. + 1998-06-08 Theodore Ts'o * k5unseal.c (kg_unseal): Clean up lint warnings. diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index dbb4902f2c..d4e83cc64c 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -663,7 +663,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, switch(ctx->subkey->enctype) { case ENCTYPE_DES_CBC_MD5: case ENCTYPE_DES_CBC_CRC: - enctype = ENCTYPE_DES_CBC_RAW; + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; ctx->signalg = 0; ctx->cksum_size = 8; ctx->sealalg = 0; diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index ae8bb7e1b1..64dc648d6c 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,14 @@ +Thu Aug 13 17:21:06 1998 Tom Yu + + * alt_prof.c (krb5_read_realm_params): Fix to check + "supported_enctypes" if "kdc_supported_enctypes" isn't there. + +Wed Aug 12 20:19:08 1998 Tom Yu + + * alt_prof.c (krb5_read_realm_params): Use + "kdc_supported_enctypes" instead of "supported_enctypes" so that + the KDC and the kadmind will use different enctype lists. + Wed Jul 8 04:48:50 1998 Geoffrey J. King * logger.c: Add the function krb5_klog_reopen() which closes diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index b2260d67a8..934785322b 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -866,8 +866,15 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp) } /* Get the value for the supported enctype/salttype matrix */ - hierarchy[2] = "supported_enctypes"; - if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { + /* XXX This is so that the kdc will search a different + enctype list than kadmind */ + hierarchy[2] = "kdc_supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + if (kret) { + hierarchy[2] = "supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + } + if (!kret) { krb5_string_to_keysalts(svalue, ", \t", /* Tuple separators */ ":.-", /* Key/salt separators */ diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 45d3d925dd..5961390080 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,26 @@ +Wed Aug 12 18:32:44 1998 Tom Yu + + * rd_req.c (krb_set_key): Nuke the krb5_keyblock if it's set. + (krb_set_key_krb5): New function to set a static krb5_keyblock for + decryption purposes. + (krb_clear_key_krb5): New function to clear the static + krb5_keyblock if it's set. + (krb_rd_req): Call decomp_ticket or decomp_tkt_krb5 as appropriate + to the key type. + + * decomp_tkt.c (decomp_tkt_krb5): New wrapper to call + dcmp_tkt_int. + (decomp_ticket): Transform into wrapper to call dcmp_tkt_int. + (dcmp_tkt_int): New internal function; use a krb5_keyblock to + decrypt the ticket if present; else just use plain old C_Block. + + * cr_tkt.c (krb_create_ticket): Transform into a wrapper that + calls krb_cr_tkt_int. + (krb_cr_tkt_krb5): New wrapper to call krb_cr_tkt_int. + (krb_cr_tkt_int): New internal function that potentially uses a + krb5_keyblock to encrypt the ticket, or just a C_Block if the + krb5_keyblock is not set. + Thu Jul 30 13:13:30 1998 Sam Hartman * tf_util.c (tf_init): s/,/= so getuid() actually gets called diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c index 39ed53859c..a8224f879a 100644 --- a/src/lib/krb4/cr_tkt.c +++ b/src/lib/krb4/cr_tkt.c @@ -13,7 +13,7 @@ #include "krb.h" #include "prot.h" #include - +#include /* * Create ticket takes as arguments information that should be in a * ticket, and the KTEXT object in which the ticket should be @@ -69,9 +69,53 @@ * <=7 bytes null null pad to 8 byte multiple * */ +int +krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key, k5key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + C_Block key; /* Service's secret key */ +{ + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, NULL); +} -int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, - session, life, time_sec, sname, sinstance, key) +int +krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, k5key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + krb5_keyblock *k5key; /* NULL if not present */ +{ + C_Block key; + + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, k5key); +} + +static int +krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key, k5key) KTEXT tkt; /* Gets filled in by the ticket */ unsigned char flags; /* Various Kerberos flags */ char *pname; /* Principal's name */ @@ -84,6 +128,7 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, char *sname; /* Service Name */ char *sinstance; /* Instance Name */ C_Block key; /* Service's secret key */ + krb5_keyblock *k5key; /* NULL if not present */ { Key_schedule key_s; register char *data; /* running index into ticket */ @@ -124,10 +169,43 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, } #ifndef NOENCRYPTION - /* Encrypt the ticket in the services key */ - key_sched(key,key_s); - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *)key,1); + /* Encrypt the ticket in the services key */ + if (k5key != NULL) { + /* block locals */ + krb5_data in; + krb5_enc_data out; + krb5_error_code ret; + size_t enclen; + + in.length = tkt->length; + in.data = tkt->dat; + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt_length(NULL, k5key->enctype, + (size_t)in.length, &enclen); + if (ret) + return KFAILURE; + out.ciphertext.length = enclen; + out.ciphertext.data = malloc(enclen); + if (out.ciphertext.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt(NULL, k5key, KRB5_KEYUSAGE_KDC_REP_TICKET, + NULL, &in, &out); + if (ret) { + free(out.ciphertext.data); + return KFAILURE; + } else { + tkt->length = out.ciphertext.length; + memcpy(tkt->dat, out.ciphertext.data, out.ciphertext.length); + memset(out.ciphertext.data, 0, out.ciphertext.length); + free(out.ciphertext.data); + } + } else { + key_sched(key,key_s); + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *)key,1); + } #endif /* !NOENCRYPTION */ return 0; } diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c index 3c59523687..d4dfd4edcb 100644 --- a/src/lib/krb4/decomp_tkt.c +++ b/src/lib/krb4/decomp_tkt.c @@ -13,6 +13,7 @@ #include "krb.h" #include "prot.h" #include +#include #ifdef KRB_CRYPT_DEBUG extern int krb_debug; @@ -64,6 +65,57 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, C_Block key; /* Service's secret key * (to decrypt the ticket) */ Key_schedule key_s; /* The precomputed key schedule */ +{ + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, + paddress, session, life, time_sec, sname, sinstance, + key, key_s, NULL); +} + +int +decomp_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, k5key) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ +{ + C_Block key; /* placeholder; doesn't get used */ + Key_schedule key_s; /* placeholder; doesn't get used */ + + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key); +} + +static int +dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + C_Block key; /* Service's secret key + * (to decrypt the ticket) */ + Key_schedule key_s; /* The precomputed key schedule */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ { static int tkt_swap_bytes; unsigned char *uptr; @@ -83,8 +135,37 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, memset(keybuf, 0, sizeof(keybuf)); /* Clear the buffer */ } #endif - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *) key,0); + if (k5key != NULL) { + /* block locals */ + krb5_enc_data in; + krb5_data out; + krb5_error_code ret; + + in.enctype = k5key->enctype; + in.kvno = 0; + in.ciphertext.length = tkt->length; + in.ciphertext.data = tkt->dat; + out.length = tkt->length; + out.data = malloc(tkt->length); + if (out.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX note the following assumes that context arg isn't used */ + ret = + krb5_c_decrypt(NULL, k5key, + KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &in, &out); + if (ret) { + free(out.data); + return KFAILURE; + } else { + memcpy(tkt->dat, out.data, out.length); + memset(out.data, 0, out.length); + free(out.data); + } + } else { + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *) key,0); + } #endif /* ! NOENCRYPTION */ #ifdef KRB_CRYPT_DEBUG if (krb_debug) { diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c index 79564e4f37..a78aadc881 100644 --- a/src/lib/krb4/rd_req.c +++ b/src/lib/krb4/rd_req.c @@ -32,6 +32,7 @@ static int st_kvno; /* version number for this key */ static char st_rlm[REALM_SZ]; /* server's realm */ static char st_nam[ANAME_SZ]; /* service name */ static char st_inst[INST_SZ]; /* server's instance */ +static int krb5_key; /* whether krb5 key is used for decrypt */ /* * This file contains two functions. krb_set_key() takes a DES @@ -62,11 +63,18 @@ static char st_inst[INST_SZ]; /* server's instance */ * krb_rd_req(). */ +#include +static krb5_keyblock srv_k5key; + int krb_set_key(key,cvt) char *key; int cvt; { + if (krb5_key) + /* XXX assumes that context arg is ignored */ + krb5_free_keyblock_contents(NULL, &srv_k5key); + krb5_key = 0; #ifdef NOENCRYPTION memset(ky, 0, sizeof(ky)); return KSUCCESS; @@ -79,6 +87,25 @@ krb_set_key(key,cvt) #endif /* NOENCRYPTION */ } +int +krb_set_key_krb5(ctx, key) + krb5_context ctx; + krb5_keyblock *key; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 1; + return krb5_copy_keyblock_contents(ctx, key, &srv_k5key); +} + +void +krb_clear_key_krb5(ctx) + krb5_context ctx; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 0; +} /* * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or @@ -234,15 +261,25 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) /* Decrypt and take apart ticket */ #endif - if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, - &(ad->address),ad->session, &(ad->life), - &(ad->time_sec),sname,iname,ky,serv_key)) { + if (!krb5_key) { + if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, + &(ad->address),ad->session, &(ad->life), + &(ad->time_sec),sname,iname,ky,serv_key)) { #ifdef KRB_CRYPT_DEBUG - log("Can't decode ticket"); + log("Can't decode ticket"); #endif - return(RD_AP_UNDEC); + return(RD_AP_UNDEC); + } + } else { + if (decomp_tkt_krb5(tkt, &ad->k_flags, ad->pname, ad->pinst, + ad->prealm, &ad->address, ad->session, + &ad->life, &ad->time_sec, sname, iname, + srv_k5key)) { + return RD_AP_UNDEC; + } } + #ifdef KRB_CRYPT_DEBUG if (krb_ap_req_debug) { log("Ticket Contents."); diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index a95bc93416..49d6ef3bb5 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,8 @@ +Wed Aug 19 17:27:51 1998 Tom Yu + + * conv_princ.c: Add some additional entries to sconv_list that + were forgotten. + Wed Jul 15 11:46:05 1998 Ezra Peisach * gic_pwd.c (krb5_get_init_creds_password): Remove unused argument diff --git a/src/lib/krb5/krb/conv_princ.c b/src/lib/krb5/krb/conv_princ.c index c835735fce..a58467f13b 100644 --- a/src/lib/krb5/krb/conv_princ.c +++ b/src/lib/krb5/krb/conv_princ.c @@ -67,6 +67,28 @@ static const struct krb_convert sconv_list[] = { {"imap", "imap", DO_REALM_CONVERSION}, {"ftp", "ftp", DO_REALM_CONVERSION}, {"ecat", "ecat", DO_REALM_CONVERSION}, + {"daemon", "daemon", DO_REALM_CONVERSION}, + {"gnats", "gnats", DO_REALM_CONVERSION}, + {"moira", "moira", DO_REALM_CONVERSION}, + {"prms", "prms", DO_REALM_CONVERSION}, + {"mandarin", "mandarin", DO_REALM_CONVERSION}, + {"register", "register", DO_REALM_CONVERSION}, + {"changepw", "changepw", DO_REALM_CONVERSION}, + {"sms", "sms", DO_REALM_CONVERSION}, + {"afpserver", "afpserver", DO_REALM_CONVERSION}, + {"gdss", "gdss", DO_REALM_CONVERSION}, + {"news", "news", DO_REALM_CONVERSION}, + {"abs", "abs", DO_REALM_CONVERSION}, + {"nfs", "nfs", DO_REALM_CONVERSION}, + {"tftp", "tftp", DO_REALM_CONVERSION}, + {"zephyr", "zephyr", DO_REALM_CONVERSION}, + {"http", "http", DO_REALM_CONVERSION}, + {"khttp", "khttp", DO_REALM_CONVERSION}, + {"pgpsigner", "pgpsigner", DO_REALM_CONVERSION}, + {"irc", "irc", DO_REALM_CONVERSION}, + {"mandarin-agent", "mandarin-agent", DO_REALM_CONVERSION}, + {"write", "write", DO_REALM_CONVERSION}, + {"palladium", "palladium", DO_REALM_CONVERSION}, {"news", "news", DO_REALM_CONVERSION}, {"abs", "abs", DO_REALM_CONVERSION}, {"nfs", "nfs", DO_REALM_CONVERSION},