diff options
| author | Ken Raeburn <raeburn@mit.edu> | 2000-06-30 00:36:31 +0000 |
|---|---|---|
| committer | Ken Raeburn <raeburn@mit.edu> | 2000-06-30 00:36:31 +0000 |
| commit | 3cdd5a1bf70b6233b7ffd0e81bcc267435a907dc (patch) | |
| tree | 67b5d0422cdd1c4b25e55c1e54bdae54e114c008 /src/kdc | |
| parent | 5aaaaf07695e6b4b4b024973984a9e8856484453 (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/ChangeLog | 36 | ||||
| -rw-r--r-- | src/kdc/kdc_util.c | 36 | ||||
| -rw-r--r-- | src/kdc/kerberos_v4.c | 49 | ||||
| -rw-r--r-- | src/kdc/network.c | 40 |
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 { |
