From bea9672a019c56d52cbe97365d919ae3fba1a276 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Thu, 25 Jan 1996 20:06:28 +0000 Subject: [PATCH] * cnv_tkt_skey.c (krb524_convert_tkt_skey): Take both a v5 and v4 service key. Use the v5 service key to decrypt the v5 ticket, and the v4 service key to encrypt the v4 ticket. * krb524d.c (do_connection): Use a separate v5 and v4 service key so that if the KDC chooses to encrypt the v5 ticket in something besides ENCTYPE_DES_CBC_CRC, we don't lose. Also, make sure we free keyblock contents and tickets on error. (lookup_service_key): Pass enctype to kdc_get_server_key (kdc_get_server_key): Only try for v4 salt if the enctype is DES_CRC. Take enctype as an argument. This creates a problem if the server key has a normal and v4 salt of ENCTYPE_DES_CBC_CRC but I can't think of a good answer to this. * k524init.c (main): Use crc32 not md5. Wed Jan 24 20:05:47 1996 Sam Hartman * krb524d.c (kdc_get_server_key): Try to find a v4 salt type key, else try any des_crc32 key, else fail. (do_connection): Lookup a crc32 key not an md5 key. (init_master): Handle reading kdc profile. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7386 dc483132-0cff-0310-8789-dd5450dbe970 --- src/krb524/ChangeLog | 27 ++++++ src/krb524/cnv_tkt_skey.c | 8 +- src/krb524/configure.in | 1 + src/krb524/k524init.c | 2 +- src/krb524/krb524.h | 2 +- src/krb524/krb524d.c | 177 +++++++++++++++++++++++++++----------- 6 files changed, 161 insertions(+), 56 deletions(-) diff --git a/src/krb524/ChangeLog b/src/krb524/ChangeLog index 0155f98ee..d95aa09c5 100644 --- a/src/krb524/ChangeLog +++ b/src/krb524/ChangeLog @@ -1,3 +1,30 @@ +Thu Jan 25 02:07:46 1996 Sam Hartman + + * cnv_tkt_skey.c (krb524_convert_tkt_skey): Take both a v5 and v4 + service key. Use the v5 service key to decrypt the v5 ticket, and + the v4 service key to encrypt the v4 ticket. + + * krb524d.c (do_connection): Use a separate v5 and v4 service key + so that if the KDC chooses to encrypt the v5 ticket in something + besides ENCTYPE_DES_CBC_CRC, we don't lose. Also, make sure we + free keyblock contents and tickets on error. + (lookup_service_key): Pass enctype to kdc_get_server_key + + (kdc_get_server_key): Only try for v4 salt if the enctype is + DES_CRC. Take enctype as an argument. This creates a problem + if the server key has a normal and v4 salt of ENCTYPE_DES_CBC_CRC + but I can't think of a good answer to this. + + + * k524init.c (main): Use crc32 not md5. + +Wed Jan 24 20:05:47 1996 Sam Hartman + + * krb524d.c (kdc_get_server_key): Try to find a v4 salt type key, + else try any des_crc32 key, else fail. + (do_connection): Lookup a crc32 key not an md5 key. + (init_master): Handle reading kdc profile. + Sun Nov 12 04:29:08 1995 Mark W. Eichin * conv_creds.c (krb524_convert_creds_kdc): loop through all of the diff --git a/src/krb524/cnv_tkt_skey.c b/src/krb524/cnv_tkt_skey.c index f433e5407..842319770 100644 --- a/src/krb524/cnv_tkt_skey.c +++ b/src/krb524/cnv_tkt_skey.c @@ -34,11 +34,11 @@ * Convert a v5 ticket for server to a v4 ticket, using service key * skey for both. */ -int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey) +int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey) krb5_context context; krb5_ticket *v5tkt; KTEXT_ST *v4tkt; - krb5_keyblock *skey; + krb5_keyblock *v5_skey, *v4_skey; { char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; char sname[ANAME_SZ], sinst[INST_SZ]; @@ -46,7 +46,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey) int ret, lifetime; v5tkt->enc_part2 = NULL; - if ((ret = krb5_decrypt_tkt_part(context, skey, v5tkt))) { + if ((ret = krb5_decrypt_tkt_part(context, v5_skey, v5tkt))) { krb5_free_ticket(context, v5tkt); return ret; } @@ -110,7 +110,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey) v5etkt->times.starttime, sname, sinst, - skey->contents); + v4_skey->contents); krb5_free_enc_tkt_part(context, v5etkt); v5tkt->enc_part2 = NULL; diff --git a/src/krb524/configure.in b/src/krb524/configure.in index 15780020c..7f7e78356 100644 --- a/src/krb524/configure.in +++ b/src/krb524/configure.in @@ -6,6 +6,7 @@ AC_PROG_RANLIB AC_PROG_INSTALL AC_TYPE_SIGNAL ET_RULES +USE_KADM_LIBRARY USE_KDB5_LIBRARY USE_KRB4_LIBRARY KRB5_LIBRARIES diff --git a/src/krb524/k524init.c b/src/krb524/k524init.c index 61c180aa4..79651f521 100644 --- a/src/krb524/k524init.c +++ b/src/krb524/k524init.c @@ -108,7 +108,7 @@ int main(argc, argv) increds.client = client; increds.server = server; increds.times.endtime = 0; - increds.keyblock.enctype = ENCTYPE_DES_CBC_MD5; + increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; if ((code = krb5_get_credentials(context, 0, cc, &increds, &v5creds))) { com_err("k524init", code, "getting V5 credentials"); exit(1); diff --git a/src/krb524/krb524.h b/src/krb524/krb524.h index 8eee85cec..7ed942c1a 100644 --- a/src/krb524/krb524.h +++ b/src/krb524/krb524.h @@ -32,7 +32,7 @@ extern int krb524_debug; int krb524_convert_tkt_skey PROTOTYPE((krb5_context context, krb5_ticket *v5tkt, KTEXT_ST *v4tkt, - krb5_keyblock *skey)); + krb5_keyblock *v5_skey, krb5_keyblock *v4_skey)); /* conv_princ.c */ diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c index 6522e7551..e062a3392 100644 --- a/src/krb524/krb524d.c +++ b/src/krb524/krb524d.c @@ -92,7 +92,8 @@ int main(argc, argv) int ret, s; fd_set rfds; krb5_context context; - + krb5_realm_params *rparams; + char *realm = 0; krb5_init_context(&context); krb524_init_ets(context); @@ -116,6 +117,11 @@ int main(argc, argv) signal(SIGINT, request_exit); signal(SIGHUP, request_exit); signal(SIGTERM, request_exit); + if (!realm&&(ret = krb5_get_default_realm(context, &realm))) + { +com_err(whoami, ret, "Getting default realm"); +exit(1); +} if (use_keytab) init_keytab(context); @@ -212,57 +218,94 @@ void init_master(context) krb5_context context; { int ret; - char *realm; - - if ((ret = krb5_get_default_realm(context, &realm))) { +krb5_realm_params *rparams; + char *realm = 0; + char *key_name =0, *dbname = 0; + char *stash_file = 0; + + /* Use the stashed enctype */ + master_keyblock.enctype = ENCTYPE_UNKNOWN; + + if (!realm&&(ret = krb5_get_default_realm(context, &realm))) { com_err(whoami, ret, "getting default realm"); cleanup_and_exit(1, context); } - if ((ret = krb5_db_setup_mkey_name(context, NULL, realm, (char **) 0, - &master_princ))) { - free(realm); - com_err(whoami, ret, "while setting up master key name"); - cleanup_and_exit(1, context); - } else { - free(realm); + if ((ret = krb5_read_realm_params(context, + realm, + (char *) NULL, (char *) NULL, + &rparams))) { + com_err(whoami, ret, "Reading KDC profile"); +krb5_xfree(realm); + cleanup_and_exit(1,context); } + + /* Get the value for the database */ + if (rparams->realm_dbname && !dbname) + dbname = strdup(rparams->realm_dbname); - /* Use the stashed enctype */ - master_keyblock.enctype = ENCTYPE_UNKNOWN; + /* Get the value for the master key name */ + if (rparams->realm_mkey_name && !key_name) + key_name = strdup(rparams->realm_mkey_name); + /* Get the value for the master key type */ + if (rparams->realm_enctype_valid ) + master_keyblock.enctype = rparams->realm_enctype; + + /* Get the value for the stashfile */ + if (rparams->realm_stash_file) + stash_file = strdup(rparams->realm_stash_file); + + if ((ret = krb5_db_set_name(context, dbname))) { + com_err(whoami, ret, "Setting database name"); + cleanup_and_exit(1,context); + } + + if ((ret = krb5_db_setup_mkey_name(context, key_name, realm, (char **) 0, + &master_princ))) { + free(realm); + com_err(whoami, ret, "while setting up master key name"); + cleanup_and_exit(1, context); + } else { + free(realm); + } + + if ((ret = krb5_db_fetch_mkey(context, master_princ, &master_encblock, - FALSE, /* non-manual type-in */ - FALSE, /* irrelevant, given prev. arg */ - (char *) NULL, - 0, &master_keyblock))) { - com_err(whoami, ret, "while fetching master key"); - cleanup_and_exit(1, context); + FALSE, /* non-manual type-in */ + FALSE, /* irrelevant, given prev. arg */ + stash_file, + 0, &master_keyblock))) { + com_err(whoami, ret, "while fetching master key"); + cleanup_and_exit(1, context); } - + if ((ret = krb5_db_init(context))) { - com_err(whoami, ret, "while initializing master database"); - cleanup_and_exit(1, context); - } + com_err(whoami, ret, "while initializing master database"); + cleanup_and_exit(1, context); + } if ((ret = krb5_process_key(context, &master_encblock, &master_keyblock))) { - krb5_db_fini(context); - com_err(whoami, ret, "while processing master key"); - cleanup_and_exit(1, context); + krb5_db_fini(context); + com_err(whoami, ret, "while processing master key"); + cleanup_and_exit(1, context); } -} + } krb5_error_code do_connection(s, context) int s; krb5_context context; { struct sockaddr saddr; - krb5_ticket *v5tkt; + krb5_ticket *v5tkt = 0; KTEXT_ST v4tkt; - krb5_keyblock service_key; + krb5_keyblock v5_service_key, v4_service_key; krb5_data msgdata, tktdata; char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p; int n, ret, saddrlen; - + + /* Clear out keyblock contents so we don't accidentally free the stack.*/ + v5_service_key.contents = v4_service_key.contents = 0; + msgdata.data = msgbuf; msgdata.length = MSGSIZE; @@ -297,18 +340,25 @@ krb5_error_code do_connection(s, context) if (debug) printf("V5 ticket decoded\n"); - /* XXX ENCTYPE_DES_CBC_MD5 shouldn't be hardcoded here. Should be - derived from the ticket. */ - if ((ret = lookup_service_key(context, v5tkt->server, ENCTYPE_DES_CBC_MD5, - &service_key))) + if ((ret = lookup_service_key(context, v5tkt->server, + v5tkt->enc_part.enctype, + &v5_service_key))) + goto error; + + if ((ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES_CBC_CRC, + &v4_service_key))) goto error; + if (debug) printf("service key retrieved\n"); - ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &service_key); + ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, + &v4_service_key); if (ret) goto error; - krb5_free_keyblock_contents(context, &service_key); + krb5_free_keyblock_contents(context, &v5_service_key); + krb5_free_keyblock_contents(context, &v4_service_key); krb5_free_ticket(context, v5tkt); if (debug) printf("credentials converted\n"); @@ -351,6 +401,14 @@ write_msg: ret = errno; if (debug) printf("reply written\n"); +/* If we have keys to clean up, do so.*/ + if (v5_service_key.contents) + krb5_free_keyblock_contents(context, &v5_service_key); + if (v4_service_key.contents) + krb5_free_keyblock_contents(context, &v4_service_key); + if (v5tkt) + krb5_free_ticket(context, v5tkt); + return ret; } @@ -372,24 +430,25 @@ krb5_error_code lookup_service_key(context, p, ktype, key) } else if (use_master) { if ((ret = krb5_db_init(context))) return ret; - return kdc_get_server_key(context, p, key, NULL); + return kdc_get_server_key(context, p, key, NULL, ktype); } return 0; } /* taken from kdc/kdc_util.c, and modified somewhat */ -krb5_error_code kdc_get_server_key(context, service, key, kvno) +krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype) krb5_context context; krb5_principal service; krb5_keyblock *key; krb5_kvno *kvno; +krb5_enctype ktype; { krb5_error_code ret; int nprincs; krb5_db_entry server; krb5_boolean more; int i, vno, ok_key; - + krb5_key_data *pkey; nprincs = 1; if ((ret = krb5_db_get_principal(context, service, &server, &nprincs, &more))) @@ -402,19 +461,37 @@ krb5_error_code kdc_get_server_key(context, service, key, kvno) krb5_db_free_principal(context, &server, nprincs); return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); } - - /* convert server key into a real key (it is encrypted in the database) */ - for (vno = i = 0; i < server.n_key_data; i++) { - if (vno < server.key_data[i].key_data_kvno) { - vno = server.key_data[i].key_data_kvno; - ok_key = i; - } - } +/* We use krb5_dbe_find_enctype twice because + * in the case of a ENCTYPE_DES_CBC_CRC key, we prefer to find a krb4 + * salt type over a normal key.. Note this may create a problem if the + * server key is passworded and has both a normal and v4 salt. There is + * no good solution to this.*/ + + if (krb5_dbe_find_enctype(context, + &server, + ktype, + (ktype == ENCTYPE_DES_CBC_CRC)? + KRB5_KDB_SALTTYPE_V4:-1, + -1, + &pkey) && + krb5_dbe_find_enctype(context, + &server, + -1, + -1, + -1, + &pkey)) + { + krb5_db_free_principal(context, &server, nprincs); + return (KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN); + } +if (kvno) + *kvno = pkey->key_data_kvno; ret = krb5_dbekd_decrypt_key_data(context, &master_encblock, - &server.key_data[ok_key], key, NULL); + pkey, key, NULL); krb5_db_free_principal(context, &server, nprincs); - if (kvno) - *kvno = vno; + + + return ret; } -- 2.26.2