diff options
author | Cy Schubert <cy@FreeBSD.org> | 2003-03-21 00:54:06 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2003-03-21 00:54:06 +0000 |
commit | af7a454fd3da00363fde4728708eb83d5e734230 (patch) | |
tree | 8dc748b7f3a65ad37e15622ed189237948b2c5db /security | |
parent | Remove special USER_H override. (diff) |
Patches from:
- MITKRB5-SA-2003-005:
Buffer overrun and underrun in principal name handling
- MITKRB5-SA-2003-004:
Cryptographic weaknesses in Kerberos v4 protocol; KDC and realm
compromise possible.
- MITKRB5-SA-2003-003:
Faulty length checks in xdrmem_getbytes may allow kadmind DoS.
- Additional patches from RedHat.
Approved by: kris (wearing his portmgr hat)
Obtained from: MIT Website and Nalin Dahyabhai <nalin@redhat.com>
Notes
Notes:
svn path=/head/; revision=77170
Diffstat (limited to 'security')
76 files changed, 3356 insertions, 0 deletions
diff --git a/security/krb5-16/Makefile b/security/krb5-16/Makefile index cff9b3b0bc9a..826ca046d324 100644 --- a/security/krb5-16/Makefile +++ b/security/krb5-16/Makefile @@ -7,6 +7,7 @@ PORTNAME= krb5 PORTVERSION= 1.2.7 +PORTREVISION= 1 CATEGORIES= security .if defined(USA_RESIDENT) && ${USA_RESIDENT} == "NO" # XXX crypto-publish.org does not at this time have the krb5-1.2.7 tarball. diff --git a/security/krb5-16/files/patch-appl::telnet::libtelnet::kerberos5.c b/security/krb5-16/files/patch-appl::telnet::libtelnet::kerberos5.c new file mode 100644 index 000000000000..2115fd77a446 --- /dev/null +++ b/security/krb5-16/files/patch-appl::telnet::libtelnet::kerberos5.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c +--- appl/telnet/libtelnet/kerberos5.c 2002-03-29 00:07:09.000000000-0500 ++++ appl/telnet/libtelnet/kerberos5.c 2003-02-03 17:30:18.000000000-0500 +@@ -441,6 +441,10 @@ + * first component of a service name especially since + * the default is of length 4. + */ ++ if (krb5_princ_size(telnet_context,ticket->server) < 1) { ++ (void) strcpy(errbuf, "malformed service name"); ++ goto errout; ++ } + if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) { + char princ[256]; + strncpy(princ, diff --git a/security/krb5-16/files/patch-clients::ksu::heuristic.c b/security/krb5-16/files/patch-clients::ksu::heuristic.c new file mode 100644 index 000000000000..9a92c4eb7058 --- /dev/null +++ b/security/krb5-16/files/patch-clients::ksu::heuristic.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/clients/ksu/heuristic.c krb5-1.2.7/src/clients/ksu/heuristic.c +--- clients/ksu/heuristic.c 2003-02-03 15:24:57.000000000 -0500 ++++ clients/ksu/heuristic.c 2003-02-03 17:56:38.000000000 -0500 +@@ -355,7 +355,7 @@ + krb5_data *p2 = + krb5_princ_component(context, temp_client, j); + +- if ((p1->length != p2->length) || ++ if (!p1 || !p2 || (p1->length != p2->length) || + memcmp(p1->data,p2->data,p1->length)){ + got_one = FALSE; + break; diff --git a/security/krb5-16/files/patch-clients::ksu::krb_auth_su.c b/security/krb5-16/files/patch-clients::ksu::krb_auth_su.c new file mode 100644 index 000000000000..150551765d3d --- /dev/null +++ b/security/krb5-16/files/patch-clients::ksu::krb_auth_su.c @@ -0,0 +1,13 @@ +--- clients/ksu/krb_auth_su.c.orig Mon Dec 6 13:56:09 1999 ++++ clients/ksu/krb_auth_su.c Tue Feb 25 19:54:14 2003 +@@ -620,7 +620,9 @@ + krb5_princ_realm(context, temp_client)->length))){ + + +- if(nelem){ ++ if(nelem && ++ (krb5_princ_size(context, *client) > 0) && ++ (krb5_princ_size(context, temp_client) > 0)){ + krb5_data *p1 = + krb5_princ_component(context, *client, 0); + krb5_data *p2 = diff --git a/security/krb5-16/files/patch-include::krb5.hin b/security/krb5-16/files/patch-include::krb5.hin new file mode 100644 index 000000000000..812664fc0b0e --- /dev/null +++ b/security/krb5-16/files/patch-include::krb5.hin @@ -0,0 +1,16 @@ +Index: include/krb5.hin +=================================================================== +RCS file: /cvs/krbdev/krb5/src/include/krb5.hin,v +retrieving revision 1.94.2.5.2.17 +diff -p -u -r1.94.2.5.2.17 krb5.hin +--- include/krb5.hin 2002/04/16 23:47:53 1.94.2.5.2.17 ++++ include/krb5.hin 2003/03/19 00:38:54 +@@ -326,7 +326,7 @@ typedef krb5_const krb5_principal_data F + #define krb5_princ_size(context, princ) (princ)->length + #define krb5_princ_type(context, princ) (princ)->type + #define krb5_princ_name(context, princ) (princ)->data +-#define krb5_princ_component(context, princ,i) ((princ)->data + i) ++#define krb5_princ_component(context, princ,i) (i < krb5_princ_size(context, princ) ? ((princ)->data + i) : NULL) + + /* + * end "base-defs.h" diff --git a/security/krb5-16/files/patch-kdc::do_tgs_req.c b/security/krb5-16/files/patch-kdc::do_tgs_req.c new file mode 100644 index 000000000000..58e41c08a5e7 --- /dev/null +++ b/security/krb5-16/files/patch-kdc::do_tgs_req.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/kdc/do_tgs_req.c krb5-1.2.7/src/kdc/do_tgs_req.c +--- kdc/do_tgs_req.c 2003-02-03 15:24:58.000000000 -0500 ++++ kdc/do_tgs_req.c 2003-02-03 17:54:27.000000000 -0500 +@@ -180,7 +180,7 @@ + krb5_data *tgs_1 = + krb5_princ_component(kdc_context, tgs_server, 1); + +- if (server_1->length != tgs_1->length || ++ if (!tgs_1 || server_1->length != tgs_1->length || + memcmp(server_1->data, tgs_1->data, tgs_1->length)) { + krb5_db_free_principal(kdc_context, &server, nprincs); + find_alternate_tgs(request, &server, &more, &nprincs); diff --git a/security/krb5-16/files/patch-kdc::kdc_util.c b/security/krb5-16/files/patch-kdc::kdc_util.c new file mode 100644 index 000000000000..078a4b73c4fe --- /dev/null +++ b/security/krb5-16/files/patch-kdc::kdc_util.c @@ -0,0 +1,27 @@ +Index: kdc/kdc_util.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.c,v +retrieving revision 5.96.2.2.2.3 +diff -p -u -r5.96.2.2.2.3 kdc_util.c +--- kdc/kdc_util.c 2002/10/31 00:38:34 5.96.2.2.2.3 ++++ kdc/kdc_util.c 2003/03/19 00:39:00 +@@ -157,7 +157,8 @@ realm_compare(princ1, princ2) + krb5_boolean krb5_is_tgs_principal(principal) + krb5_principal principal; + { +- if ((krb5_princ_component(kdc_context, principal, 0)->length == ++ if (krb5_princ_size(kdc_context, principal) > 0 && ++ (krb5_princ_component(kdc_context, principal, 0)->length == + KRB5_TGS_NAME_SIZE) && + (!memcmp(krb5_princ_component(kdc_context, principal, 0)->data, + KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE))) +@@ -1195,7 +1196,8 @@ + return KRB_AP_ERR_NOT_US; + } + /* ...and that the second component matches the server realm... */ +- if ((krb5_princ_component(kdc_context, ticket->server, 1)->length != ++ if ((krb5_princ_size(kdc_context, ticket->server) <= 1) || ++ (krb5_princ_component(kdc_context, ticket->server, 1)->length != + krb5_princ_realm(kdc_context, request->server)->length) || + memcmp(krb5_princ_component(kdc_context, ticket->server, 1)->data, + krb5_princ_realm(kdc_context, request->server)->data, diff --git a/security/krb5-16/files/patch-kdc::kdc_util.h b/security/krb5-16/files/patch-kdc::kdc_util.h new file mode 100644 index 000000000000..262f3ff8cb29 --- /dev/null +++ b/security/krb5-16/files/patch-kdc::kdc_util.h @@ -0,0 +1,15 @@ +Index: kdc/kdc_util.h +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.h,v +retrieving revision 5.44.4.1 +diff -u -r5.44.4.1 kdc_util.h +--- kdc/kdc_util.h 2001/10/13 00:12:26 5.44.4.1 ++++ kdc/kdc_util.h 2002/10/15 23:32:45 +@@ -183,6 +183,7 @@ + const krb5_fulladdr *, + int is_secondary, + krb5_data **)); ++void enable_v4_crossrealm(char *); + #else + #define process_v4(foo,bar,quux,foobar) KRB5KRB_AP_ERR_BADVERSION + #endif diff --git a/security/krb5-16/files/patch-kdc::kerberos_v4.c b/security/krb5-16/files/patch-kdc::kerberos_v4.c new file mode 100644 index 000000000000..5b197f68afd9 --- /dev/null +++ b/security/krb5-16/files/patch-kdc::kerberos_v4.c @@ -0,0 +1,233 @@ +Index: kdc/kerberos_v4.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kerberos_v4.c,v +retrieving revision 5.68.2.3.2.1 +diff -u -r5.68.2.3.2.1 kerberos_v4.c +--- kdc/kerberos_v4.c 2002/08/15 21:28:54 5.68.2.3.2.1 ++++ kdc/kerberos_v4.c 2002/10/15 23:32:45 +@@ -149,7 +149,7 @@ + + void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); + void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); +-static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); ++static int set_tgtkey PROTOTYPE((char *, krb5_kvno, krb5_boolean)); + + /* Attributes converted from V5 to V4 - internal representation */ + #define V4_KDB_REQUIRES_PREAUTH 0x1 +@@ -182,6 +182,7 @@ + + static const int v4mode_table_nents = sizeof(v4mode_table)/ + sizeof(v4mode_table[0]); ++static int allow_v4_crossrealm = 0; + + void process_v4_mode(progname, string) + const char *progname; +@@ -210,6 +211,11 @@ + return; + } + ++void enable_v4_crossrealm ( char *programname) { ++ allow_v4_crossrealm = 1; ++ krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole"); ++} ++ + krb5_error_code + process_v4( pkt, client_fulladdr, is_secondary, resp) + const krb5_data *pkt; +@@ -401,6 +407,14 @@ + #define MIN5 300 + #define HR21 255 + ++/* ++ * Previously this code returned either a v4 key or a v5 key and you ++ * could tell from the enctype of the v5 key whether the v4 key was ++ * useful. Now we return both keys so the code can try both des3 and ++ * des decryption. We fail if the ticket doesn't have a v4 key. ++ * Also, note as a side effect, the v5 key is basically useless in ++ * the client case. It is still returned so the caller can free it. ++ */ + static int + kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) + char *name; /* could have wild card */ +@@ -482,8 +496,28 @@ + return(0); + } + } else { +- /* XXX yes I know this is a hardcoded search order */ +- if (krb5_dbe_find_enctype(kdc_context, &entries, ++ if ( krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && ++ krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ -1, kvno, &pkey)) { ++ lt = klog(L_KRB_PERR, ++ "KDC V4: failed to find key for %s.%s #%d", ++ name, inst, kvno); ++ krb5_db_free_principal(kdc_context, &entries, nprinc); ++ return(0); ++ } ++ } ++ ++ if (!compat_decrypt_key(pkey, k, k5key, issrv)) { ++ memcpy( &principal->key_low, k, LONGLEN); ++ memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); ++ } ++ memset(k, 0, sizeof k); ++ if (issrv) { ++ krb5_free_keyblock_contents (kdc_context, k5key); ++ if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, +@@ -504,12 +538,10 @@ + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } ++ compat_decrypt_key(pkey, k, k5key, issrv); ++ memset (k, 0, sizeof k); + } + +- if (!compat_decrypt_key(pkey, k, k5key, issrv)) { +- memcpy( &principal->key_low, k, LONGLEN); +- memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); +- } + /* convert v5's entries struct to v4's Principal struct: + * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes. + */ +@@ -746,21 +778,14 @@ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* We always issue des tickets; the 3des tickets are a broken hack*/ ++ krb_create_ticket(tk, k_flags, a_name_data.name, ++ a_name_data.instance, local_realm, ++ client_host.s_addr, (char *) session_key, ++ lifetime, kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); ++ + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -840,8 +865,15 @@ + 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, ++ if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) { ++ lt = klog(L_ERR_UNK, ++ "Cross realm ticket from %s denied by policy,", tktrlm); ++ kerb_err_reply(client, pkt, ++ KERB_ERR_PRINCIPAL_UNKNOWN, lt); ++ return; ++ } ++ if (set_tgtkey(tktrlm, kvno, 0)) { ++ lt = klog(L_ERR_UNK, + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); + /* no better error code */ +@@ -851,6 +883,19 @@ + } + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, + ad, 0); ++ if (kerno) { ++ if (set_tgtkey(tktrlm, kvno, 1)) { ++ lt = klog(L_ERR_UNK, ++ "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ", ++ tktrlm, kvno, inet_ntoa(client_host)); ++ /* 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, ++ ad, 0); ++ } + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", +@@ -916,21 +961,13 @@ + des_new_random_key(session_key); + #endif + +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* ALways issue des tickets*/ ++ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, ++ ad->prealm, client_host.s_addr, ++ (char *) session_key, lifetime, ++ kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -1138,20 +1175,22 @@ + + /* Set the key for krb_rd_req so we can check tgt */ + static int +-set_tgtkey(r, kvno) ++set_tgtkey(r, kvno, use_3des) + char *r; /* Realm for desired key */ + krb5_kvno kvno; ++ krb5_boolean use_3des; + { + int n; + static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; ++ static krb5_boolean last_use_3des = 0; + Principal p_st; + Principal *p = &p_st; + C_Block key; + krb5_keyblock k5key; + + k5key.contents = NULL; +- if (!strcmp(lastrealm, r) && last_kvno == kvno) ++ if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des) + return (KSUCCESS); + + /* log("Getting key for %s", r); */ +@@ -1173,11 +1212,12 @@ + return KFAILURE; + } + +- if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { ++ if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; + last_kvno = kvno; ++ last_use_3des = use_3des; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); diff --git a/security/krb5-16/files/patch-kdc::main.c b/security/krb5-16/files/patch-kdc::main.c new file mode 100644 index 000000000000..2e16cbece0fb --- /dev/null +++ b/security/krb5-16/files/patch-kdc::main.c @@ -0,0 +1,37 @@ +Index: kdc/main.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/main.c,v +retrieving revision 5.99.4.1 +diff -u -r5.99.4.1 main.c +--- kdc/main.c 2001/09/26 00:46:11 5.99.4.1 ++++ kdc/main.c 2002/10/15 23:32:45 +@@ -559,7 +559,7 @@ + usage(name) + char *name; + { +- fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-n]\n", name); ++ fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n", name); + return; + } + +@@ -611,7 +611,7 @@ + * Loop through the option list. Each time we encounter a realm name, + * use the previously scanned options to fill in for defaults. + */ +- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:3")) != -1) { ++ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) { + switch(c) { + case 'r': /* realm name for db */ + if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { +@@ -661,6 +661,11 @@ + v4mode = strdup(optarg); + #endif + break; ++ case 'X': ++#ifdef KRB5_KRB4_COMPAT ++ enable_v4_crossrealm(argv[0]); ++#endif ++ break; + case '3': + #ifdef ATHENA_DES3_KLUDGE + if (krb5_enctypes_list[krb5_enctypes_length-1].etype diff --git a/security/krb5-16/files/patch-krb524::cnv_tkt_skey.c b/security/krb5-16/files/patch-krb524::cnv_tkt_skey.c new file mode 100644 index 000000000000..b8204faee367 --- /dev/null +++ b/security/krb5-16/files/patch-krb524::cnv_tkt_skey.c @@ -0,0 +1,34 @@ +Index: krb524/cnv_tkt_skey.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/cnv_tkt_skey.c,v +retrieving revision 1.17.2.1.2.1 +diff -u -r1.17.2.1.2.1 cnv_tkt_skey.c +--- krb524/cnv_tkt_skey.c 2002/03/01 16:05:20 1.17.2.1.2.1 ++++ krb524/cnv_tkt_skey.c 2002/10/15 23:32:45 +@@ -173,25 +173,7 @@ + sname, + sinst, + v4_skey->contents); +- } else { +- /* Force enctype to be raw if using DES3. */ +- if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 || +- v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) +- v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; +- ret = krb_cr_tkt_krb5(v4tkt, +- 0, /* flags */ +- pname, +- pinst, +- prealm, +- *((unsigned long *)kaddr.contents), +- (char *) v5etkt->session->contents, +- lifetime, +- /* issue_data */ +- server_time, +- sname, +- sinst, +- v4_skey); +- } ++ } else abort(); + + krb5_free_enc_tkt_part(context, v5etkt); + v5tkt->enc_part2 = NULL; diff --git a/security/krb5-16/files/patch-krb524::krb524d.c b/security/krb5-16/files/patch-krb524::krb524d.c new file mode 100644 index 000000000000..5d121045582a --- /dev/null +++ b/security/krb5-16/files/patch-krb524::krb524d.c @@ -0,0 +1,89 @@ +Index: krb524/krb524d.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/krb524d.c,v +retrieving revision 1.40.4.3 +diff -u -r1.40.4.3 krb524d.c +--- krb524/krb524d.c 2002/08/29 06:48:05 1.40.4.3 ++++ krb524/krb524d.c 2002/10/15 23:32:45 +@@ -70,6 +70,7 @@ + void *handle; + + int use_keytab, use_master; ++int allow_v4_crossrealm = 0; + char *keytab = NULL; + krb5_keytab kt; + +@@ -134,7 +135,10 @@ + config_params.mask = 0; + + while (argc) { +- if (strncmp(*argv, "-k", 2) == 0) ++ if (strncmp(*argv, "-X", 2) == 0) { ++ allow_v4_crossrealm = 1; ++ } ++ else if (strncmp(*argv, "-k", 2) == 0) + use_keytab = 1; + else if (strncmp(*argv, "-m", 2) == 0) + use_master = 1; +@@ -317,7 +317,7 @@ + if (debug) + printf("V5 ticket decoded\n"); + +- if( v5tkt->server->length >= 1 ++ if( krb5_princ_size(context, v5tkt->server) >= 1 + &&krb5_princ_component(context, v5tkt->server, 0)->length == 3 + &&strncmp(krb5_princ_component(context, v5tkt->server, 0)->data, + "afs", 3) == 0) { +@@ -495,19 +499,7 @@ + &v5_service_key, NULL))) + goto error; + +- if ((ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_RAW, +- 0, /* highest kvno */ +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_LOCAL_DES3_HMAC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, ++ if ( (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES_CBC_CRC, + 0, + &v4_service_key, v4kvno))) +@@ -515,8 +507,19 @@ + + if (debug) + printf("service key retrieved\n"); ++ if ((ret = krb5_decrypt_tkt_part(context, &v5_service_key, v5tkt))) { ++ goto error; ++ } + +- ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, ++ if (!(allow_v4_crossrealm || krb5_realm_compare(context, v5tkt->server, ++ v5tkt->enc_part2->client))) { ++ret = KRB5KDC_ERR_POLICY ; ++ goto error; ++ } ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ v5tkt->enc_part2= NULL; ++ ++ ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, + &v4_service_key, + (struct sockaddr_in *)saddr); + if (ret) +@@ -532,6 +535,9 @@ + printf("v4 credentials encoded\n"); + + error: ++ if (v5tkt->enc_part2) ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ + if(v5_service_key.contents) + krb5_free_keyblock_contents(context, &v5_service_key); + if (v4_service_key.contents) +diff -ur krb5-1.2.7/src/krb524/krb524d.c krb5-1.2.7/src/krb524/krb524d.c diff --git a/security/krb5-16/files/patch-lib::kdb::keytab.c b/security/krb5-16/files/patch-lib::kdb::keytab.c new file mode 100644 index 000000000000..a77f4bc32718 --- /dev/null +++ b/security/krb5-16/files/patch-lib::kdb::keytab.c @@ -0,0 +1,86 @@ +Index: lib/kdb/keytab.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/kdb/keytab.c,v +retrieving revision 5.11.4.2 +diff -u -r5.11.4.2 keytab.c +--- lib/kdb/keytab.c 2002/08/15 21:27:34 5.11.4.2 ++++ lib/kdb/keytab.c 2002/10/15 23:32:46 +@@ -28,6 +28,8 @@ + #include "k5-int.h" + #include "kdb_kt.h" + ++static int ++is_xrealm_tgt(krb5_context, krb5_const_principal); + krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab)); + + krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal, +@@ -98,6 +100,8 @@ + krb5_db_entry db_entry; + krb5_boolean more = 0; + int n = 0; ++ int xrealm_tgt = is_xrealm_tgt(context, principal); ++ int similar; + + /* Open database */ + /* krb5_db_init(context); */ +@@ -127,16 +131,31 @@ + if (kerror) + goto error; + ++ /* For cross realm tgts, we match whatever enctype is provided; ++ * for other principals, we only match the first enctype that is ++ * found. Since the TGS and AS code do the same thing, then we ++ * will only successfully decrypt tickets we have issued.*/ + kerror = krb5_dbe_find_enctype(context, &db_entry, +- enctype, -1, kvno, &key_data); ++ xrealm_tgt?enctype:-1, ++ -1, kvno, &key_data); + if (kerror) + goto error; + ++ + kerror = krb5_dbekd_decrypt_key_data(context, master_key, + key_data, &entry->key, NULL); + if (kerror) + goto error; + ++ kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar); ++ if (kerror) ++ goto error; ++ ++ if (!similar) { ++ kerror = KRB5_KDB_NO_PERMITTED_KEY; ++ goto error; ++ } ++ + /* + * Coerce the enctype of the output keyblock in case we got an + * inexact match on the enctype; this behavior will go away when +@@ -154,3 +173,27 @@ + krb5_db_close_database(context); + return(kerror); + } ++ ++/* ++ * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT ++ * principal-- a principal with first component krbtgt and second ++ * component not equal to realm. ++ */ ++static int ++is_xrealm_tgt(krb5_context context, krb5_const_principal princ) ++{ ++ krb5_data *dat; ++ if (krb5_princ_size(context, princ) != 2) ++ return 0; ++ dat = krb5_princ_component(context, princ, 0); ++ if (strncmp("krbtgt", dat->data, dat->length) != 0) ++ return 0; ++ dat = krb5_princ_component(context, princ, 1); ++ if (dat->length != princ->realm.length) ++ return 1; ++ if (strcmp(dat->data, princ->realm.data) == 0) ++ return 0; ++ return 1; ++ ++} ++ diff --git a/security/krb5-16/files/patch-lib::krb5::keytab::file:ktf_util.c b/security/krb5-16/files/patch-lib::krb5::keytab::file:ktf_util.c new file mode 100644 index 000000000000..c97b3a3c85ae --- /dev/null +++ b/security/krb5-16/files/patch-lib::krb5::keytab::file:ktf_util.c @@ -0,0 +1,42 @@ +diff -ur krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c +--- lib/krb5/keytab/file/ktf_util.c 1999-09-24 17:19:01.000000000-0400 ++++ lib/krb5/keytab/file/ktf_util.c 2003-02-03 18:02:25.000000000-0500 +@@ -441,7 +441,7 @@ + return 0; + fail: + +- for (i = 0; i < ret_entry->principal->length; i++) { ++ for (i = 0; i < krb5_princ_size(context, ret_entry->principal); i++) { + princ = krb5_princ_component(context, ret_entry->principal, i); + if (princ->data) + free(princ->data); +@@ -498,9 +498,9 @@ + } + + if (KTVERSION(id) == KRB5_KT_VNO_1) { +- count = (krb5_int16) entry->principal->length + 1; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal) + 1; + } else { +- count = htons((u_short) entry->principal->length); ++ count = htons((u_short) krb5_princ_size(context, entry->principal)); + } + + if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) { +@@ -519,7 +519,7 @@ + goto abend; + } + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + for (i = 0; i < count; i++) { + princ = krb5_princ_component(context, entry->principal, i); + size = princ->length; +@@ -620,7 +620,7 @@ + krb5_int32 total_size, i; + krb5_error_code retval = 0; + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + + total_size = sizeof(count); + total_size += krb5_princ_realm(context, entry->principal)->length + (sizeof(krb5_int16)); diff --git a/security/krb5-16/files/patch-lib::krb5::krb::gc_frm_kdc.c b/security/krb5-16/files/patch-lib::krb5::krb::gc_frm_kdc.c new file mode 100644 index 000000000000..4ad0d8cc43c5 --- /dev/null +++ b/security/krb5-16/files/patch-lib::krb5::krb::gc_frm_kdc.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c +--- lib/krb5/krb/gc_frm_kdc.c 1999-09-24 17:19:24.000000000 -0400 ++++ lib/krb5/krb/gc_frm_kdc.c 2003-02-03 17:35:40.000000000 -0500 +@@ -347,7 +347,9 @@ + for (next_server = top_server; *next_server; next_server++) { + krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1); + krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1); +- if (realm_1->length == realm_2->length && ++ if (realm_1 != NULL && ++ realm_2 != NULL && ++ realm_1->length == realm_2->length && + !memcmp(realm_1->data, realm_2->data, realm_1->length)) { + break; + } diff --git a/security/krb5-16/files/patch-lib::krb5::krb::parse.c b/security/krb5-16/files/patch-lib::krb5::krb::parse.c new file mode 100644 index 000000000000..8eb73b24c158 --- /dev/null +++ b/security/krb5-16/files/patch-lib::krb5::krb::parse.c @@ -0,0 +1,29 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/parse.c krb5-1.2.7/src/lib/krb5/krb/parse.c +--- lib/krb5/krb/parse.c 2002-02-28 12:08:35.000000000 -0500 ++++ lib/krb5/krb/parse.c 2003-02-03 17:44:04.000000000 -0500 +@@ -173,11 +173,13 @@ + cp++; + size++; + } else if (c == COMPONENT_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + i++; + } else if (c == REALM_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + parsed_realm = cp+1; + } else +@@ -186,7 +188,8 @@ + if (parsed_realm) + krb5_princ_realm(context, principal)->length = size; + else +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + if (i + 1 != components) { + #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) + fprintf(stderr, diff --git a/security/krb5-16/files/patch-lib::krb5::krb::srv_rcache.c b/security/krb5-16/files/patch-lib::krb5::krb::srv_rcache.c new file mode 100644 index 000000000000..79e16f93110d --- /dev/null +++ b/security/krb5-16/files/patch-lib::krb5::krb::srv_rcache.c @@ -0,0 +1,12 @@ +--- lib/krb5/krb/srv_rcache.c 1999-09-24 17:19:48.000000000 -0400 ++++ lib/krb5/krb/srv_rcache.c 2003-02-03 19:29:32.000000000 -0500 +@@ -48,6 +48,9 @@ + unsigned long uid = geteuid(); + #endif + ++ if (piece == NULL) ++ return ENOMEM; ++ + rcache = (krb5_rcache) malloc(sizeof(*rcache)); + if (!rcache) + return ENOMEM; diff --git a/security/krb5-16/files/patch-lib::krb5::krb::unparse.c b/security/krb5-16/files/patch-lib::krb5::krb::unparse.c new file mode 100644 index 000000000000..690eb5febea2 --- /dev/null +++ b/security/krb5-16/files/patch-lib::krb5::krb::unparse.c @@ -0,0 +1,17 @@ +Index: lib/krb5/krb/unparse.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/unparse.c,v +retrieving revision 5.27.4.1 +diff -p -u -r5.27.4.1 unparse.c +--- lib/krb5/krb/unparse.c 2002/08/12 22:55:01 5.27.4.1 ++++ lib/krb5/krb/unparse.c 2003/03/19 00:39:02 +@@ -153,7 +153,8 @@ krb5_unparse_name_ext(context, principal + *q++ = COMPONENT_SEP; + } + +- q--; /* Back up last component separator */ ++ if (i > 0) ++ q--; /* Back up last component separator */ + *q++ = REALM_SEP; + + cp = krb5_princ_realm(context, principal)->data; diff --git a/security/krb5-16/files/patch-lib::rpc::xdr_mem.c b/security/krb5-16/files/patch-lib::rpc::xdr_mem.c new file mode 100644 index 000000000000..2508c3620772 --- /dev/null +++ b/security/krb5-16/files/patch-lib::rpc::xdr_mem.c @@ -0,0 +1,136 @@ +Index: xdr_mem.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/rpc/xdr_mem.c,v +retrieving revision 1.8 +diff -c -r1.8 xdr_mem.c +*** lib/rpc/xdr_mem.c 1998/02/14 02:27:24 1.8 +--- lib/rpc/xdr_mem.c 2003/02/04 22:57:24 +*************** +*** 47,52 **** +--- 47,54 ---- + #include <gssrpc/xdr.h> + #include <netinet/in.h> + #include <stdio.h> ++ #include <string.h> ++ #include <limits.h> + + static bool_t xdrmem_getlong(); + static bool_t xdrmem_putlong(); +*************** +*** 83,89 **** + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = size; + } + + static void +--- 85,91 ---- + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ + } + + static void +*************** +*** 98,105 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 100,109 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 111,118 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 115,124 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 125,132 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +--- 131,140 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 139,146 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +--- 147,156 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 179,185 **** + { + rpc_int32 *buf = 0; + +! if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; +--- 189,195 ---- + { + rpc_int32 *buf = 0; + +! if (len >= 0 && xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; diff --git a/security/krb5-17/Makefile b/security/krb5-17/Makefile index cff9b3b0bc9a..826ca046d324 100644 --- a/security/krb5-17/Makefile +++ b/security/krb5-17/Makefile @@ -7,6 +7,7 @@ PORTNAME= krb5 PORTVERSION= 1.2.7 +PORTREVISION= 1 CATEGORIES= security .if defined(USA_RESIDENT) && ${USA_RESIDENT} == "NO" # XXX crypto-publish.org does not at this time have the krb5-1.2.7 tarball. diff --git a/security/krb5-17/files/patch-appl::telnet::libtelnet::kerberos5.c b/security/krb5-17/files/patch-appl::telnet::libtelnet::kerberos5.c new file mode 100644 index 000000000000..2115fd77a446 --- /dev/null +++ b/security/krb5-17/files/patch-appl::telnet::libtelnet::kerberos5.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c +--- appl/telnet/libtelnet/kerberos5.c 2002-03-29 00:07:09.000000000-0500 ++++ appl/telnet/libtelnet/kerberos5.c 2003-02-03 17:30:18.000000000-0500 +@@ -441,6 +441,10 @@ + * first component of a service name especially since + * the default is of length 4. + */ ++ if (krb5_princ_size(telnet_context,ticket->server) < 1) { ++ (void) strcpy(errbuf, "malformed service name"); ++ goto errout; ++ } + if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) { + char princ[256]; + strncpy(princ, diff --git a/security/krb5-17/files/patch-clients::ksu::heuristic.c b/security/krb5-17/files/patch-clients::ksu::heuristic.c new file mode 100644 index 000000000000..9a92c4eb7058 --- /dev/null +++ b/security/krb5-17/files/patch-clients::ksu::heuristic.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/clients/ksu/heuristic.c krb5-1.2.7/src/clients/ksu/heuristic.c +--- clients/ksu/heuristic.c 2003-02-03 15:24:57.000000000 -0500 ++++ clients/ksu/heuristic.c 2003-02-03 17:56:38.000000000 -0500 +@@ -355,7 +355,7 @@ + krb5_data *p2 = + krb5_princ_component(context, temp_client, j); + +- if ((p1->length != p2->length) || ++ if (!p1 || !p2 || (p1->length != p2->length) || + memcmp(p1->data,p2->data,p1->length)){ + got_one = FALSE; + break; diff --git a/security/krb5-17/files/patch-clients::ksu::krb_auth_su.c b/security/krb5-17/files/patch-clients::ksu::krb_auth_su.c new file mode 100644 index 000000000000..150551765d3d --- /dev/null +++ b/security/krb5-17/files/patch-clients::ksu::krb_auth_su.c @@ -0,0 +1,13 @@ +--- clients/ksu/krb_auth_su.c.orig Mon Dec 6 13:56:09 1999 ++++ clients/ksu/krb_auth_su.c Tue Feb 25 19:54:14 2003 +@@ -620,7 +620,9 @@ + krb5_princ_realm(context, temp_client)->length))){ + + +- if(nelem){ ++ if(nelem && ++ (krb5_princ_size(context, *client) > 0) && ++ (krb5_princ_size(context, temp_client) > 0)){ + krb5_data *p1 = + krb5_princ_component(context, *client, 0); + krb5_data *p2 = diff --git a/security/krb5-17/files/patch-include::krb5.hin b/security/krb5-17/files/patch-include::krb5.hin new file mode 100644 index 000000000000..812664fc0b0e --- /dev/null +++ b/security/krb5-17/files/patch-include::krb5.hin @@ -0,0 +1,16 @@ +Index: include/krb5.hin +=================================================================== +RCS file: /cvs/krbdev/krb5/src/include/krb5.hin,v +retrieving revision 1.94.2.5.2.17 +diff -p -u -r1.94.2.5.2.17 krb5.hin +--- include/krb5.hin 2002/04/16 23:47:53 1.94.2.5.2.17 ++++ include/krb5.hin 2003/03/19 00:38:54 +@@ -326,7 +326,7 @@ typedef krb5_const krb5_principal_data F + #define krb5_princ_size(context, princ) (princ)->length + #define krb5_princ_type(context, princ) (princ)->type + #define krb5_princ_name(context, princ) (princ)->data +-#define krb5_princ_component(context, princ,i) ((princ)->data + i) ++#define krb5_princ_component(context, princ,i) (i < krb5_princ_size(context, princ) ? ((princ)->data + i) : NULL) + + /* + * end "base-defs.h" diff --git a/security/krb5-17/files/patch-kdc::do_tgs_req.c b/security/krb5-17/files/patch-kdc::do_tgs_req.c new file mode 100644 index 000000000000..58e41c08a5e7 --- /dev/null +++ b/security/krb5-17/files/patch-kdc::do_tgs_req.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/kdc/do_tgs_req.c krb5-1.2.7/src/kdc/do_tgs_req.c +--- kdc/do_tgs_req.c 2003-02-03 15:24:58.000000000 -0500 ++++ kdc/do_tgs_req.c 2003-02-03 17:54:27.000000000 -0500 +@@ -180,7 +180,7 @@ + krb5_data *tgs_1 = + krb5_princ_component(kdc_context, tgs_server, 1); + +- if (server_1->length != tgs_1->length || ++ if (!tgs_1 || server_1->length != tgs_1->length || + memcmp(server_1->data, tgs_1->data, tgs_1->length)) { + krb5_db_free_principal(kdc_context, &server, nprincs); + find_alternate_tgs(request, &server, &more, &nprincs); diff --git a/security/krb5-17/files/patch-kdc::kdc_util.c b/security/krb5-17/files/patch-kdc::kdc_util.c new file mode 100644 index 000000000000..078a4b73c4fe --- /dev/null +++ b/security/krb5-17/files/patch-kdc::kdc_util.c @@ -0,0 +1,27 @@ +Index: kdc/kdc_util.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.c,v +retrieving revision 5.96.2.2.2.3 +diff -p -u -r5.96.2.2.2.3 kdc_util.c +--- kdc/kdc_util.c 2002/10/31 00:38:34 5.96.2.2.2.3 ++++ kdc/kdc_util.c 2003/03/19 00:39:00 +@@ -157,7 +157,8 @@ realm_compare(princ1, princ2) + krb5_boolean krb5_is_tgs_principal(principal) + krb5_principal principal; + { +- if ((krb5_princ_component(kdc_context, principal, 0)->length == ++ if (krb5_princ_size(kdc_context, principal) > 0 && ++ (krb5_princ_component(kdc_context, principal, 0)->length == + KRB5_TGS_NAME_SIZE) && + (!memcmp(krb5_princ_component(kdc_context, principal, 0)->data, + KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE))) +@@ -1195,7 +1196,8 @@ + return KRB_AP_ERR_NOT_US; + } + /* ...and that the second component matches the server realm... */ +- if ((krb5_princ_component(kdc_context, ticket->server, 1)->length != ++ if ((krb5_princ_size(kdc_context, ticket->server) <= 1) || ++ (krb5_princ_component(kdc_context, ticket->server, 1)->length != + krb5_princ_realm(kdc_context, request->server)->length) || + memcmp(krb5_princ_component(kdc_context, ticket->server, 1)->data, + krb5_princ_realm(kdc_context, request->server)->data, diff --git a/security/krb5-17/files/patch-kdc::kdc_util.h b/security/krb5-17/files/patch-kdc::kdc_util.h new file mode 100644 index 000000000000..262f3ff8cb29 --- /dev/null +++ b/security/krb5-17/files/patch-kdc::kdc_util.h @@ -0,0 +1,15 @@ +Index: kdc/kdc_util.h +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.h,v +retrieving revision 5.44.4.1 +diff -u -r5.44.4.1 kdc_util.h +--- kdc/kdc_util.h 2001/10/13 00:12:26 5.44.4.1 ++++ kdc/kdc_util.h 2002/10/15 23:32:45 +@@ -183,6 +183,7 @@ + const krb5_fulladdr *, + int is_secondary, + krb5_data **)); ++void enable_v4_crossrealm(char *); + #else + #define process_v4(foo,bar,quux,foobar) KRB5KRB_AP_ERR_BADVERSION + #endif diff --git a/security/krb5-17/files/patch-kdc::kerberos_v4.c b/security/krb5-17/files/patch-kdc::kerberos_v4.c new file mode 100644 index 000000000000..5b197f68afd9 --- /dev/null +++ b/security/krb5-17/files/patch-kdc::kerberos_v4.c @@ -0,0 +1,233 @@ +Index: kdc/kerberos_v4.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kerberos_v4.c,v +retrieving revision 5.68.2.3.2.1 +diff -u -r5.68.2.3.2.1 kerberos_v4.c +--- kdc/kerberos_v4.c 2002/08/15 21:28:54 5.68.2.3.2.1 ++++ kdc/kerberos_v4.c 2002/10/15 23:32:45 +@@ -149,7 +149,7 @@ + + void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); + void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); +-static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); ++static int set_tgtkey PROTOTYPE((char *, krb5_kvno, krb5_boolean)); + + /* Attributes converted from V5 to V4 - internal representation */ + #define V4_KDB_REQUIRES_PREAUTH 0x1 +@@ -182,6 +182,7 @@ + + static const int v4mode_table_nents = sizeof(v4mode_table)/ + sizeof(v4mode_table[0]); ++static int allow_v4_crossrealm = 0; + + void process_v4_mode(progname, string) + const char *progname; +@@ -210,6 +211,11 @@ + return; + } + ++void enable_v4_crossrealm ( char *programname) { ++ allow_v4_crossrealm = 1; ++ krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole"); ++} ++ + krb5_error_code + process_v4( pkt, client_fulladdr, is_secondary, resp) + const krb5_data *pkt; +@@ -401,6 +407,14 @@ + #define MIN5 300 + #define HR21 255 + ++/* ++ * Previously this code returned either a v4 key or a v5 key and you ++ * could tell from the enctype of the v5 key whether the v4 key was ++ * useful. Now we return both keys so the code can try both des3 and ++ * des decryption. We fail if the ticket doesn't have a v4 key. ++ * Also, note as a side effect, the v5 key is basically useless in ++ * the client case. It is still returned so the caller can free it. ++ */ + static int + kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) + char *name; /* could have wild card */ +@@ -482,8 +496,28 @@ + return(0); + } + } else { +- /* XXX yes I know this is a hardcoded search order */ +- if (krb5_dbe_find_enctype(kdc_context, &entries, ++ if ( krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && ++ krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ -1, kvno, &pkey)) { ++ lt = klog(L_KRB_PERR, ++ "KDC V4: failed to find key for %s.%s #%d", ++ name, inst, kvno); ++ krb5_db_free_principal(kdc_context, &entries, nprinc); ++ return(0); ++ } ++ } ++ ++ if (!compat_decrypt_key(pkey, k, k5key, issrv)) { ++ memcpy( &principal->key_low, k, LONGLEN); ++ memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); ++ } ++ memset(k, 0, sizeof k); ++ if (issrv) { ++ krb5_free_keyblock_contents (kdc_context, k5key); ++ if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, +@@ -504,12 +538,10 @@ + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } ++ compat_decrypt_key(pkey, k, k5key, issrv); ++ memset (k, 0, sizeof k); + } + +- if (!compat_decrypt_key(pkey, k, k5key, issrv)) { +- memcpy( &principal->key_low, k, LONGLEN); +- memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); +- } + /* convert v5's entries struct to v4's Principal struct: + * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes. + */ +@@ -746,21 +778,14 @@ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* We always issue des tickets; the 3des tickets are a broken hack*/ ++ krb_create_ticket(tk, k_flags, a_name_data.name, ++ a_name_data.instance, local_realm, ++ client_host.s_addr, (char *) session_key, ++ lifetime, kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); ++ + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -840,8 +865,15 @@ + 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, ++ if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) { ++ lt = klog(L_ERR_UNK, ++ "Cross realm ticket from %s denied by policy,", tktrlm); ++ kerb_err_reply(client, pkt, ++ KERB_ERR_PRINCIPAL_UNKNOWN, lt); ++ return; ++ } ++ if (set_tgtkey(tktrlm, kvno, 0)) { ++ lt = klog(L_ERR_UNK, + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); + /* no better error code */ +@@ -851,6 +883,19 @@ + } + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, + ad, 0); ++ if (kerno) { ++ if (set_tgtkey(tktrlm, kvno, 1)) { ++ lt = klog(L_ERR_UNK, ++ "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ", ++ tktrlm, kvno, inet_ntoa(client_host)); ++ /* 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, ++ ad, 0); ++ } + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", +@@ -916,21 +961,13 @@ + des_new_random_key(session_key); + #endif + +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* ALways issue des tickets*/ ++ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, ++ ad->prealm, client_host.s_addr, ++ (char *) session_key, lifetime, ++ kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -1138,20 +1175,22 @@ + + /* Set the key for krb_rd_req so we can check tgt */ + static int +-set_tgtkey(r, kvno) ++set_tgtkey(r, kvno, use_3des) + char *r; /* Realm for desired key */ + krb5_kvno kvno; ++ krb5_boolean use_3des; + { + int n; + static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; ++ static krb5_boolean last_use_3des = 0; + Principal p_st; + Principal *p = &p_st; + C_Block key; + krb5_keyblock k5key; + + k5key.contents = NULL; +- if (!strcmp(lastrealm, r) && last_kvno == kvno) ++ if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des) + return (KSUCCESS); + + /* log("Getting key for %s", r); */ +@@ -1173,11 +1212,12 @@ + return KFAILURE; + } + +- if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { ++ if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; + last_kvno = kvno; ++ last_use_3des = use_3des; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); diff --git a/security/krb5-17/files/patch-kdc::main.c b/security/krb5-17/files/patch-kdc::main.c new file mode 100644 index 000000000000..2e16cbece0fb --- /dev/null +++ b/security/krb5-17/files/patch-kdc::main.c @@ -0,0 +1,37 @@ +Index: kdc/main.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/main.c,v +retrieving revision 5.99.4.1 +diff -u -r5.99.4.1 main.c +--- kdc/main.c 2001/09/26 00:46:11 5.99.4.1 ++++ kdc/main.c 2002/10/15 23:32:45 +@@ -559,7 +559,7 @@ + usage(name) + char *name; + { +- fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-n]\n", name); ++ fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n", name); + return; + } + +@@ -611,7 +611,7 @@ + * Loop through the option list. Each time we encounter a realm name, + * use the previously scanned options to fill in for defaults. + */ +- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:3")) != -1) { ++ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) { + switch(c) { + case 'r': /* realm name for db */ + if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { +@@ -661,6 +661,11 @@ + v4mode = strdup(optarg); + #endif + break; ++ case 'X': ++#ifdef KRB5_KRB4_COMPAT ++ enable_v4_crossrealm(argv[0]); ++#endif ++ break; + case '3': + #ifdef ATHENA_DES3_KLUDGE + if (krb5_enctypes_list[krb5_enctypes_length-1].etype diff --git a/security/krb5-17/files/patch-krb524::cnv_tkt_skey.c b/security/krb5-17/files/patch-krb524::cnv_tkt_skey.c new file mode 100644 index 000000000000..b8204faee367 --- /dev/null +++ b/security/krb5-17/files/patch-krb524::cnv_tkt_skey.c @@ -0,0 +1,34 @@ +Index: krb524/cnv_tkt_skey.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/cnv_tkt_skey.c,v +retrieving revision 1.17.2.1.2.1 +diff -u -r1.17.2.1.2.1 cnv_tkt_skey.c +--- krb524/cnv_tkt_skey.c 2002/03/01 16:05:20 1.17.2.1.2.1 ++++ krb524/cnv_tkt_skey.c 2002/10/15 23:32:45 +@@ -173,25 +173,7 @@ + sname, + sinst, + v4_skey->contents); +- } else { +- /* Force enctype to be raw if using DES3. */ +- if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 || +- v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) +- v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; +- ret = krb_cr_tkt_krb5(v4tkt, +- 0, /* flags */ +- pname, +- pinst, +- prealm, +- *((unsigned long *)kaddr.contents), +- (char *) v5etkt->session->contents, +- lifetime, +- /* issue_data */ +- server_time, +- sname, +- sinst, +- v4_skey); +- } ++ } else abort(); + + krb5_free_enc_tkt_part(context, v5etkt); + v5tkt->enc_part2 = NULL; diff --git a/security/krb5-17/files/patch-krb524::krb524d.c b/security/krb5-17/files/patch-krb524::krb524d.c new file mode 100644 index 000000000000..5d121045582a --- /dev/null +++ b/security/krb5-17/files/patch-krb524::krb524d.c @@ -0,0 +1,89 @@ +Index: krb524/krb524d.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/krb524d.c,v +retrieving revision 1.40.4.3 +diff -u -r1.40.4.3 krb524d.c +--- krb524/krb524d.c 2002/08/29 06:48:05 1.40.4.3 ++++ krb524/krb524d.c 2002/10/15 23:32:45 +@@ -70,6 +70,7 @@ + void *handle; + + int use_keytab, use_master; ++int allow_v4_crossrealm = 0; + char *keytab = NULL; + krb5_keytab kt; + +@@ -134,7 +135,10 @@ + config_params.mask = 0; + + while (argc) { +- if (strncmp(*argv, "-k", 2) == 0) ++ if (strncmp(*argv, "-X", 2) == 0) { ++ allow_v4_crossrealm = 1; ++ } ++ else if (strncmp(*argv, "-k", 2) == 0) + use_keytab = 1; + else if (strncmp(*argv, "-m", 2) == 0) + use_master = 1; +@@ -317,7 +317,7 @@ + if (debug) + printf("V5 ticket decoded\n"); + +- if( v5tkt->server->length >= 1 ++ if( krb5_princ_size(context, v5tkt->server) >= 1 + &&krb5_princ_component(context, v5tkt->server, 0)->length == 3 + &&strncmp(krb5_princ_component(context, v5tkt->server, 0)->data, + "afs", 3) == 0) { +@@ -495,19 +499,7 @@ + &v5_service_key, NULL))) + goto error; + +- if ((ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_RAW, +- 0, /* highest kvno */ +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_LOCAL_DES3_HMAC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, ++ if ( (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES_CBC_CRC, + 0, + &v4_service_key, v4kvno))) +@@ -515,8 +507,19 @@ + + if (debug) + printf("service key retrieved\n"); ++ if ((ret = krb5_decrypt_tkt_part(context, &v5_service_key, v5tkt))) { ++ goto error; ++ } + +- ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, ++ if (!(allow_v4_crossrealm || krb5_realm_compare(context, v5tkt->server, ++ v5tkt->enc_part2->client))) { ++ret = KRB5KDC_ERR_POLICY ; ++ goto error; ++ } ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ v5tkt->enc_part2= NULL; ++ ++ ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, + &v4_service_key, + (struct sockaddr_in *)saddr); + if (ret) +@@ -532,6 +535,9 @@ + printf("v4 credentials encoded\n"); + + error: ++ if (v5tkt->enc_part2) ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ + if(v5_service_key.contents) + krb5_free_keyblock_contents(context, &v5_service_key); + if (v4_service_key.contents) +diff -ur krb5-1.2.7/src/krb524/krb524d.c krb5-1.2.7/src/krb524/krb524d.c diff --git a/security/krb5-17/files/patch-lib::kdb::keytab.c b/security/krb5-17/files/patch-lib::kdb::keytab.c new file mode 100644 index 000000000000..a77f4bc32718 --- /dev/null +++ b/security/krb5-17/files/patch-lib::kdb::keytab.c @@ -0,0 +1,86 @@ +Index: lib/kdb/keytab.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/kdb/keytab.c,v +retrieving revision 5.11.4.2 +diff -u -r5.11.4.2 keytab.c +--- lib/kdb/keytab.c 2002/08/15 21:27:34 5.11.4.2 ++++ lib/kdb/keytab.c 2002/10/15 23:32:46 +@@ -28,6 +28,8 @@ + #include "k5-int.h" + #include "kdb_kt.h" + ++static int ++is_xrealm_tgt(krb5_context, krb5_const_principal); + krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab)); + + krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal, +@@ -98,6 +100,8 @@ + krb5_db_entry db_entry; + krb5_boolean more = 0; + int n = 0; ++ int xrealm_tgt = is_xrealm_tgt(context, principal); ++ int similar; + + /* Open database */ + /* krb5_db_init(context); */ +@@ -127,16 +131,31 @@ + if (kerror) + goto error; + ++ /* For cross realm tgts, we match whatever enctype is provided; ++ * for other principals, we only match the first enctype that is ++ * found. Since the TGS and AS code do the same thing, then we ++ * will only successfully decrypt tickets we have issued.*/ + kerror = krb5_dbe_find_enctype(context, &db_entry, +- enctype, -1, kvno, &key_data); ++ xrealm_tgt?enctype:-1, ++ -1, kvno, &key_data); + if (kerror) + goto error; + ++ + kerror = krb5_dbekd_decrypt_key_data(context, master_key, + key_data, &entry->key, NULL); + if (kerror) + goto error; + ++ kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar); ++ if (kerror) ++ goto error; ++ ++ if (!similar) { ++ kerror = KRB5_KDB_NO_PERMITTED_KEY; ++ goto error; ++ } ++ + /* + * Coerce the enctype of the output keyblock in case we got an + * inexact match on the enctype; this behavior will go away when +@@ -154,3 +173,27 @@ + krb5_db_close_database(context); + return(kerror); + } ++ ++/* ++ * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT ++ * principal-- a principal with first component krbtgt and second ++ * component not equal to realm. ++ */ ++static int ++is_xrealm_tgt(krb5_context context, krb5_const_principal princ) ++{ ++ krb5_data *dat; ++ if (krb5_princ_size(context, princ) != 2) ++ return 0; ++ dat = krb5_princ_component(context, princ, 0); ++ if (strncmp("krbtgt", dat->data, dat->length) != 0) ++ return 0; ++ dat = krb5_princ_component(context, princ, 1); ++ if (dat->length != princ->realm.length) ++ return 1; ++ if (strcmp(dat->data, princ->realm.data) == 0) ++ return 0; ++ return 1; ++ ++} ++ diff --git a/security/krb5-17/files/patch-lib::krb5::keytab::file:ktf_util.c b/security/krb5-17/files/patch-lib::krb5::keytab::file:ktf_util.c new file mode 100644 index 000000000000..c97b3a3c85ae --- /dev/null +++ b/security/krb5-17/files/patch-lib::krb5::keytab::file:ktf_util.c @@ -0,0 +1,42 @@ +diff -ur krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c +--- lib/krb5/keytab/file/ktf_util.c 1999-09-24 17:19:01.000000000-0400 ++++ lib/krb5/keytab/file/ktf_util.c 2003-02-03 18:02:25.000000000-0500 +@@ -441,7 +441,7 @@ + return 0; + fail: + +- for (i = 0; i < ret_entry->principal->length; i++) { ++ for (i = 0; i < krb5_princ_size(context, ret_entry->principal); i++) { + princ = krb5_princ_component(context, ret_entry->principal, i); + if (princ->data) + free(princ->data); +@@ -498,9 +498,9 @@ + } + + if (KTVERSION(id) == KRB5_KT_VNO_1) { +- count = (krb5_int16) entry->principal->length + 1; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal) + 1; + } else { +- count = htons((u_short) entry->principal->length); ++ count = htons((u_short) krb5_princ_size(context, entry->principal)); + } + + if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) { +@@ -519,7 +519,7 @@ + goto abend; + } + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + for (i = 0; i < count; i++) { + princ = krb5_princ_component(context, entry->principal, i); + size = princ->length; +@@ -620,7 +620,7 @@ + krb5_int32 total_size, i; + krb5_error_code retval = 0; + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + + total_size = sizeof(count); + total_size += krb5_princ_realm(context, entry->principal)->length + (sizeof(krb5_int16)); diff --git a/security/krb5-17/files/patch-lib::krb5::krb::gc_frm_kdc.c b/security/krb5-17/files/patch-lib::krb5::krb::gc_frm_kdc.c new file mode 100644 index 000000000000..4ad0d8cc43c5 --- /dev/null +++ b/security/krb5-17/files/patch-lib::krb5::krb::gc_frm_kdc.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c +--- lib/krb5/krb/gc_frm_kdc.c 1999-09-24 17:19:24.000000000 -0400 ++++ lib/krb5/krb/gc_frm_kdc.c 2003-02-03 17:35:40.000000000 -0500 +@@ -347,7 +347,9 @@ + for (next_server = top_server; *next_server; next_server++) { + krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1); + krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1); +- if (realm_1->length == realm_2->length && ++ if (realm_1 != NULL && ++ realm_2 != NULL && ++ realm_1->length == realm_2->length && + !memcmp(realm_1->data, realm_2->data, realm_1->length)) { + break; + } diff --git a/security/krb5-17/files/patch-lib::krb5::krb::parse.c b/security/krb5-17/files/patch-lib::krb5::krb::parse.c new file mode 100644 index 000000000000..8eb73b24c158 --- /dev/null +++ b/security/krb5-17/files/patch-lib::krb5::krb::parse.c @@ -0,0 +1,29 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/parse.c krb5-1.2.7/src/lib/krb5/krb/parse.c +--- lib/krb5/krb/parse.c 2002-02-28 12:08:35.000000000 -0500 ++++ lib/krb5/krb/parse.c 2003-02-03 17:44:04.000000000 -0500 +@@ -173,11 +173,13 @@ + cp++; + size++; + } else if (c == COMPONENT_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + i++; + } else if (c == REALM_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + parsed_realm = cp+1; + } else +@@ -186,7 +188,8 @@ + if (parsed_realm) + krb5_princ_realm(context, principal)->length = size; + else +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + if (i + 1 != components) { + #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) + fprintf(stderr, diff --git a/security/krb5-17/files/patch-lib::krb5::krb::srv_rcache.c b/security/krb5-17/files/patch-lib::krb5::krb::srv_rcache.c new file mode 100644 index 000000000000..79e16f93110d --- /dev/null +++ b/security/krb5-17/files/patch-lib::krb5::krb::srv_rcache.c @@ -0,0 +1,12 @@ +--- lib/krb5/krb/srv_rcache.c 1999-09-24 17:19:48.000000000 -0400 ++++ lib/krb5/krb/srv_rcache.c 2003-02-03 19:29:32.000000000 -0500 +@@ -48,6 +48,9 @@ + unsigned long uid = geteuid(); + #endif + ++ if (piece == NULL) ++ return ENOMEM; ++ + rcache = (krb5_rcache) malloc(sizeof(*rcache)); + if (!rcache) + return ENOMEM; diff --git a/security/krb5-17/files/patch-lib::krb5::krb::unparse.c b/security/krb5-17/files/patch-lib::krb5::krb::unparse.c new file mode 100644 index 000000000000..690eb5febea2 --- /dev/null +++ b/security/krb5-17/files/patch-lib::krb5::krb::unparse.c @@ -0,0 +1,17 @@ +Index: lib/krb5/krb/unparse.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/unparse.c,v +retrieving revision 5.27.4.1 +diff -p -u -r5.27.4.1 unparse.c +--- lib/krb5/krb/unparse.c 2002/08/12 22:55:01 5.27.4.1 ++++ lib/krb5/krb/unparse.c 2003/03/19 00:39:02 +@@ -153,7 +153,8 @@ krb5_unparse_name_ext(context, principal + *q++ = COMPONENT_SEP; + } + +- q--; /* Back up last component separator */ ++ if (i > 0) ++ q--; /* Back up last component separator */ + *q++ = REALM_SEP; + + cp = krb5_princ_realm(context, principal)->data; diff --git a/security/krb5-17/files/patch-lib::rpc::xdr_mem.c b/security/krb5-17/files/patch-lib::rpc::xdr_mem.c new file mode 100644 index 000000000000..2508c3620772 --- /dev/null +++ b/security/krb5-17/files/patch-lib::rpc::xdr_mem.c @@ -0,0 +1,136 @@ +Index: xdr_mem.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/rpc/xdr_mem.c,v +retrieving revision 1.8 +diff -c -r1.8 xdr_mem.c +*** lib/rpc/xdr_mem.c 1998/02/14 02:27:24 1.8 +--- lib/rpc/xdr_mem.c 2003/02/04 22:57:24 +*************** +*** 47,52 **** +--- 47,54 ---- + #include <gssrpc/xdr.h> + #include <netinet/in.h> + #include <stdio.h> ++ #include <string.h> ++ #include <limits.h> + + static bool_t xdrmem_getlong(); + static bool_t xdrmem_putlong(); +*************** +*** 83,89 **** + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = size; + } + + static void +--- 85,91 ---- + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ + } + + static void +*************** +*** 98,105 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 100,109 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 111,118 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 115,124 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 125,132 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +--- 131,140 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 139,146 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +--- 147,156 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 179,185 **** + { + rpc_int32 *buf = 0; + +! if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; +--- 189,195 ---- + { + rpc_int32 *buf = 0; + +! if (len >= 0 && xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; diff --git a/security/krb5-appl/Makefile b/security/krb5-appl/Makefile index cff9b3b0bc9a..826ca046d324 100644 --- a/security/krb5-appl/Makefile +++ b/security/krb5-appl/Makefile @@ -7,6 +7,7 @@ PORTNAME= krb5 PORTVERSION= 1.2.7 +PORTREVISION= 1 CATEGORIES= security .if defined(USA_RESIDENT) && ${USA_RESIDENT} == "NO" # XXX crypto-publish.org does not at this time have the krb5-1.2.7 tarball. diff --git a/security/krb5-appl/files/patch-appl::telnet::libtelnet::kerberos5.c b/security/krb5-appl/files/patch-appl::telnet::libtelnet::kerberos5.c new file mode 100644 index 000000000000..2115fd77a446 --- /dev/null +++ b/security/krb5-appl/files/patch-appl::telnet::libtelnet::kerberos5.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c +--- appl/telnet/libtelnet/kerberos5.c 2002-03-29 00:07:09.000000000-0500 ++++ appl/telnet/libtelnet/kerberos5.c 2003-02-03 17:30:18.000000000-0500 +@@ -441,6 +441,10 @@ + * first component of a service name especially since + * the default is of length 4. + */ ++ if (krb5_princ_size(telnet_context,ticket->server) < 1) { ++ (void) strcpy(errbuf, "malformed service name"); ++ goto errout; ++ } + if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) { + char princ[256]; + strncpy(princ, diff --git a/security/krb5-appl/files/patch-clients::ksu::heuristic.c b/security/krb5-appl/files/patch-clients::ksu::heuristic.c new file mode 100644 index 000000000000..9a92c4eb7058 --- /dev/null +++ b/security/krb5-appl/files/patch-clients::ksu::heuristic.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/clients/ksu/heuristic.c krb5-1.2.7/src/clients/ksu/heuristic.c +--- clients/ksu/heuristic.c 2003-02-03 15:24:57.000000000 -0500 ++++ clients/ksu/heuristic.c 2003-02-03 17:56:38.000000000 -0500 +@@ -355,7 +355,7 @@ + krb5_data *p2 = + krb5_princ_component(context, temp_client, j); + +- if ((p1->length != p2->length) || ++ if (!p1 || !p2 || (p1->length != p2->length) || + memcmp(p1->data,p2->data,p1->length)){ + got_one = FALSE; + break; diff --git a/security/krb5-appl/files/patch-clients::ksu::krb_auth_su.c b/security/krb5-appl/files/patch-clients::ksu::krb_auth_su.c new file mode 100644 index 000000000000..150551765d3d --- /dev/null +++ b/security/krb5-appl/files/patch-clients::ksu::krb_auth_su.c @@ -0,0 +1,13 @@ +--- clients/ksu/krb_auth_su.c.orig Mon Dec 6 13:56:09 1999 ++++ clients/ksu/krb_auth_su.c Tue Feb 25 19:54:14 2003 +@@ -620,7 +620,9 @@ + krb5_princ_realm(context, temp_client)->length))){ + + +- if(nelem){ ++ if(nelem && ++ (krb5_princ_size(context, *client) > 0) && ++ (krb5_princ_size(context, temp_client) > 0)){ + krb5_data *p1 = + krb5_princ_component(context, *client, 0); + krb5_data *p2 = diff --git a/security/krb5-appl/files/patch-include::krb5.hin b/security/krb5-appl/files/patch-include::krb5.hin new file mode 100644 index 000000000000..812664fc0b0e --- /dev/null +++ b/security/krb5-appl/files/patch-include::krb5.hin @@ -0,0 +1,16 @@ +Index: include/krb5.hin +=================================================================== +RCS file: /cvs/krbdev/krb5/src/include/krb5.hin,v +retrieving revision 1.94.2.5.2.17 +diff -p -u -r1.94.2.5.2.17 krb5.hin +--- include/krb5.hin 2002/04/16 23:47:53 1.94.2.5.2.17 ++++ include/krb5.hin 2003/03/19 00:38:54 +@@ -326,7 +326,7 @@ typedef krb5_const krb5_principal_data F + #define krb5_princ_size(context, princ) (princ)->length + #define krb5_princ_type(context, princ) (princ)->type + #define krb5_princ_name(context, princ) (princ)->data +-#define krb5_princ_component(context, princ,i) ((princ)->data + i) ++#define krb5_princ_component(context, princ,i) (i < krb5_princ_size(context, princ) ? ((princ)->data + i) : NULL) + + /* + * end "base-defs.h" diff --git a/security/krb5-appl/files/patch-kdc::do_tgs_req.c b/security/krb5-appl/files/patch-kdc::do_tgs_req.c new file mode 100644 index 000000000000..58e41c08a5e7 --- /dev/null +++ b/security/krb5-appl/files/patch-kdc::do_tgs_req.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/kdc/do_tgs_req.c krb5-1.2.7/src/kdc/do_tgs_req.c +--- kdc/do_tgs_req.c 2003-02-03 15:24:58.000000000 -0500 ++++ kdc/do_tgs_req.c 2003-02-03 17:54:27.000000000 -0500 +@@ -180,7 +180,7 @@ + krb5_data *tgs_1 = + krb5_princ_component(kdc_context, tgs_server, 1); + +- if (server_1->length != tgs_1->length || ++ if (!tgs_1 || server_1->length != tgs_1->length || + memcmp(server_1->data, tgs_1->data, tgs_1->length)) { + krb5_db_free_principal(kdc_context, &server, nprincs); + find_alternate_tgs(request, &server, &more, &nprincs); diff --git a/security/krb5-appl/files/patch-kdc::kdc_util.c b/security/krb5-appl/files/patch-kdc::kdc_util.c new file mode 100644 index 000000000000..078a4b73c4fe --- /dev/null +++ b/security/krb5-appl/files/patch-kdc::kdc_util.c @@ -0,0 +1,27 @@ +Index: kdc/kdc_util.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.c,v +retrieving revision 5.96.2.2.2.3 +diff -p -u -r5.96.2.2.2.3 kdc_util.c +--- kdc/kdc_util.c 2002/10/31 00:38:34 5.96.2.2.2.3 ++++ kdc/kdc_util.c 2003/03/19 00:39:00 +@@ -157,7 +157,8 @@ realm_compare(princ1, princ2) + krb5_boolean krb5_is_tgs_principal(principal) + krb5_principal principal; + { +- if ((krb5_princ_component(kdc_context, principal, 0)->length == ++ if (krb5_princ_size(kdc_context, principal) > 0 && ++ (krb5_princ_component(kdc_context, principal, 0)->length == + KRB5_TGS_NAME_SIZE) && + (!memcmp(krb5_princ_component(kdc_context, principal, 0)->data, + KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE))) +@@ -1195,7 +1196,8 @@ + return KRB_AP_ERR_NOT_US; + } + /* ...and that the second component matches the server realm... */ +- if ((krb5_princ_component(kdc_context, ticket->server, 1)->length != ++ if ((krb5_princ_size(kdc_context, ticket->server) <= 1) || ++ (krb5_princ_component(kdc_context, ticket->server, 1)->length != + krb5_princ_realm(kdc_context, request->server)->length) || + memcmp(krb5_princ_component(kdc_context, ticket->server, 1)->data, + krb5_princ_realm(kdc_context, request->server)->data, diff --git a/security/krb5-appl/files/patch-kdc::kdc_util.h b/security/krb5-appl/files/patch-kdc::kdc_util.h new file mode 100644 index 000000000000..262f3ff8cb29 --- /dev/null +++ b/security/krb5-appl/files/patch-kdc::kdc_util.h @@ -0,0 +1,15 @@ +Index: kdc/kdc_util.h +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.h,v +retrieving revision 5.44.4.1 +diff -u -r5.44.4.1 kdc_util.h +--- kdc/kdc_util.h 2001/10/13 00:12:26 5.44.4.1 ++++ kdc/kdc_util.h 2002/10/15 23:32:45 +@@ -183,6 +183,7 @@ + const krb5_fulladdr *, + int is_secondary, + krb5_data **)); ++void enable_v4_crossrealm(char *); + #else + #define process_v4(foo,bar,quux,foobar) KRB5KRB_AP_ERR_BADVERSION + #endif diff --git a/security/krb5-appl/files/patch-kdc::kerberos_v4.c b/security/krb5-appl/files/patch-kdc::kerberos_v4.c new file mode 100644 index 000000000000..5b197f68afd9 --- /dev/null +++ b/security/krb5-appl/files/patch-kdc::kerberos_v4.c @@ -0,0 +1,233 @@ +Index: kdc/kerberos_v4.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kerberos_v4.c,v +retrieving revision 5.68.2.3.2.1 +diff -u -r5.68.2.3.2.1 kerberos_v4.c +--- kdc/kerberos_v4.c 2002/08/15 21:28:54 5.68.2.3.2.1 ++++ kdc/kerberos_v4.c 2002/10/15 23:32:45 +@@ -149,7 +149,7 @@ + + void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); + void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); +-static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); ++static int set_tgtkey PROTOTYPE((char *, krb5_kvno, krb5_boolean)); + + /* Attributes converted from V5 to V4 - internal representation */ + #define V4_KDB_REQUIRES_PREAUTH 0x1 +@@ -182,6 +182,7 @@ + + static const int v4mode_table_nents = sizeof(v4mode_table)/ + sizeof(v4mode_table[0]); ++static int allow_v4_crossrealm = 0; + + void process_v4_mode(progname, string) + const char *progname; +@@ -210,6 +211,11 @@ + return; + } + ++void enable_v4_crossrealm ( char *programname) { ++ allow_v4_crossrealm = 1; ++ krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole"); ++} ++ + krb5_error_code + process_v4( pkt, client_fulladdr, is_secondary, resp) + const krb5_data *pkt; +@@ -401,6 +407,14 @@ + #define MIN5 300 + #define HR21 255 + ++/* ++ * Previously this code returned either a v4 key or a v5 key and you ++ * could tell from the enctype of the v5 key whether the v4 key was ++ * useful. Now we return both keys so the code can try both des3 and ++ * des decryption. We fail if the ticket doesn't have a v4 key. ++ * Also, note as a side effect, the v5 key is basically useless in ++ * the client case. It is still returned so the caller can free it. ++ */ + static int + kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) + char *name; /* could have wild card */ +@@ -482,8 +496,28 @@ + return(0); + } + } else { +- /* XXX yes I know this is a hardcoded search order */ +- if (krb5_dbe_find_enctype(kdc_context, &entries, ++ if ( krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && ++ krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ -1, kvno, &pkey)) { ++ lt = klog(L_KRB_PERR, ++ "KDC V4: failed to find key for %s.%s #%d", ++ name, inst, kvno); ++ krb5_db_free_principal(kdc_context, &entries, nprinc); ++ return(0); ++ } ++ } ++ ++ if (!compat_decrypt_key(pkey, k, k5key, issrv)) { ++ memcpy( &principal->key_low, k, LONGLEN); ++ memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); ++ } ++ memset(k, 0, sizeof k); ++ if (issrv) { ++ krb5_free_keyblock_contents (kdc_context, k5key); ++ if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, +@@ -504,12 +538,10 @@ + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } ++ compat_decrypt_key(pkey, k, k5key, issrv); ++ memset (k, 0, sizeof k); + } + +- if (!compat_decrypt_key(pkey, k, k5key, issrv)) { +- memcpy( &principal->key_low, k, LONGLEN); +- memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); +- } + /* convert v5's entries struct to v4's Principal struct: + * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes. + */ +@@ -746,21 +778,14 @@ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* We always issue des tickets; the 3des tickets are a broken hack*/ ++ krb_create_ticket(tk, k_flags, a_name_data.name, ++ a_name_data.instance, local_realm, ++ client_host.s_addr, (char *) session_key, ++ lifetime, kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); ++ + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -840,8 +865,15 @@ + 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, ++ if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) { ++ lt = klog(L_ERR_UNK, ++ "Cross realm ticket from %s denied by policy,", tktrlm); ++ kerb_err_reply(client, pkt, ++ KERB_ERR_PRINCIPAL_UNKNOWN, lt); ++ return; ++ } ++ if (set_tgtkey(tktrlm, kvno, 0)) { ++ lt = klog(L_ERR_UNK, + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); + /* no better error code */ +@@ -851,6 +883,19 @@ + } + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, + ad, 0); ++ if (kerno) { ++ if (set_tgtkey(tktrlm, kvno, 1)) { ++ lt = klog(L_ERR_UNK, ++ "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ", ++ tktrlm, kvno, inet_ntoa(client_host)); ++ /* 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, ++ ad, 0); ++ } + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", +@@ -916,21 +961,13 @@ + des_new_random_key(session_key); + #endif + +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* ALways issue des tickets*/ ++ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, ++ ad->prealm, client_host.s_addr, ++ (char *) session_key, lifetime, ++ kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -1138,20 +1175,22 @@ + + /* Set the key for krb_rd_req so we can check tgt */ + static int +-set_tgtkey(r, kvno) ++set_tgtkey(r, kvno, use_3des) + char *r; /* Realm for desired key */ + krb5_kvno kvno; ++ krb5_boolean use_3des; + { + int n; + static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; ++ static krb5_boolean last_use_3des = 0; + Principal p_st; + Principal *p = &p_st; + C_Block key; + krb5_keyblock k5key; + + k5key.contents = NULL; +- if (!strcmp(lastrealm, r) && last_kvno == kvno) ++ if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des) + return (KSUCCESS); + + /* log("Getting key for %s", r); */ +@@ -1173,11 +1212,12 @@ + return KFAILURE; + } + +- if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { ++ if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; + last_kvno = kvno; ++ last_use_3des = use_3des; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); diff --git a/security/krb5-appl/files/patch-kdc::main.c b/security/krb5-appl/files/patch-kdc::main.c new file mode 100644 index 000000000000..2e16cbece0fb --- /dev/null +++ b/security/krb5-appl/files/patch-kdc::main.c @@ -0,0 +1,37 @@ +Index: kdc/main.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/main.c,v +retrieving revision 5.99.4.1 +diff -u -r5.99.4.1 main.c +--- kdc/main.c 2001/09/26 00:46:11 5.99.4.1 ++++ kdc/main.c 2002/10/15 23:32:45 +@@ -559,7 +559,7 @@ + usage(name) + char *name; + { +- fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-n]\n", name); ++ fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n", name); + return; + } + +@@ -611,7 +611,7 @@ + * Loop through the option list. Each time we encounter a realm name, + * use the previously scanned options to fill in for defaults. + */ +- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:3")) != -1) { ++ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) { + switch(c) { + case 'r': /* realm name for db */ + if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { +@@ -661,6 +661,11 @@ + v4mode = strdup(optarg); + #endif + break; ++ case 'X': ++#ifdef KRB5_KRB4_COMPAT ++ enable_v4_crossrealm(argv[0]); ++#endif ++ break; + case '3': + #ifdef ATHENA_DES3_KLUDGE + if (krb5_enctypes_list[krb5_enctypes_length-1].etype diff --git a/security/krb5-appl/files/patch-krb524::cnv_tkt_skey.c b/security/krb5-appl/files/patch-krb524::cnv_tkt_skey.c new file mode 100644 index 000000000000..b8204faee367 --- /dev/null +++ b/security/krb5-appl/files/patch-krb524::cnv_tkt_skey.c @@ -0,0 +1,34 @@ +Index: krb524/cnv_tkt_skey.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/cnv_tkt_skey.c,v +retrieving revision 1.17.2.1.2.1 +diff -u -r1.17.2.1.2.1 cnv_tkt_skey.c +--- krb524/cnv_tkt_skey.c 2002/03/01 16:05:20 1.17.2.1.2.1 ++++ krb524/cnv_tkt_skey.c 2002/10/15 23:32:45 +@@ -173,25 +173,7 @@ + sname, + sinst, + v4_skey->contents); +- } else { +- /* Force enctype to be raw if using DES3. */ +- if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 || +- v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) +- v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; +- ret = krb_cr_tkt_krb5(v4tkt, +- 0, /* flags */ +- pname, +- pinst, +- prealm, +- *((unsigned long *)kaddr.contents), +- (char *) v5etkt->session->contents, +- lifetime, +- /* issue_data */ +- server_time, +- sname, +- sinst, +- v4_skey); +- } ++ } else abort(); + + krb5_free_enc_tkt_part(context, v5etkt); + v5tkt->enc_part2 = NULL; diff --git a/security/krb5-appl/files/patch-krb524::krb524d.c b/security/krb5-appl/files/patch-krb524::krb524d.c new file mode 100644 index 000000000000..5d121045582a --- /dev/null +++ b/security/krb5-appl/files/patch-krb524::krb524d.c @@ -0,0 +1,89 @@ +Index: krb524/krb524d.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/krb524d.c,v +retrieving revision 1.40.4.3 +diff -u -r1.40.4.3 krb524d.c +--- krb524/krb524d.c 2002/08/29 06:48:05 1.40.4.3 ++++ krb524/krb524d.c 2002/10/15 23:32:45 +@@ -70,6 +70,7 @@ + void *handle; + + int use_keytab, use_master; ++int allow_v4_crossrealm = 0; + char *keytab = NULL; + krb5_keytab kt; + +@@ -134,7 +135,10 @@ + config_params.mask = 0; + + while (argc) { +- if (strncmp(*argv, "-k", 2) == 0) ++ if (strncmp(*argv, "-X", 2) == 0) { ++ allow_v4_crossrealm = 1; ++ } ++ else if (strncmp(*argv, "-k", 2) == 0) + use_keytab = 1; + else if (strncmp(*argv, "-m", 2) == 0) + use_master = 1; +@@ -317,7 +317,7 @@ + if (debug) + printf("V5 ticket decoded\n"); + +- if( v5tkt->server->length >= 1 ++ if( krb5_princ_size(context, v5tkt->server) >= 1 + &&krb5_princ_component(context, v5tkt->server, 0)->length == 3 + &&strncmp(krb5_princ_component(context, v5tkt->server, 0)->data, + "afs", 3) == 0) { +@@ -495,19 +499,7 @@ + &v5_service_key, NULL))) + goto error; + +- if ((ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_RAW, +- 0, /* highest kvno */ +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_LOCAL_DES3_HMAC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, ++ if ( (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES_CBC_CRC, + 0, + &v4_service_key, v4kvno))) +@@ -515,8 +507,19 @@ + + if (debug) + printf("service key retrieved\n"); ++ if ((ret = krb5_decrypt_tkt_part(context, &v5_service_key, v5tkt))) { ++ goto error; ++ } + +- ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, ++ if (!(allow_v4_crossrealm || krb5_realm_compare(context, v5tkt->server, ++ v5tkt->enc_part2->client))) { ++ret = KRB5KDC_ERR_POLICY ; ++ goto error; ++ } ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ v5tkt->enc_part2= NULL; ++ ++ ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, + &v4_service_key, + (struct sockaddr_in *)saddr); + if (ret) +@@ -532,6 +535,9 @@ + printf("v4 credentials encoded\n"); + + error: ++ if (v5tkt->enc_part2) ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ + if(v5_service_key.contents) + krb5_free_keyblock_contents(context, &v5_service_key); + if (v4_service_key.contents) +diff -ur krb5-1.2.7/src/krb524/krb524d.c krb5-1.2.7/src/krb524/krb524d.c diff --git a/security/krb5-appl/files/patch-lib::kdb::keytab.c b/security/krb5-appl/files/patch-lib::kdb::keytab.c new file mode 100644 index 000000000000..a77f4bc32718 --- /dev/null +++ b/security/krb5-appl/files/patch-lib::kdb::keytab.c @@ -0,0 +1,86 @@ +Index: lib/kdb/keytab.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/kdb/keytab.c,v +retrieving revision 5.11.4.2 +diff -u -r5.11.4.2 keytab.c +--- lib/kdb/keytab.c 2002/08/15 21:27:34 5.11.4.2 ++++ lib/kdb/keytab.c 2002/10/15 23:32:46 +@@ -28,6 +28,8 @@ + #include "k5-int.h" + #include "kdb_kt.h" + ++static int ++is_xrealm_tgt(krb5_context, krb5_const_principal); + krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab)); + + krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal, +@@ -98,6 +100,8 @@ + krb5_db_entry db_entry; + krb5_boolean more = 0; + int n = 0; ++ int xrealm_tgt = is_xrealm_tgt(context, principal); ++ int similar; + + /* Open database */ + /* krb5_db_init(context); */ +@@ -127,16 +131,31 @@ + if (kerror) + goto error; + ++ /* For cross realm tgts, we match whatever enctype is provided; ++ * for other principals, we only match the first enctype that is ++ * found. Since the TGS and AS code do the same thing, then we ++ * will only successfully decrypt tickets we have issued.*/ + kerror = krb5_dbe_find_enctype(context, &db_entry, +- enctype, -1, kvno, &key_data); ++ xrealm_tgt?enctype:-1, ++ -1, kvno, &key_data); + if (kerror) + goto error; + ++ + kerror = krb5_dbekd_decrypt_key_data(context, master_key, + key_data, &entry->key, NULL); + if (kerror) + goto error; + ++ kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar); ++ if (kerror) ++ goto error; ++ ++ if (!similar) { ++ kerror = KRB5_KDB_NO_PERMITTED_KEY; ++ goto error; ++ } ++ + /* + * Coerce the enctype of the output keyblock in case we got an + * inexact match on the enctype; this behavior will go away when +@@ -154,3 +173,27 @@ + krb5_db_close_database(context); + return(kerror); + } ++ ++/* ++ * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT ++ * principal-- a principal with first component krbtgt and second ++ * component not equal to realm. ++ */ ++static int ++is_xrealm_tgt(krb5_context context, krb5_const_principal princ) ++{ ++ krb5_data *dat; ++ if (krb5_princ_size(context, princ) != 2) ++ return 0; ++ dat = krb5_princ_component(context, princ, 0); ++ if (strncmp("krbtgt", dat->data, dat->length) != 0) ++ return 0; ++ dat = krb5_princ_component(context, princ, 1); ++ if (dat->length != princ->realm.length) ++ return 1; ++ if (strcmp(dat->data, princ->realm.data) == 0) ++ return 0; ++ return 1; ++ ++} ++ diff --git a/security/krb5-appl/files/patch-lib::krb5::keytab::file:ktf_util.c b/security/krb5-appl/files/patch-lib::krb5::keytab::file:ktf_util.c new file mode 100644 index 000000000000..c97b3a3c85ae --- /dev/null +++ b/security/krb5-appl/files/patch-lib::krb5::keytab::file:ktf_util.c @@ -0,0 +1,42 @@ +diff -ur krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c +--- lib/krb5/keytab/file/ktf_util.c 1999-09-24 17:19:01.000000000-0400 ++++ lib/krb5/keytab/file/ktf_util.c 2003-02-03 18:02:25.000000000-0500 +@@ -441,7 +441,7 @@ + return 0; + fail: + +- for (i = 0; i < ret_entry->principal->length; i++) { ++ for (i = 0; i < krb5_princ_size(context, ret_entry->principal); i++) { + princ = krb5_princ_component(context, ret_entry->principal, i); + if (princ->data) + free(princ->data); +@@ -498,9 +498,9 @@ + } + + if (KTVERSION(id) == KRB5_KT_VNO_1) { +- count = (krb5_int16) entry->principal->length + 1; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal) + 1; + } else { +- count = htons((u_short) entry->principal->length); ++ count = htons((u_short) krb5_princ_size(context, entry->principal)); + } + + if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) { +@@ -519,7 +519,7 @@ + goto abend; + } + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + for (i = 0; i < count; i++) { + princ = krb5_princ_component(context, entry->principal, i); + size = princ->length; +@@ -620,7 +620,7 @@ + krb5_int32 total_size, i; + krb5_error_code retval = 0; + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + + total_size = sizeof(count); + total_size += krb5_princ_realm(context, entry->principal)->length + (sizeof(krb5_int16)); diff --git a/security/krb5-appl/files/patch-lib::krb5::krb::gc_frm_kdc.c b/security/krb5-appl/files/patch-lib::krb5::krb::gc_frm_kdc.c new file mode 100644 index 000000000000..4ad0d8cc43c5 --- /dev/null +++ b/security/krb5-appl/files/patch-lib::krb5::krb::gc_frm_kdc.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c +--- lib/krb5/krb/gc_frm_kdc.c 1999-09-24 17:19:24.000000000 -0400 ++++ lib/krb5/krb/gc_frm_kdc.c 2003-02-03 17:35:40.000000000 -0500 +@@ -347,7 +347,9 @@ + for (next_server = top_server; *next_server; next_server++) { + krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1); + krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1); +- if (realm_1->length == realm_2->length && ++ if (realm_1 != NULL && ++ realm_2 != NULL && ++ realm_1->length == realm_2->length && + !memcmp(realm_1->data, realm_2->data, realm_1->length)) { + break; + } diff --git a/security/krb5-appl/files/patch-lib::krb5::krb::parse.c b/security/krb5-appl/files/patch-lib::krb5::krb::parse.c new file mode 100644 index 000000000000..8eb73b24c158 --- /dev/null +++ b/security/krb5-appl/files/patch-lib::krb5::krb::parse.c @@ -0,0 +1,29 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/parse.c krb5-1.2.7/src/lib/krb5/krb/parse.c +--- lib/krb5/krb/parse.c 2002-02-28 12:08:35.000000000 -0500 ++++ lib/krb5/krb/parse.c 2003-02-03 17:44:04.000000000 -0500 +@@ -173,11 +173,13 @@ + cp++; + size++; + } else if (c == COMPONENT_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + i++; + } else if (c == REALM_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + parsed_realm = cp+1; + } else +@@ -186,7 +188,8 @@ + if (parsed_realm) + krb5_princ_realm(context, principal)->length = size; + else +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + if (i + 1 != components) { + #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) + fprintf(stderr, diff --git a/security/krb5-appl/files/patch-lib::krb5::krb::srv_rcache.c b/security/krb5-appl/files/patch-lib::krb5::krb::srv_rcache.c new file mode 100644 index 000000000000..79e16f93110d --- /dev/null +++ b/security/krb5-appl/files/patch-lib::krb5::krb::srv_rcache.c @@ -0,0 +1,12 @@ +--- lib/krb5/krb/srv_rcache.c 1999-09-24 17:19:48.000000000 -0400 ++++ lib/krb5/krb/srv_rcache.c 2003-02-03 19:29:32.000000000 -0500 +@@ -48,6 +48,9 @@ + unsigned long uid = geteuid(); + #endif + ++ if (piece == NULL) ++ return ENOMEM; ++ + rcache = (krb5_rcache) malloc(sizeof(*rcache)); + if (!rcache) + return ENOMEM; diff --git a/security/krb5-appl/files/patch-lib::krb5::krb::unparse.c b/security/krb5-appl/files/patch-lib::krb5::krb::unparse.c new file mode 100644 index 000000000000..690eb5febea2 --- /dev/null +++ b/security/krb5-appl/files/patch-lib::krb5::krb::unparse.c @@ -0,0 +1,17 @@ +Index: lib/krb5/krb/unparse.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/unparse.c,v +retrieving revision 5.27.4.1 +diff -p -u -r5.27.4.1 unparse.c +--- lib/krb5/krb/unparse.c 2002/08/12 22:55:01 5.27.4.1 ++++ lib/krb5/krb/unparse.c 2003/03/19 00:39:02 +@@ -153,7 +153,8 @@ krb5_unparse_name_ext(context, principal + *q++ = COMPONENT_SEP; + } + +- q--; /* Back up last component separator */ ++ if (i > 0) ++ q--; /* Back up last component separator */ + *q++ = REALM_SEP; + + cp = krb5_princ_realm(context, principal)->data; diff --git a/security/krb5-appl/files/patch-lib::rpc::xdr_mem.c b/security/krb5-appl/files/patch-lib::rpc::xdr_mem.c new file mode 100644 index 000000000000..2508c3620772 --- /dev/null +++ b/security/krb5-appl/files/patch-lib::rpc::xdr_mem.c @@ -0,0 +1,136 @@ +Index: xdr_mem.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/rpc/xdr_mem.c,v +retrieving revision 1.8 +diff -c -r1.8 xdr_mem.c +*** lib/rpc/xdr_mem.c 1998/02/14 02:27:24 1.8 +--- lib/rpc/xdr_mem.c 2003/02/04 22:57:24 +*************** +*** 47,52 **** +--- 47,54 ---- + #include <gssrpc/xdr.h> + #include <netinet/in.h> + #include <stdio.h> ++ #include <string.h> ++ #include <limits.h> + + static bool_t xdrmem_getlong(); + static bool_t xdrmem_putlong(); +*************** +*** 83,89 **** + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = size; + } + + static void +--- 85,91 ---- + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ + } + + static void +*************** +*** 98,105 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 100,109 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 111,118 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 115,124 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 125,132 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +--- 131,140 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 139,146 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +--- 147,156 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 179,185 **** + { + rpc_int32 *buf = 0; + +! if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; +--- 189,195 ---- + { + rpc_int32 *buf = 0; + +! if (len >= 0 && xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; diff --git a/security/krb5/Makefile b/security/krb5/Makefile index cff9b3b0bc9a..826ca046d324 100644 --- a/security/krb5/Makefile +++ b/security/krb5/Makefile @@ -7,6 +7,7 @@ PORTNAME= krb5 PORTVERSION= 1.2.7 +PORTREVISION= 1 CATEGORIES= security .if defined(USA_RESIDENT) && ${USA_RESIDENT} == "NO" # XXX crypto-publish.org does not at this time have the krb5-1.2.7 tarball. diff --git a/security/krb5/files/patch-appl::telnet::libtelnet::kerberos5.c b/security/krb5/files/patch-appl::telnet::libtelnet::kerberos5.c new file mode 100644 index 000000000000..2115fd77a446 --- /dev/null +++ b/security/krb5/files/patch-appl::telnet::libtelnet::kerberos5.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c krb5-1.2.7/src/appl/telnet/libtelnet/kerberos5.c +--- appl/telnet/libtelnet/kerberos5.c 2002-03-29 00:07:09.000000000-0500 ++++ appl/telnet/libtelnet/kerberos5.c 2003-02-03 17:30:18.000000000-0500 +@@ -441,6 +441,10 @@ + * first component of a service name especially since + * the default is of length 4. + */ ++ if (krb5_princ_size(telnet_context,ticket->server) < 1) { ++ (void) strcpy(errbuf, "malformed service name"); ++ goto errout; ++ } + if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) { + char princ[256]; + strncpy(princ, diff --git a/security/krb5/files/patch-clients::ksu::heuristic.c b/security/krb5/files/patch-clients::ksu::heuristic.c new file mode 100644 index 000000000000..9a92c4eb7058 --- /dev/null +++ b/security/krb5/files/patch-clients::ksu::heuristic.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/clients/ksu/heuristic.c krb5-1.2.7/src/clients/ksu/heuristic.c +--- clients/ksu/heuristic.c 2003-02-03 15:24:57.000000000 -0500 ++++ clients/ksu/heuristic.c 2003-02-03 17:56:38.000000000 -0500 +@@ -355,7 +355,7 @@ + krb5_data *p2 = + krb5_princ_component(context, temp_client, j); + +- if ((p1->length != p2->length) || ++ if (!p1 || !p2 || (p1->length != p2->length) || + memcmp(p1->data,p2->data,p1->length)){ + got_one = FALSE; + break; diff --git a/security/krb5/files/patch-clients::ksu::krb_auth_su.c b/security/krb5/files/patch-clients::ksu::krb_auth_su.c new file mode 100644 index 000000000000..150551765d3d --- /dev/null +++ b/security/krb5/files/patch-clients::ksu::krb_auth_su.c @@ -0,0 +1,13 @@ +--- clients/ksu/krb_auth_su.c.orig Mon Dec 6 13:56:09 1999 ++++ clients/ksu/krb_auth_su.c Tue Feb 25 19:54:14 2003 +@@ -620,7 +620,9 @@ + krb5_princ_realm(context, temp_client)->length))){ + + +- if(nelem){ ++ if(nelem && ++ (krb5_princ_size(context, *client) > 0) && ++ (krb5_princ_size(context, temp_client) > 0)){ + krb5_data *p1 = + krb5_princ_component(context, *client, 0); + krb5_data *p2 = diff --git a/security/krb5/files/patch-include::krb5.hin b/security/krb5/files/patch-include::krb5.hin new file mode 100644 index 000000000000..812664fc0b0e --- /dev/null +++ b/security/krb5/files/patch-include::krb5.hin @@ -0,0 +1,16 @@ +Index: include/krb5.hin +=================================================================== +RCS file: /cvs/krbdev/krb5/src/include/krb5.hin,v +retrieving revision 1.94.2.5.2.17 +diff -p -u -r1.94.2.5.2.17 krb5.hin +--- include/krb5.hin 2002/04/16 23:47:53 1.94.2.5.2.17 ++++ include/krb5.hin 2003/03/19 00:38:54 +@@ -326,7 +326,7 @@ typedef krb5_const krb5_principal_data F + #define krb5_princ_size(context, princ) (princ)->length + #define krb5_princ_type(context, princ) (princ)->type + #define krb5_princ_name(context, princ) (princ)->data +-#define krb5_princ_component(context, princ,i) ((princ)->data + i) ++#define krb5_princ_component(context, princ,i) (i < krb5_princ_size(context, princ) ? ((princ)->data + i) : NULL) + + /* + * end "base-defs.h" diff --git a/security/krb5/files/patch-kdc::do_tgs_req.c b/security/krb5/files/patch-kdc::do_tgs_req.c new file mode 100644 index 000000000000..58e41c08a5e7 --- /dev/null +++ b/security/krb5/files/patch-kdc::do_tgs_req.c @@ -0,0 +1,12 @@ +diff -ur krb5-1.2.7/src/kdc/do_tgs_req.c krb5-1.2.7/src/kdc/do_tgs_req.c +--- kdc/do_tgs_req.c 2003-02-03 15:24:58.000000000 -0500 ++++ kdc/do_tgs_req.c 2003-02-03 17:54:27.000000000 -0500 +@@ -180,7 +180,7 @@ + krb5_data *tgs_1 = + krb5_princ_component(kdc_context, tgs_server, 1); + +- if (server_1->length != tgs_1->length || ++ if (!tgs_1 || server_1->length != tgs_1->length || + memcmp(server_1->data, tgs_1->data, tgs_1->length)) { + krb5_db_free_principal(kdc_context, &server, nprincs); + find_alternate_tgs(request, &server, &more, &nprincs); diff --git a/security/krb5/files/patch-kdc::kdc_util.c b/security/krb5/files/patch-kdc::kdc_util.c new file mode 100644 index 000000000000..078a4b73c4fe --- /dev/null +++ b/security/krb5/files/patch-kdc::kdc_util.c @@ -0,0 +1,27 @@ +Index: kdc/kdc_util.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.c,v +retrieving revision 5.96.2.2.2.3 +diff -p -u -r5.96.2.2.2.3 kdc_util.c +--- kdc/kdc_util.c 2002/10/31 00:38:34 5.96.2.2.2.3 ++++ kdc/kdc_util.c 2003/03/19 00:39:00 +@@ -157,7 +157,8 @@ realm_compare(princ1, princ2) + krb5_boolean krb5_is_tgs_principal(principal) + krb5_principal principal; + { +- if ((krb5_princ_component(kdc_context, principal, 0)->length == ++ if (krb5_princ_size(kdc_context, principal) > 0 && ++ (krb5_princ_component(kdc_context, principal, 0)->length == + KRB5_TGS_NAME_SIZE) && + (!memcmp(krb5_princ_component(kdc_context, principal, 0)->data, + KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE))) +@@ -1195,7 +1196,8 @@ + return KRB_AP_ERR_NOT_US; + } + /* ...and that the second component matches the server realm... */ +- if ((krb5_princ_component(kdc_context, ticket->server, 1)->length != ++ if ((krb5_princ_size(kdc_context, ticket->server) <= 1) || ++ (krb5_princ_component(kdc_context, ticket->server, 1)->length != + krb5_princ_realm(kdc_context, request->server)->length) || + memcmp(krb5_princ_component(kdc_context, ticket->server, 1)->data, + krb5_princ_realm(kdc_context, request->server)->data, diff --git a/security/krb5/files/patch-kdc::kdc_util.h b/security/krb5/files/patch-kdc::kdc_util.h new file mode 100644 index 000000000000..262f3ff8cb29 --- /dev/null +++ b/security/krb5/files/patch-kdc::kdc_util.h @@ -0,0 +1,15 @@ +Index: kdc/kdc_util.h +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kdc_util.h,v +retrieving revision 5.44.4.1 +diff -u -r5.44.4.1 kdc_util.h +--- kdc/kdc_util.h 2001/10/13 00:12:26 5.44.4.1 ++++ kdc/kdc_util.h 2002/10/15 23:32:45 +@@ -183,6 +183,7 @@ + const krb5_fulladdr *, + int is_secondary, + krb5_data **)); ++void enable_v4_crossrealm(char *); + #else + #define process_v4(foo,bar,quux,foobar) KRB5KRB_AP_ERR_BADVERSION + #endif diff --git a/security/krb5/files/patch-kdc::kerberos_v4.c b/security/krb5/files/patch-kdc::kerberos_v4.c new file mode 100644 index 000000000000..5b197f68afd9 --- /dev/null +++ b/security/krb5/files/patch-kdc::kerberos_v4.c @@ -0,0 +1,233 @@ +Index: kdc/kerberos_v4.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/kerberos_v4.c,v +retrieving revision 5.68.2.3.2.1 +diff -u -r5.68.2.3.2.1 kerberos_v4.c +--- kdc/kerberos_v4.c 2002/08/15 21:28:54 5.68.2.3.2.1 ++++ kdc/kerberos_v4.c 2002/10/15 23:32:45 +@@ -149,7 +149,7 @@ + + void kerberos_v4 PROTOTYPE((struct sockaddr_in *, KTEXT)); + void kerb_err_reply PROTOTYPE((struct sockaddr_in *, KTEXT, long, char *)); +-static int set_tgtkey PROTOTYPE((char *, krb5_kvno)); ++static int set_tgtkey PROTOTYPE((char *, krb5_kvno, krb5_boolean)); + + /* Attributes converted from V5 to V4 - internal representation */ + #define V4_KDB_REQUIRES_PREAUTH 0x1 +@@ -182,6 +182,7 @@ + + static const int v4mode_table_nents = sizeof(v4mode_table)/ + sizeof(v4mode_table[0]); ++static int allow_v4_crossrealm = 0; + + void process_v4_mode(progname, string) + const char *progname; +@@ -210,6 +211,11 @@ + return; + } + ++void enable_v4_crossrealm ( char *programname) { ++ allow_v4_crossrealm = 1; ++ krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole"); ++} ++ + krb5_error_code + process_v4( pkt, client_fulladdr, is_secondary, resp) + const krb5_data *pkt; +@@ -401,6 +407,14 @@ + #define MIN5 300 + #define HR21 255 + ++/* ++ * Previously this code returned either a v4 key or a v5 key and you ++ * could tell from the enctype of the v5 key whether the v4 key was ++ * useful. Now we return both keys so the code can try both des3 and ++ * des decryption. We fail if the ticket doesn't have a v4 key. ++ * Also, note as a side effect, the v5 key is basically useless in ++ * the client case. It is still returned so the caller can free it. ++ */ + static int + kerb_get_principal(name, inst, principal, maxn, more, k5key, kvno, issrv) + char *name; /* could have wild card */ +@@ -482,8 +496,28 @@ + return(0); + } + } else { +- /* XXX yes I know this is a hardcoded search order */ +- if (krb5_dbe_find_enctype(kdc_context, &entries, ++ if ( krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ KRB5_KDB_SALTTYPE_V4, kvno, &pkey) && ++ krb5_dbe_find_enctype(kdc_context, &entries, ++ ENCTYPE_DES_CBC_CRC, ++ -1, kvno, &pkey)) { ++ lt = klog(L_KRB_PERR, ++ "KDC V4: failed to find key for %s.%s #%d", ++ name, inst, kvno); ++ krb5_db_free_principal(kdc_context, &entries, nprinc); ++ return(0); ++ } ++ } ++ ++ if (!compat_decrypt_key(pkey, k, k5key, issrv)) { ++ memcpy( &principal->key_low, k, LONGLEN); ++ memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); ++ } ++ memset(k, 0, sizeof k); ++ if (issrv) { ++ krb5_free_keyblock_contents (kdc_context, k5key); ++ if (krb5_dbe_find_enctype(kdc_context, &entries, + ENCTYPE_DES3_CBC_RAW, + -1, kvno, &pkey) && + krb5_dbe_find_enctype(kdc_context, &entries, +@@ -504,12 +538,10 @@ + krb5_db_free_principal(kdc_context, &entries, nprinc); + return(0); + } ++ compat_decrypt_key(pkey, k, k5key, issrv); ++ memset (k, 0, sizeof k); + } + +- if (!compat_decrypt_key(pkey, k, k5key, issrv)) { +- memcpy( &principal->key_low, k, LONGLEN); +- memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN); +- } + /* convert v5's entries struct to v4's Principal struct: + * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes. + */ +@@ -746,21 +778,14 @@ + kdb_encrypt_key(key, key, master_key, + master_key_schedule, DECRYPT); + /* construct and seal the ticket */ +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, a_name_data.name, +- a_name_data.instance, local_realm, +- client_host.s_addr, (char *) session_key, +- lifetime, kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* We always issue des tickets; the 3des tickets are a broken hack*/ ++ krb_create_ticket(tk, k_flags, a_name_data.name, ++ a_name_data.instance, local_realm, ++ client_host.s_addr, (char *) session_key, ++ lifetime, kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); ++ + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -840,8 +865,15 @@ + 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, ++ if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) { ++ lt = klog(L_ERR_UNK, ++ "Cross realm ticket from %s denied by policy,", tktrlm); ++ kerb_err_reply(client, pkt, ++ KERB_ERR_PRINCIPAL_UNKNOWN, lt); ++ return; ++ } ++ if (set_tgtkey(tktrlm, kvno, 0)) { ++ lt = klog(L_ERR_UNK, + "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", + tktrlm, kvno, inet_ntoa(client_host)); + /* no better error code */ +@@ -851,6 +883,19 @@ + } + kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, + ad, 0); ++ if (kerno) { ++ if (set_tgtkey(tktrlm, kvno, 1)) { ++ lt = klog(L_ERR_UNK, ++ "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ", ++ tktrlm, kvno, inet_ntoa(client_host)); ++ /* 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, ++ ad, 0); ++ } + + if (kerno) { + klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", +@@ -916,21 +961,13 @@ + des_new_random_key(session_key); + #endif + +- if (K4KDC_ENCTYPE_OK(k5key.enctype)) { +- krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- key); +- } else { +- krb_cr_tkt_krb5(tk, k_flags, ad->pname, ad->pinst, +- ad->prealm, client_host.s_addr, +- (char *) session_key, lifetime, +- kerb_time.tv_sec, +- s_name_data.name, s_name_data.instance, +- &k5key); +- } ++ /* ALways issue des tickets*/ ++ krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, ++ ad->prealm, client_host.s_addr, ++ (char *) session_key, lifetime, ++ kerb_time.tv_sec, ++ s_name_data.name, s_name_data.instance, ++ key); + krb5_free_keyblock_contents(kdc_context, &k5key); + memset(key, 0, sizeof(key)); + memset(key_s, 0, sizeof(key_s)); +@@ -1138,20 +1175,22 @@ + + /* Set the key for krb_rd_req so we can check tgt */ + static int +-set_tgtkey(r, kvno) ++set_tgtkey(r, kvno, use_3des) + char *r; /* Realm for desired key */ + krb5_kvno kvno; ++ krb5_boolean use_3des; + { + int n; + static char lastrealm[REALM_SZ] = ""; + static int last_kvno = 0; ++ static krb5_boolean last_use_3des = 0; + Principal p_st; + Principal *p = &p_st; + C_Block key; + krb5_keyblock k5key; + + k5key.contents = NULL; +- if (!strcmp(lastrealm, r) && last_kvno == kvno) ++ if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des) + return (KSUCCESS); + + /* log("Getting key for %s", r); */ +@@ -1173,11 +1212,12 @@ + return KFAILURE; + } + +- if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { ++ if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) { + krb_set_key_krb5(kdc_context, &k5key); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; + last_kvno = kvno; ++ last_use_3des = use_3des; + } else { + /* unseal tgt key from master key */ + memcpy(key, &p->key_low, 4); diff --git a/security/krb5/files/patch-kdc::main.c b/security/krb5/files/patch-kdc::main.c new file mode 100644 index 000000000000..2e16cbece0fb --- /dev/null +++ b/security/krb5/files/patch-kdc::main.c @@ -0,0 +1,37 @@ +Index: kdc/main.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/kdc/main.c,v +retrieving revision 5.99.4.1 +diff -u -r5.99.4.1 main.c +--- kdc/main.c 2001/09/26 00:46:11 5.99.4.1 ++++ kdc/main.c 2002/10/15 23:32:45 +@@ -559,7 +559,7 @@ + usage(name) + char *name; + { +- fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-n]\n", name); ++ fprintf(stderr, "usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n", name); + return; + } + +@@ -611,7 +611,7 @@ + * Loop through the option list. Each time we encounter a realm name, + * use the previously scanned options to fill in for defaults. + */ +- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:3")) != -1) { ++ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) { + switch(c) { + case 'r': /* realm name for db */ + if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { +@@ -661,6 +661,11 @@ + v4mode = strdup(optarg); + #endif + break; ++ case 'X': ++#ifdef KRB5_KRB4_COMPAT ++ enable_v4_crossrealm(argv[0]); ++#endif ++ break; + case '3': + #ifdef ATHENA_DES3_KLUDGE + if (krb5_enctypes_list[krb5_enctypes_length-1].etype diff --git a/security/krb5/files/patch-krb524::cnv_tkt_skey.c b/security/krb5/files/patch-krb524::cnv_tkt_skey.c new file mode 100644 index 000000000000..b8204faee367 --- /dev/null +++ b/security/krb5/files/patch-krb524::cnv_tkt_skey.c @@ -0,0 +1,34 @@ +Index: krb524/cnv_tkt_skey.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/cnv_tkt_skey.c,v +retrieving revision 1.17.2.1.2.1 +diff -u -r1.17.2.1.2.1 cnv_tkt_skey.c +--- krb524/cnv_tkt_skey.c 2002/03/01 16:05:20 1.17.2.1.2.1 ++++ krb524/cnv_tkt_skey.c 2002/10/15 23:32:45 +@@ -173,25 +173,7 @@ + sname, + sinst, + v4_skey->contents); +- } else { +- /* Force enctype to be raw if using DES3. */ +- if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 || +- v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1) +- v4_skey->enctype = ENCTYPE_DES3_CBC_RAW; +- ret = krb_cr_tkt_krb5(v4tkt, +- 0, /* flags */ +- pname, +- pinst, +- prealm, +- *((unsigned long *)kaddr.contents), +- (char *) v5etkt->session->contents, +- lifetime, +- /* issue_data */ +- server_time, +- sname, +- sinst, +- v4_skey); +- } ++ } else abort(); + + krb5_free_enc_tkt_part(context, v5etkt); + v5tkt->enc_part2 = NULL; diff --git a/security/krb5/files/patch-krb524::krb524d.c b/security/krb5/files/patch-krb524::krb524d.c new file mode 100644 index 000000000000..5d121045582a --- /dev/null +++ b/security/krb5/files/patch-krb524::krb524d.c @@ -0,0 +1,89 @@ +Index: krb524/krb524d.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/krb524/krb524d.c,v +retrieving revision 1.40.4.3 +diff -u -r1.40.4.3 krb524d.c +--- krb524/krb524d.c 2002/08/29 06:48:05 1.40.4.3 ++++ krb524/krb524d.c 2002/10/15 23:32:45 +@@ -70,6 +70,7 @@ + void *handle; + + int use_keytab, use_master; ++int allow_v4_crossrealm = 0; + char *keytab = NULL; + krb5_keytab kt; + +@@ -134,7 +135,10 @@ + config_params.mask = 0; + + while (argc) { +- if (strncmp(*argv, "-k", 2) == 0) ++ if (strncmp(*argv, "-X", 2) == 0) { ++ allow_v4_crossrealm = 1; ++ } ++ else if (strncmp(*argv, "-k", 2) == 0) + use_keytab = 1; + else if (strncmp(*argv, "-m", 2) == 0) + use_master = 1; +@@ -317,7 +317,7 @@ + if (debug) + printf("V5 ticket decoded\n"); + +- if( v5tkt->server->length >= 1 ++ if( krb5_princ_size(context, v5tkt->server) >= 1 + &&krb5_princ_component(context, v5tkt->server, 0)->length == 3 + &&strncmp(krb5_princ_component(context, v5tkt->server, 0)->data, + "afs", 3) == 0) { +@@ -495,19 +499,7 @@ + &v5_service_key, NULL))) + goto error; + +- if ((ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_RAW, +- 0, /* highest kvno */ +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_LOCAL_DES3_HMAC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, +- ENCTYPE_DES3_CBC_SHA1, +- 0, +- &v4_service_key, v4kvno)) && +- (ret = lookup_service_key(context, v5tkt->server, ++ if ( (ret = lookup_service_key(context, v5tkt->server, + ENCTYPE_DES_CBC_CRC, + 0, + &v4_service_key, v4kvno))) +@@ -515,8 +507,19 @@ + + if (debug) + printf("service key retrieved\n"); ++ if ((ret = krb5_decrypt_tkt_part(context, &v5_service_key, v5tkt))) { ++ goto error; ++ } + +- ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, ++ if (!(allow_v4_crossrealm || krb5_realm_compare(context, v5tkt->server, ++ v5tkt->enc_part2->client))) { ++ret = KRB5KDC_ERR_POLICY ; ++ goto error; ++ } ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ v5tkt->enc_part2= NULL; ++ ++ ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key, + &v4_service_key, + (struct sockaddr_in *)saddr); + if (ret) +@@ -532,6 +535,9 @@ + printf("v4 credentials encoded\n"); + + error: ++ if (v5tkt->enc_part2) ++ krb5_free_enc_tkt_part(context, v5tkt->enc_part2); ++ + if(v5_service_key.contents) + krb5_free_keyblock_contents(context, &v5_service_key); + if (v4_service_key.contents) +diff -ur krb5-1.2.7/src/krb524/krb524d.c krb5-1.2.7/src/krb524/krb524d.c diff --git a/security/krb5/files/patch-lib::kdb::keytab.c b/security/krb5/files/patch-lib::kdb::keytab.c new file mode 100644 index 000000000000..a77f4bc32718 --- /dev/null +++ b/security/krb5/files/patch-lib::kdb::keytab.c @@ -0,0 +1,86 @@ +Index: lib/kdb/keytab.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/kdb/keytab.c,v +retrieving revision 5.11.4.2 +diff -u -r5.11.4.2 keytab.c +--- lib/kdb/keytab.c 2002/08/15 21:27:34 5.11.4.2 ++++ lib/kdb/keytab.c 2002/10/15 23:32:46 +@@ -28,6 +28,8 @@ + #include "k5-int.h" + #include "kdb_kt.h" + ++static int ++is_xrealm_tgt(krb5_context, krb5_const_principal); + krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab)); + + krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal, +@@ -98,6 +100,8 @@ + krb5_db_entry db_entry; + krb5_boolean more = 0; + int n = 0; ++ int xrealm_tgt = is_xrealm_tgt(context, principal); ++ int similar; + + /* Open database */ + /* krb5_db_init(context); */ +@@ -127,16 +131,31 @@ + if (kerror) + goto error; + ++ /* For cross realm tgts, we match whatever enctype is provided; ++ * for other principals, we only match the first enctype that is ++ * found. Since the TGS and AS code do the same thing, then we ++ * will only successfully decrypt tickets we have issued.*/ + kerror = krb5_dbe_find_enctype(context, &db_entry, +- enctype, -1, kvno, &key_data); ++ xrealm_tgt?enctype:-1, ++ -1, kvno, &key_data); + if (kerror) + goto error; + ++ + kerror = krb5_dbekd_decrypt_key_data(context, master_key, + key_data, &entry->key, NULL); + if (kerror) + goto error; + ++ kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar); ++ if (kerror) ++ goto error; ++ ++ if (!similar) { ++ kerror = KRB5_KDB_NO_PERMITTED_KEY; ++ goto error; ++ } ++ + /* + * Coerce the enctype of the output keyblock in case we got an + * inexact match on the enctype; this behavior will go away when +@@ -154,3 +173,27 @@ + krb5_db_close_database(context); + return(kerror); + } ++ ++/* ++ * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT ++ * principal-- a principal with first component krbtgt and second ++ * component not equal to realm. ++ */ ++static int ++is_xrealm_tgt(krb5_context context, krb5_const_principal princ) ++{ ++ krb5_data *dat; ++ if (krb5_princ_size(context, princ) != 2) ++ return 0; ++ dat = krb5_princ_component(context, princ, 0); ++ if (strncmp("krbtgt", dat->data, dat->length) != 0) ++ return 0; ++ dat = krb5_princ_component(context, princ, 1); ++ if (dat->length != princ->realm.length) ++ return 1; ++ if (strcmp(dat->data, princ->realm.data) == 0) ++ return 0; ++ return 1; ++ ++} ++ diff --git a/security/krb5/files/patch-lib::krb5::keytab::file:ktf_util.c b/security/krb5/files/patch-lib::krb5::keytab::file:ktf_util.c new file mode 100644 index 000000000000..c97b3a3c85ae --- /dev/null +++ b/security/krb5/files/patch-lib::krb5::keytab::file:ktf_util.c @@ -0,0 +1,42 @@ +diff -ur krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c krb5-1.2.7/src/lib/krb5/keytab/file/ktf_util.c +--- lib/krb5/keytab/file/ktf_util.c 1999-09-24 17:19:01.000000000-0400 ++++ lib/krb5/keytab/file/ktf_util.c 2003-02-03 18:02:25.000000000-0500 +@@ -441,7 +441,7 @@ + return 0; + fail: + +- for (i = 0; i < ret_entry->principal->length; i++) { ++ for (i = 0; i < krb5_princ_size(context, ret_entry->principal); i++) { + princ = krb5_princ_component(context, ret_entry->principal, i); + if (princ->data) + free(princ->data); +@@ -498,9 +498,9 @@ + } + + if (KTVERSION(id) == KRB5_KT_VNO_1) { +- count = (krb5_int16) entry->principal->length + 1; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal) + 1; + } else { +- count = htons((u_short) entry->principal->length); ++ count = htons((u_short) krb5_princ_size(context, entry->principal)); + } + + if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) { +@@ -519,7 +519,7 @@ + goto abend; + } + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + for (i = 0; i < count; i++) { + princ = krb5_princ_component(context, entry->principal, i); + size = princ->length; +@@ -620,7 +620,7 @@ + krb5_int32 total_size, i; + krb5_error_code retval = 0; + +- count = (krb5_int16) entry->principal->length; ++ count = (krb5_int16) krb5_princ_size(context, entry->principal); + + total_size = sizeof(count); + total_size += krb5_princ_realm(context, entry->principal)->length + (sizeof(krb5_int16)); diff --git a/security/krb5/files/patch-lib::krb5::krb::gc_frm_kdc.c b/security/krb5/files/patch-lib::krb5::krb::gc_frm_kdc.c new file mode 100644 index 000000000000..4ad0d8cc43c5 --- /dev/null +++ b/security/krb5/files/patch-lib::krb5::krb::gc_frm_kdc.c @@ -0,0 +1,14 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c krb5-1.2.7/src/lib/krb5/krb/gc_frm_kdc.c +--- lib/krb5/krb/gc_frm_kdc.c 1999-09-24 17:19:24.000000000 -0400 ++++ lib/krb5/krb/gc_frm_kdc.c 2003-02-03 17:35:40.000000000 -0500 +@@ -347,7 +347,9 @@ + for (next_server = top_server; *next_server; next_server++) { + krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1); + krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1); +- if (realm_1->length == realm_2->length && ++ if (realm_1 != NULL && ++ realm_2 != NULL && ++ realm_1->length == realm_2->length && + !memcmp(realm_1->data, realm_2->data, realm_1->length)) { + break; + } diff --git a/security/krb5/files/patch-lib::krb5::krb::parse.c b/security/krb5/files/patch-lib::krb5::krb::parse.c new file mode 100644 index 000000000000..8eb73b24c158 --- /dev/null +++ b/security/krb5/files/patch-lib::krb5::krb::parse.c @@ -0,0 +1,29 @@ +diff -ur krb5-1.2.7/src/lib/krb5/krb/parse.c krb5-1.2.7/src/lib/krb5/krb/parse.c +--- lib/krb5/krb/parse.c 2002-02-28 12:08:35.000000000 -0500 ++++ lib/krb5/krb/parse.c 2003-02-03 17:44:04.000000000 -0500 +@@ -173,11 +173,13 @@ + cp++; + size++; + } else if (c == COMPONENT_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + i++; + } else if (c == REALM_SEP) { +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + size = 0; + parsed_realm = cp+1; + } else +@@ -186,7 +188,8 @@ + if (parsed_realm) + krb5_princ_realm(context, principal)->length = size; + else +- krb5_princ_component(context, principal, i)->length = size; ++ if (krb5_princ_size(context, principal) > i) ++ krb5_princ_component(context, principal, i)->length = size; + if (i + 1 != components) { + #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) + fprintf(stderr, diff --git a/security/krb5/files/patch-lib::krb5::krb::srv_rcache.c b/security/krb5/files/patch-lib::krb5::krb::srv_rcache.c new file mode 100644 index 000000000000..79e16f93110d --- /dev/null +++ b/security/krb5/files/patch-lib::krb5::krb::srv_rcache.c @@ -0,0 +1,12 @@ +--- lib/krb5/krb/srv_rcache.c 1999-09-24 17:19:48.000000000 -0400 ++++ lib/krb5/krb/srv_rcache.c 2003-02-03 19:29:32.000000000 -0500 +@@ -48,6 +48,9 @@ + unsigned long uid = geteuid(); + #endif + ++ if (piece == NULL) ++ return ENOMEM; ++ + rcache = (krb5_rcache) malloc(sizeof(*rcache)); + if (!rcache) + return ENOMEM; diff --git a/security/krb5/files/patch-lib::krb5::krb::unparse.c b/security/krb5/files/patch-lib::krb5::krb::unparse.c new file mode 100644 index 000000000000..690eb5febea2 --- /dev/null +++ b/security/krb5/files/patch-lib::krb5::krb::unparse.c @@ -0,0 +1,17 @@ +Index: lib/krb5/krb/unparse.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/krb5/krb/unparse.c,v +retrieving revision 5.27.4.1 +diff -p -u -r5.27.4.1 unparse.c +--- lib/krb5/krb/unparse.c 2002/08/12 22:55:01 5.27.4.1 ++++ lib/krb5/krb/unparse.c 2003/03/19 00:39:02 +@@ -153,7 +153,8 @@ krb5_unparse_name_ext(context, principal + *q++ = COMPONENT_SEP; + } + +- q--; /* Back up last component separator */ ++ if (i > 0) ++ q--; /* Back up last component separator */ + *q++ = REALM_SEP; + + cp = krb5_princ_realm(context, principal)->data; diff --git a/security/krb5/files/patch-lib::rpc::xdr_mem.c b/security/krb5/files/patch-lib::rpc::xdr_mem.c new file mode 100644 index 000000000000..2508c3620772 --- /dev/null +++ b/security/krb5/files/patch-lib::rpc::xdr_mem.c @@ -0,0 +1,136 @@ +Index: xdr_mem.c +=================================================================== +RCS file: /cvs/krbdev/krb5/src/lib/rpc/xdr_mem.c,v +retrieving revision 1.8 +diff -c -r1.8 xdr_mem.c +*** lib/rpc/xdr_mem.c 1998/02/14 02:27:24 1.8 +--- lib/rpc/xdr_mem.c 2003/02/04 22:57:24 +*************** +*** 47,52 **** +--- 47,54 ---- + #include <gssrpc/xdr.h> + #include <netinet/in.h> + #include <stdio.h> ++ #include <string.h> ++ #include <limits.h> + + static bool_t xdrmem_getlong(); + static bool_t xdrmem_putlong(); +*************** +*** 83,89 **** + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = size; + } + + static void +--- 85,91 ---- + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; +! xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ + } + + static void +*************** +*** 98,105 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 100,109 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private))); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 111,118 **** + long *lp; + { + +! if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0) + return (FALSE); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +--- 115,124 ---- + long *lp; + { + +! if (xdrs->x_handy < sizeof(rpc_int32)) + return (FALSE); ++ else ++ xdrs->x_handy -= sizeof(rpc_int32); + *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp)); + xdrs->x_private += sizeof(rpc_int32); + return (TRUE); +*************** +*** 125,132 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +--- 131,140 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 139,146 **** + register unsigned int len; + { + +! if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +--- 147,156 ---- + register unsigned int len; + { + +! if (xdrs->x_handy < len) + return (FALSE); ++ else ++ xdrs->x_handy -= len; + memmove(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +*************** +*** 179,185 **** + { + rpc_int32 *buf = 0; + +! if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; +--- 189,195 ---- + { + rpc_int32 *buf = 0; + +! if (len >= 0 && xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (rpc_int32 *) xdrs->x_private; + xdrs->x_private += len; |