Date: | Fri, 17 May 2013 15:29:37 -0400 |
From: | Nalin Dahyabhai <nalin@redhat.com> |
To: | krb5-bugs@mit.edu |
Subject: | Transited realm checks sometimes fail for GSSAPI |
We've gotten a report of illegal-cross-realm-ticket failures in GSSAPI
acceptor applications after updating from 1.9 to 1.10.3. In the
customer case, they're using sshd, but I can see it happen with
gss-client and gss-server, too, with both 1.10.3 and master.
When kg_accept_krb5() doesn't have a default identity to use, it calls
kg_acceptor_princ() to figure out parts of the acceptor name to be
passed to krb5_rd_req().
The name produced has its realm name field set to "". (Whether that's
supposed to mean KRB5_REFERRAL_REALM or is just the same value by
coincidence, I can't tell.)
When this server name is passed to krb5_rd_req(), and eventually to
rd_req_decoded_opt(), the ticket is successfully decrypted, but if the
ticket's transited field isn't empty, the subsequent call to
krb5_check_transited_list() attempts to compute a path from the client's
realm to a realm named "", and with the set of names in my test setup
(the client is in XXX.REDHAT.COM, the server is in ZZZ.REDHAT.COM, with
YYY.REDHAT.COM being the realm in between), the result is always
KRB5KRB_AP_ERR_ILL_CR_TKT.
Using the server principal, as specified in the ticket, which includes
the correct realm name, causes the test to succeed on my test system.
I'm appending a proposed patch.
Thanks,
Nalin
--- src/lib/krb5/krb/rd_req_dec.c
+++ src/lib/krb5/krb/rd_req_dec.c
@@ -363,11 +363,12 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
/* Hierarchical Cross-Realm */
{
- krb5_data * realm;
+ krb5_data * crealm, *srealm;
krb5_transited * trans;
- realm = &req->ticket->enc_part2->client->realm;
+ crealm = &req->ticket->enc_part2->client->realm;
trans = &(req->ticket->enc_part2->transited);
+ srealm = &req->ticket->server->realm;
/*
* If the transited list is not empty, then check that all realms
@@ -376,7 +377,7 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
*/
if (trans->tr_contents.length > 0 && trans->tr_contents.data[0]) {
retval = krb5_check_transited_list(context, &(trans->tr_contents),
- realm, &server->realm);
+ crealm, srealm);
}
}
acceptor applications after updating from 1.9 to 1.10.3. In the
customer case, they're using sshd, but I can see it happen with
gss-client and gss-server, too, with both 1.10.3 and master.
When kg_accept_krb5() doesn't have a default identity to use, it calls
kg_acceptor_princ() to figure out parts of the acceptor name to be
passed to krb5_rd_req().
The name produced has its realm name field set to "". (Whether that's
supposed to mean KRB5_REFERRAL_REALM or is just the same value by
coincidence, I can't tell.)
When this server name is passed to krb5_rd_req(), and eventually to
rd_req_decoded_opt(), the ticket is successfully decrypted, but if the
ticket's transited field isn't empty, the subsequent call to
krb5_check_transited_list() attempts to compute a path from the client's
realm to a realm named "", and with the set of names in my test setup
(the client is in XXX.REDHAT.COM, the server is in ZZZ.REDHAT.COM, with
YYY.REDHAT.COM being the realm in between), the result is always
KRB5KRB_AP_ERR_ILL_CR_TKT.
Using the server principal, as specified in the ticket, which includes
the correct realm name, causes the test to succeed on my test system.
I'm appending a proposed patch.
Thanks,
Nalin
--- src/lib/krb5/krb/rd_req_dec.c
+++ src/lib/krb5/krb/rd_req_dec.c
@@ -363,11 +363,12 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
/* Hierarchical Cross-Realm */
{
- krb5_data * realm;
+ krb5_data * crealm, *srealm;
krb5_transited * trans;
- realm = &req->ticket->enc_part2->client->realm;
+ crealm = &req->ticket->enc_part2->client->realm;
trans = &(req->ticket->enc_part2->transited);
+ srealm = &req->ticket->server->realm;
/*
* If the transited list is not empty, then check that all realms
@@ -376,7 +377,7 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
*/
if (trans->tr_contents.length > 0 && trans->tr_contents.data[0]) {
retval = krb5_check_transited_list(context, &(trans->tr_contents),
- realm, &server->realm);
+ crealm, srealm);
}
}