3571e53040
patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
706 lines
20 KiB
Diff
706 lines
20 KiB
Diff
diff -urN crypto/heimdal/kdc/config.c heimdal-0.5.3/kdc/config.c
|
|
--- crypto/heimdal/kdc/config.c 2003-03-17 07:46:55.000000000 +0100
|
|
+++ crypto/heimdal/kdc/config.c 2004-02-16 20:08:49.000000000 +0100
|
|
@@ -64,6 +64,8 @@
|
|
krb5_boolean check_ticket_addresses;
|
|
krb5_boolean allow_null_ticket_addresses;
|
|
krb5_boolean allow_anonymous;
|
|
+int trpolicy;
|
|
+static const char *trpolicy_str;
|
|
|
|
static struct getarg_strings addresses_str; /* addresses to listen on */
|
|
krb5_addresses explicit_addresses;
|
|
@@ -292,9 +294,8 @@
|
|
|
|
get_dbinfo();
|
|
|
|
- if(max_request_str){
|
|
+ if(max_request_str)
|
|
max_request = parse_bytes(max_request_str, NULL);
|
|
- }
|
|
|
|
if(max_request == 0){
|
|
p = krb5_config_get_string (context,
|
|
@@ -365,6 +366,23 @@
|
|
allow_anonymous =
|
|
krb5_config_get_bool(context, NULL, "kdc",
|
|
"allow-anonymous", NULL);
|
|
+ trpolicy_str =
|
|
+ krb5_config_get_string_default(context, NULL, "always-check", "kdc",
|
|
+ "transited-policy", NULL);
|
|
+ if(strcasecmp(trpolicy_str, "always-check") == 0)
|
|
+ trpolicy = TRPOLICY_ALWAYS_CHECK;
|
|
+ else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0)
|
|
+ trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
|
|
+ else if(strcasecmp(trpolicy_str, "always-honour-request") == 0)
|
|
+ trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
|
|
+ else {
|
|
+ kdc_log(0, "unknown transited-policy: %s, reverting to always-check",
|
|
+ trpolicy_str);
|
|
+ trpolicy = TRPOLICY_ALWAYS_CHECK;
|
|
+ }
|
|
+
|
|
+ krb5_config_get_bool_default(context, NULL, TRUE, "kdc",
|
|
+ "enforce-transited-policy", NULL);
|
|
#ifdef KRB4
|
|
if(v4_realm == NULL){
|
|
p = krb5_config_get_string (context, NULL,
|
|
diff -urN crypto/heimdal/kdc/kdc.8 heimdal-0.5.3/kdc/kdc.8
|
|
--- crypto/heimdal/kdc/kdc.8 2003-03-17 07:47:03.000000000 +0100
|
|
+++ crypto/heimdal/kdc/kdc.8 2004-02-16 18:50:11.000000000 +0100
|
|
@@ -2,5 +2,5 @@
|
|
.\"
|
|
-.Dd August 22, 2002
|
|
+.Dd October 22, 2003
|
|
.Dt KDC 8
|
|
.Os HEIMDAL
|
|
.Sh NAME
|
|
@@ -145,6 +145,27 @@
|
|
check-ticket-addresses is TRUE.
|
|
.It Li allow-anonymous = Va boolean
|
|
Permit anonymous tickets with no addresses.
|
|
+.It Li transited-policy = Xo
|
|
+.Li always-check \*(Ba
|
|
+.Li allow-per-principal |
|
|
+.Li always-honour-request
|
|
+.Xc
|
|
+This controls how KDC requests with the
|
|
+.Li disable-transited-check
|
|
+flag are handled. It can be one of:
|
|
+.Bl -tag -width "xxx" -offset indent
|
|
+.It Li always-check
|
|
+Always check transited encoding, this is the default.
|
|
+.It Li allow-per-principal
|
|
+Currently this is identical to
|
|
+.Li always-check .
|
|
+In a future release, it will be possible to mark a principal as able
|
|
+to handle unchecked requests.
|
|
+.It Li always-honour-request
|
|
+Always do what the client asked.
|
|
+In a future release, it will be possible to force a check per
|
|
+principal.
|
|
+.El
|
|
.It encode_as_rep_as_tgs_rep = Va boolean
|
|
Encode AS-Rep as TGS-Rep to be bug-compatible with old DCE code. The
|
|
Heimdal clients allow both.
|
|
diff -urN crypto/heimdal/kdc/kdc_locl.h heimdal-0.5.3/kdc/kdc_locl.h
|
|
--- crypto/heimdal/kdc/kdc_locl.h 2003-03-17 07:47:23.000000000 +0100
|
|
+++ crypto/heimdal/kdc/kdc_locl.h 2004-02-16 19:24:43.000000000 +0100
|
|
@@ -62,6 +62,11 @@
|
|
extern krb5_boolean check_ticket_addresses;
|
|
extern krb5_boolean allow_null_ticket_addresses;
|
|
extern krb5_boolean allow_anonymous;
|
|
+enum { TRPOLICY_ALWAYS_CHECK,
|
|
+ TRPOLICY_ALLOW_PER_PRINCIPAL,
|
|
+ TRPOLICY_ALWAYS_HONOUR_REQUEST };
|
|
+extern int trpolicy;
|
|
+extern int enable_v4_cross_realm;
|
|
|
|
#ifdef KRB4
|
|
extern char *v4_realm;
|
|
diff -urN crypto/heimdal/kdc/kerberos5.c heimdal-0.5.3/kdc/kerberos5.c
|
|
--- crypto/heimdal/kdc/kerberos5.c 2002-09-09 16:03:02.000000000 +0200
|
|
+++ crypto/heimdal/kdc/kerberos5.c 2004-02-16 19:23:20.000000000 +0100
|
|
@@ -355,10 +355,13 @@
|
|
|
|
if(n != pa.len) {
|
|
char *name;
|
|
- krb5_unparse_name(context, client->principal, &name);
|
|
+ ret = krb5_unparse_name(context, client->principal, &name);
|
|
+ if (ret)
|
|
+ name = "<unparse_name failed>";
|
|
kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
|
|
name, n, pa.len);
|
|
- free(name);
|
|
+ if (ret == 0)
|
|
+ free(name);
|
|
pa.len = n;
|
|
}
|
|
|
|
@@ -496,8 +499,8 @@
|
|
krb5_enctype cetype, setype;
|
|
EncTicketPart et;
|
|
EncKDCRepPart ek;
|
|
- krb5_principal client_princ, server_princ;
|
|
- char *client_name, *server_name;
|
|
+ krb5_principal client_princ = NULL, server_princ = NULL;
|
|
+ char *client_name = NULL, *server_name = NULL;
|
|
krb5_error_code ret = 0;
|
|
const char *e_text = NULL;
|
|
krb5_crypto crypto;
|
|
@@ -506,28 +509,32 @@
|
|
memset(&rep, 0, sizeof(rep));
|
|
|
|
if(b->sname == NULL){
|
|
- server_name = "<unknown server>";
|
|
ret = KRB5KRB_ERR_GENERIC;
|
|
e_text = "No server in request";
|
|
} else{
|
|
principalname2krb5_principal (&server_princ, *(b->sname), b->realm);
|
|
- krb5_unparse_name(context, server_princ, &server_name);
|
|
+ ret = krb5_unparse_name(context, server_princ, &server_name);
|
|
+ }
|
|
+ if (ret) {
|
|
+ kdc_log(0, "AS-REQ malformed server name from %s", from);
|
|
+ goto out;
|
|
}
|
|
|
|
if(b->cname == NULL){
|
|
- client_name = "<unknown client>";
|
|
ret = KRB5KRB_ERR_GENERIC;
|
|
e_text = "No client in request";
|
|
} else {
|
|
principalname2krb5_principal (&client_princ, *(b->cname), b->realm);
|
|
- krb5_unparse_name(context, client_princ, &client_name);
|
|
+ ret = krb5_unparse_name(context, client_princ, &client_name);
|
|
}
|
|
+ if (ret) {
|
|
+ kdc_log(0, "AS-REQ malformed client name from %s", from);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
kdc_log(0, "AS-REQ %s from %s for %s",
|
|
client_name, from, server_name);
|
|
|
|
- if(ret)
|
|
- goto out;
|
|
-
|
|
ret = db_fetch(client_princ, &client);
|
|
if(ret){
|
|
kdc_log(0, "UNKNOWN -- %s: %s", client_name,
|
|
@@ -559,7 +566,6 @@
|
|
while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
|
|
krb5_data ts_data;
|
|
PA_ENC_TS_ENC p;
|
|
- time_t patime;
|
|
size_t len;
|
|
EncryptedData enc_data;
|
|
Key *pa_key;
|
|
@@ -635,7 +641,6 @@
|
|
client_name);
|
|
continue;
|
|
}
|
|
- patime = p.patimestamp;
|
|
free_PA_ENC_TS_ENC(&p);
|
|
if (abs(kdc_time - p.patimestamp) > context->max_skew) {
|
|
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
|
@@ -716,9 +721,10 @@
|
|
if (ret == 0) {
|
|
kdc_log(5, "Using %s/%s", cet, set);
|
|
free(set);
|
|
- } else
|
|
- free(cet);
|
|
- } else
|
|
+ }
|
|
+ free(cet);
|
|
+ }
|
|
+ if (ret != 0)
|
|
kdc_log(5, "Using e-types %d/%d", cetype, setype);
|
|
}
|
|
|
|
@@ -841,13 +847,8 @@
|
|
copy_HostAddresses(b->addresses, et.caddr);
|
|
}
|
|
|
|
- {
|
|
- krb5_data empty_string;
|
|
-
|
|
- krb5_data_zero(&empty_string);
|
|
- et.transited.tr_type = DOMAIN_X500_COMPRESS;
|
|
- et.transited.contents = empty_string;
|
|
- }
|
|
+ et.transited.tr_type = DOMAIN_X500_COMPRESS;
|
|
+ krb5_data_zero(&et.transited.contents);
|
|
|
|
copy_EncryptionKey(&et.key, &ek.key);
|
|
|
|
@@ -914,8 +915,8 @@
|
|
client->kvno, &ckey->key, &e_text, reply);
|
|
free_EncTicketPart(&et);
|
|
free_EncKDCRepPart(&ek);
|
|
- free_AS_REP(&rep);
|
|
out:
|
|
+ free_AS_REP(&rep);
|
|
if(ret){
|
|
krb5_mk_error(context,
|
|
ret,
|
|
@@ -929,9 +930,11 @@
|
|
ret = 0;
|
|
}
|
|
out2:
|
|
- krb5_free_principal(context, client_princ);
|
|
+ if (client_princ)
|
|
+ krb5_free_principal(context, client_princ);
|
|
free(client_name);
|
|
- krb5_free_principal(context, server_princ);
|
|
+ if (server_princ)
|
|
+ krb5_free_principal(context, server_princ);
|
|
free(server_name);
|
|
if(client)
|
|
free_ent(client);
|
|
@@ -1054,33 +1057,35 @@
|
|
}
|
|
|
|
static krb5_error_code
|
|
-fix_transited_encoding(TransitedEncoding *tr,
|
|
+fix_transited_encoding(krb5_boolean check_policy,
|
|
+ TransitedEncoding *tr,
|
|
+ EncTicketPart *et,
|
|
const char *client_realm,
|
|
const char *server_realm,
|
|
const char *tgt_realm)
|
|
{
|
|
krb5_error_code ret = 0;
|
|
- if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)){
|
|
- char **realms = NULL, **tmp;
|
|
- int num_realms = 0;
|
|
- int i;
|
|
- if(tr->tr_type && tr->contents.length != 0) {
|
|
- if(tr->tr_type != DOMAIN_X500_COMPRESS){
|
|
- kdc_log(0, "Unknown transited type: %u",
|
|
- tr->tr_type);
|
|
- return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
|
- }
|
|
- ret = krb5_domain_x500_decode(context,
|
|
- tr->contents,
|
|
- &realms,
|
|
- &num_realms,
|
|
- client_realm,
|
|
- server_realm);
|
|
- if(ret){
|
|
- krb5_warn(context, ret, "Decoding transited encoding");
|
|
- return ret;
|
|
- }
|
|
- }
|
|
+ char **realms, **tmp;
|
|
+ int num_realms;
|
|
+ int i;
|
|
+
|
|
+ if(tr->tr_type != DOMAIN_X500_COMPRESS) {
|
|
+ kdc_log(0, "Unknown transited type: %u", tr->tr_type);
|
|
+ return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
|
+ }
|
|
+
|
|
+ ret = krb5_domain_x500_decode(context,
|
|
+ tr->contents,
|
|
+ &realms,
|
|
+ &num_realms,
|
|
+ client_realm,
|
|
+ server_realm);
|
|
+ if(ret){
|
|
+ krb5_warn(context, ret, "Decoding transited encoding");
|
|
+ return ret;
|
|
+ }
|
|
+ if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
|
|
+ /* not us, so add the previous realm to transited set */
|
|
if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
|
|
ret = ERANGE;
|
|
goto free_realms;
|
|
@@ -1097,16 +1102,46 @@
|
|
goto free_realms;
|
|
}
|
|
num_realms++;
|
|
- free_TransitedEncoding(tr);
|
|
- tr->tr_type = DOMAIN_X500_COMPRESS;
|
|
- ret = krb5_domain_x500_encode(realms, num_realms, &tr->contents);
|
|
- if(ret)
|
|
- krb5_warn(context, ret, "Encoding transited encoding");
|
|
- free_realms:
|
|
+ }
|
|
+ if(num_realms == 0) {
|
|
+ if(strcmp(client_realm, server_realm))
|
|
+ kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm);
|
|
+ } else {
|
|
+ size_t l = 0;
|
|
+ char *rs;
|
|
for(i = 0; i < num_realms; i++)
|
|
- free(realms[i]);
|
|
- free(realms);
|
|
+ l += strlen(realms[i]) + 2;
|
|
+ rs = malloc(l);
|
|
+ if(rs != NULL) {
|
|
+ *rs = '\0';
|
|
+ for(i = 0; i < num_realms; i++) {
|
|
+ if(i > 0)
|
|
+ strlcat(rs, ", ", l);
|
|
+ strlcat(rs, realms[i], l);
|
|
+ }
|
|
+ kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs);
|
|
+ free(rs);
|
|
+ }
|
|
}
|
|
+ if(check_policy) {
|
|
+ ret = krb5_check_transited(context, client_realm,
|
|
+ server_realm,
|
|
+ realms, num_realms, NULL);
|
|
+ if(ret) {
|
|
+ krb5_warn(context, ret, "cross-realm %s -> %s",
|
|
+ client_realm, server_realm);
|
|
+ goto free_realms;
|
|
+ }
|
|
+ et->flags.transited_policy_checked = 1;
|
|
+ }
|
|
+ et->transited.tr_type = DOMAIN_X500_COMPRESS;
|
|
+ ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
|
|
+ if(ret)
|
|
+ krb5_warn(context, ret, "Encoding transited encoding");
|
|
+ free_realms:
|
|
+ for(i = 0; i < num_realms; i++)
|
|
+ free(realms[i]);
|
|
+ free(realms);
|
|
return ret;
|
|
}
|
|
|
|
@@ -1172,18 +1207,35 @@
|
|
|
|
ret = check_tgs_flags(b, tgt, &et);
|
|
if(ret)
|
|
- return ret;
|
|
+ goto out;
|
|
|
|
- copy_TransitedEncoding(&tgt->transited, &et.transited);
|
|
- ret = fix_transited_encoding(&et.transited,
|
|
+ /* We should check the transited encoding if:
|
|
+ 1) the request doesn't ask not to be checked
|
|
+ 2) globally enforcing a check
|
|
+ 3) principal requires checking
|
|
+ 4) we allow non-check per-principal, but principal isn't marked as allowing this
|
|
+ 5) we don't globally allow this
|
|
+ */
|
|
+
|
|
+#define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
|
|
+#define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
|
|
+#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
|
|
+/* these will consult the database in future release */
|
|
+#define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
|
|
+#define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
|
|
+
|
|
+ ret = fix_transited_encoding(!f.disable_transited_check ||
|
|
+ GLOBAL_FORCE_TRANSITED_CHECK ||
|
|
+ PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
|
|
+ !((GLOBAL_ALLOW_PER_PRINCIPAL &&
|
|
+ PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
|
|
+ GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
|
|
+ &tgt->transited, &et,
|
|
*krb5_princ_realm(context, client_principal),
|
|
*krb5_princ_realm(context, server->principal),
|
|
*krb5_princ_realm(context, krbtgt->principal));
|
|
- if(ret){
|
|
- free_TransitedEncoding(&et.transited);
|
|
- return ret;
|
|
- }
|
|
-
|
|
+ if(ret)
|
|
+ goto out;
|
|
|
|
copy_Realm(krb5_princ_realm(context, server->principal),
|
|
&rep.ticket.realm);
|
|
@@ -1278,7 +1330,7 @@
|
|
DES3? */
|
|
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
|
|
0, &tgt->key, e_text, reply);
|
|
-out:
|
|
+ out:
|
|
free_TGS_REP(&rep);
|
|
free_TransitedEncoding(&et.transited);
|
|
if(et.starttime)
|
|
@@ -1380,13 +1432,13 @@
|
|
}
|
|
|
|
static Realm
|
|
-find_rpath(Realm r)
|
|
+find_rpath(Realm crealm, Realm srealm)
|
|
{
|
|
const char *new_realm = krb5_config_get_string(context,
|
|
NULL,
|
|
- "libdefaults",
|
|
- "capath",
|
|
- r,
|
|
+ "capaths",
|
|
+ crealm,
|
|
+ srealm,
|
|
NULL);
|
|
return (Realm)new_realm;
|
|
}
|
|
@@ -1456,10 +1508,14 @@
|
|
|
|
if(ret) {
|
|
char *p;
|
|
- krb5_unparse_name(context, princ, &p);
|
|
+ ret = krb5_unparse_name(context, princ, &p);
|
|
+ if (ret != 0)
|
|
+ p = "<unparse_name failed>";
|
|
+ krb5_free_principal(context, princ);
|
|
kdc_log(0, "Ticket-granting ticket not found in database: %s: %s",
|
|
p, krb5_get_err_text(context, ret));
|
|
- free(p);
|
|
+ if (ret == 0)
|
|
+ free(p);
|
|
ret = KRB5KRB_AP_ERR_NOT_US;
|
|
goto out2;
|
|
}
|
|
@@ -1468,12 +1524,16 @@
|
|
*ap_req.ticket.enc_part.kvno != krbtgt->kvno){
|
|
char *p;
|
|
|
|
- krb5_unparse_name (context, princ, &p);
|
|
+ ret = krb5_unparse_name (context, princ, &p);
|
|
+ krb5_free_principal(context, princ);
|
|
+ if (ret != 0)
|
|
+ p = "<unparse_name failed>";
|
|
kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
|
|
*ap_req.ticket.enc_part.kvno,
|
|
krbtgt->kvno,
|
|
p);
|
|
- free (p);
|
|
+ if (ret == 0)
|
|
+ free (p);
|
|
ret = KRB5KRB_AP_ERR_BADKEYVER;
|
|
goto out2;
|
|
}
|
|
@@ -1657,9 +1717,13 @@
|
|
}
|
|
|
|
principalname2krb5_principal(&sp, *s, r);
|
|
- krb5_unparse_name(context, sp, &spn);
|
|
+ ret = krb5_unparse_name(context, sp, &spn);
|
|
+ if (ret)
|
|
+ goto out;
|
|
principalname2krb5_principal(&cp, tgt->cname, tgt->crealm);
|
|
- krb5_unparse_name(context, cp, &cpn);
|
|
+ ret = krb5_unparse_name(context, cp, &cpn);
|
|
+ if (ret)
|
|
+ goto out;
|
|
unparse_flags (KDCOptions2int(b->kdc_options), KDCOptions_units,
|
|
opt_str, sizeof(opt_str));
|
|
if(*opt_str)
|
|
@@ -1676,7 +1740,7 @@
|
|
|
|
if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
|
|
if(loop++ < 2) {
|
|
- new_rlm = find_rpath(req_rlm);
|
|
+ new_rlm = find_rpath(tgt->crealm, req_rlm);
|
|
if(new_rlm) {
|
|
kdc_log(5, "krbtgt for realm %s not found, trying %s",
|
|
req_rlm, new_rlm);
|
|
@@ -1684,7 +1748,9 @@
|
|
free(spn);
|
|
krb5_make_principal(context, &sp, r,
|
|
KRB5_TGS_NAME, new_rlm, NULL);
|
|
- krb5_unparse_name(context, sp, &spn);
|
|
+ ret = krb5_unparse_name(context, sp, &spn);
|
|
+ if (ret)
|
|
+ goto out;
|
|
goto server_lookup;
|
|
}
|
|
}
|
|
@@ -1697,7 +1763,9 @@
|
|
free(spn);
|
|
krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
|
|
realms[0], NULL);
|
|
- krb5_unparse_name(context, sp, &spn);
|
|
+ ret = krb5_unparse_name(context, sp, &spn);
|
|
+ if (ret)
|
|
+ goto out;
|
|
krb5_free_host_realm(context, realms);
|
|
goto server_lookup;
|
|
}
|
|
@@ -1725,6 +1793,18 @@
|
|
}
|
|
#endif
|
|
|
|
+ if(strcmp(krb5_principal_get_realm(context, sp),
|
|
+ krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) {
|
|
+ char *tpn;
|
|
+ ret = krb5_unparse_name(context, krbtgt->principal, &tpn);
|
|
+ kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : "<unknown>");
|
|
+ if(ret == 0)
|
|
+ free(tpn);
|
|
+ ret = KRB5KRB_AP_ERR_NOT_US;
|
|
+ goto out;
|
|
+
|
|
+ }
|
|
+
|
|
ret = check_flags(client, cpn, server, spn, FALSE);
|
|
if(ret)
|
|
goto out;
|
|
diff -urN crypto/heimdal/lib/krb5/krb5-protos.h heimdal-0.5.3/lib/krb5/krb5-protos.h
|
|
--- crypto/heimdal/lib/krb5/krb5-protos.h 2003-03-17 11:27:40.000000000 +0100
|
|
+++ crypto/heimdal/lib/krb5/krb5-protos.h 2004-04-01 16:16:33.000000000 +0200
|
|
@@ -521,6 +521,15 @@
|
|
krb5_data */*result_string*/);
|
|
|
|
krb5_error_code
|
|
+krb5_check_transited (
|
|
+ krb5_context /*context*/,
|
|
+ krb5_const_realm /*client_realm*/,
|
|
+ krb5_const_realm /*server_realm*/,
|
|
+ krb5_realm */*realms*/,
|
|
+ int /*num_realms*/,
|
|
+ int */*bad_realm*/);
|
|
+
|
|
+krb5_error_code
|
|
krb5_check_transited_realms (
|
|
krb5_context /*context*/,
|
|
const char *const */*realms*/,
|
|
diff -urN crypto/heimdal/lib/krb5/rd_req.c heimdal-0.5.3/lib/krb5/rd_req.c
|
|
--- crypto/heimdal/lib/krb5/rd_req.c 2001-06-18 04:48:18.000000000 +0200
|
|
+++ crypto/heimdal/lib/krb5/rd_req.c 2004-02-16 19:17:47.000000000 +0100
|
|
@@ -129,6 +129,32 @@
|
|
return 0;
|
|
}
|
|
|
|
+static krb5_error_code
|
|
+check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
|
|
+{
|
|
+ char **realms;
|
|
+ int num_realms;
|
|
+ krb5_error_code ret;
|
|
+
|
|
+ if(enc->transited.tr_type != DOMAIN_X500_COMPRESS)
|
|
+ return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
|
+
|
|
+ if(enc->transited.contents.length == 0)
|
|
+ return 0;
|
|
+
|
|
+ ret = krb5_domain_x500_decode(context, enc->transited.contents,
|
|
+ &realms, &num_realms,
|
|
+ enc->crealm,
|
|
+ ticket->realm);
|
|
+ if(ret)
|
|
+ return ret;
|
|
+ ret = krb5_check_transited(context, enc->crealm,
|
|
+ ticket->realm,
|
|
+ realms, num_realms, NULL);
|
|
+ free(realms);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
krb5_error_code
|
|
krb5_decrypt_ticket(krb5_context context,
|
|
Ticket *ticket,
|
|
@@ -161,6 +187,14 @@
|
|
krb5_clear_error_string (context);
|
|
return KRB5KRB_AP_ERR_TKT_EXPIRED;
|
|
}
|
|
+
|
|
+ if(!t.flags.transited_policy_checked) {
|
|
+ ret = check_transited(context, ticket, &t);
|
|
+ if(ret) {
|
|
+ free_EncTicketPart(&t);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
if(out)
|
|
@@ -209,29 +243,6 @@
|
|
return ret;
|
|
}
|
|
|
|
-#if 0
|
|
-static krb5_error_code
|
|
-check_transited(krb5_context context,
|
|
- krb5_ticket *ticket)
|
|
-{
|
|
- char **realms;
|
|
- int num_realms;
|
|
- krb5_error_code ret;
|
|
-
|
|
- if(ticket->ticket.transited.tr_type != DOMAIN_X500_COMPRESS)
|
|
- return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
|
-
|
|
- ret = krb5_domain_x500_decode(ticket->ticket.transited.contents,
|
|
- &realms, &num_realms,
|
|
- ticket->client->realm,
|
|
- ticket->server->realm);
|
|
- if(ret)
|
|
- return ret;
|
|
- ret = krb5_check_transited_realms(context, realms, num_realms, NULL);
|
|
- free(realms);
|
|
- return ret;
|
|
-}
|
|
-#endif
|
|
|
|
krb5_error_code
|
|
krb5_verify_ap_req(krb5_context context,
|
|
diff -urN crypto/heimdal/lib/krb5/transited.c heimdal-0.5.3/lib/krb5/transited.c
|
|
--- crypto/heimdal/lib/krb5/transited.c 2002-09-09 16:03:03.000000000 +0200
|
|
+++ crypto/heimdal/lib/krb5/transited.c 2004-02-16 19:20:52.000000000 +0100
|
|
@@ -304,6 +304,12 @@
|
|
struct tr_realm *p, **q;
|
|
int ret;
|
|
|
|
+ if(tr.length == 0) {
|
|
+ *realms = NULL;
|
|
+ *num_realms = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
/* split string in components */
|
|
ret = decode_realms(context, tr.data, tr.length, &r);
|
|
if(ret)
|
|
@@ -358,6 +364,9 @@
|
|
char *s = NULL;
|
|
int len = 0;
|
|
int i;
|
|
+ krb5_data_zero(encoding);
|
|
+ if (num_realms == 0)
|
|
+ return 0;
|
|
for(i = 0; i < num_realms; i++){
|
|
len += strlen(realms[i]);
|
|
if(realms[i][0] == '/')
|
|
@@ -365,6 +374,8 @@
|
|
}
|
|
len += num_realms - 1;
|
|
s = malloc(len + 1);
|
|
+ if (s == NULL)
|
|
+ return ENOMEM;
|
|
*s = '\0';
|
|
for(i = 0; i < num_realms; i++){
|
|
if(i && i < num_realms - 1)
|
|
@@ -379,6 +390,44 @@
|
|
}
|
|
|
|
krb5_error_code
|
|
+krb5_check_transited(krb5_context context,
|
|
+ krb5_const_realm client_realm,
|
|
+ krb5_const_realm server_realm,
|
|
+ krb5_realm *realms,
|
|
+ int num_realms,
|
|
+ int *bad_realm)
|
|
+{
|
|
+ char **tr_realms;
|
|
+ char **p;
|
|
+ int i;
|
|
+
|
|
+ if(num_realms == 0)
|
|
+ return 0;
|
|
+
|
|
+ tr_realms = krb5_config_get_strings(context, NULL,
|
|
+ "capaths",
|
|
+ client_realm,
|
|
+ server_realm,
|
|
+ NULL);
|
|
+ for(i = 0; i < num_realms; i++) {
|
|
+ for(p = tr_realms; p && *p; p++) {
|
|
+ if(strcmp(*p, realms[i]) == 0)
|
|
+ break;
|
|
+ }
|
|
+ if(p == NULL || *p == NULL) {
|
|
+ krb5_config_free_strings(tr_realms);
|
|
+ krb5_set_error_string (context, "no transit through realm %s",
|
|
+ realms[i]);
|
|
+ if(bad_realm)
|
|
+ *bad_realm = i;
|
|
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
|
|
+ }
|
|
+ }
|
|
+ krb5_config_free_strings(tr_realms);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+krb5_error_code
|
|
krb5_check_transited_realms(krb5_context context,
|
|
const char *const *realms,
|
|
int num_realms,
|