diff options
author | Sam Hartman <hartmans@mit.edu> | 1996-01-25 20:06:28 +0000 |
---|---|---|
committer | Sam Hartman <hartmans@mit.edu> | 1996-01-25 20:06:28 +0000 |
commit | bea9672a019c56d52cbe97365d919ae3fba1a276 (patch) | |
tree | 5e7d43ddcbfe443e5041557a8d392445fa59824e /src/krb524/krb524d.c | |
parent | f77df5517ab35f56e5be03faccd22f4b542b9d05 (diff) | |
download | krb5-bea9672a019c56d52cbe97365d919ae3fba1a276.tar.gz krb5-bea9672a019c56d52cbe97365d919ae3fba1a276.tar.xz krb5-bea9672a019c56d52cbe97365d919ae3fba1a276.zip |
* 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 <hartmans@tertius.mit.edu>
* 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
Diffstat (limited to 'src/krb524/krb524d.c')
-rw-r--r-- | src/krb524/krb524d.c | 177 |
1 files changed, 127 insertions, 50 deletions
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; } |