6659990: KerberosTicket.getEndTime does not copy date (findbugs)
Reviewed-by: mullan
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java Fri Apr 25 15:19:55 2008 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java Fri Apr 25 15:24:48 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -253,7 +253,24 @@
Date endTime,
Date renewTill,
InetAddress[] clientAddresses) {
+ if (sessionKey == null)
+ throw new IllegalArgumentException("Session key for ticket"
+ + " cannot be null");
+ init(asn1Encoding, client, server,
+ new KeyImpl(sessionKey, keyType), flags, authTime,
+ startTime, endTime, renewTill, clientAddresses);
+ }
+ private void init(byte[] asn1Encoding,
+ KerberosPrincipal client,
+ KerberosPrincipal server,
+ KeyImpl sessionKey,
+ boolean[] flags,
+ Date authTime,
+ Date startTime,
+ Date endTime,
+ Date renewTill,
+ InetAddress[] clientAddresses) {
if (asn1Encoding == null)
throw new IllegalArgumentException("ASN.1 encoding of ticket"
+ " cannot be null");
@@ -269,10 +286,8 @@
+ " cannot be null");
this.server = server;
- if (sessionKey == null)
- throw new IllegalArgumentException("Session key for ticket"
- + " cannot be null");
- this.sessionKey = new KeyImpl(sessionKey, keyType);
+ // Caller needs to make sure `sessionKey` will not be null
+ this.sessionKey = sessionKey;
if (flags != null) {
if (flags.length >= NUM_FLAGS)
@@ -291,17 +306,22 @@
throw new IllegalArgumentException("The renewable period "
+ "end time cannot be null for renewable tickets.");
- this.renewTill = renewTill;
+ this.renewTill = new Date(renewTill.getTime());
}
- this.authTime = authTime;
-
- this.startTime = (startTime != null? startTime: authTime);
+ if (authTime != null) {
+ this.authTime = new Date(authTime.getTime());
+ }
+ if (startTime != null) {
+ this.startTime = new Date(startTime.getTime());
+ } else {
+ this.startTime = this.authTime;
+ }
if (endTime == null)
throw new IllegalArgumentException("End time for ticket validity"
+ " cannot be null");
- this.endTime = endTime;
+ this.endTime = new Date(endTime.getTime());
if (clientAddresses != null)
this.clientAddresses = clientAddresses.clone();
@@ -440,7 +460,7 @@
* or null if not set.
*/
public final java.util.Date getAuthTime() {
- return (authTime == null) ? null : new Date(authTime.getTime());
+ return (authTime == null) ? null : (Date)authTime.clone();
}
/**
@@ -450,7 +470,7 @@
* or null if not set.
*/
public final java.util.Date getStartTime() {
- return (startTime == null) ? null : new Date(startTime.getTime());
+ return (startTime == null) ? null : (Date)startTime.clone();
}
/**
@@ -459,7 +479,7 @@
* @return the expiration time for this ticket's validity period.
*/
public final java.util.Date getEndTime() {
- return endTime;
+ return (Date) endTime.clone();
}
/**
@@ -469,7 +489,7 @@
* @return the latest expiration time for this ticket.
*/
public final java.util.Date getRenewTill() {
- return (renewTill == null) ? null: new Date(renewTill.getTime());
+ return (renewTill == null) ? null: (Date)renewTill.clone();
}
/**
@@ -745,4 +765,20 @@
return true;
}
+
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ if (sessionKey == null) {
+ throw new InvalidObjectException("Session key cannot be null");
+ }
+ try {
+ init(asn1Encoding, client, server, sessionKey,
+ flags, authTime, startTime, endTime,
+ renewTill, clientAddresses);
+ } catch (IllegalArgumentException iae) {
+ throw (InvalidObjectException)
+ new InvalidObjectException(iae.getMessage()).initCause(iae);
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/kerberos/KerberosTixDateTest.java Fri Apr 25 15:24:48 2008 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6659990
+ * @summary test the immutability of the Date fields in KerberosTicket class.
+ */
+
+import java.net.InetAddress;
+import java.util.Date;
+import java.io.*;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+import sun.misc.BASE64Decoder;
+
+public class KerberosTixDateTest {
+
+ // Serialized KerberosTicket from JDK6 (encoded in BASE64)
+ // Note: the KerberosTicket object is created using the same values as
+ // the KerberosTicket 't' in main(). Deserialization should succeed
+ // and the deserialized object should equal to 't'.
+ static String serializedKerberosTix =
+"rO0ABXNyACtqYXZheC5zZWN1cml0eS5hdXRoLmtlcmJlcm9zLktlcmJlcm9zVGlja2V0ZqGBbXB3" +
+"w7sCAApbAAxhc24xRW5jb2Rpbmd0AAJbQkwACGF1dGhUaW1ldAAQTGphdmEvdXRpbC9EYXRlO0wA" +
+"BmNsaWVudHQAMExqYXZheC9zZWN1cml0eS9hdXRoL2tlcmJlcm9zL0tlcmJlcm9zUHJpbmNpcGFs" +
+"O1sAD2NsaWVudEFkZHJlc3Nlc3QAF1tMamF2YS9uZXQvSW5ldEFkZHJlc3M7TAAHZW5kVGltZXEA" +
+"fgACWwAFZmxhZ3N0AAJbWkwACXJlbmV3VGlsbHEAfgACTAAGc2VydmVycQB+AANMAApzZXNzaW9u" +
+"S2V5dAAmTGphdmF4L3NlY3VyaXR5L2F1dGgva2VyYmVyb3MvS2V5SW1wbDtMAAlzdGFydFRpbWVx" +
+"AH4AAnhwdXIAAltCrPMX+AYIVOACAAB4cAAAAARhc24xc3IADmphdmEudXRpbC5EYXRlaGqBAUtZ" +
+"dBkDAAB4cHcIAAAAAAC8YU54c3IALmphdmF4LnNlY3VyaXR5LmF1dGgua2VyYmVyb3MuS2VyYmVy" +
+"b3NQcmluY2lwYWyZp31dDx4zKQMAAHhwdXEAfgAIAAAAEzARoAMCAQGhCjAIGwZjbGllbnR1cQB+" +
+"AAgAAAAVGxNKTEFCUy5TRkJBWS5TVU4uQ09NeHBxAH4AC3VyAAJbWlePIDkUuF3iAgAAeHAAAAAg" +
+"AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxAH4AC3NxAH4ADHVxAH4ACAAAABMwEaAD" +
+"AgEBoQowCBsGc2VydmVydXEAfgAIAAAAFRsTSkxBQlMuU0ZCQVkuU1VOLkNPTXhzcgAkamF2YXgu" +
+"c2VjdXJpdHkuYXV0aC5rZXJiZXJvcy5LZXlJbXBskoOG6DyvS9cDAAB4cHVxAH4ACAAAABUwE6AD" +
+ "AgEBoQwECnNlc3Npb25LZXl4cQB+AAs=";
+
+ public static void main(String[] args) throws Exception {
+ byte[] asn1Bytes = "asn1".getBytes();
+ KerberosPrincipal client = new KerberosPrincipal("client");
+ KerberosPrincipal server = new KerberosPrincipal("server");
+ byte[] keyBytes = "sessionKey".getBytes();
+ long originalTime = 12345678L;
+ Date inDate = new Date(originalTime);
+ boolean[] flags = new boolean[9];
+ flags[8] = true; // renewable
+ KerberosTicket t = new KerberosTicket(asn1Bytes, client, server,
+ keyBytes, 1 /*keyType*/, flags, inDate /*authTime*/,
+ inDate /*startTime*/, inDate /*endTime*/,
+ inDate /*renewTill*/, null /*clientAddresses*/);
+ inDate.setTime(0); // for testing the constructor
+
+ testDateImmutability(t, originalTime);
+ testS11nCompatibility(t); // S11n: Serialization
+ }
+
+ private static void checkTime(KerberosTicket kt, long timeValue) {
+ if (kt.getAuthTime().getTime() != timeValue) {
+ throw new RuntimeException("authTime check fails!");
+ }
+ if (kt.getStartTime().getTime() != timeValue) {
+ throw new RuntimeException("startTime check fails!");
+ }
+ if (kt.getEndTime().getTime() != timeValue) {
+ throw new RuntimeException("endTime check fails!");
+ }
+ if (kt.getRenewTill().getTime() != timeValue) {
+ throw new RuntimeException("renewTill check fails!");
+ }
+ }
+
+ private static void testDateImmutability(KerberosTicket t, long origTime)
+ throws Exception {
+ // test the constructor
+ System.out.println("Testing constructor...");
+ checkTime(t, origTime);
+
+ // test the getAuth/Start/EndTime() & getRenewTill() methods
+ System.out.println("Testing getAuth/Start/EndTime() & getRenewTill()...");
+ t.getAuthTime().setTime(0);
+ t.getStartTime().setTime(0);
+ t.getEndTime().setTime(0);
+ t.getRenewTill().setTime(0);
+ checkTime(t, origTime);
+
+ System.out.println("DateImmutability Test Passed");
+ }
+
+ private static void checkEqualsAndHashCode(byte[] bytes, KerberosTicket t)
+ throws IOException, ClassNotFoundException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ KerberosTicket deserializedTicket = (KerberosTicket)
+ (new ObjectInputStream(bais).readObject());
+ if (!deserializedTicket.equals(t)) {
+ throw new RuntimeException("equals() check fails!");
+ }
+ if (deserializedTicket.hashCode() != t.hashCode()) {
+ throw new RuntimeException("hashCode() check fails!");
+ }
+ }
+
+ private static void testS11nCompatibility(KerberosTicket t)
+ throws Exception {
+
+ System.out.println("Testing against KerberosTicket from JDK6...");
+ byte[] serializedBytes =
+ new BASE64Decoder().decodeBuffer(serializedKerberosTix);
+ checkEqualsAndHashCode(serializedBytes, t);
+
+ System.out.println("Testing against KerberosTicket from current rel...");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(t);
+ checkEqualsAndHashCode(baos.toByteArray(), t);
+
+ System.out.println("S11nCompatibility Test Passed");
+ }
+}