HI All
webrev at --
http://cr.openjdk.java.net/~weijun/6979329/webrev.00/
I'm not sure if there will be other type of non-ticket entries later, so
just ignore once an exception is thrown.
I'll be glad if there can be more than one code reviewers. Mostly likely
this will need to backported to update releases of JDK 6.
Thanks
Max
-------- Original Message --------
*Change Request ID*: 6979329
*Synopsis*: CCacheInputStream fails to read ticket cache files from
Kerberos 1.8.1
=== *Description*
============================================================
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux thomas 2.6.32-24-generic #39-Ubuntu SMP Wed Jul 28 05:14:15 UTC
2010 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
Kerberos 1.8.1
A DESCRIPTION OF THE PROBLEM :
Kerberos 1.8.1 introduced a new feature by which configuration settings
can be stored in the ticket cache file using a special principal name:
http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=6206
This breaks CCacheInputStream in such a way that the entire ticket cache
file is unreadable.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Install Kerberos 1.8.1 or later
- kinit
- strings /path/to/ticketcache | grep X-CACHE
If X-CACHE is in the file, then the Krb5Login module will not be able to
make use of the cache.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Ticket cache is parsed correctly with new-style configuration
credentials ignored.
ACTUAL -
Ticket cache fails to load. Debug output shows an exception trying to
parse the configuration variable "yes" as if it were an encrypted ticket.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
DEBUG <CCacheInputStream> client principal is a...@atm-local
DEBUG <CCacheInputStream> server principal is
X-CACHECONF:/krb5_ccache_conf_data/fast_avail/krbtgt/atm-lo...@atm-local
DEBUG <CCacheInputStream> key type: 0
DEBUG <CCacheInputStream> auth time: Wed Dec 31 16:00:00 PST 1969
DEBUG <CCacheInputStream> start time: Wed Dec 31 16:00:00 PST 1969
DEBUG <CCacheInputStream> end time: Wed Dec 31 16:00:00 PST 1969
DEBUG <CCacheInputStream> renew_till time: Wed Dec 31 16:00:00 PST 1969
CCacheInputStream: readFlags()
java.io.IOException: extra data given to DerValue constructor
at sun.security.util.DerValue.init(DerValue.java:368)
at sun.security.util.DerValue.<init>(DerValue.java:277)
at sun.security.krb5.internal.Ticket.<init>(Ticket.java:81)
at
sun.security.krb5.internal.ccache.CCacheInputStream.readData(CCacheInputStream.java:250)
at
sun.security.krb5.internal.ccache.CCacheInputStream.readCred(CCacheInputStream.java:357)
at
sun.security.krb5.internal.ccache.FileCredentialsCache.load(FileCredentialsCache.java:225)
at
sun.security.krb5.internal.ccache.FileCredentialsCache.acquireInstance(FileCredentialsCache.java:104)
at
sun.security.krb5.internal.ccache.CredentialsCache.getInstance(CredentialsCache.java:75)
at
sun.security.krb5.Credentials.acquireTGTFromCache(Credentials.java:309)
at
com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:589)
at
com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
On Kerberos 1.8.1, renewing the local kerberos ticket with "kinit -R"
drops the special configuration credential initially added by "kinit",
allowing this to succeed.
The following patch resolves the problem:
diff -r krb5.orig/internal/ccache/CCacheInputStream.java
krb5.new/internal/ccache/CCacheInputStream.java
362a363,367
if (isConfigurationPrincipal(spname)) {
skipLengthPrefixedData(); // skip ticket
skipLengthPrefixedData(); // skip secondary ticket
return null;
}
375a381,400
/**
* Return true if the given principal corresponds to a non-ticket
configuration
* entry in the cache file.
*/
private boolean isConfigurationPrincipal(PrincipalName princ) {
String[] components = princ.getNameStrings();
return (components.length > 2 &&
PrincipalName.CONFIGURATION_REALM.equals(components[0]) &&
PrincipalName.CONFIGURATION_NAME.equals(components[1]));
}
/**
* Read a 32-bit length from the stream and skip an equal number of bytes.
*/
private void skipLengthPrefixedData() throws IOException {
int skip = read(4);
byte[] skipbuf = new byte[skip];
read(skipbuf, 0, skip);
}
diff -r krb5.orig/internal/ccache/FileCredentialsCache.java
krb5.new/internal/ccache/FileCredentialsCache.java
189c189,192
< credentialsList.addElement(cis.readCred(version));
---
Credentials cred = cis.readCred(version);
if (cred != null) {
credentialsList.addElement(cred);
}
diff -r krb5.orig/PrincipalName.java krb5.new/PrincipalName.java
89a90,99
/**
* The realm used for non-ticket configuration data stored in ccache
*/
public static final String CONFIGURATION_REALM = "X-CACHECONF:";
/**
* The nameused for non-ticket configuration data stored in ccache
*/
public static final String CONFIGURATION_NAME = "krb5_ccache_conf_data";
*** (#1 of 1): 2010-08-24 01:26:27 GMT+00:00 [email protected]