summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/kdc/kerberos4.c
diff options
context:
space:
mode:
authorassar <assar@FreeBSD.org>2001-02-13 16:46:19 +0000
committerassar <assar@FreeBSD.org>2001-02-13 16:46:19 +0000
commitebfe6dc471c206300fd82c7c0fd145f683aa52f6 (patch)
treee66aa570ad1d12c43b32a7313b0f8e28971bf8a9 /crypto/heimdal/kdc/kerberos4.c
parente5f617598c2db0dd51906a38ecea9208123a8b70 (diff)
downloadFreeBSD-src-ebfe6dc471c206300fd82c7c0fd145f683aa52f6.zip
FreeBSD-src-ebfe6dc471c206300fd82c7c0fd145f683aa52f6.tar.gz
import of heimdal 0.3e
Diffstat (limited to 'crypto/heimdal/kdc/kerberos4.c')
-rw-r--r--crypto/heimdal/kdc/kerberos4.c212
1 files changed, 140 insertions, 72 deletions
diff --git a/crypto/heimdal/kdc/kerberos4.c b/crypto/heimdal/kdc/kerberos4.c
index 23d59dd..111bd9f 100644
--- a/crypto/heimdal/kdc/kerberos4.c
+++ b/crypto/heimdal/kdc/kerberos4.c
@@ -33,12 +33,10 @@
#include "kdc_locl.h"
-RCSID("$Id: kerberos4.c,v 1.27 2000/02/13 19:27:36 assar Exp $");
+RCSID("$Id: kerberos4.c,v 1.36 2001/01/30 01:44:08 assar Exp $");
#ifdef KRB4
-#include "kerberos4.h"
-
#ifndef swap32
static u_int32_t
swap32(u_int32_t x)
@@ -61,7 +59,7 @@ make_err_reply(krb5_data *reply, int code, const char *msg)
{
KTEXT_ST er;
- /* name, instance and realm is not checked in most (all?) version
+ /* name, instance and realm are not checked in most (all?)
implementations; msg is also never used, but we send it anyway
(for debugging purposes) */
@@ -74,51 +72,92 @@ make_err_reply(krb5_data *reply, int code, const char *msg)
static krb5_boolean
valid_princ(krb5_context context, krb5_principal princ)
{
+ krb5_error_code ret;
char *s;
hdb_entry *ent;
- krb5_unparse_name(context, princ, &s);
- ent = db_fetch(princ);
- if(ent == NULL){
- kdc_log(7, "Lookup %s failed", s);
+
+ ret = krb5_unparse_name(context, princ, &s);
+ if (ret)
+ return 0;
+ ret = db_fetch(princ, &ent);
+ if (ret) {
+ kdc_log(7, "Lookup %s failed: %s", s,
+ krb5_get_err_text (context, ret));
free(s);
return 0;
}
kdc_log(7, "Lookup %s succeeded", s);
free(s);
- hdb_free_entry(context, ent);
- free(ent);
+ free_ent(ent);
return 1;
}
-hdb_entry*
-db_fetch4(const char *name, const char *instance, const char *realm)
+krb5_error_code
+db_fetch4(const char *name, const char *instance, const char *realm,
+ hdb_entry **ent)
{
krb5_principal p;
- hdb_entry *ent;
krb5_error_code ret;
ret = krb5_425_conv_principal_ext(context, name, instance, realm,
valid_princ, 0, &p);
if(ret)
- return NULL;
- ent = db_fetch(p);
+ return ret;
+ ret = db_fetch(p, ent);
krb5_free_principal(context, p);
- return ent;
+ return ret;
}
krb5_error_code
-get_des_key(hdb_entry *principal, Key **key)
+get_des_key(hdb_entry *principal, krb5_boolean prefer_afs_key, Key **ret_key)
{
- krb5_error_code ret;
+ Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL;
+ int i;
+ krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_CRC };
+
+ for(i = 0;
+ i < sizeof(etypes)/sizeof(etypes[0])
+ && (v5_key == NULL || v4_key == NULL || afs_key == NULL);
+ ++i) {
+ Key *key = NULL;
+ while(hdb_next_enctype2key(context, principal, etypes[i], &key) == 0) {
+ if(key->salt == NULL) {
+ if(v5_key == NULL)
+ v5_key = key;
+ } else if(key->salt->type == hdb_pw_salt &&
+ key->salt->salt.length == 0) {
+ if(v4_key == NULL)
+ v4_key = key;
+ } else if(key->salt->type == hdb_afs3_salt) {
+ if(afs_key == NULL)
+ afs_key = key;
+ }
+ }
+ }
- ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key);
- if(ret)
- ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key);
- if(ret)
- ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key);
- if(ret)
- return ret;
- if ((*key)->key.keyvalue.length == 0)
+ if(prefer_afs_key) {
+ if(afs_key)
+ *ret_key = afs_key;
+ else if(v4_key)
+ *ret_key = v4_key;
+ else if(v5_key)
+ *ret_key = v5_key;
+ else
+ return KERB_ERR_NULL_KEY;
+ } else {
+ if(v4_key)
+ *ret_key = v4_key;
+ else if(afs_key)
+ *ret_key = afs_key;
+ else if(v5_key)
+ *ret_key = v5_key;
+ else
+ return KERB_ERR_NULL_KEY;
+ }
+
+ if((*ret_key)->key.keyvalue.length == 0)
return KERB_ERR_NULL_KEY;
return 0;
}
@@ -150,6 +189,14 @@ do_version4(unsigned char *buf,
int32_t req_time;
time_t max_life;
u_int8_t life;
+ char client_name[256];
+ char server_name[256];
+
+ if(!enable_v4) {
+ kdc_log(0, "Rejected version 4 request from %s", from);
+ make_err_reply(reply, KDC_GEN_ERR, "function not enabled");
+ return 0;
+ }
sp = krb5_storage_from_mem(buf, len);
RCHECK(krb5_ret_int8(sp, &pvno), out);
@@ -172,24 +219,38 @@ do_version4(unsigned char *buf,
RCHECK(krb5_ret_int8(sp, &life), out1);
RCHECK(krb5_ret_stringz(sp, &sname), out1);
RCHECK(krb5_ret_stringz(sp, &sinst), out1);
- kdc_log(0, "AS-REQ %s.%s@%s from %s for %s.%s",
- name, inst, realm, from, sname, sinst);
+ snprintf (client_name, sizeof(client_name),
+ "%s.%s@%s", name, inst, realm);
+ snprintf (server_name, sizeof(server_name),
+ "%s.%s@%s", sname, sinst, v4_realm);
+
+ kdc_log(0, "AS-REQ %s from %s for %s",
+ client_name, from, server_name);
- client = db_fetch4(name, inst, realm);
- if(client == NULL){
- kdc_log(0, "Client not found in database: %s.%s@%s",
- name, inst, realm);
+ ret = db_fetch4(name, inst, realm, &client);
+ if(ret) {
+ kdc_log(0, "Client not found in database: %s: %s",
+ client_name, krb5_get_err_text(context, ret));
make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL);
goto out1;
}
- server = db_fetch4(sname, sinst, v4_realm);
- if(server == NULL){
- kdc_log(0, "Server not found in database: %s.%s@%s",
- sname, sinst, v4_realm);
+ ret = db_fetch4(sname, sinst, v4_realm, &server);
+ if(ret){
+ kdc_log(0, "Server not found in database: %s: %s",
+ server_name, krb5_get_err_text(context, ret));
make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL);
goto out1;
}
+ ret = check_flags (client, client_name,
+ server, server_name,
+ TRUE);
+ if (ret) {
+ /* good error code? */
+ make_err_reply(reply, KERB_ERR_NAME_EXP, NULL);
+ goto out1;
+ }
+
/*
* There's no way to do pre-authentication in v4 and thus no
* good error code to return if preauthentication is required.
@@ -200,14 +261,13 @@ do_version4(unsigned char *buf,
|| server->flags.require_preauth) {
kdc_log(0,
"Pre-authentication required for v4-request: "
- "%s.%s@%s for %s.%s@%s",
- name, inst, realm,
- sname, sinst, v4_realm);
+ "%s for %s",
+ client_name, server_name);
make_err_reply(reply, KERB_ERR_NULL_KEY, NULL);
goto out1;
}
- ret = get_des_key(client, &ckey);
+ ret = get_des_key(client, FALSE, &ckey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -230,7 +290,7 @@ do_version4(unsigned char *buf,
}
#endif
- ret = get_des_key(server, &skey);
+ ret = get_des_key(server, FALSE, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -295,12 +355,13 @@ do_version4(unsigned char *buf,
goto out2;
}
- tgt = db_fetch(tgt_princ);
- if(tgt == NULL){
+ ret = db_fetch(tgt_princ, &tgt);
+ if(ret){
char *s;
s = kdc_log_msg(0, "Ticket-granting ticket not "
- "found in database: krbtgt.%s@%s",
- realm, v4_realm);
+ "found in database: krbtgt.%s@%s: %s",
+ realm, v4_realm,
+ krb5_get_err_text(context, ret));
make_err_reply(reply, KFAILURE, s);
free(s);
goto out2;
@@ -314,7 +375,7 @@ do_version4(unsigned char *buf,
goto out2;
}
- ret = get_des_key(tgt, &tkey);
+ ret = get_des_key(tgt, FALSE, &tkey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -349,8 +410,12 @@ do_version4(unsigned char *buf,
RCHECK(krb5_ret_int8(sp, &life), out2);
RCHECK(krb5_ret_stringz(sp, &sname), out2);
RCHECK(krb5_ret_stringz(sp, &sinst), out2);
- kdc_log(0, "TGS-REQ %s.%s@%s from %s for %s.%s",
- ad.pname, ad.pinst, ad.prealm, from, sname, sinst);
+ snprintf (server_name, sizeof(server_name),
+ "%s.%s@%s",
+ sname, sinst, v4_realm);
+
+ kdc_log(0, "TGS-REQ %s.%s@%s from %s for %s",
+ ad.pname, ad.pinst, ad.prealm, from, server_name);
if(strcmp(ad.prealm, realm)){
kdc_log(0, "Can't hop realms %s -> %s", realm, ad.prealm);
@@ -367,28 +432,38 @@ do_version4(unsigned char *buf,
}
#if 0
- client = db_fetch4(ad.pname, ad.pinst, ad.prealm);
- if(client == NULL){
+ ret = db_fetch4(ad.pname, ad.pinst, ad.prealm, &client);
+ if(ret){
char *s;
- s = kdc_log_msg(0, "Client not found in database: %s.%s@%s",
- ad.pname, ad.pinst, ad.prealm);
+ s = kdc_log_msg(0, "Client not found in database: %s.%s@%s: %s",
+ ad.pname, ad.pinst, ad.prealm,
+ krb5_get_err_text(context, ret));
make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
free(s);
goto out2;
}
#endif
- server = db_fetch4(sname, sinst, v4_realm);
- if(server == NULL){
+ ret = db_fetch4(sname, sinst, v4_realm, &server);
+ if(ret){
char *s;
- s = kdc_log_msg(0, "Server not found in database: %s.%s@%s",
- sname, sinst, v4_realm);
+ s = kdc_log_msg(0, "Server not found in database: %s: %s",
+ server_name, krb5_get_err_text(context, ret));
make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
free(s);
goto out2;
}
- ret = get_des_key(server, &skey);
+ ret = check_flags (NULL, NULL,
+ server, server_name,
+ FALSE);
+ if (ret) {
+ /* good error code? */
+ make_err_reply(reply, KERB_ERR_NAME_EXP, NULL);
+ goto out2;
+ }
+
+ ret = get_des_key(server, FALSE, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -433,11 +508,8 @@ do_version4(unsigned char *buf,
out2:
if(tgt_princ)
krb5_free_principal(context, tgt_princ);
- if(tgt){
- hdb_free_entry(context, tgt);
- free(tgt);
- }
-
+ if(tgt)
+ free_ent(tgt);
break;
}
@@ -460,14 +532,10 @@ out:
free(sname);
if(sinst)
free(sinst);
- if(client){
- hdb_free_entry(context, client);
- free(client);
- }
- if(server){
- hdb_free_entry(context, server);
- free(server);
- }
+ if(client)
+ free_ent(client);
+ if(server)
+ free_ent(server);
krb5_storage_free(sp);
return 0;
}
@@ -498,8 +566,8 @@ encrypt_v4_ticket(void *buf, size_t len, des_cblock *key, EncryptedData *reply)
}
krb5_error_code
-encode_v4_ticket(void *buf, size_t len, EncTicketPart *et,
- PrincipalName *service, size_t *size)
+encode_v4_ticket(void *buf, size_t len, const EncTicketPart *et,
+ const PrincipalName *service, size_t *size)
{
krb5_storage *sp;
krb5_error_code ret;
OpenPOWER on IntegriCloud