Add support for Kerberos principal name canonicalization and cross-realm referrals as described by [RFC 6806] protocol extension.
The OpenJDK Kerberos client does not support [RFC 6806] principal name canonicalization nor cross-realm referrals in Authentication Service (AS) and Ticket-Granting Service (TGS) protocols. As a consequence, it cannot take advantage of more dynamic environment configurations and need to know (in advanced) how to reach the realm of the target principal (user or service).
Implement [RFC 6068] on top of the, already supported, [RFC 4120] cross-realm referrals feature. The OpenJDK Kerberos client will announce support of [RFC 6068] when sending AS-REQ and TGS-REQ requests to a server. If the server supports [RFC 6068], both parties will proceed as defined in the referred document. If the server does not support [RFC 6068], the client announcement should be ignored. In cases in which the server sends an error after -and, probably, as a consequence-of- the announcement, the client will retry without claiming support of [RFC 6068]. This latter scheme acts as a backward compatibility fallback and mitigates the risk of changing the previous client behavior.
**Client (AS-REQ) and server (TGS-REQ) referrals**
When issuing AS-REQ and TGS-REQ requests, the Kerberos client sets the *canonicalize* option to announce support of [RFC 6068] client and server referrals respectively.
If a KDC_ERR_WRONG_REALM is received in response to a AS-REQ, and the number of requests currently issued is below the limit (see *sun.security.krb5.maxReferrals* system property below), the client issues a new request to the referred realm.
If a referral TGT is received in response to a TGS-REQ, and the number of requests currently issued is below the limit (see *sun.security.krb5.maxReferrals* system property below), the client issues a new request to the referred realm. The TGT referral ticket is sent as part of the new request.
If a server error is received after a AS-REQ or TGS-REQ is sent, the client retries without setting the *canonicalize* option and announcing support of [RFC 6068]. The cross-referrals feature will be temporary disabled throughout the communication. This is a backward compatibility fallback mode.
**capaths and domain_realm configurations**
Previous to [RFC 6806] cross-realm referrals implementation, *capaths* configuration and the DNS hierarchy were used to statically or heuristically obtain a cross-realm TGT. A cross-realm TGT belongs to the same realm than the target principal and can be used to finally obtain the corresponding TGS. This is described by [RFC 4120] (section 1.2. Cross-Realm Operation) and still holds true after [RFC 6806].
The difference with [RFC 6806] is that upon receiving a dynamic-referral (as a result of any request), the next request targets the referred realm and is no longer a [RFC 4120] cross-realm operation. In other words, service realm for the next request matches the one in the credentials that will be used (which are the referral-TGT previously received).
domain_realm configuration is used to map DNS names to realms. When creating a service principal without a realm, this map is used to determine its realm. This map may also be used to find the default realm for the local host. A service principal realm is used in the first place when requesting a ticket. Cross-realm referrals may be followed afterwards.
**Enterprise Principal Name Type**
NT-ENTERPRISE principals are supported by the client library. When issuing a AS-REQ request with a NT-ENTERPRISE principal, *canonicalize* option turns mandatory.
Principal name changes are allowed in AS-REQ responses only if 1) *canonicalize* option was set in the AS-REQ request, 2) PA-REQ-ENC-PA-REP pre-authentication data was sent in the AS-REQ response (meaning the server supports [RFC 6068] FAST scheme) and 3) the authenticated checksum is correct.
Principal name changes are allowed in TGS-REQ responses only if 1) *canonicalize* option was set in the TGS-REQ request, and 2) *sname* has a referral value of the form *krbtgt/TO-REALM.COM@FROM-REALM.COM*.
Principal name changes are NOT allowed in other cases and a KRB_AP_ERR_MODIFIED exception is thrown.
TGT referral tickets (received in response to TGS-REQ requests) are saved in a in-memory cache until they expire. When a TGS-REQ request is issued, the cache is scrutinized. If a TGT referral ticket is available, it's used instead of sending a new request. As suggested by [RFC 6806], this minimizes the network traffic and speeds up the process.
If a loop is introduced when adding a new referral TGT to the cache, the loop is broken by removing the *next* referred TGT.
Adding a TGT referral ticket to the cache may override a previous one, under the assumption that newer information is more accurate.
Flexible Authentication Secure Tunneling (FAST) scheme described in [RFC 6068] Section 11 is supported. Complete FAST support as described in [RFC 6113] is out of scope.
PA-REQ-ENC-PA-REP pre-authentication data is sent in AS-REQ requests and responses are verified as previously described (see *Name canonicalization*). PA-REQ-ENC-PA-REP pre-authentication data is sent for TGS-REQ requests but response verification is not enforced for compatibility reasons.
Review thread: http://mail.openjdk.java.net/pipermail/security-dev/2018-December/018952.html
Proposed webrev: http://cr.openjdk.java.net/~mbalao/webrevs/8215032/8215032.webrev.02/
The following Security and System properties are introduced:
- sun.security.krb5.disableReferrals (default value: *false*)
- When *true*, completely disables support for [RFC 6806] principal name canonicalization and cross-realm referrals. Note: cross-realm referrals defined by [RFC 4120] remain enabled.
- sun.security.krb5.maxReferrals (default value: *5*)
- Limit the number of cross-realm referrals to avoid infinite loops. Default value is suggested by [RFC 6806].
Note that *sun.security.krb5.disableReferrals* and *sun.security.krb5.maxReferrals* Security properties persist in the *java.security* configuration file and can be overwritten in run time by their corresponding System properties.
A KRB_NT_ENTERPRISE public static field is added to *javax.security.auth.kerberos.KerberosPrincipal* class, with value *10* (as specified by [RFC 4120 section 6.2. Principal Names]).