summaryrefslogtreecommitdiffstats
path: root/src/kdc
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2000-06-30 00:36:31 +0000
committerKen Raeburn <raeburn@mit.edu>2000-06-30 00:36:31 +0000
commit3cdd5a1bf70b6233b7ffd0e81bcc267435a907dc (patch)
tree67b5d0422cdd1c4b25e55c1e54bdae54e114c008 /src/kdc
parent5aaaaf07695e6b4b4b024973984a9e8856484453 (diff)
pullup from 1.2-beta4
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12472 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc')
-rw-r--r--src/kdc/ChangeLog36
-rw-r--r--src/kdc/kdc_util.c36
-rw-r--r--src/kdc/kerberos_v4.c49
-rw-r--r--src/kdc/network.c40
4 files changed, 129 insertions, 32 deletions
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog
index 700aabc1a..5d905f9d7 100644
--- a/src/kdc/ChangeLog
+++ b/src/kdc/ChangeLog
@@ -1,3 +1,39 @@
+2000-05-17 Tom Yu <tlyu@mit.edu>
+
+ * kerberos_v4.c (process_v4): Zero out v4_pkt.mbz.
+ (kerberos_v4): Fix handling of APPL_REQUEST messages to deal with
+ ridiculously long realms, etc. Fix up some calls to
+ kerb_err_reply() to be more useful. Set req_*_ptr before any
+ possible calls to kerb_err_reply().
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * kdc_util.c (add_to_transited): Use strncpy/strncat when building
+ data in buffers so as not to overrun "prev", "current", and "exp".
+ * kerberos_v4.c (process_v4): Don't assume that the realm is null-
+ terminated.
+ (set_tgtkey): Truncate realm name if it's too long.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * kdc_util.c (add_to_transited): Use strncpy/strncat when building
+ data in buffers. Fix some limit checks.
+ * kerberos_v4.c (kerb_err_reply): Use strncat so as not to overrun
+ error buffer.
+
+2000-04-22 Ken Raeburn <raeburn@mit.edu>
+
+ * network.c: Include stddef.h.
+ (foreach_localaddr): Check each address against previously used
+ addresses, and skip duplicates, in case multiple interfaces have
+ the same address.
+
+2000-04-21 Ken Raeburn <raeburn@mit.edu>
+
+ * network.c (foreach_localaddr): If called functions fail, drop
+ out of loop and return nonzero.
+
2000-03-14 Ken Raeburn <raeburn@mit.edu>
* sock2p.c: New file.
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index f5a0016b7..e2c73a0f8 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -657,26 +657,30 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server)
clst = strlen(current) - 1;
if (current[0] == ' ') {
- strcpy(exp, current+1);
+ strncpy(exp, current+1, sizeof(exp) - 1);
+ exp[sizeof(exp) - 1] = '\0';
}
else if ((current[0] == '/') && (prev[0] == '/')) {
- strcpy(exp, prev);
+ strncpy(exp, prev, sizeof(exp) - 1);
+ exp[sizeof(exp) - 1] = '\0';
if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(exp, current);
+ strncat(exp, current, sizeof(exp) - 1 - strlen(exp));
}
else if (current[clst] == '.') {
- strcpy(exp, current);
- if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) {
+ strncpy(exp, current, sizeof(exp) - 1);
+ exp[sizeof(exp) - 1] = '\0';
+ if (strlen(exp) + strlen(prev) + 1 >= MAX_REALM_LN) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(exp, prev);
+ strncat(exp, prev, sizeof(exp) - 1 - strlen(exp));
}
else {
- strcpy(exp, current);
+ strncpy(exp, current, sizeof(exp) - 1);
+ exp[sizeof(exp) - 1] = '\0';
}
/* read field into next */
@@ -718,11 +722,12 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server)
if ((next[nlst] != '.') && (next[0] != '/') &&
(pl = subrealm(exp, realm))) {
added = TRUE;
+ current[sizeof(current) - 1] = '\0';
if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(current, ",");
+ strncat(current, ",", sizeof(current) - 1 - strlen(current));
if (pl > 0) {
strncat(current, realm, pl);
}
@@ -762,19 +767,22 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server)
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(current, " ");
+ strncat(current, " ", sizeof(current) - 1 - strlen(current));
+ current[sizeof(current) - 1] = '\0';
}
if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(current, realm);
+ strncat(current, realm, sizeof(current) - 1 - strlen(current));
+ current[sizeof(current) - 1] = '\0';
}
if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto fail;
}
- strcat(current,",");
+ strncat(current,",", sizeof(current) - 1 - strlen(current));
+ current[sizeof(current) - 1] = '\0';
if (pl > 0) {
strncat(current, exp, pl);
}
@@ -798,8 +806,10 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server)
strcat(trans, current);
new_trans->length = strlen(trans) + 1;
- strcpy(prev, exp);
- strcpy(current, next);
+ strncpy(prev, exp, sizeof(prev) - 1);
+ prev[sizeof(prev) - 1] = '\0';
+ strncpy(current, next, sizeof(current) - 1);
+ current[sizeof(current) - 1] = '\0';
}
if (!added) {
diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c
index f05452e18..6629c3e35 100644
--- a/src/kdc/kerberos_v4.c
+++ b/src/kdc/kerberos_v4.c
@@ -233,11 +233,11 @@ krb5_data **resp;
return(retval);
if (!*local_realm) { /* local-realm name already set up */
- /* XXX assumes realm is null-terminated! */
lrealm = master_princ->realm.data;
- if (strlen(lrealm) < sizeof(local_realm))
- strcpy(local_realm, lrealm);
- else
+ if (master_princ->realm.length < sizeof(local_realm)) {
+ memcpy(local_realm, lrealm, master_princ->realm.length);
+ local_realm[master_princ->realm.length] = '\0';
+ } else
retval = KRB5_CONFIG_NOTENUFSPACE;
}
/* convert client_fulladdr to client_sockaddr:
@@ -256,6 +256,7 @@ krb5_data **resp;
return KRB5KRB_ERR_FIELD_TOOLONG;
}
v4_pkt.length = pkt->length;
+ v4_pkt.mbz = 0;
memcpy( v4_pkt.dat, pkt->data, pkt->length);
kerberos_v4( &client_sockaddr, &v4_pkt);
@@ -622,6 +623,9 @@ kerberos_v4(client, pkt)
req_act_vno = req_version;
+ /* set these to point to something safe */
+ req_name_ptr = req_inst_ptr = req_realm_ptr = "";
+
/* check if disabled, but we tell client */
if (kdc_v4 == KDC_V4_DISABLE) {
lt = klog(L_KRB_PERR,
@@ -700,7 +704,7 @@ kerberos_v4(client, pkt)
if ((i = check_princ(req_name_ptr, req_inst_ptr, 0,
&a_name_data, &k5key, 0))) {
- kerb_err_reply(client, pkt, i, lt);
+ kerb_err_reply(client, pkt, i, "check_princ failed");
a_name_data.key_low = a_name_data.key_high = 0;
krb5_free_keyblock_contents(kdc_context, &k5key);
return;
@@ -715,7 +719,7 @@ kerberos_v4(client, pkt)
/* this does all the checking */
if ((i = check_princ(service, instance, lifetime,
&s_name_data, &k5key, 1))) {
- kerb_err_reply(client, pkt, i, lt);
+ kerb_err_reply(client, pkt, i, "check_princ failed");
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);
@@ -806,19 +810,40 @@ kerberos_v4(client, pkt)
tk->length = 0;
k_flags = 0; /* various kerberos flags */
+ auth->mbz = 0; /* pkt->mbz already zeroed */
auth->length = 4 + strlen((char *)pkt->dat + 3);
+ if (auth->length + 1 > MAX_KTXT_LEN) {
+ lt = klog(L_KRB_PERR,
+ "APPL request with realm length too long from %s",
+ inet_ntoa(client_host));
+ kerb_err_reply(client, pkt, RD_AP_INCON,
+ "realm length too long");
+ return;
+ }
+
auth->length += (int) *(pkt->dat + auth->length) +
(int) *(pkt->dat + auth->length + 1) + 2;
+ if (auth->length > MAX_KTXT_LEN) {
+ lt = klog(L_KRB_PERR,
+ "APPL request with funky tkt or req_id length from %s",
+ inet_ntoa(client_host));
+ kerb_err_reply(client, pkt, RD_AP_INCON,
+ "funky tkt or req_id length");
+ return;
+ }
memcpy(auth->dat, pkt->dat, auth->length);
strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ);
+ tktrlm[REALM_SZ-1] = '\0';
kvno = (krb5_kvno)auth->dat[2];
if (set_tgtkey(tktrlm, kvno)) {
lt = klog(L_ERR_UNK,
"FAILED set_tgtkey realm %s, kvno %d. Host: %s ",
tktrlm, kvno, inet_ntoa(client_host));
- kerb_err_reply(client, pkt, kerno, lt);
+ /* no better error code */
+ kerb_err_reply(client, pkt,
+ KERB_ERR_PRINCIPAL_UNKNOWN, lt);
return;
}
kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
@@ -863,7 +888,7 @@ kerberos_v4(client, pkt)
kerno = check_princ(service, instance, req_life,
&s_name_data, &k5key, 1);
if (kerno) {
- kerb_err_reply(client, pkt, kerno, lt);
+ kerb_err_reply(client, pkt, kerno, "check_princ failed");
s_name_data.key_high = s_name_data.key_low = 0;
krb5_free_keyblock_contents(kdc_context, &k5key);
return;
@@ -968,7 +993,7 @@ kerb_err_reply(client, pkt, err, string)
static char e_msg[128];
strcpy(e_msg, "\nKerberos error -- ");
- strcat(e_msg, string);
+ strncat(e_msg, string, sizeof(e_msg) - 1 - 19);
cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
req_time_ws, err, e_msg);
krb4_sendto(f, (char *) e_pkt->dat, e_pkt->length, 0,
@@ -1127,7 +1152,8 @@ set_tgtkey(r, kvno)
if (!K4KDC_ENCTYPE_OK(k5key.enctype)) {
krb_set_key_krb5(kdc_context, &k5key);
- strcpy(lastrealm, r);
+ strncpy(lastrealm, r, sizeof(lastrealm) - 1);
+ lastrealm[sizeof(lastrealm) - 1] = '\0';
last_kvno = kvno;
} else {
/* unseal tgt key from master key */
@@ -1136,7 +1162,8 @@ set_tgtkey(r, kvno)
kdb_encrypt_key(key, key, master_key,
master_key_schedule, DECRYPT);
krb_set_key((char *) key, 0);
- strcpy(lastrealm, r);
+ strncpy(lastrealm, r, sizeof(lastrealm) - 1);
+ lastrealm[sizeof(lastrealm) - 1] = '\0';
last_kvno = kvno;
}
krb5_free_keyblock_contents(kdc_context, &k5key);
diff --git a/src/kdc/network.c b/src/kdc/network.c
index 502682a86..a91fc95b8 100644
--- a/src/kdc/network.c
+++ b/src/kdc/network.c
@@ -1,7 +1,7 @@
/*
* kdc/network.c
*
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2000 by the Massachusetts Institute of Technology.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
@@ -35,6 +35,7 @@
#include <sys/ioctl.h>
#include <syslog.h>
+#include <stddef.h>
#include <ctype.h>
#ifdef HAVE_NETINET_IN_H
#include <sys/types.h>
@@ -120,13 +121,14 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
int (*betweenfn) (void *);
int (*pass2fn) (void *, struct sockaddr *);
{
- struct ifreq *ifr, ifreq;
+ struct ifreq *ifr, ifreq, *ifr2;
struct ifconf ifc;
- int s, code, n, i;
+ int s, code, n, i, j;
int est_if_count = 8, est_ifreq_size;
char *buf = 0;
size_t current_buf_size = 0;
-
+ int fail = 0;
+
s = socket (USE_AF, USE_TYPE, USE_PROTO);
if (s < 0)
return SOCKET_ERRNO;
@@ -184,6 +186,7 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
continue;
}
+
#ifdef IFF_LOOPBACK
/* None of the current callers want loopback addresses. */
if (ifreq.ifr_flags & IFF_LOOPBACK)
@@ -193,13 +196,32 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
if (!(ifreq.ifr_flags & IFF_UP))
goto skip;
+ /* Make sure we didn't process this address already. */
+ for (j = 0; j < i; j += ifreq_size(*ifr2)) {
+ ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j);
+ if (ifr2->ifr_name[0] == 0)
+ continue;
+ if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family
+ && ifreq_size (*ifr) == ifreq_size (*ifr2)
+ /* Compare address info. If this isn't good enough --
+ i.e., if random padding bytes turn out to differ
+ when the addresses are the same -- then we'll have
+ to do it on a per address family basis. */
+ && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data,
+ (ifreq_size (*ifr)
+ - offsetof (struct ifreq, ifr_addr.sa_data))))
+ goto skip;
+ }
+
if ((*pass1fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
if (betweenfn && (*betweenfn)(data)) {
- abort ();
+ fail = 1;
+ goto punt;
}
if (pass2fn)
@@ -211,13 +233,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
continue;
if ((*pass2fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
+ punt:
closesocket(s);
free (buf);
- return 0;
+ return fail;
}
struct socksetup {