From 8249846a75d3f44ab4cee83fb7fcb0943b2abdcc Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 22 Sep 2009 16:11:23 -0700 Subject: [PATCH 01/22] 6468534: (reflect) Exception types cannot be parameterized, rephrase getGenericExceptionTypes Reviewed-by: alanb --- jdk/src/share/classes/java/lang/reflect/Constructor.java | 4 ---- jdk/src/share/classes/java/lang/reflect/Method.java | 4 ---- 2 files changed, 8 deletions(-) diff --git a/jdk/src/share/classes/java/lang/reflect/Constructor.java b/jdk/src/share/classes/java/lang/reflect/Constructor.java index bdd158a3eb8..ae812ad72f5 100644 --- a/jdk/src/share/classes/java/lang/reflect/Constructor.java +++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java @@ -275,10 +275,6 @@ public final * Returns an array of length 0 if the underlying method declares * no exceptions in its {@code throws} clause. * - *

If an exception type is a parameterized type, the {@code Type} - * object returned for it must accurately reflect the actual type - * parameters used in the source code. - * *

If an exception type is a type variable or a parameterized * type, it is created. Otherwise, it is resolved. * diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java index 1c660f2dca8..fc9e467ae48 100644 --- a/jdk/src/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/share/classes/java/lang/reflect/Method.java @@ -317,10 +317,6 @@ public final * Returns an array of length 0 if the underlying method declares * no exceptions in its {@code throws} clause. * - *

If an exception type is a parameterized type, the {@code Type} - * object returned for it must accurately reflect the actual type - * parameters used in the source code. - * *

If an exception type is a type variable or a parameterized * type, it is created. Otherwise, it is resolved. * From 4e63c9bc06dd2e8752ee4f823772145158531907 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 22 Sep 2009 18:30:58 -0700 Subject: [PATCH 02/22] 4245470: algorithm of java.lang.Byte.hashCode() is not specified Specify some hashCode methods are equivalent to intValue Reviewed-by: darcy --- jdk/src/share/classes/java/lang/Byte.java | 5 +- .../share/classes/java/lang/Character.java | 6 +- jdk/src/share/classes/java/lang/Short.java | 5 +- jdk/test/java/lang/HashCode.java | 80 +++++++++++++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/lang/HashCode.java diff --git a/jdk/src/share/classes/java/lang/Byte.java b/jdk/src/share/classes/java/lang/Byte.java index 459c2237a18..0650b0af879 100644 --- a/jdk/src/share/classes/java/lang/Byte.java +++ b/jdk/src/share/classes/java/lang/Byte.java @@ -378,7 +378,10 @@ public final class Byte extends Number implements Comparable { } /** - * Returns a hash code for this {@code Byte}. + * Returns a hash code for this {@code Byte}; equal to the result + * of invoking {@code intValue()}. + * + * @return a hash code value for this {@code Byte} */ public int hashCode() { return (int)value; diff --git a/jdk/src/share/classes/java/lang/Character.java b/jdk/src/share/classes/java/lang/Character.java index bc4284c20df..2d1ece383bb 100644 --- a/jdk/src/share/classes/java/lang/Character.java +++ b/jdk/src/share/classes/java/lang/Character.java @@ -2612,8 +2612,10 @@ class Character extends Object implements java.io.Serializable, ComparableCharacter. - * @return a hash code value for this object. + * Returns a hash code for this {@code Character}; equal to the result + * of invoking {@code charValue()}. + * + * @return a hash code value for this {@code Character} */ public int hashCode() { return (int)value; diff --git a/jdk/src/share/classes/java/lang/Short.java b/jdk/src/share/classes/java/lang/Short.java index a2d98b277ee..fdd5f15107f 100644 --- a/jdk/src/share/classes/java/lang/Short.java +++ b/jdk/src/share/classes/java/lang/Short.java @@ -383,7 +383,10 @@ public final class Short extends Number implements Comparable { } /** - * Returns a hash code for this {@code Short}. + * Returns a hash code for this {@code Short}; equal to the result + * of invoking {@code intValue()}. + * + * @return a hash code value for this {@code Short} */ public int hashCode() { return (int)value; diff --git a/jdk/test/java/lang/HashCode.java b/jdk/test/java/lang/HashCode.java new file mode 100644 index 00000000000..6d62facea7b --- /dev/null +++ b/jdk/test/java/lang/HashCode.java @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Google, 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 4245470 + * @summary Test the primitive wrappers hashCode() + */ + +import java.util.Random; + +public class HashCode { + + final Random rnd = new Random(); + + void test(String args[]) throws Exception { + int[] ints = { + Integer.MIN_VALUE, + Short.MIN_VALUE, + Character.MIN_VALUE, + Byte.MIN_VALUE, + -1, 0, 1, + Byte.MAX_VALUE, + Character.MAX_VALUE, + Short.MAX_VALUE, + Integer.MAX_VALUE, + rnd.nextInt(), + }; + + for (int x : ints) { + check( new Long(x).hashCode() == (int)((long)x ^ (long)x>>>32)); + check(Long.valueOf(x).hashCode() == (int)((long)x ^ (long)x>>>32)); + check( new Integer(x).hashCode() == x); + check(Integer.valueOf(x).hashCode() == x); + check( new Short((short)x).hashCode() == (short) x); + check(Short.valueOf((short)x).hashCode() == (short) x); + check( new Character((char) x).hashCode() == (char) x); + check(Character.valueOf((char) x).hashCode() == (char) x); + check( new Byte((byte) x).hashCode() == (byte) x); + check(Byte.valueOf((byte) x).hashCode() == (byte) x); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new HashCode().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From beaa8fd82d08d364d9503e80a497e50d197f78f3 Mon Sep 17 00:00:00 2001 From: Kevin Bourrillion Date: Tue, 22 Sep 2009 18:30:58 -0700 Subject: [PATCH 03/22] 6582946: Add suite of compare(T, T) methods for ints, longs etc Reviewed-by: darcy --- jdk/src/share/classes/java/lang/Boolean.java | 20 ++- jdk/src/share/classes/java/lang/Byte.java | 20 ++- .../share/classes/java/lang/Character.java | 20 ++- jdk/src/share/classes/java/lang/Integer.java | 22 ++- jdk/src/share/classes/java/lang/Long.java | 22 ++- jdk/src/share/classes/java/lang/Short.java | 20 ++- jdk/test/java/lang/Compare.java | 142 ++++++++++++++++++ 7 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 jdk/test/java/lang/Compare.java diff --git a/jdk/src/share/classes/java/lang/Boolean.java b/jdk/src/share/classes/java/lang/Boolean.java index b614dafdaae..8a3d6ab996e 100644 --- a/jdk/src/share/classes/java/lang/Boolean.java +++ b/jdk/src/share/classes/java/lang/Boolean.java @@ -255,7 +255,25 @@ public final class Boolean implements java.io.Serializable, * @since 1.5 */ public int compareTo(Boolean b) { - return (b.value == value ? 0 : (value ? 1 : -1)); + return compare(this.value, b.value); + } + + /** + * Compares two {@code boolean} values. + * The value returned is identical to what would be returned by: + *

+     *    Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
+     * 
+ * + * @param x the first {@code boolean} to compare + * @param y the second {@code boolean} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code !x && y}; and + * a value greater than {@code 0} if {@code x && !y} + * @since 1.7 + */ + public static int compare(boolean x, boolean y) { + return (x == y) ? 0 : (x ? 1 : -1); } private static boolean toBoolean(String name) { diff --git a/jdk/src/share/classes/java/lang/Byte.java b/jdk/src/share/classes/java/lang/Byte.java index 0650b0af879..4725f3278b7 100644 --- a/jdk/src/share/classes/java/lang/Byte.java +++ b/jdk/src/share/classes/java/lang/Byte.java @@ -418,7 +418,25 @@ public final class Byte extends Number implements Comparable { * @since 1.2 */ public int compareTo(Byte anotherByte) { - return this.value - anotherByte.value; + return compare(this.value, anotherByte.value); + } + + /** + * Compares two {@code byte} values numerically. + * The value returned is identical to what would be returned by: + *
+     *    Byte.valueOf(x).compareTo(Byte.valueOf(y))
+     * 
+ * + * @param x the first {@code byte} to compare + * @param y the second {@code byte} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code x < y}; and + * a value greater than {@code 0} if {@code x > y} + * @since 1.7 + */ + public static int compare(byte x, byte y) { + return x - y; } /** diff --git a/jdk/src/share/classes/java/lang/Character.java b/jdk/src/share/classes/java/lang/Character.java index 2d1ece383bb..8f106a473dd 100644 --- a/jdk/src/share/classes/java/lang/Character.java +++ b/jdk/src/share/classes/java/lang/Character.java @@ -4964,7 +4964,25 @@ class Character extends Object implements java.io.Serializable, Comparable + * Character.valueOf(x).compareTo(Character.valueOf(y)) + * + * + * @param x the first {@code char} to compare + * @param y the second {@code char} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code x < y}; and + * a value greater than {@code 0} if {@code x > y} + * @since 1.7 + */ + public static int compare(char x, char y) { + return x - y; } /** diff --git a/jdk/src/share/classes/java/lang/Integer.java b/jdk/src/share/classes/java/lang/Integer.java index a66a8fae792..1c457c548e7 100644 --- a/jdk/src/share/classes/java/lang/Integer.java +++ b/jdk/src/share/classes/java/lang/Integer.java @@ -1010,9 +1010,25 @@ public final class Integer extends Number implements Comparable { * @since 1.2 */ public int compareTo(Integer anotherInteger) { - int thisVal = this.value; - int anotherVal = anotherInteger.value; - return (thisVal + * Integer.valueOf(x).compareTo(Integer.valueOf(y)) + * + * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code x < y}; and + * a value greater than {@code 0} if {@code x > y} + * @since 1.7 + */ + public static int compare(int x, int y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); } diff --git a/jdk/src/share/classes/java/lang/Long.java b/jdk/src/share/classes/java/lang/Long.java index 58014997f35..c5fd7ee5e29 100644 --- a/jdk/src/share/classes/java/lang/Long.java +++ b/jdk/src/share/classes/java/lang/Long.java @@ -950,9 +950,25 @@ public final class Long extends Number implements Comparable { * @since 1.2 */ public int compareTo(Long anotherLong) { - long thisVal = this.value; - long anotherVal = anotherLong.value; - return (thisVal + * Long.valueOf(x).compareTo(Long.valueOf(y)) + * + * + * @param x the first {@code long} to compare + * @param y the second {@code long} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code x < y}; and + * a value greater than {@code 0} if {@code x > y} + * @since 1.7 + */ + public static int compare(long x, long y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); } diff --git a/jdk/src/share/classes/java/lang/Short.java b/jdk/src/share/classes/java/lang/Short.java index fdd5f15107f..cf1551da8e5 100644 --- a/jdk/src/share/classes/java/lang/Short.java +++ b/jdk/src/share/classes/java/lang/Short.java @@ -423,7 +423,25 @@ public final class Short extends Number implements Comparable { * @since 1.2 */ public int compareTo(Short anotherShort) { - return this.value - anotherShort.value; + return compare(this.value, anotherShort.value); + } + + /** + * Compares two {@code short} values numerically. + * The value returned is identical to what would be returned by: + *
+     *    Short.valueOf(x).compareTo(Short.valueOf(y))
+     * 
+ * + * @param x the first {@code short} to compare + * @param y the second {@code short} to compare + * @return the value {@code 0} if {@code x == y}; + * a value less than {@code 0} if {@code x < y}; and + * a value greater than {@code 0} if {@code x > y} + * @since 1.7 + */ + public static int compare(short x, short y) { + return x - y; } /** diff --git a/jdk/test/java/lang/Compare.java b/jdk/test/java/lang/Compare.java new file mode 100644 index 00000000000..ea2fa580653 --- /dev/null +++ b/jdk/test/java/lang/Compare.java @@ -0,0 +1,142 @@ +/* + * Copyright 2009 Google, 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 6582946 + * @summary Test the primitive wrappers compare and compareTo methods + */ + +import java.util.Random; + +public class Compare { + + final Random rnd = new Random(); + + boolean toBoolean(long x) { return x > 0; } + + void compareAll(long x, long y) { + check(Double.compare(x, y) == + Double.valueOf(x).compareTo(Double.valueOf(y))); + check(Float.compare(x, y) == + Float.valueOf(x).compareTo(Float.valueOf(y))); + check(Long.compare(x, y) == + Long.valueOf(x).compareTo(Long.valueOf(y))); + check(Integer.compare((int) x, (int) y) == + Integer.valueOf((int) x).compareTo(Integer.valueOf((int) y))); + check(Short.compare((short) x, (short) y) == + Short.valueOf((short) x).compareTo(Short.valueOf((short) y))); + check(Character.compare((char) x, (char) y) == + Character.valueOf((char) x).compareTo(Character.valueOf((char) y))); + check(Byte.compare((byte) x, (byte) y) == + Byte.valueOf((byte) x).compareTo(Byte.valueOf((byte) y))); + check(Boolean.compare(toBoolean(x), toBoolean(y)) == + Boolean.valueOf(toBoolean(x)).compareTo(Boolean.valueOf(toBoolean(y)))); + + check(Double.compare(x, y) == -Double.compare(y, x)); + check(Float.compare(x, y) == -Float.compare(y, x)); + check(Long.compare(x, y) == -Long.compare(y, x)); + check(Integer.compare((int) x, (int) y) == + -Integer.compare((int) y, (int) x)); + check(Short.compare((short) x, (short) y) == + -Short.compare((short) y, (short) x)); + check(Character.compare((char) x, (char) y) == + -Character.compare((char) y, (char) x)); + check(Byte.compare((byte) x, (byte) y) == + -Byte.compare((byte) y, (byte) x)); + + equal(Long.compare(x, y), + x < y ? -1 : x > y ? 1 : 0); + + { + int a = (int) x, b = (int) y; + equal(Integer.compare(a, b), + a < b ? -1 : a > b ? 1 : 0); + } + + { + short a = (short) x, b = (short) y; + equal(Short.compare(a, b), + a - b); + } + + { + char a = (char) x, b = (char) y; + equal(Character.compare(a, b), + a - b); + } + + { + byte a = (byte) x, b = (byte) y; + equal(Byte.compare(a, b), + a - b); + } + + { + boolean a = toBoolean(x), b = toBoolean(y); + equal(Boolean.compare(a, b), + a == b ? 0 : a ? 1 : -1); + } + } + + void test(String args[]) throws Exception { + long[] longs = { + Long.MIN_VALUE, + Integer.MIN_VALUE, + Short.MIN_VALUE, + Character.MIN_VALUE, + Byte.MIN_VALUE, + -1, 0, 1, + Byte.MAX_VALUE, + Character.MAX_VALUE, + Short.MAX_VALUE, + Integer.MAX_VALUE, + Long.MAX_VALUE, + rnd.nextLong(), + rnd.nextInt(), + }; + + for (long x : longs) { + for (long y : longs) { + compareAll(x, y); + } + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new Compare().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From a4622c3ab0b5ba9b2ad2449397876afffaf53dfc Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 24 Sep 2009 21:35:34 +0800 Subject: [PATCH 04/22] 6885166: regression test for 6877357 (IPv6 address does not work) error (timed out) Reviewed-by: xuelei --- jdk/test/sun/security/krb5/IPv6.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jdk/test/sun/security/krb5/IPv6.java b/jdk/test/sun/security/krb5/IPv6.java index 763745f8fba..768a10f5a16 100644 --- a/jdk/test/sun/security/krb5/IPv6.java +++ b/jdk/test/sun/security/krb5/IPv6.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6877357 + * @bug 6877357 6885166 * @summary IPv6 address does not work */ @@ -57,6 +57,7 @@ public class IPv6 { PrintStream out = new PrintStream(new FileOutputStream("ipv6.conf")); out.println("[libdefaults]"); out.println("default_realm = V6"); + out.println("kdc_timeout = 1"); out.println("[realms]"); out.println("V6 = {"); for (String[] hp: kdcs) { @@ -95,10 +96,12 @@ public class IPv6 { po.flush(); System.setOut(oldout); - String[] lines = new String(bo.toByteArray()).split("\n"); + BufferedReader br = new BufferedReader(new StringReader( + new String(bo.toByteArray()))); int cc = 0; Pattern r = Pattern.compile(".*KrbKdcReq send: kdc=(.*) UDP:(\\d+),.*"); - for (String line: lines) { + String line; + while ((line = br.readLine()) != null) { Matcher m = r.matcher(line.subSequence(0, line.length())); if (m.matches()) { System.out.println("------------------"); From ef945f97223869b1be6534c77d138fb4414ac8e7 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Tue, 29 Sep 2009 10:00:57 +0100 Subject: [PATCH 05/22] 6886108: Test case B4933582 binding to fixed port number Reviewed-by: chegar --- jdk/test/java/net/Authenticator/B4933582.java | 26 +++++++++++++++++-- .../sun/net/www/httptest/HttpTransaction.java | 3 ++- .../net/www/httpstest/HttpTransaction.java | 3 ++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/jdk/test/java/net/Authenticator/B4933582.java b/jdk/test/java/net/Authenticator/B4933582.java index 1ea04ae08d3..aa41ce045ee 100644 --- a/jdk/test/java/net/Authenticator/B4933582.java +++ b/jdk/test/java/net/Authenticator/B4933582.java @@ -125,9 +125,16 @@ public class B4933582 implements HttpCallback { firstTime = args[0].equals ("first"); MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); - AuthCacheValue.setAuthCache (new CacheImpl()); + CacheImpl cache; try { - server = new HttpServer (new B4933582(), 1, 10, 5009); + if (firstTime) { + server = new HttpServer (new B4933582(), 1, 10, 0); + cache = new CacheImpl (server.getLocalPort()); + } else { + cache = new CacheImpl (); + server = new HttpServer(new B4933582(), 1, 10, cache.getPort()); + } + AuthCacheValue.setAuthCache (cache); System.out.println ("Server: listening on port: " + server.getLocalPort()); client ("http://localhost:"+server.getLocalPort()+"/d1/foo.html"); } catch (Exception e) { @@ -172,8 +179,15 @@ public class B4933582 implements HttpCallback { static class CacheImpl extends AuthCacheImpl { HashMap map; + int port; // need to store the port number the server is using + CacheImpl () throws IOException { + this (-1); + } + + CacheImpl (int port) throws IOException { super(); + this.port = port; File src = new File ("cache.ser"); if (src.exists()) { ObjectInputStream is = new ObjectInputStream ( @@ -181,6 +195,8 @@ public class B4933582 implements HttpCallback { ); try { map = (HashMap)is.readObject (); + this.port = (Integer)is.readObject (); + System.out.println ("read port from file " + port); } catch (ClassNotFoundException e) { assert false; } @@ -192,6 +208,10 @@ public class B4933582 implements HttpCallback { setMap (map); } + int getPort () { + return port; + } + private void writeMap () { try { File dst = new File ("cache.ser"); @@ -203,6 +223,8 @@ public class B4933582 implements HttpCallback { new FileOutputStream (dst) ); os.writeObject(map); + os.writeObject(port); + System.out.println ("wrote port " + port); os.close(); } catch (IOException e) {} } diff --git a/jdk/test/sun/net/www/httptest/HttpTransaction.java b/jdk/test/sun/net/www/httptest/HttpTransaction.java index 37cdf0e0ab8..81b0d82d491 100644 --- a/jdk/test/sun/net/www/httptest/HttpTransaction.java +++ b/jdk/test/sun/net/www/httptest/HttpTransaction.java @@ -102,7 +102,8 @@ public class HttpTransaction { if (rspheaders != null) { buf.append (rspheaders.toString()).append("\r\n"); } - buf.append ("Body: ").append (new String(rspbody)).append("\r\n"); + String rbody = rspbody == null? "": new String (rspbody); + buf.append ("Body: ").append (rbody).append("\r\n"); return new String (buf); } diff --git a/jdk/test/sun/security/ssl/sun/net/www/httpstest/HttpTransaction.java b/jdk/test/sun/security/ssl/sun/net/www/httpstest/HttpTransaction.java index 058632abb19..3d011a41db6 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/httpstest/HttpTransaction.java +++ b/jdk/test/sun/security/ssl/sun/net/www/httpstest/HttpTransaction.java @@ -102,7 +102,8 @@ public class HttpTransaction { if (rspheaders != null) { buf.append (rspheaders.toString()).append("\r\n"); } - buf.append ("Body: ").append (new String(rspbody)).append("\r\n"); + String rbody = rspbody == null? "": new String (rspbody); + buf.append ("Body: ").append (rbody).append("\r\n"); return new String (buf); } From 3bb6edd16751427aff022f67e38467d123de3022 Mon Sep 17 00:00:00 2001 From: Pavel Tisnovsky Date: Wed, 30 Sep 2009 11:49:10 +0200 Subject: [PATCH 06/22] 6884837: JTReg test SetOutgoingIf is not correct Added check of network interfaces status Reviewed-by: alanb, chegar --- jdk/test/java/net/MulticastSocket/SetOutgoingIf.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java index d24b03c79f3..d793f196215 100644 --- a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java +++ b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java @@ -70,7 +70,8 @@ public class SetOutgoingIf { // List nics = new ArrayList(); for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) { - if (!nic.isLoopback()) + // we should use only network interfaces with multicast support which are in "up" state + if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp()) nics.add(nic); } if (nics.size() <= 1) { From fcaded312e2c212707c817076567c07ff18f7f57 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 2 Oct 2009 18:44:34 +0800 Subject: [PATCH 07/22] 6324292: keytool -help is unhelpful Reviewed-by: xuelei, mullan --- .../classes/sun/security/tools/KeyTool.java | 609 ++++++++---------- .../classes/sun/security/util/Resources.java | 271 ++++---- .../sun/security/tools/keytool/newhelp.sh | 53 ++ 3 files changed, 450 insertions(+), 483 deletions(-) create mode 100644 jdk/test/sun/security/tools/keytool/newhelp.sh diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index 8f9e86ee063..df686a732c3 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -76,6 +76,7 @@ import sun.security.util.DerValue; import sun.security.x509.*; import static java.security.KeyStore.*; +import static sun.security.tools.KeyTool.Command.*; /** * This tool manages keystores. @@ -92,7 +93,7 @@ import static java.security.KeyStore.*; public final class KeyTool { private boolean debug = false; - private int command = -1; + private Command command = null; private String sigAlgName = null; private String keyAlgName = null; private boolean verbose = false; @@ -146,24 +147,132 @@ public final class KeyTool { private List v3ext = new ArrayList (); - private static final int CERTREQ = 1; - private static final int CHANGEALIAS = 2; - private static final int DELETE = 3; - private static final int EXPORTCERT = 4; - private static final int GENKEYPAIR = 5; - private static final int GENSECKEY = 6; - // there is no HELP - private static final int IDENTITYDB = 7; - private static final int IMPORTCERT = 8; - private static final int IMPORTKEYSTORE = 9; - private static final int KEYCLONE = 10; - private static final int KEYPASSWD = 11; - private static final int LIST = 12; - private static final int PRINTCERT = 13; - private static final int SELFCERT = 14; - private static final int STOREPASSWD = 15; - private static final int GENCERT = 16; - private static final int PRINTCERTREQ = 17; + enum Command { + CERTREQ("Generates a certificate request", + "-alias", "-sigalg", "-file", "-keypass", "-keystore", + "-storepass", "-storetype", "-providername", "-providerclass", + "-providerarg", "-providerpath", "-v", "-protected"), + CHANGEALIAS("Changes an entry's alias", + "-alias", "-destalias", "-keypass", "-keystore", "-storepass", + "-storetype", "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v", "-protected"), + DELETE("Deletes an entry", + "-alias", "-keystore", "-storepass", "-storetype", + "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v", "-protected"), + EXPORTCERT("Exports certificate", + "-rfc", "-alias", "-file", "-keystore", "-storepass", + "-storetype", "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v", "-protected"), + GENKEYPAIR("Generates a key pair", + "-alias", "-keyalg", "-keysize", "-sigalg", "-destalias", + "-startdate", "-ext", "-validity", "-keypass", "-keystore", + "-storepass", "-storetype", "-providername", "-providerclass", + "-providerarg", "-providerpath", "-v", "-protected"), + GENSECKEY("Generates a secret key", + "-alias", "-keypass", "-keyalg", "-keysize", "-keystore", + "-storepass", "-storetype", "-providername", "-providerclass", + "-providerarg", "-providerpath", "-v", "-protected"), + GENCERT("Generates certificate from a certificate request", + "-rfc", "-infile", "-outfile", "-alias", "-sigalg", + "-startdate", "-ext", "-validity", "-keypass", "-keystore", + "-storepass", "-storetype", "-providername", "-providerclass", + "-providerarg", "-providerpath", "-v", "-protected"), + IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database", + "-file", "-storetype", "-keystore", "-storepass", "-providername", + "-providerclass", "-providerarg", "-providerpath", "-v"), + IMPORTCERT("Imports a certificate or a certificate chain", + "-noprompt", "-trustcacerts", "-protected", "-alias", "-file", + "-keypass", "-keystore", "-storepass", "-storetype", + "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v"), + IMPORTKEYSTORE("Imports one or all entries from another keystore", + "-srckeystore", "-destkeystore", "-srcstoretype", + "-deststoretype", "-srcstorepass", "-deststorepass", + "-srcprotected", "-srcprovidername", "-destprovidername", + "-srcalias", "-destalias", "-srckeypass", "-destkeypass", + "-noprompt", "-providerclass", "-providerarg", "-providerpath", + "-v"), + KEYCLONE("Clones a key entry", + "-alias", "-destalias", "-keypass", "-new", "-storetype", + "-keystore", "-storepass", "-providername", "-providerclass", + "-providerarg", "-providerpath", "-v"), + KEYPASSWD("Changes the key password of an entry", + "-alias", "-keypass", "-new", "-keystore", "-storepass", + "-storetype", "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v"), + LIST("Lists entries in a keystore", + "-rfc", "-alias", "-keystore", "-storepass", "-storetype", + "-providername", "-providerclass", "-providerarg", + "-providerpath", "-v", "-protected"), + PRINTCERT("Prints the content of a certificate", + "-rfc", "-file", "-sslserver", "-v"), + PRINTCERTREQ("Prints the content of a certificate request", + "-file", "-v"), + SELFCERT("Generates a self-signed certificate", + "-alias", "-sigalg", "-dname", "-startdate", "-validity", "-keypass", + "-storetype", "-keystore", "-storepass", "-providername", + "-providerclass", "-providerarg", "-providerpath", "-v"), + STOREPASSWD("Changes the store password of a keystore", + "-new", "-keystore", "-storepass", "-storetype", "-providername", + "-providerclass", "-providerarg", "-providerpath", "-v"); + + final String description; + final String[] options; + Command(String d, String... o) { + description = d; + options = o; + } + @Override + public String toString() { + return "-" + name().toLowerCase(Locale.ENGLISH); + } + }; + + private static String[][] options = { + // name, arg, description + {"-alias", "", "alias name of the entry to process"}, + {"-destalias", "", "destination alias"}, + {"-destkeypass", "", "destination key password"}, + {"-destkeystore", "", "destination keystore name"}, + {"-destprotected", null, "destination keystore password protected"}, + {"-destprovidername", "", "destination keystore provider name"}, + {"-deststorepass", "", "destination keystore password"}, + {"-deststoretype", "", "destination keystore type"}, + {"-dname", "", "distinguished name"}, + {"-ext", "", "X.509 extension"}, + {"-file", "", "output file name"}, + {"-file", "", "input file name"}, + {"-infile", "", "input file name"}, + {"-keyalg", "", "key algorithm name"}, + {"-keypass", "", "key password"}, + {"-keysize", "", "key bit size"}, + {"-keystore", "", "keystore name"}, + {"-new", "", "new password"}, + {"-noprompt", null, "do not prompt"}, + {"-outfile", "", "output file name"}, + {"-protected", null, "password through protected mechanism"}, + {"-providerarg", "", "provider argument"}, + {"-providerclass", "", "provider class name"}, + {"-providername", "", "provider name"}, + {"-providerpath", "", "provider classpath"}, + {"-rfc", null, "output in RFC style"}, + {"-sigalg", "", "signature algorithm name"}, + {"-srcalias", "", "source alias"}, + {"-srckeypass", "", "source keystore password"}, + {"-srckeystore", "", "source keystore name"}, + {"-srcprotected", null, "source keystore password protected"}, + {"-srcprovidername", "", "source keystore provider name"}, + {"-srcstorepass", "", "source keystore password"}, + {"-srcstoretype", "", "source keystore type"}, + {"-sslserver", "", "SSL server host and port"}, + {"-startdate", "", "certificate validity start date/time"}, + {"-storepass", "", "keystore password"}, + {"-storetype", "", "keystore type"}, + {"-trustcacerts", null, "trust certificates from cacerts"}, + {"-v", null, "verbose output"}, + {"-validity", "", "validity number of days"}, + }; private static final Class[] PARAM_STRING = { String.class }; @@ -192,7 +301,7 @@ public final class KeyTool { private void run(String[] args, PrintStream out) throws Exception { try { parseArgs(args); - if (command != -1) { + if (command != null) { doCommands(out); } } catch (Exception e) { @@ -224,59 +333,50 @@ public final class KeyTool { */ void parseArgs(String[] args) { - if (args.length == 0) { - usage(); - return; - } - int i=0; + boolean help = args.length == 0; for (i=0; (i < args.length) && args[i].startsWith("-"); i++) { String flags = args[i]; + + // Check if the last option needs an arg + if (i == args.length - 1) { + for (String[] option: options) { + // Only options with an arg need to be checked + if (collator.compare(flags, option[0]) == 0) { + if (option[1] != null) errorNeedArgument(flags); + break; + } + } + } + /* * command modes */ - if (collator.compare(flags, "-certreq") == 0) { - command = CERTREQ; - } else if (collator.compare(flags, "-delete") == 0) { - command = DELETE; - } else if (collator.compare(flags, "-export") == 0 || - collator.compare(flags, "-exportcert") == 0) { + boolean isCommand = false; + for (Command c: Command.values()) { + if (collator.compare(flags, c.toString()) == 0) { + command = c; + isCommand = true; + break; + } + } + + if (isCommand) { + // already recognized as a command + } else if (collator.compare(flags, "-export") == 0) { command = EXPORTCERT; - } else if (collator.compare(flags, "-genkey") == 0 || - collator.compare(flags, "-genkeypair") == 0) { + } else if (collator.compare(flags, "-genkey") == 0) { command = GENKEYPAIR; - } else if (collator.compare(flags, "-help") == 0) { - usage(); - return; - } else if (collator.compare(flags, "-identitydb") == 0) { // obsolete - command = IDENTITYDB; - } else if (collator.compare(flags, "-import") == 0 || - collator.compare(flags, "-importcert") == 0) { + } else if (collator.compare(flags, "-import") == 0) { command = IMPORTCERT; - } else if (collator.compare(flags, "-keyclone") == 0) { // obsolete - command = KEYCLONE; - } else if (collator.compare(flags, "-changealias") == 0) { - command = CHANGEALIAS; - } else if (collator.compare(flags, "-keypasswd") == 0) { - command = KEYPASSWD; - } else if (collator.compare(flags, "-list") == 0) { - command = LIST; - } else if (collator.compare(flags, "-printcert") == 0) { - command = PRINTCERT; - } else if (collator.compare(flags, "-selfcert") == 0) { // obsolete - command = SELFCERT; - } else if (collator.compare(flags, "-storepasswd") == 0) { - command = STOREPASSWD; - } else if (collator.compare(flags, "-importkeystore") == 0) { - command = IMPORTKEYSTORE; - } else if (collator.compare(flags, "-genseckey") == 0) { - command = GENSECKEY; - } else if (collator.compare(flags, "-gencert") == 0) { - command = GENCERT; - } else if (collator.compare(flags, "-printcertreq") == 0) { - command = PRINTCERTREQ; + } + /* + * Help + */ + else if (collator.compare(flags, "-help") == 0) { + help = true; } /* @@ -284,101 +384,74 @@ public final class KeyTool { */ else if (collator.compare(flags, "-keystore") == 0 || collator.compare(flags, "-destkeystore") == 0) { - if (++i == args.length) errorNeedArgument(flags); - ksfname = args[i]; + ksfname = args[++i]; } else if (collator.compare(flags, "-storepass") == 0 || collator.compare(flags, "-deststorepass") == 0) { - if (++i == args.length) errorNeedArgument(flags); - storePass = args[i].toCharArray(); + storePass = args[++i].toCharArray(); passwords.add(storePass); } else if (collator.compare(flags, "-storetype") == 0 || collator.compare(flags, "-deststoretype") == 0) { - if (++i == args.length) errorNeedArgument(flags); - storetype = args[i]; + storetype = args[++i]; } else if (collator.compare(flags, "-srcstorepass") == 0) { - if (++i == args.length) errorNeedArgument(flags); - srcstorePass = args[i].toCharArray(); + srcstorePass = args[++i].toCharArray(); passwords.add(srcstorePass); } else if (collator.compare(flags, "-srcstoretype") == 0) { - if (++i == args.length) errorNeedArgument(flags); - srcstoretype = args[i]; + srcstoretype = args[++i]; } else if (collator.compare(flags, "-srckeypass") == 0) { - if (++i == args.length) errorNeedArgument(flags); - srckeyPass = args[i].toCharArray(); + srckeyPass = args[++i].toCharArray(); passwords.add(srckeyPass); } else if (collator.compare(flags, "-srcprovidername") == 0) { - if (++i == args.length) errorNeedArgument(flags); - srcProviderName = args[i]; + srcProviderName = args[++i]; } else if (collator.compare(flags, "-providername") == 0 || collator.compare(flags, "-destprovidername") == 0) { - if (++i == args.length) errorNeedArgument(flags); - providerName = args[i]; + providerName = args[++i]; } else if (collator.compare(flags, "-providerpath") == 0) { - if (++i == args.length) errorNeedArgument(flags); - pathlist = args[i]; + pathlist = args[++i]; } else if (collator.compare(flags, "-keypass") == 0) { - if (++i == args.length) errorNeedArgument(flags); - keyPass = args[i].toCharArray(); + keyPass = args[++i].toCharArray(); passwords.add(keyPass); } else if (collator.compare(flags, "-new") == 0) { - if (++i == args.length) errorNeedArgument(flags); - newPass = args[i].toCharArray(); + newPass = args[++i].toCharArray(); passwords.add(newPass); } else if (collator.compare(flags, "-destkeypass") == 0) { - if (++i == args.length) errorNeedArgument(flags); - destKeyPass = args[i].toCharArray(); + destKeyPass = args[++i].toCharArray(); passwords.add(destKeyPass); } else if (collator.compare(flags, "-alias") == 0 || collator.compare(flags, "-srcalias") == 0) { - if (++i == args.length) errorNeedArgument(flags); - alias = args[i]; + alias = args[++i]; } else if (collator.compare(flags, "-dest") == 0 || collator.compare(flags, "-destalias") == 0) { - if (++i == args.length) errorNeedArgument(flags); - dest = args[i]; + dest = args[++i]; } else if (collator.compare(flags, "-dname") == 0) { - if (++i == args.length) errorNeedArgument(flags); - dname = args[i]; + dname = args[++i]; } else if (collator.compare(flags, "-keysize") == 0) { - if (++i == args.length) errorNeedArgument(flags); - keysize = Integer.parseInt(args[i]); + keysize = Integer.parseInt(args[++i]); } else if (collator.compare(flags, "-keyalg") == 0) { - if (++i == args.length) errorNeedArgument(flags); - keyAlgName = args[i]; + keyAlgName = args[++i]; } else if (collator.compare(flags, "-sigalg") == 0) { - if (++i == args.length) errorNeedArgument(flags); - sigAlgName = args[i]; + sigAlgName = args[++i]; } else if (collator.compare(flags, "-startdate") == 0) { - if (++i == args.length) errorNeedArgument(flags); - startDate = args[i]; + startDate = args[++i]; } else if (collator.compare(flags, "-validity") == 0) { - if (++i == args.length) errorNeedArgument(flags); - validity = Long.parseLong(args[i]); + validity = Long.parseLong(args[++i]); } else if (collator.compare(flags, "-ext") == 0) { - if (++i == args.length) errorNeedArgument(flags); - v3ext.add(args[i]); + v3ext.add(args[++i]); } else if (collator.compare(flags, "-file") == 0) { - if (++i == args.length) errorNeedArgument(flags); - filename = args[i]; + filename = args[++i]; } else if (collator.compare(flags, "-infile") == 0) { - if (++i == args.length) errorNeedArgument(flags); - infilename = args[i]; + infilename = args[++i]; } else if (collator.compare(flags, "-outfile") == 0) { - if (++i == args.length) errorNeedArgument(flags); - outfilename = args[i]; + outfilename = args[++i]; } else if (collator.compare(flags, "-sslserver") == 0) { - if (++i == args.length) errorNeedArgument(flags); - sslserver = args[i]; + sslserver = args[++i]; } else if (collator.compare(flags, "-srckeystore") == 0) { - if (++i == args.length) errorNeedArgument(flags); - srcksfname = args[i]; + srcksfname = args[++i]; } else if ((collator.compare(flags, "-provider") == 0) || (collator.compare(flags, "-providerclass") == 0)) { - if (++i == args.length) errorNeedArgument(flags); if (providers == null) { providers = new HashSet> (3); } - String providerClass = args[i]; + String providerClass = args[++i]; String providerArg = null; if (args.length > (i+1)) { @@ -418,19 +491,24 @@ public final class KeyTool { } if (i is not a legal command")); - Object[] source = {args[i]}; - throw new RuntimeException(form.format(source)); + System.err.println(rb.getString("Illegal option: ") + args[i]); + tinyHelp(); } - if (command == -1) { - System.err.println(rb.getString("Usage error: no command provided")); - tinyHelp(); + if (command == null) { + if (help) { + usage(); + } else { + System.err.println(rb.getString("Usage error: no command provided")); + tinyHelp(); + } + } else if (help) { + usage(); + command = null; } } - boolean isKeyStoreRelated(int cmd) { + boolean isKeyStoreRelated(Command cmd) { return cmd != PRINTCERT && cmd != PRINTCERTREQ; } @@ -2600,7 +2678,7 @@ public final class KeyTool { do { if (maxRetry-- < 0) { throw new RuntimeException(rb.getString( - "Too may retries, program terminated")); + "Too many retries, program terminated")); } commonName = inputString(in, rb.getString("What is your first and last name?"), @@ -3086,7 +3164,7 @@ public final class KeyTool { do { if (maxRetry-- < 0) { throw new RuntimeException(rb.getString( - "Too may retries, program terminated")); + "Too many retries, program terminated")); } System.err.print(prompt); System.err.flush(); @@ -3258,7 +3336,8 @@ public final class KeyTool { int nmatch = 0; for (int i = 0; i] [-sigalg ]")); - System.err.println(rb.getString - ("\t [-dname ]")); - System.err.println(rb.getString - ("\t [-file ] [-keypass ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); + // Left and right sides of the options list + String[] left = new String[command.options.length]; + String[] right = new String[command.options.length]; - System.err.println(rb.getString - ("-changealias [-v] [-protected] -alias -destalias ")); - System.err.println(rb.getString - ("\t [-keypass ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); + // Check if there's an unknown option + boolean found = false; - System.err.println(rb.getString - ("-delete [-v] [-protected] -alias ")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-exportcert [-v] [-rfc] [-protected]")); - System.err.println(rb.getString - ("\t [-alias ] [-file ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-genkeypair [-v] [-protected]")); - System.err.println(rb.getString - ("\t [-alias ]")); - System.err.println(rb.getString - ("\t [-keyalg ] [-keysize ]")); - System.err.println(rb.getString - ("\t [-sigalg ] [-dname ]")); - System.err.println(rb.getString - ("\t [-startdate ]")); - System.err.println(rb.getString - ("\t [-ext [:critical][=]]...")); - System.err.println(rb.getString - ("\t [-validity ] [-keypass ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-gencert [-v] [-rfc] [-protected]")); - System.err.println(rb.getString - ("\t [-infile ] [-outfile ]")); - System.err.println(rb.getString - ("\t [-alias ]")); - System.err.println(rb.getString - ("\t [-dname ]")); - System.err.println(rb.getString - ("\t [-sigalg ]")); - System.err.println(rb.getString - ("\t [-startdate ]")); - System.err.println(rb.getString - ("\t [-ext [:critical][=]]...")); - System.err.println(rb.getString - ("\t [-validity ] [-keypass ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-genseckey [-v] [-protected]")); - System.err.println(rb.getString - ("\t [-alias ] [-keypass ]")); - System.err.println(rb.getString - ("\t [-keyalg ] [-keysize ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString("-help")); - System.err.println(); - - System.err.println(rb.getString - ("-importcert [-v] [-noprompt] [-trustcacerts] [-protected]")); - System.err.println(rb.getString - ("\t [-alias ]")); - System.err.println(rb.getString - ("\t [-file ] [-keypass ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-importkeystore [-v] ")); - System.err.println(rb.getString - ("\t [-srckeystore ] [-destkeystore ]")); - System.err.println(rb.getString - ("\t [-srcstoretype ] [-deststoretype ]")); - System.err.println(rb.getString - ("\t [-srcstorepass ] [-deststorepass ]")); - System.err.println(rb.getString - ("\t [-srcprotected] [-destprotected]")); - System.err.println(rb.getString - ("\t [-srcprovidername ]\n\t [-destprovidername ]")); - System.err.println(rb.getString - ("\t [-srcalias [-destalias ]")); - System.err.println(rb.getString - ("\t [-srckeypass ] [-destkeypass ]]")); - System.err.println(rb.getString - ("\t [-noprompt]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-keypasswd [-v] [-alias ]")); - System.err.println(rb.getString - ("\t [-keypass ] [-new ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-list [-v | -rfc] [-protected]")); - System.err.println(rb.getString - ("\t [-alias ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); - System.err.println(); - - System.err.println(rb.getString - ("-printcert [-v] [-rfc] [-file | -sslserver ]")); - System.err.println(); - - System.err.println(rb.getString - ("-printcertreq [-v] [-file ]")); - System.err.println(); - - System.err.println(rb.getString - ("-storepasswd [-v] [-new ]")); - System.err.println(rb.getString - ("\t [-keystore ] [-storepass ]")); - System.err.println(rb.getString - ("\t [-storetype ] [-providername ]")); - System.err.println(rb.getString - ("\t [-providerclass [-providerarg ]] ...")); - System.err.println(rb.getString - ("\t [-providerpath ]")); + // Length of left side of options list + int lenLeft = 0; + for (int j=0; j lenLeft) { + lenLeft = left[j].length(); + } + right[j] = rb.getString(opt[2]); + found = true; + break; + } + } + if (!found) { + throw new RuntimeException("ERROR: CANNOT FIND " + command.options[j]); + } + } + for (int j=0; j needs an argument.", "Command option {0} needs an argument."}, {"Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified value.", "Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."}, {"-keystore must be NONE if -storetype is {0}", "-keystore must be NONE if -storetype is {0}"}, - {"Too may retries, program terminated", - "Too may retries, program terminated"}, + {"Too many retries, program terminated", + "Too many retries, program terminated"}, {"-storepasswd and -keypasswd commands not supported if -storetype is {0}", "-storepasswd and -keypasswd commands not supported if -storetype is {0}"}, {"-keypasswd commands not supported if -storetype is PKCS12", @@ -77,7 +204,6 @@ public class Resources extends java.util.ListResourceBundle { "Validity must be greater than zero"}, {"provName not a provider", "{0} not a provider"}, {"Usage error: no command provided", "Usage error: no command provided"}, - {"Usage error, is not a legal command", "Usage error, {0} is not a legal command"}, {"Source keystore file exists, but is empty: ", "Source keystore file exists, but is empty: "}, {"Please specify -srckeystore", "Please specify -srckeystore"}, {"Must not specify both -v and -rfc with 'list' command", @@ -279,7 +405,6 @@ public class Resources extends java.util.ListResourceBundle { "Secret Key not generated, alias <{0}> already exists"}, {"Please provide -keysize for secret key generation", "Please provide -keysize for secret key generation"}, - {"keytool usage:\n", "keytool usage:\n"}, {"Extensions: ", "Extensions: "}, {"(Empty value)", "(Empty value)"}, @@ -297,139 +422,6 @@ public class Resources extends java.util.ListResourceBundle { {"Odd number of hex digits found: ", "Odd number of hex digits found: "}, {"command {0} is ambiguous:", "command {0} is ambiguous:"}, - {"-certreq [-v] [-protected]", - "-certreq [-v] [-protected]"}, - {"\t [-alias ] [-sigalg ]", - "\t [-alias ] [-sigalg ]"}, - {"\t [-dname ]", "\t [-dname ]"}, - {"\t [-file ] [-keypass ]", - "\t [-file ] [-keypass ]"}, - {"\t [-keystore ] [-storepass ]", - "\t [-keystore ] [-storepass ]"}, - {"\t [-storetype ] [-providername ]", - "\t [-storetype ] [-providername ]"}, - {"\t [-providerclass [-providerarg ]] ...", - "\t [-providerclass [-providerarg ]] ..."}, - {"\t [-providerpath ]", - "\t [-providerpath ]"}, - {"-delete [-v] [-protected] -alias ", - "-delete [-v] [-protected] -alias "}, - /** rest is same as -certreq starting from -keystore **/ - - //{"-export [-v] [-rfc] [-protected]", - // "-export [-v] [-rfc] [-protected]"}, - {"-exportcert [-v] [-rfc] [-protected]", - "-exportcert [-v] [-rfc] [-protected]"}, - {"\t [-alias ] [-file ]", - "\t [-alias ] [-file ]"}, - /** rest is same as -certreq starting from -keystore **/ - - //{"-genkey [-v] [-protected]", - // "-genkey [-v] [-protected]"}, - {"-genkeypair [-v] [-protected]", - "-genkeypair [-v] [-protected]"}, - {"\t [-alias ]", "\t [-alias ]"}, - {"\t [-keyalg ] [-keysize ]", - "\t [-keyalg ] [-keysize ]"}, - {"\t [-sigalg ] [-dname ]", - "\t [-sigalg ] [-dname ]"}, - {"\t [-startdate ]", - "\t [-startdate ]"}, - {"\t [-validity ] [-keypass ]", - "\t [-validity ] [-keypass ]"}, - /** rest is same as -certreq starting from -keystore **/ - {"-gencert [-v] [-rfc] [-protected]", - "-gencert [-v] [-rfc] [-protected]"}, - {"\t [-infile ] [-outfile ]", - "\t [-infile ] [-outfile ]"}, - {"\t [-sigalg ]", - "\t [-sigalg ]"}, - {"\t [-ext [:critical][=]]...", - "\t [-ext [:critical][=]]..."}, - - {"-genseckey [-v] [-protected]", - "-genseckey [-v] [-protected]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-help", "-help"}, - //{"-identitydb [-v] [-protected]", - // "-identitydb [-v] [-protected]"}, - //{"\t [-file ]", "\t [-file ]"}, - /** rest is same as -certreq starting from -keystore **/ - - //{"-import [-v] [-noprompt] [-trustcacerts] [-protected]", - // "-import [-v] [-noprompt] [-trustcacerts] [-protected]"}, - {"-importcert [-v] [-noprompt] [-trustcacerts] [-protected]", - "-importcert [-v] [-noprompt] [-trustcacerts] [-protected]"}, - {"\t [-alias ]", "\t [-alias ]"}, - {"\t [-alias ] [-keypass ]", - "\t [-alias ] [-keypass ]"}, - {"\t [-file ] [-keypass ]", - "\t [-file ] [-keypass ]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-importkeystore [-v] ", - "-importkeystore [-v] "}, - {"\t [-srckeystore ] [-destkeystore ]", - "\t [-srckeystore ] [-destkeystore ]"}, - {"\t [-srcstoretype ] [-deststoretype ]", - "\t [-srcstoretype ] [-deststoretype ]"}, - {"\t [-srcprotected] [-destprotected]", - "\t [-srcprotected] [-destprotected]"}, - {"\t [-srcstorepass ] [-deststorepass ]", - "\t [-srcstorepass ] [-deststorepass ]"}, - {"\t [-srcprovidername ]\n\t [-destprovidername ]", // line too long, split to 2 - "\t [-srcprovidername ]\n\t [-destprovidername ]"}, - {"\t [-srcalias [-destalias ]", - "\t [-srcalias [-destalias ]"}, - {"\t [-srckeypass ] [-destkeypass ]]", - "\t [-srckeypass ] [-destkeypass ]]"}, - {"\t [-noprompt]", "\t [-noprompt]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-changealias [-v] [-protected] -alias -destalias ", - "-changealias [-v] [-protected] -alias -destalias "}, - {"\t [-keypass ]", "\t [-keypass ]"}, - - //{"-keyclone [-v] [-protected]", - // "-keyclone [-v] [-protected]"}, - //{"\t [-alias ] -dest ", - // "\t [-alias ] -dest "}, - //{"\t [-keypass ] [-new ]", - // "\t [-keypass ] [-new ]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-keypasswd [-v] [-alias ]", - "-keypasswd [-v] [-alias ]"}, - {"\t [-keypass ] [-new ]", - "\t [-keypass ] [-new ]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-list [-v | -rfc] [-protected]", - "-list [-v | -rfc] [-protected]"}, - {"\t [-alias ]", "\t [-alias ]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-printcert [-v] [-rfc] [-file | -sslserver ]", - "-printcert [-v] [-rfc] [-file | -sslserver ]"}, - {"-printcertreq [-v] [-file ]", - "-printcertreq [-v] [-file ]"}, - {"No certificate from the SSL server", - "No certificate from the SSL server"}, - - //{"-selfcert [-v] [-protected]", - // "-selfcert [-v] [-protected]"}, - {"\t [-alias ]", "\t [-alias ]"}, - //{"\t [-dname ] [-validity ]", - // "\t [-dname ] [-validity ]"}, - //{"\t [-keypass ] [-sigalg ]", - // "\t [-keypass ] [-sigalg ]"}, - /** rest is same as -certreq starting from -keystore **/ - - {"-storepasswd [-v] [-new ]", - "-storepasswd [-v] [-new ]"}, - /** rest is same as -certreq starting from -keystore **/ - // policytool {"Warning: A public key for alias 'signers[i]' does not exist. Make sure a KeyStore is properly configured.", "Warning: A public key for alias {0} does not exist. Make sure a KeyStore is properly configured."}, @@ -679,3 +671,4 @@ public class Resources extends java.util.ListResourceBundle { return contents; } } + diff --git a/jdk/test/sun/security/tools/keytool/newhelp.sh b/jdk/test/sun/security/tools/keytool/newhelp.sh new file mode 100644 index 00000000000..08c7422e545 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/newhelp.sh @@ -0,0 +1,53 @@ +# +# Copyright 2009 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 6324292 +# @summary keytool -help is unhelpful +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +LANG=C +$TESTJAVA${FS}bin${FS}keytool -help 2> h1 || exit 1 +$TESTJAVA${FS}bin${FS}keytool -help -list 2> h2 || exit 2 + +grep Commands: h1 || exit 3 +grep Options: h2 || exit 4 + +exit 0 + From 10b2d33a487f84fea68ec8c0b4e9a9900d3d5c06 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 2 Oct 2009 18:47:34 +0800 Subject: [PATCH 08/22] 6862679: ESC: AD Authentication with user with umlauts fails Reviewed-by: valeriep, mullan --- .../sun/security/krb5/Credentials.java | 11 +- .../classes/sun/security/krb5/KrbAsReq.java | 17 +- .../sun/security/krb5/PrincipalName.java | 5 +- .../classes/sun/security/krb5/Realm.java | 10 +- .../sun/security/krb5/internal/ETypeInfo.java | 46 ++-- .../security/krb5/internal/ETypeInfo2.java | 18 +- .../sun/security/krb5/internal/KRBError.java | 14 +- .../security/krb5/internal/crypto/Des.java | 26 +- .../krb5/internal/util/KerberosString.java | 82 ++++++ .../security/krb5/internal/tools/Kinit.java | 12 +- jdk/test/sun/security/krb5/RFC396xTest.java | 248 ++++++++++++++++++ 11 files changed, 420 insertions(+), 69 deletions(-) create mode 100644 jdk/src/share/classes/sun/security/krb5/internal/util/KerberosString.java create mode 100644 jdk/test/sun/security/krb5/RFC396xTest.java diff --git a/jdk/src/share/classes/sun/security/krb5/Credentials.java b/jdk/src/share/classes/sun/security/krb5/Credentials.java index 3fde713fd3c..c003a29fa64 100644 --- a/jdk/src/share/classes/sun/security/krb5/Credentials.java +++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java @@ -33,16 +33,11 @@ package sun.security.krb5; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.CredentialsCache; -import java.util.StringTokenizer; import sun.security.krb5.internal.ktab.*; import sun.security.krb5.internal.crypto.EType; import java.io.File; import java.io.IOException; import java.util.Date; -import java.util.Vector; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; import java.net.InetAddress; /** @@ -378,9 +373,9 @@ public class Credentials { KRBError error = ke.getError(); // update salt in PrincipalName - byte[] newSalt = error.getSalt(); - if (newSalt != null && newSalt.length > 0) { - princ.setSalt(new String(newSalt)); + String newSalt = error.getSalt(); + if (newSalt != null && newSalt.length() > 0) { + princ.setSalt(newSalt); } // refresh keys diff --git a/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java b/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java index c493d405f51..fec6998ce3a 100644 --- a/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java +++ b/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2009 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 @@ -56,7 +56,7 @@ public class KrbAsReq extends KrbKdcReq { private boolean PA_ENC_TIMESTAMP_REQUIRED = false; private boolean pa_exists = false; private int pa_etype = 0; - private byte[] pa_salt = null; + private String pa_salt = null; private byte[] pa_s2kparams = null; // default is address-less tickets @@ -88,7 +88,7 @@ public class KrbAsReq extends KrbKdcReq { * with pre-authentication values */ KrbAsReq(PrincipalName principal, EncryptionKey[] keys, - boolean pa_exists, int etype, byte[] salt, byte[] s2kparams) + boolean pa_exists, int etype, String salt, byte[] s2kparams) throws KrbException, IOException { this(keys, // for pre-authentication pa_exists, etype, salt, s2kparams, // pre-auth values @@ -112,7 +112,7 @@ public class KrbAsReq extends KrbKdcReq { } // update with pre-auth info - public void updatePA(int etype, byte[] salt, byte[] params, PrincipalName name) { + public void updatePA(int etype, String salt, byte[] params, PrincipalName name) { // set the pre-auth values pa_exists = true; pa_etype = etype; @@ -120,9 +120,8 @@ public class KrbAsReq extends KrbKdcReq { pa_s2kparams = params; // update salt in PrincipalName - if (salt != null && salt.length > 0) { - String newSalt = new String(salt); - name.setSalt(newSalt); + if (salt != null && salt.length() > 0) { + name.setSalt(salt); if (DEBUG) { System.out.println("Updated salt from pre-auth = " + name.getSalt()); } @@ -161,7 +160,7 @@ public class KrbAsReq extends KrbKdcReq { char[] password, boolean pa_exists, int etype, - byte[] salt, + String salt, byte[] s2kparams, KDCOptions options, PrincipalName cname, @@ -246,7 +245,7 @@ public class KrbAsReq extends KrbKdcReq { EncryptionKey[] keys, boolean pa_exists, int etype, - byte[] salt, + String salt, byte[] s2kparams, KDCOptions options, PrincipalName cname, diff --git a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java index 3761ffbb469..6705fd63e9a 100644 --- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java +++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java @@ -38,6 +38,7 @@ import java.util.Vector; import java.io.IOException; import java.math.BigInteger; import sun.security.krb5.internal.ccache.CCacheOutputStream; +import sun.security.krb5.internal.util.KerberosString; /** @@ -246,7 +247,7 @@ public class PrincipalName DerValue subSubDer; while(subDer.getData().available() > 0) { subSubDer = subDer.getData().getDerValue(); - v.addElement(subSubDer.getGeneralString()); + v.addElement(new KerberosString(subSubDer).toString()); } if (v.size() > 0) { nameStrings = new String[v.size()]; @@ -554,7 +555,7 @@ public class PrincipalName temp = new DerOutputStream(); DerValue der[] = new DerValue[nameStrings.length]; for (int i = 0; i < nameStrings.length; i++) { - der[i] = new DerValue(DerValue.tag_GeneralString, nameStrings[i]); + der[i] = new KerberosString(nameStrings[i]).toDerValue(); } temp.putSequence(der); bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); diff --git a/jdk/src/share/classes/sun/security/krb5/Realm.java b/jdk/src/share/classes/sun/security/krb5/Realm.java index bf57e7a54ce..7ba959bdcf4 100644 --- a/jdk/src/share/classes/sun/security/krb5/Realm.java +++ b/jdk/src/share/classes/sun/security/krb5/Realm.java @@ -31,11 +31,6 @@ package sun.security.krb5; -import sun.security.krb5.Config; -import sun.security.krb5.PrincipalName; -import sun.security.krb5.KrbException; -import sun.security.krb5.Asn1Exception; -import sun.security.krb5.RealmException; import sun.security.krb5.internal.Krb5; import sun.security.util.*; import java.io.IOException; @@ -43,6 +38,7 @@ import java.util.StringTokenizer; import java.util.Vector; import java.util.Stack; import java.util.EmptyStackException; +import sun.security.krb5.internal.util.KerberosString; /** * Implements the ASN.1 Realm type. @@ -109,7 +105,7 @@ public class Realm implements Cloneable { if (encoding == null) { throw new IllegalArgumentException("encoding can not be null"); } - realm = encoding.getGeneralString(); + realm = new KerberosString(encoding).toString(); if (realm == null || realm.length() == 0) throw new RealmException(Krb5.REALM_NULL); if (!isValidRealmString(realm)) @@ -206,7 +202,7 @@ public class Realm implements Cloneable { */ public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream out = new DerOutputStream(); - out.putGeneralString(this.realm); + out.putDerValue(new KerberosString(this.realm).toDerValue()); return out.toByteArray(); } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo.java b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo.java index 9790bb8696f..7625a6eb5d9 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 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 @@ -28,6 +28,7 @@ package sun.security.krb5.internal; import sun.security.util.*; import sun.security.krb5.Asn1Exception; import java.io.IOException; +import sun.security.krb5.internal.util.KerberosString; /** * Implements the ASN.1 ETYPE-INFO-ENTRY type. @@ -43,7 +44,7 @@ import java.io.IOException; public class ETypeInfo { private int etype; - private byte[] salt = null; + private String salt = null; private static final byte TAG_TYPE = 0; private static final byte TAG_VALUE = 1; @@ -51,21 +52,13 @@ public class ETypeInfo { private ETypeInfo() { } - public ETypeInfo(int etype, byte[] salt) { + public ETypeInfo(int etype, String salt) { this.etype = etype; - if (salt != null) { - this.salt = salt.clone(); - } + this.salt = salt; } public Object clone() { - ETypeInfo etypeInfo = new ETypeInfo(); - etypeInfo.etype = etype; - if (salt != null) { - etypeInfo.salt = new byte[salt.length]; - System.arraycopy(salt, 0, etypeInfo.salt, 0, salt.length); - } - return etypeInfo; + return new ETypeInfo(etype, salt); } /** @@ -94,7 +87,22 @@ public class ETypeInfo { if (encoding.getData().available() > 0) { der = encoding.getData().getDerValue(); if ((der.getTag() & 0x1F) == 0x01) { - this.salt = der.getData().getOctetString(); + byte[] saltBytes = der.getData().getOctetString(); + + // Although salt is defined as an OCTET STRING, it's the + // encoding from of a string. As RFC 4120 says: + // + // "The salt, ..., is also completely unspecified with respect + // to character set and is probably locale-specific". + // + // It's known that this field is using the same encoding as + // KerberosString in most implementations. + + if (KerberosString.MSNAME) { + this.salt = new String(saltBytes, "UTF8"); + } else { + this.salt = new String(saltBytes); + } } } @@ -120,7 +128,11 @@ public class ETypeInfo { if (salt != null) { temp = new DerOutputStream(); - temp.putOctetString(salt); + if (KerberosString.MSNAME) { + temp.putOctetString(salt.getBytes("UTF8")); + } else { + temp.putOctetString(salt.getBytes()); + } bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_VALUE), temp); } @@ -135,8 +147,8 @@ public class ETypeInfo { return etype; } - public byte[] getSalt() { - return ((salt == null) ? null : salt.clone()); + public String getSalt() { + return salt; } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java index f1b657116f6..14807745433 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 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 @@ -28,6 +28,7 @@ package sun.security.krb5.internal; import sun.security.util.*; import sun.security.krb5.Asn1Exception; import java.io.IOException; +import sun.security.krb5.internal.util.KerberosString; /** * Implements the ASN.1 ETYPE-INFO-ENTRY type. @@ -54,11 +55,9 @@ public class ETypeInfo2 { private ETypeInfo2() { } - public ETypeInfo2(int etype, byte[] salt, byte[] s2kparams) { + public ETypeInfo2(int etype, String salt, byte[] s2kparams) { this.etype = etype; - if (salt != null) { - this.saltStr = new String(salt); - } + this.saltStr = salt; if (s2kparams != null) { this.s2kparams = s2kparams.clone(); } @@ -102,7 +101,8 @@ public class ETypeInfo2 { if (encoding.getData().available() > 0) { if ((encoding.getData().peekByte() & 0x1F) == 0x01) { der = encoding.getData().getDerValue(); - this.saltStr = der.getData().getGeneralString(); + this.saltStr = new KerberosString( + der.getData().getDerValue()).toString(); } } @@ -136,7 +136,7 @@ public class ETypeInfo2 { if (saltStr != null) { temp = new DerOutputStream(); - temp.putGeneralString(saltStr); + temp.putDerValue(new KerberosString(saltStr).toDerValue()); bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_VALUE1), temp); } @@ -157,8 +157,8 @@ public class ETypeInfo2 { return etype; } - public byte[] getSalt() { - return ((saltStr == null) ? null : saltStr.getBytes()); + public String getSalt() { + return saltStr; } public byte[] getParams() { diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java b/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java index febc959cb80..e7c73181cf7 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2009 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 @@ -42,6 +42,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.math.BigInteger; import java.util.Arrays; +import sun.security.krb5.internal.util.KerberosString; /** * Implements the ASN.1 KRBError type. * @@ -97,7 +98,7 @@ public class KRBError implements java.io.Serializable { // pre-auth info private int etype = 0; - private byte[] salt = null; + private String salt = null; private byte[] s2kparams = null; private static boolean DEBUG = Krb5.DEBUG; @@ -334,8 +335,8 @@ public class KRBError implements java.io.Serializable { } // access pre-auth info - public final byte[] getSalt() { - return ((salt == null) ? null : salt.clone()); + public final String getSalt() { + return salt; } // access pre-auth info @@ -415,7 +416,8 @@ public class KRBError implements java.io.Serializable { if (der.getData().available() >0) { if ((der.getData().peekByte() & 0x1F) == 0x0B) { subDer = der.getData().getDerValue(); - eText = subDer.getData().getGeneralString(); + eText = new KerberosString(subDer.getData().getDerValue()) + .toString(); } } if (der.getData().available() >0) { @@ -515,7 +517,7 @@ public class KRBError implements java.io.Serializable { if (eText != null) { temp = new DerOutputStream(); - temp.putGeneralString(eText); + temp.putDerValue(new KerberosString(eText).toDerValue()); bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), temp); } if (eData != null) { diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/Des.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/Des.java index 61a03c02a94..feaf8cf42a5 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/Des.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/Des.java @@ -34,17 +34,29 @@ import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKey; -import java.security.Security; -import java.security.Provider; import java.security.GeneralSecurityException; import javax.crypto.spec.IvParameterSpec; import sun.security.krb5.KrbCryptoException; -import sun.security.krb5.internal.Krb5; -import java.io.UnsupportedEncodingException; import java.util.Arrays; +import sun.security.action.GetPropertyAction; public final class Des { + // RFC 3961 demands that UTF-8 encoding be used in DES's + // string-to-key function. For historical reasons, some + // implementations use a locale-specific encoding. Even + // so, when the client and server use different locales, + // they must agree on a common value, normally the one + // used when the password is set/reset. + // + // The following system property is provided to perform the + // string-to-key encoding. When set, the specified charset + // name is used. Otherwise, the system default charset. + + private final static String CHARSET = + java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.security.krb5.msinterop.des.s2kcharset")); + private static final long[] bad_keys = { 0x0101010101010101L, 0xfefefefefefefefeL, 0x1f1f1f1f1f1f1f1fL, 0xe0e0e0e0e0e0e0e0L, @@ -226,7 +238,11 @@ public final class Des { // Convert password to byte array try { - cbytes = (new String(passwdChars)).getBytes(); + if (CHARSET == null) { + cbytes = (new String(passwdChars)).getBytes(); + } else { + cbytes = (new String(passwdChars)).getBytes(CHARSET); + } } catch (Exception e) { // clear-up sensitive information if (cbytes != null) { diff --git a/jdk/src/share/classes/sun/security/krb5/internal/util/KerberosString.java b/jdk/src/share/classes/sun/security/krb5/internal/util/KerberosString.java new file mode 100644 index 00000000000..2c50fe601b9 --- /dev/null +++ b/jdk/src/share/classes/sun/security/krb5/internal/util/KerberosString.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.security.krb5.internal.util; + +import java.io.IOException; +import java.security.AccessController; +import sun.security.action.GetBooleanAction; +import sun.security.util.DerValue; + +/** + * Implements the ASN.1 KerberosString type. + * + *
+ * KerberosString  ::= GeneralString (IA5String)
+ * 
+ * + * This definition reflects the Network Working Group RFC 4120 + * specification available at + * + * http://www.ietf.org/rfc/rfc4120.txt. + */ +public final class KerberosString { + /** + * RFC 4120 defines KerberosString as GeneralString (IA5String), which + * only includes ASCII characters. However, other implementations have been + * known to use GeneralString to contain UTF-8 encoding. To interop + * with these implementations, the following system property is defined. + * When set as true, KerberosString is encoded as UTF-8. Note that this + * only affects the byte encoding, the tag of the ASN.1 type is still + * GeneralString. + */ + public static final boolean MSNAME = AccessController.doPrivileged( + new GetBooleanAction("sun.security.krb5.msinterop.kstring")); + + private final String s; + + public KerberosString(String s) { + this.s = s; + } + + public KerberosString(DerValue der) throws IOException { + if (der.tag != DerValue.tag_GeneralString) { + throw new IOException( + "KerberosString's tag is incorrect: " + der.tag); + } + s = new String(der.getDataBytes(), MSNAME?"UTF8":"ASCII"); + } + + public String toString() { + return s; + } + + public DerValue toDerValue() throws IOException { + // No need to cache the result since this method is + // only called once. + return new DerValue(DerValue.tag_GeneralString, + s.getBytes(MSNAME?"UTF8":"ASCII")); + } +} diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java index cb4ded6e668..44dee2c86c5 100644 --- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java +++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2009 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 @@ -252,15 +252,15 @@ public class Kinit { } KRBError error = ke.getError(); int etype = error.getEType(); - byte[] salt = error.getSalt(); + String salt = error.getSalt(); byte[] s2kparams = error.getParams(); if (useKeytab) { - as_req = new KrbAsReq(skeys, true, etype, salt, s2kparams, - opt, principal, sname, + as_req = new KrbAsReq(skeys, true, etype, salt, + s2kparams, opt, principal, sname, null, null, null, null, addresses, null); } else { - as_req = new KrbAsReq(psswd, true, etype, salt, s2kparams, - opt, principal, sname, + as_req = new KrbAsReq(psswd, true, etype, salt, + s2kparams, opt, principal, sname, null, null, null, null, addresses, null); } as_rep = sendASRequest(as_req, useKeytab, realm, psswd, skeys); diff --git a/jdk/test/sun/security/krb5/RFC396xTest.java b/jdk/test/sun/security/krb5/RFC396xTest.java new file mode 100644 index 00000000000..6ab9255d4f5 --- /dev/null +++ b/jdk/test/sun/security/krb5/RFC396xTest.java @@ -0,0 +1,248 @@ +/* + * Copyright 2009 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 6862679 + * @summary ESC: AD Authentication with user with umlauts fails + */ + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import sun.security.krb5.EncryptedData; +import sun.security.krb5.internal.crypto.Des; +import sun.security.krb5.internal.crypto.EType; +import sun.security.krb5.internal.crypto.crc32; +import sun.security.krb5.internal.crypto.dk.AesDkCrypto; +import sun.security.krb5.internal.crypto.dk.Des3DkCrypto; +import sun.security.krb5.internal.crypto.dk.DkCrypto; +import java.nio.*; +import javax.crypto.*; +import javax.crypto.spec.*; + +public class RFC396xTest { + + static final String gclef = new String(Character.toChars(0x1d11e)); + + /** Creates a new instance of NewClass */ + public static void main(String[] args) throws Exception { + System.setProperty("sun.security.krb5.msinterop.des.s2kcharset", + "utf-8"); + test(); + } + + static void test() throws Exception { + // RFC 3961 + // A.1 + Method nfold = DkCrypto.class.getDeclaredMethod("nfold", byte[].class, Integer.TYPE); + nfold.setAccessible(true); + assertStringEquals(hex((byte[])nfold.invoke(null, "012345".getBytes("UTF-8"), 64)), "be072631276b1955"); + assertStringEquals(hex((byte[])nfold.invoke(null, "password".getBytes("UTF-8"), 56)), "78a07b6caf85fa"); + assertStringEquals(hex((byte[])nfold.invoke(null, "Rough Consensus, and Running Code".getBytes("UTF-8"), 64)), "bb6ed30870b7f0e0"); + assertStringEquals(hex((byte[])nfold.invoke(null, "password".getBytes("UTF-8"), 168)), "59e4a8ca7c0385c3c37b3f6d2000247cb6e6bd5b3e"); + assertStringEquals(hex((byte[])nfold.invoke(null, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY".getBytes("UTF-8"), 192)), "db3b0d8f0b061e603282b308a50841229ad798fab9540c1b"); + assertStringEquals(hex((byte[])nfold.invoke(null, "Q".getBytes("UTF-8"), 168)), "518a54a215a8452a518a54a215a8452a518a54a215"); + assertStringEquals(hex((byte[])nfold.invoke(null, "ba".getBytes("UTF-8"), 168)), "fb25d531ae8974499f52fd92ea9857c4ba24cf297e"); + assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 64)), "6b65726265726f73"); + assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 128)), "6b65726265726f737b9b5b2b93132b93"); + assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 168)), "8372c236344e5f1550cd0747e15d62ca7a5a3bcea4"); + assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 256)), "6b65726265726f737b9b5b2b93132b935c9bdcdad95c9899c4cae4dee6d6cae4"); + + // A.2 + assertStringEquals(hex(Des.string_to_key_bytes("passwordATHENA.MIT.EDUraeburn".toCharArray())), "cbc22fae235298e3"); + assertStringEquals(hex(Des.string_to_key_bytes("potatoeWHITEHOUSE.GOVdanny".toCharArray())), "df3d32a74fd92a01"); + assertStringEquals(hex(Des.string_to_key_bytes((gclef+"EXAMPLE.COMpianist").toCharArray())), "4ffb26bab0cd9413"); + assertStringEquals(hex(Des.string_to_key_bytes("\u00dfATHENA.MIT.EDUJuri\u0161i\u0107".toCharArray())), "62c81a5232b5e69d"); + // Next 2 won't pass, since there's no real weak key here + //assertStringEquals(hex(Des.string_to_key_bytes("11119999AAAAAAAA".toCharArray())), "984054d0f1a73e31"); + //assertStringEquals(hex(Des.string_to_key_bytes("NNNN6666FFFFAAAA".toCharArray())), "c4bf6b25adf7a4f8"); + + // A.3 + Object o = Des3DkCrypto.class.getConstructor().newInstance(); + Method dr = DkCrypto.class.getDeclaredMethod("dr", byte[].class, byte[].class); + Method randomToKey = DkCrypto.class.getDeclaredMethod("randomToKey", byte[].class); + dr.setAccessible(true); + randomToKey.setAccessible(true); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("dce06b1f64c857a11c3db57c51899b2cc1791008ce973b92"), + xeh("0000000155")))), + "925179d04591a79b5d3192c4a7e9c289b049c71f6ee604cd"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("5e13d31c70ef765746578531cb51c15bf11ca82c97cee9f2"), + xeh("00000001aa")))), + "9e58e5a146d9942a101c469845d67a20e3c4259ed913f207"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("98e6fd8a04a4b6859b75a176540b9752bad3ecd610a252bc"), + xeh("0000000155")))), + "13fef80d763e94ec6d13fd2ca1d085070249dad39808eabf"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("622aec25a2fe2cad7094680b7c64940280084c1a7cec92b5"), + xeh("00000001aa")))), + "f8dfbf04b097e6d9dc0702686bcb3489d91fd9a4516b703e"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("d3f8298ccb166438dcb9b93ee5a7629286a491f838f802fb"), + xeh("6b65726265726f73")))), + "2370da575d2a3da864cebfdc5204d56df779a7df43d9da43"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("c1081649ada74362e6a1459d01dfd30d67c2234c940704da"), + xeh("0000000155")))), + "348057ec98fdc48016161c2a4c7a943e92ae492c989175f7"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("5d154af238f46713155719d55e2f1f790dd661f279a7917c"), + xeh("00000001aa")))), + "a8808ac267dada3dcbe9a7c84626fbc761c294b01315e5c1"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("798562e049852f57dc8c343ba17f2ca1d97394efc8adc443"), + xeh("0000000155")))), + "c813f88a3be3b334f75425ce9175fbe3c8493b89c8703b49"); + assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o, + xeh("26dce334b545292f2feab9a8701a89a4b99eb9942cecd016"), + xeh("00000001aa")))), + "f48ffd6e83f83e7354e694fd252cf83bfe58f7d5ba37ec5d"); + + // A.4 + assertStringEquals(hex(new Des3DkCrypto().stringToKey("passwordATHENA.MIT.EDUraeburn".toCharArray())), "850bb51358548cd05e86768c313e3bfef7511937dcf72c3e"); + assertStringEquals(hex(new Des3DkCrypto().stringToKey("potatoeWHITEHOUSE.GOVdanny".toCharArray())), "dfcd233dd0a43204ea6dc437fb15e061b02979c1f74f377a"); + assertStringEquals(hex(new Des3DkCrypto().stringToKey("pennyEXAMPLE.COMbuckaroo".toCharArray())), "6d2fcdf2d6fbbc3ddcadb5da5710a23489b0d3b69d5d9d4a"); + assertStringEquals(hex(new Des3DkCrypto().stringToKey("\u00DFATHENA.MIT.EDUJuri\u0161i\u0107".toCharArray())), "16d5a40e1ce3bacb61b9dce00470324c831973a7b952feb0"); + assertStringEquals(hex(new Des3DkCrypto().stringToKey((gclef+"EXAMPLE.COMpianist").toCharArray())), "85763726585dbc1cce6ec43e1f751f07f1c4cbb098f40b19"); + + // A.5 + assertStringEquals(hex(crc32.byte2crc32sum_bytes("foo".getBytes("UTF-8"))), "33bc3273"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes("test0123456789".getBytes("UTF-8"))), "d6883eb8"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes("MASSACHVSETTS INSTITVTE OF TECHNOLOGY".getBytes("UTF-8"))), "f78041e3"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80, 0})), "4b98833b"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, 8})), "3288db0e"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, (byte)0x80})), "2083b8ed"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80})), "2083b8ed"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80, 0, 0, 0})), "3bb659ed"); + assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, 0, 0, 1})), "96300777"); + + // RFC 3962 + AesDkCrypto a1 = new AesDkCrypto(128); + Method pbkdf2 = AesDkCrypto.class.getDeclaredMethod("PBKDF2", char[].class, byte[].class, Integer.TYPE, Integer.TYPE); + Method s2k = AesDkCrypto.class.getDeclaredMethod("stringToKey", char[].class, byte[].class, byte[].class); + pbkdf2.setAccessible(true); + s2k.setAccessible(true); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1, 128)), "cd ed b5 28 1b b2 f8 01 56 5a 11 22 b2 56 35 15"); + assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1))), "42 26 3c 6e 89 f4 fc 28 b8 df 68 ee 09 79 9f 15"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1, 256)), "cd ed b5 28 1b b2 f8 01 56 5a 11 22 b2 56 35 15 0a d1 f7 a0 4b b9 f3 a3 33 ec c0 e2 e1 f7 08 37"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 2, 128)), "01 db ee 7f 4a 9e 24 3e 98 8b 62 c7 3c da 93 5d"); + assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(2))), "c6 51 bf 29 e2 30 0a c2 7f a4 69 d6 93 bd da 13"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 2, 256)), "01 db ee 7f 4a 9e 24 3e 98 8b 62 c7 3c da 93 5d a0 53 78 b9 32 44 ec 8f 48 a9 9e 61 ad 79 9d 86"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1200, 128)), "5c 08 eb 61 fd f7 1e 4e 4e c3 cf 6b a1 f5 51 2b"); + assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1200))), "4c 01 cd 46 d6 32 d0 1e 6d be 23 0a 01 ed 64 2a"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1200, 256)), "5c 08 eb 61 fd f7 1e 4e 4e c3 cf 6b a1 f5 51 2b a7 e5 2d db c5 e5 14 2f 70 8a 31 e2 e6 2b 1e 13"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), xeh("1234567878563412"), 5, 128)), "d1 da a7 86 15 f2 87 e6 a1 c8 b1 20 d7 06 2a 49"); + assertStringEquals(hex((byte[])s2k.invoke(a1, "password".toCharArray(), xeh("1234567878563412"), i2b(5))), "e9 b2 3d 52 27 37 47 dd 5c 35 cb 55 be 61 9d 8e"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), xeh("1234567878563412"), 5, 256)), "d1 da a7 86 15 f2 87 e6 a1 c8 b1 20 d7 06 2a 49 3f 98 d2 03 e6 be 49 a6 ad f4 fa 57 4b 6e 64 ee"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size".getBytes("UTF-8"), 1200, 128)), "13 9c 30 c0 96 6b c3 2b a5 5f db f2 12 53 0a c9"); + assertStringEquals(hex(a1.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size", i2b(1200))), "59 d1 bb 78 9a 82 8b 1a a5 4e f9 c2 88 3f 69 ed"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size".getBytes("UTF-8"), 1200, 256)), "13 9c 30 c0 96 6b c3 2b a5 5f db f2 12 53 0a c9 c5 ec 59 f1 a4 52 f5 cc 9a d9 40 fe a0 59 8e d1"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size".getBytes("UTF-8"), 1200, 128)), "9c ca d6 d4 68 77 0c d5 1b 10 e6 a6 87 21 be 61"); + assertStringEquals(hex(a1.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size", i2b(1200))), "cb 80 05 dc 5f 90 17 9a 7f 02 10 4c 00 18 75 1d"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size".getBytes("UTF-8"), 1200, 256)), "9c ca d6 d4 68 77 0c d5 1b 10 e6 a6 87 21 be 61 1a 8b 4d 28 26 01 db 3b 36 be 92 46 91 5e c8 2a"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, gclef.toCharArray(), "EXAMPLE.COMpianist".getBytes("UTF-8"), 50, 128)), "6b 9c f2 6d 45 45 5a 43 a5 b8 bb 27 6a 40 3b 39"); + assertStringEquals(hex(a1.stringToKey(gclef.toCharArray(), "EXAMPLE.COMpianist", i2b(50))), "f1 49 c1 f2 e1 54 a7 34 52 d4 3e 7f e6 2a 56 e5"); + assertStringEquals(hex((byte[])pbkdf2.invoke(null, gclef.toCharArray(), "EXAMPLE.COMpianist".getBytes("UTF-8"), 50, 256)), "6b 9c f2 6d 45 45 5a 43 a5 b8 bb 27 6a 40 3b 39 e7 fe 37 a0 c4 1e 02 c2 81 ff 30 69 e1 e9 4f 52"); + + if (EType.isSupported(EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96)) { + AesDkCrypto a2 = new AesDkCrypto(256); + assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1))), "fe 69 7b 52 bc 0d 3c e1 44 32 ba 03 6a 92 e6 5b bb 52 28 09 90 a2 fa 27 88 39 98 d7 2a f3 01 61"); + assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(2))), "a2 e1 6d 16 b3 60 69 c1 35 d5 e9 d2 e2 5f 89 61 02 68 56 18 b9 59 14 b4 67 c6 76 22 22 58 24 ff"); + assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1200))), "55 a6 ac 74 0a d1 7b 48 46 94 10 51 e1 e8 b0 a7 54 8d 93 b0 ab 30 a8 bc 3f f1 62 80 38 2b 8c 2a"); + assertStringEquals(hex((byte[])s2k.invoke(a2, "password".toCharArray(), xeh("1234567878563412"), i2b(5))), "97 a4 e7 86 be 20 d8 1a 38 2d 5e bc 96 d5 90 9c ab cd ad c8 7c a4 8f 57 45 04 15 9f 16 c3 6e 31"); + assertStringEquals(hex(a2.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size", i2b(1200))), "89 ad ee 36 08 db 8b c7 1f 1b fb fe 45 94 86 b0 56 18 b7 0c ba e2 20 92 53 4e 56 c5 53 ba 4b 34"); + assertStringEquals(hex(a2.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size", i2b(1200))), "d7 8c 5c 9c b8 72 a8 c9 da d4 69 7f 0b b5 b2 d2 14 96 c8 2b eb 2c ae da 21 12 fc ee a0 57 40 1b"); + assertStringEquals(hex(a2.stringToKey(gclef.toCharArray(), "EXAMPLE.COMpianist", i2b(50))), "4b 6d 98 39 f8 44 06 df 1f 09 cc 16 6d b4 b8 3c 57 18 48 b7 84 a3 d6 bd c3 46 58 9a 3e 39 3f 9e"); + } + + Cipher cipher = Cipher.getInstance("AES/CTS/NoPadding"); + + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec( + xeh("63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69"), "AES"), + new IvParameterSpec( + xeh("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"), 0, 16)); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20"))), + "c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f 97"); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20"))), + "fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5"); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43"))), + "39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84"); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c"))), + "97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5"); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20"))), + "97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8"); + assertStringEquals(hex(cipher.doFinal( + xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20 61 6e 64 20 77 6f 6e 74 6f 6e 20 73 6f 75 70 2e"))), + "97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8"); + } + + static byte[] i2b(int i) { + ByteBuffer bb = ByteBuffer.allocate(4); + byte[] b = new byte[4]; + bb.putInt(i); + bb.flip(); + bb.get(b); + return b; + } + + static String hex(byte[] bs) { + StringBuffer sb = new StringBuffer(bs.length * 2); + for(byte b: bs) { + char c = (char)((b+256)%256); + if (c / 16 < 10) + sb.append((char)(c/16+'0')); + else + sb.append((char)(c/16-10+'a')); + if (c % 16 < 10) + sb.append((char)(c%16+'0')); + else + sb.append((char)(c%16-10+'a')); + } + return new String(sb); + } + + static byte[] xeh(String in) { + in = in.replaceAll(" ", ""); + int len = in.length()/2; + byte[] out = new byte[len]; + for (int i=0; i Date: Fri, 2 Oct 2009 18:49:05 +0800 Subject: [PATCH 09/22] 6874472: display address lists for tickets in klist tool Reviewed-by: valeriep --- .../security/krb5/internal/tools/Klist.java | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java index 5cb919b9d52..40f2942e3a9 100644 --- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java +++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java @@ -30,17 +30,12 @@ package sun.security.krb5.internal.tools; +import java.net.InetAddress; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.*; import sun.security.krb5.internal.ktab.*; import sun.security.krb5.internal.crypto.EType; -import sun.security.krb5.KrbCryptoException; -import java.lang.RuntimeException; -import java.io.IOException; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.File; /** * This class can execute as a command-line tool to list entries in @@ -51,9 +46,9 @@ import java.io.File; */ public class Klist { Object target; - // for credentials cache, options are 'f' and 'e'; + // for credentials cache, options are 'f', 'e', 'a' and 'n'; // for keytab, optionsare 't' and 'K' and 'e' - char[] options = new char[3]; + char[] options = new char[4]; String name; // the name of credentials cache and keytable. char action; // actions would be 'c' for credentials cache // and 'k' for keytable. @@ -62,7 +57,7 @@ public class Klist { /** * The main program that can be invoked at command line. *
Usage: klist - * [[-c] [-f] [-e]] [-k [-t] [-K]] [name] + * [[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name] * -c specifes that credential cache is to be listed * -k specifies that key tab is to be listed * name name of the credentials cache or keytab @@ -70,6 +65,8 @@ public class Klist { *
    *
  • -f shows credentials flags *
  • -e shows the encryption type + *
  • -a shows addresses + *
  • -n do not reverse-resolve addresses *
* available options for keytabs: *
  • -t shows keytab entry timestamps @@ -141,6 +138,12 @@ public class Klist { case 'k': action = 'k'; break; + case 'a': + options[2] = 'a'; + break; + case 'n': + options[3] = 'n'; + break; case 'f': options[1] = 'f'; break; @@ -202,7 +205,7 @@ public class Klist { } if (options[2] == 't') { System.out.println("\t Time stamp: " + - reformat(entries[i].getTimeStamp().toDate().toString())); + reformat(entries[i].getTimeStamp().toDate().toString())); } } } @@ -249,12 +252,33 @@ public class Klist { System.out.println(" Expires: " + endtime); if (options[0] == 'e') { etype = EType.toString(creds[i].getEType()); - System.out.println("\t Encryption type: " + etype); + System.out.println(" Encryption type: " + etype); } if (options[1] == 'f') { - System.out.println("\t Flags: " + + System.out.println(" Flags: " + creds[i].getTicketFlags().toString()); } + if (options[2] == 'a') { + boolean first = true; + InetAddress[] caddr + = creds[i].setKrbCreds().getClientAddresses(); + if (caddr != null) { + for (InetAddress ia: caddr) { + String out; + if (options[3] == 'n') { + out = ia.getHostAddress(); + } else { + out = ia.getCanonicalHostName(); + } + System.out.println(" " + + (first?"Addresses:":" ") + + " " + out); + first = false; + } + } else { + System.out.println(" [No host addresses info]"); + } + } } catch (RealmException e) { System.out.println("Error reading principal from "+ "the entry."); @@ -295,7 +319,7 @@ public class Klist { */ void printHelp() { System.out.println("\nUsage: klist " + - "[[-c] [-f] [-e]] [-k [-t] [-K]] [name]"); + "[[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name]"); System.out.println(" name\t name of credentials cache or " + " keytab with the prefix. File-based cache or " + "keytab's prefix is FILE:."); @@ -305,6 +329,8 @@ public class Klist { System.out.println(" options for credentials caches:"); System.out.println("\t-f \t shows credentials flags"); System.out.println("\t-e \t shows the encryption type"); + System.out.println("\t-a \t shows addresses"); + System.out.println("\t -n \t do not reverse-resolve addresses"); System.out.println(" options for keytabs:"); System.out.println("\t-t \t shows keytab entry timestamps"); System.out.println("\t-K \t shows keytab entry key value"); From 2882b91893c412e7fde40f2e059a511cb84df6f4 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 2 Oct 2009 18:49:46 +0800 Subject: [PATCH 10/22] 6868579: RFE: jarsigner to support reading password from environment variable Reviewed-by: xuelei, wetmore --- .../classes/sun/security/tools/JarSigner.java | 33 +++++--- .../classes/sun/security/tools/KeyTool.java | 77 +++++++++++++++++-- .../classes/sun/security/util/Resources.java | 4 + .../sun/security/tools/jarsigner/passtype.sh | 72 +++++++++++++++++ 4 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 jdk/test/sun/security/tools/jarsigner/passtype.sh diff --git a/jdk/src/share/classes/sun/security/tools/JarSigner.java b/jdk/src/share/classes/sun/security/tools/JarSigner.java index c62018c99b0..3e1d0929104 100644 --- a/jdk/src/share/classes/sun/security/tools/JarSigner.java +++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java @@ -291,13 +291,21 @@ public class JarSigner { for (n=0; n < args.length; n++) { String flags = args[n]; + String modifier = null; + if (flags.charAt(0) == '-') { + int pos = flags.indexOf(':'); + if (pos > 0) { + modifier = flags.substring(pos+1); + flags = flags.substring(0, pos); + } + } if (collator.compare(flags, "-keystore") == 0) { if (++n == args.length) usageNoArg(); keystore = args[n]; } else if (collator.compare(flags, "-storepass") ==0) { if (++n == args.length) usageNoArg(); - storepass = args[n].toCharArray(); + storepass = getPass(modifier, args[n]); } else if (collator.compare(flags, "-storetype") ==0) { if (++n == args.length) usageNoArg(); storetype = args[n]; @@ -329,7 +337,7 @@ public class JarSigner { debug = true; } else if (collator.compare(flags, "-keypass") ==0) { if (++n == args.length) usageNoArg(); - keypass = args[n].toCharArray(); + keypass = getPass(modifier, args[n]); } else if (collator.compare(flags, "-sigfile") ==0) { if (++n == args.length) usageNoArg(); sigfile = args[n]; @@ -355,13 +363,7 @@ public class JarSigner { } else if (collator.compare(flags, "-verify") ==0) { verify = true; } else if (collator.compare(flags, "-verbose") ==0) { - verbose = "all"; - } else if (collator.compare(flags, "-verbose:all") ==0) { - verbose = "all"; - } else if (collator.compare(flags, "-verbose:summary") ==0) { - verbose = "summary"; - } else if (collator.compare(flags, "-verbose:grouped") ==0) { - verbose = "grouped"; + verbose = (modifier != null) ? modifier : "all"; } else if (collator.compare(flags, "-sigalg") ==0) { if (++n == args.length) usageNoArg(); sigalg = args[n]; @@ -465,18 +467,25 @@ public class JarSigner { } } - void usageNoArg() { + static char[] getPass(String modifier, String arg) { + char[] output = KeyTool.getPassWithModifier(modifier, arg); + if (output != null) return output; + usage(); + return null; // Useless, usage() already exit + } + + static void usageNoArg() { System.out.println(rb.getString("Option lacks argument")); usage(); } - void usage() { + static void usage() { System.out.println(); System.out.println(rb.getString("Please type jarsigner -help for usage")); System.exit(1); } - void fullusage() { + static void fullusage() { System.out.println(rb.getString ("Usage: jarsigner [options] jar-file alias")); System.out.println(rb.getString diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index df686a732c3..d34d0bcdc48 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -351,6 +351,15 @@ public final class KeyTool { } } + /* + * Check modifiers + */ + String modifier = null; + int pos = flags.indexOf(':'); + if (pos > 0) { + modifier = flags.substring(pos+1); + flags = flags.substring(0, pos); + } /* * command modes */ @@ -387,18 +396,18 @@ public final class KeyTool { ksfname = args[++i]; } else if (collator.compare(flags, "-storepass") == 0 || collator.compare(flags, "-deststorepass") == 0) { - storePass = args[++i].toCharArray(); + storePass = getPass(modifier, args[++i]); passwords.add(storePass); } else if (collator.compare(flags, "-storetype") == 0 || collator.compare(flags, "-deststoretype") == 0) { storetype = args[++i]; } else if (collator.compare(flags, "-srcstorepass") == 0) { - srcstorePass = args[++i].toCharArray(); + srcstorePass = getPass(modifier, args[++i]); passwords.add(srcstorePass); } else if (collator.compare(flags, "-srcstoretype") == 0) { srcstoretype = args[++i]; } else if (collator.compare(flags, "-srckeypass") == 0) { - srckeyPass = args[++i].toCharArray(); + srckeyPass = getPass(modifier, args[++i]); passwords.add(srckeyPass); } else if (collator.compare(flags, "-srcprovidername") == 0) { srcProviderName = args[++i]; @@ -408,13 +417,13 @@ public final class KeyTool { } else if (collator.compare(flags, "-providerpath") == 0) { pathlist = args[++i]; } else if (collator.compare(flags, "-keypass") == 0) { - keyPass = args[++i].toCharArray(); + keyPass = getPass(modifier, args[++i]); passwords.add(keyPass); } else if (collator.compare(flags, "-new") == 0) { - newPass = args[++i].toCharArray(); + newPass = getPass(modifier, args[++i]); passwords.add(newPass); } else if (collator.compare(flags, "-destkeypass") == 0) { - destKeyPass = args[++i].toCharArray(); + destKeyPass = getPass(modifier, args[++i]); passwords.add(destKeyPass); } else if (collator.compare(flags, "-alias") == 0 || collator.compare(flags, "-srcalias") == 0) { @@ -3842,6 +3851,61 @@ public final class KeyTool { rb.getString("Command option needs an argument.")).format(source)); tinyHelp(); } + + private char[] getPass(String modifier, String arg) { + char[] output = getPassWithModifier(modifier, arg); + if (output != null) return output; + tinyHelp(); + return null; // Useless, tinyHelp() already exits. + } + + // This method also used by JarSigner + public static char[] getPassWithModifier(String modifier, String arg) { + if (modifier == null) { + return arg.toCharArray(); + } else if (collator.compare(modifier, "env") == 0) { + String value = System.getenv(arg); + if (value == null) { + System.err.println(rb.getString( + "Cannot find environment variable: ") + arg); + return null; + } else { + return value.toCharArray(); + } + } else if (collator.compare(modifier, "file") == 0) { + try { + URL url = null; + try { + url = new URL(arg); + } catch (java.net.MalformedURLException mue) { + File f = new File(arg); + if (f.exists()) { + url = f.toURI().toURL(); + } else { + System.err.println(rb.getString( + "Cannot find file: ") + arg); + return null; + } + } + BufferedReader br = new BufferedReader(new InputStreamReader( + url.openStream())); + String value = br.readLine(); + br.close(); + if (value == null) { + return new char[0]; + } else { + return value.toCharArray(); + } + } catch (IOException ioe) { + System.err.println(ioe); + return null; + } + } else { + System.err.println(rb.getString("Unknown password type: ") + + modifier); + return null; + } + } } // This class is exactly the same as com.sun.tools.javac.util.Pair, @@ -3881,3 +3945,4 @@ class Pair { return new Pair(a,b); } } + diff --git a/jdk/src/share/classes/sun/security/util/Resources.java b/jdk/src/share/classes/sun/security/util/Resources.java index af49592e3d6..686e91469a8 100644 --- a/jdk/src/share/classes/sun/security/util/Resources.java +++ b/jdk/src/share/classes/sun/security/util/Resources.java @@ -178,6 +178,10 @@ public class Resources extends java.util.ListResourceBundle { {"keytool error: ", "keytool error: "}, {"Illegal option: ", "Illegal option: "}, {"Illegal value: ", "Illegal value: "}, + {"Unknown password type: ", "Unknown password type: "}, + {"Cannot find environment variable: ", + "Cannot find environment variable: "}, + {"Cannot find file: ", "Cannot find file: "}, {"Command option needs an argument.", "Command option {0} needs an argument."}, {"Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified value.", "Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."}, diff --git a/jdk/test/sun/security/tools/jarsigner/passtype.sh b/jdk/test/sun/security/tools/jarsigner/passtype.sh new file mode 100644 index 00000000000..7e942350956 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/passtype.sh @@ -0,0 +1,72 @@ +# +# Copyright 2009 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 6868579 +# @summary RFE: jarsigner to support reading password from environment variable +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +KS=pt.jks +JFILE=pt.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -keystore $KS -validity 300" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner + +rm $KS $JFILE + +$KT -alias a -dname CN=a -keyalg rsa -genkey \ + -storepass test12 -keypass test12 || exit 1 +PASSENV=test12 $KT -alias b -dname CN=b -keyalg rsa -genkey \ + -storepass:env PASSENV -keypass:env PASSENV || exit 2 +echo test12 > passfile +$KT -alias c -dname CN=c -keyalg rsa -genkey \ + -storepass:file passfile -keypass:file passfile || exit 3 + +echo A > A +$JAR cvf $JFILE A + +$JARSIGNER -keystore $KS -storepass test12 $JFILE a || exit 4 +PASSENV=test12 $JARSIGNER -keystore $KS -storepass:env PASSENV $JFILE b || exit 5 +$JARSIGNER -keystore $KS -storepass:file passfile $JFILE b || exit 6 + +$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 7 + +exit 0 + From 45d2886ea71f5518483f8e07abc04c89d6a2b22b Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Fri, 2 Oct 2009 13:57:41 +0100 Subject: [PATCH 11/22] 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash Reviewed-by: chegar --- .../www/protocol/http/AuthenticationInfo.java | 7 - .../protocol/http/BasicAuthentication.java | 7 - .../protocol/http/DigestAuthentication.java | 8 +- .../www/protocol/http/HttpURLConnection.java | 60 +++- .../http/NegotiateAuthentication.java | 6 - .../www/protocol/http/NTLMAuthentication.java | 7 - .../www/protocol/http/NTLMAuthentication.java | 5 - jdk/test/java/net/Authenticator/B6870935.java | 262 ++++++++++++++++++ 8 files changed, 314 insertions(+), 48 deletions(-) create mode 100644 jdk/test/java/net/Authenticator/B6870935.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java b/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java index f5cfd33c998..cb3362efe86 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java @@ -398,13 +398,6 @@ abstract class AuthenticationInfo extends AuthCacheValue implements Cloneable { */ abstract boolean isAuthorizationStale (String header); - /** - * Check for any expected authentication information in the response - * from the server - */ - abstract void checkResponse (String header, String method, URL url) - throws IOException; - /** * Give a key for hash table lookups. * @param includeRealm if you want the realm considered. Preemptively diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java index ba2cfad52b7..7a92067f050 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java @@ -178,13 +178,6 @@ class BasicAuthentication extends AuthenticationInfo { return false; } - /** - * For Basic Authentication, there is no security information in the - * response - */ - void checkResponse (String header, String method, URL url) { - } - /** * @return the common root path between npath and path. * This is used to detect when we have an authentication for two diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java b/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java index 99026760089..e62e3c2eccf 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java @@ -291,7 +291,7 @@ class DigestAuthentication extends AuthenticationInfo { uri = HttpURLConnection.connectRequestURI(conn.getURL()); method = HTTP_CONNECT; } else { - uri = conn.getURL().getFile(); + uri = conn.getRequestURI(); method = conn.getMethod(); } @@ -385,7 +385,11 @@ class DigestAuthentication extends AuthenticationInfo { public void checkResponse (String header, String method, URL url) throws IOException { - String uri = url.getFile(); + checkResponse (header, method, url.getFile()); + } + + public void checkResponse (String header, String method, String uri) + throws IOException { char[] passwd = pw.getPassword(); String username = pw.getUserName(); boolean qop = params.authQop(); diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 5a52099fdee..f1a60f85fe3 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -390,7 +390,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * request. */ if (!failedOnce) - requests.prepend(method + " " + http.getURLFile()+" " + + requests.prepend(method + " " + getRequestURI()+" " + httpVersion, null); if (!getUseCaches()) { requests.setIfNotSet ("Cache-Control", "no-cache"); @@ -1546,10 +1546,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (proxyAuthentication.isAuthorizationStale (raw)) { /* we can retry with the current credentials */ String value; - if (tunnelState() == TunnelState.SETUP && - proxyAuthentication instanceof DigestAuthentication) { - value = ((DigestAuthentication)proxyAuthentication) - .getHeaderValue(connectRequestURI(url), HTTP_CONNECT); + if (proxyAuthentication instanceof DigestAuthentication) { + DigestAuthentication digestProxy = (DigestAuthentication) + proxyAuthentication; + if (tunnelState() == TunnelState.SETUP) { + value = digestProxy.getHeaderValue(connectRequestURI(url), HTTP_CONNECT); + } else { + value = digestProxy.getHeaderValue(getRequestURI(), method); + } } else { value = proxyAuthentication.getHeaderValue(url, method); } @@ -1765,10 +1769,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { http.getProxyPortUsed()); if (pauth != null && pauth.supportsPreemptiveAuthorization()) { String value; - if (tunnelState() == TunnelState.SETUP && - pauth instanceof DigestAuthentication) { - value = ((DigestAuthentication)pauth) + if (pauth instanceof DigestAuthentication) { + DigestAuthentication digestProxy = (DigestAuthentication) pauth; + if (tunnelState() == TunnelState.SETUP) { + value = digestProxy .getHeaderValue(connectRequestURI(url), HTTP_CONNECT); + } else { + value = digestProxy.getHeaderValue(getRequestURI(), method); + } } else { value = pauth.getHeaderValue(url, method); } @@ -2075,17 +2083,23 @@ public class HttpURLConnection extends java.net.HttpURLConnection { try { if (!needToCheck) return; - if (validateProxy && currentProxyCredentials != null) { + if ((validateProxy && currentProxyCredentials != null) && + (currentProxyCredentials instanceof DigestAuthentication)) { String raw = responses.findValue ("Proxy-Authentication-Info"); if (inClose || (raw != null)) { - currentProxyCredentials.checkResponse (raw, method, url); + DigestAuthentication da = (DigestAuthentication) + currentProxyCredentials; + da.checkResponse (raw, method, getRequestURI()); currentProxyCredentials = null; } } - if (validateServer && currentServerCredentials != null) { + if ((validateServer && currentServerCredentials != null) && + (currentServerCredentials instanceof DigestAuthentication)) { String raw = responses.findValue ("Authentication-Info"); if (inClose || (raw != null)) { - currentServerCredentials.checkResponse (raw, method, url); + DigestAuthentication da = (DigestAuthentication) + currentServerCredentials; + da.checkResponse (raw, method, url); currentServerCredentials = null; } } @@ -2099,6 +2113,23 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + /* The request URI used in the request line for this request. + * Also, needed for digest authentication + */ + + String requestURI = null; + + String getRequestURI() { + if (requestURI == null) { + try { + requestURI = http.getURLFile(); + } catch (IOException e) { + requestURI = ""; + } + } + return requestURI; + } + /* Tells us whether to follow a redirect. If so, it * closes the connection (break any keep-alive) and * resets the url, re-connects, and resets the request @@ -2160,13 +2191,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } setProxiedClient (url, proxyHost, proxyPort); - requests.set(0, method + " " + http.getURLFile()+" " + + requests.set(0, method + " " + getRequestURI()+" " + httpVersion, null); connected = true; } else { // maintain previous headers, just change the name // of the file we're getting url = locUrl; + requestURI = null; // force it to be recalculated if (method.equals("POST") && !Boolean.getBoolean("http.strictPostRedirect") && (stat!=307)) { /* The HTTP/1.1 spec says that a redirect from a POST * *should not* be immediately turned into a GET, and @@ -2204,7 +2236,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * CacheResponse. */ if (http != null) { - requests.set(0, method + " " + http.getURLFile()+" " + + requests.set(0, method + " " + getRequestURI()+" " + httpVersion, null); int port = url.getPort(); String host = url.getHost(); diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 3faedd279f2..6d3931d0958 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -214,12 +214,6 @@ class NegotiateAuthentication extends AuthenticationInfo { return negotiator.nextToken(token); } - /** - * no-use for Negotiate - */ - public void checkResponse (String header, String method, URL url) throws IOException { - } - class B64Encoder extends BASE64Encoder { protected int bytesPerLine () { return 100000; // as big as it can be, maybe INT_MAX diff --git a/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java b/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java index 07899928f42..f1ed83fb70c 100644 --- a/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java +++ b/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java @@ -244,13 +244,6 @@ class NTLMAuthentication extends AuthenticationInfo { } } - /* This is a no-op for NTLM, because there is no authentication information - * provided by the server to the client - */ - public void checkResponse (String header, String method, URL url) throws IOException { - } - - private void copybytes (byte[] dest, int destpos, String src, String enc) { try { byte[] x = src.getBytes(enc); diff --git a/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java b/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java index e14381f9ce5..d3be6820161 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java @@ -192,9 +192,4 @@ class NTLMAuthentication extends AuthenticationInfo { } } - /* This is a no-op for NTLM, because there is no authentication information - * provided by the server to the client - */ - public void checkResponse (String header, String method, URL url) throws IOException { - } } diff --git a/jdk/test/java/net/Authenticator/B6870935.java b/jdk/test/java/net/Authenticator/B6870935.java new file mode 100644 index 00000000000..5afaed9d73b --- /dev/null +++ b/jdk/test/java/net/Authenticator/B6870935.java @@ -0,0 +1,262 @@ +/* + * Copyright 2001-2009 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 6870935 + * @run main/othervm -Dhttp.nonProxyHosts="" -Dhttp.auth.digest.validateProxy=true B6870935 + */ + +import java.io.*; +import java.util.*; +import java.net.*; +import java.security.*; +import sun.net.www.*; + +/* This is one simple test of the RFC2617 digest authentication behavior + * It specifically tests that the client correctly checks the returned + * Authentication-Info header field from the server and throws an exception + * if the password is wrong + */ + +public class B6870935 { + + static char[] passwd = "password".toCharArray(); + static String username = "user"; + static String nonce = "abcdefghijklmnopqrstuvwxyz"; + static String realm = "wallyworld"; + static String uri = "http://www.ibm.com"; + static volatile boolean error = false; + + static class DigestServer extends Thread { + + ServerSocket s; + InputStream is; + OutputStream os; + int port; + + String reply1 = "HTTP/1.1 407 Proxy Authentication Required\r\n"+ + "Proxy-Authenticate: Digest realm=\""+realm+"\" domain=/ "+ + "nonce=\""+nonce+"\" qop=\"auth\"\r\n\r\n"; + + String reply2 = "HTTP/1.1 200 OK\r\n" + + "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" + + "Server: Apache/1.3.14 (Unix)\r\n" + + "Content-Type: text/html; charset=iso-8859-1\r\n" + + "Transfer-encoding: chunked\r\n\r\n"+ + "B\r\nHelloWorld1\r\n"+ + "B\r\nHelloWorld2\r\n"+ + "B\r\nHelloWorld3\r\n"+ + "B\r\nHelloWorld4\r\n"+ + "B\r\nHelloWorld5\r\n"+ + "0\r\n"+ + "Proxy-Authentication-Info: "; + + DigestServer (ServerSocket y) { + s = y; + port = s.getLocalPort(); + } + + public void run () { + try { + Socket s1 = s.accept (); + is = s1.getInputStream (); + os = s1.getOutputStream (); + is.read (); + os.write (reply1.getBytes()); + Thread.sleep (2000); + s1.close (); + + s1 = s.accept (); + is = s1.getInputStream (); + os = s1.getOutputStream (); + is.read (); + // need to get the cnonce out of the response + MessageHeader header = new MessageHeader (is); + String raw = header.findValue ("Proxy-Authorization"); + HeaderParser parser = new HeaderParser (raw); + String cnonce = parser.findValue ("cnonce"); + String cnstring = parser.findValue ("nc"); + String clientrsp = parser.findValue ("response"); + String expected = computeDigest( + true, username,passwd,realm, + "GET", uri, nonce, cnonce, cnstring + ); + if (!expected.equals(clientrsp)) { + s1.close (); + s.close (); + error = true; + return; + } + + String reply = reply2 + getAuthorization ( + realm, false, uri, "GET", cnonce, + cnstring, passwd, username + ) +"\r\n"; + os.write (reply.getBytes()); + Thread.sleep (2000); + s1.close (); + } + catch (Exception e) { + System.out.println (e); + e.printStackTrace(); + } + } + + private String getAuthorization (String realm, boolean isRequest, String uri, String method, String cnonce, String cnstring, char[] password, String username) { + String response; + + try { + response = computeDigest(isRequest, username,passwd,realm, + method, uri, nonce, cnonce, cnstring); + } catch (NoSuchAlgorithmException ex) { + return null; + } + + String value = "Digest" + + " qop=\"auth" + + "\", cnonce=\"" + cnonce + + "\", rspauth=\"" + response + + "\", nc=\"" + cnstring + "\""; + return (value+ "\r\n"); + } + + private String computeDigest( + boolean isRequest, String userName, char[] password, + String realm, String connMethod, + String requestURI, String nonceString, + String cnonce, String ncValue + ) throws NoSuchAlgorithmException + { + + String A1, HashA1; + + MessageDigest md = MessageDigest.getInstance("MD5"); + + { + A1 = userName + ":" + realm + ":"; + HashA1 = encode(A1, password, md); + } + + String A2; + if (isRequest) { + A2 = connMethod + ":" + requestURI; + } else { + A2 = ":" + requestURI; + } + String HashA2 = encode(A2, null, md); + String combo, finalHash; + + { /* RRC2617 when qop=auth */ + combo = HashA1+ ":" + nonceString + ":" + ncValue + ":" + + cnonce + ":auth:" +HashA2; + + } + finalHash = encode(combo, null, md); + return finalHash; + } + + private final static char charArray[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + private String encode(String src, char[] passwd, MessageDigest md) { + md.update(src.getBytes()); + if (passwd != null) { + byte[] passwdBytes = new byte[passwd.length]; + for (int i=0; i>> 4) & 0xf); + res.append(charArray[hashchar]); + hashchar = (digest[i] & 0xf); + res.append(charArray[hashchar]); + } + return res.toString(); + } + } + + + static class MyAuthenticator extends Authenticator { + public MyAuthenticator () { + super (); + } + + public PasswordAuthentication getPasswordAuthentication () + { + return (new PasswordAuthentication (username, passwd)); + } + } + + + public static void main(String[] args) throws Exception { + int nLoops = 1; + int nSize = 10; + int port, n =0; + byte b[] = new byte[nSize]; + DigestServer server; + ServerSocket sock; + + try { + sock = new ServerSocket (0); + port = sock.getLocalPort (); + } + catch (Exception e) { + System.out.println ("Exception: " + e); + return; + } + + server = new DigestServer(sock); + server.start (); + + try { + + Authenticator.setDefault (new MyAuthenticator ()); + SocketAddress addr = new InetSocketAddress ("127.0.0.1", port); + Proxy proxy = new Proxy (Proxy.Type.HTTP, addr); + String s = "http://www.ibm.com"; + URL url = new URL(s); + java.net.URLConnection conURL = url.openConnection(proxy); + + InputStream in = conURL.getInputStream(); + int c; + while ((c = in.read ()) != -1) { + } + in.close (); + } + catch(IOException e) { + e.printStackTrace(); + error = true; + } + if (error) { + throw new RuntimeException ("Error in test"); + } + } +} From 1686f3996fab01fe589272a4c7b8a447a7909e49 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Fri, 2 Oct 2009 08:49:25 -0700 Subject: [PATCH 12/22] 6787605: OpenSolaris doesn't have /usr/ucb/ps so ShellScaffold fails Reviewed-by: dcubed --- jdk/test/com/sun/jdi/ShellScaffold.sh | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/jdk/test/com/sun/jdi/ShellScaffold.sh b/jdk/test/com/sun/jdi/ShellScaffold.sh index a133a8673bb..0ca14814e6c 100644 --- a/jdk/test/com/sun/jdi/ShellScaffold.sh +++ b/jdk/test/com/sun/jdi/ShellScaffold.sh @@ -193,11 +193,17 @@ findPid() { # Return 0 if $1 is the pid of a running process. if [ -z "$isWin98" ] ; then - # Never use plain 'ps', which requires a "controlling terminal" - # and will fail with a "ps: no controlling terminal" error. - # Running under 'rsh' will cause this ps error. - # cygwin ps puts an I in column 1 for some reason. - $psCmd -e | $grep '^I* *'"$1 " > $devnull 2>&1 + if [ "$osname" = SunOS ] ; then + #Solaris and OpenSolaris use pgrep and not ps in psCmd + findPidCmd="$psCmd" + else + # Never use plain 'ps', which requires a "controlling terminal" + # and will fail with a "ps: no controlling terminal" error. + # Running under 'rsh' will cause this ps error. + # cygwin ps puts an I in column 1 for some reason. + findPidCmd="$psCmd -e" + fi + $findPidCmd | $grep '^I* *'"$1 " > $devnull 2>&1 return $? fi @@ -292,7 +298,17 @@ EOF # On linux, core files take a long time, and can leave # zombie processes if [ "$osname" = SunOS ] ; then - psCmd="/usr/ucb/ps -axwww" + #Experiments show Solaris '/usr/ucb/ps -axwww' and + #'/usr/bin/pgrep -f -l' provide the same small amount of the + #argv string (PRARGSZ=80 in /usr/include/sys/procfs.h) + # 1) This seems to have been working OK in ShellScaffold. + # 2) OpenSolaris does not provide /usr/ucb/ps, so use pgrep + # instead + #The alternative would be to use /usr/bin/pargs [pid] to get + #all the args for a process, splice them back into one + #long string, then grep. + UU=`/usr/bin/id -un` + psCmd="pgrep -f -l -U $UU" else ulimit -c 0 # See bug 6238593. From 936d0362c2f3bc027f309d93ee6348351b7ad38a Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 4 Oct 2009 15:42:00 +0100 Subject: [PATCH 13/22] 6884800: (file) Path.newInputStream does not usefully implement available() Reviewed-by: martin, chegar --- .../share/classes/sun/nio/ch/ChannelInputStream.java | 10 ++++++++++ jdk/test/java/nio/channels/Channels/Basic.java | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/nio/ch/ChannelInputStream.java b/jdk/src/share/classes/sun/nio/ch/ChannelInputStream.java index 46e3e28b921..f7e12cf0501 100644 --- a/jdk/src/share/classes/sun/nio/ch/ChannelInputStream.java +++ b/jdk/src/share/classes/sun/nio/ch/ChannelInputStream.java @@ -109,6 +109,16 @@ public class ChannelInputStream return ChannelInputStream.read(ch, bb, true); } + public int available() throws IOException { + // special case where the channel is to a file + if (ch instanceof SeekableByteChannel) { + SeekableByteChannel sbc = (SeekableByteChannel)ch; + long rem = Math.max(0, sbc.size() - sbc.position()); + return (rem > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)rem; + } + return 0; + } + public void close() throws IOException { ch.close(); } diff --git a/jdk/test/java/nio/channels/Channels/Basic.java b/jdk/test/java/nio/channels/Channels/Basic.java index 3a931a3f4c5..bfa9f0d404e 100644 --- a/jdk/test/java/nio/channels/Channels/Basic.java +++ b/jdk/test/java/nio/channels/Channels/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4417152 4481572 6248930 6725399 + * @bug 4417152 4481572 6248930 6725399 6884800 * @summary Test Channels basic functionality */ @@ -225,8 +225,7 @@ public class Basic { private static void testNewInputStream(File blah) throws Exception { FileInputStream fis = new FileInputStream(blah); FileChannel fc = fis.getChannel(); - ReadableByteChannel rbc = (ReadableByteChannel)fc; - InputStream is = Channels.newInputStream(rbc); + InputStream is = Channels.newInputStream(fc); int messageSize = message.length() * ITERATIONS * 3 + 1; byte bb[] = new byte[messageSize]; @@ -234,8 +233,13 @@ public class Basic { int totalRead = 0; while (bytesRead != -1) { totalRead += bytesRead; + long rem = Math.min(fc.size() - totalRead, (long)Integer.MAX_VALUE); + if (is.available() != (int)rem) + throw new RuntimeException("available not useful or not maximally useful"); bytesRead = is.read(bb, totalRead, messageSize - totalRead); } + if (is.available() != 0) + throw new RuntimeException("available() should return 0 at EOF"); String result = new String(bb, 0, totalRead, encoding); int len = message.length(); From 2170e604da3043d4828816477cc4d7d3f72691e8 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 5 Oct 2009 16:45:55 +0100 Subject: [PATCH 14/22] 6854954: Eliminate static dependency on java.awt.AWTPermission Reviewed-by: mullan, mchung, anthony --- jdk/src/share/classes/java/awt/Dialog.java | 2 +- jdk/src/share/classes/java/awt/MouseInfo.java | 2 +- jdk/src/share/classes/java/awt/Robot.java | 4 +- .../share/classes/java/awt/SystemTray.java | 2 +- jdk/src/share/classes/java/awt/Toolkit.java | 8 +- jdk/src/share/classes/java/awt/Window.java | 4 +- .../classes/java/lang/SecurityManager.java | 6 +- .../share/classes/javax/swing/JPopupMenu.java | 2 +- .../classes/sun/awt/AWTPermissionFactory.java | 42 ++++++ .../sun/security/provider/PolicyFile.java | 3 - .../sun/security/util/PermissionFactory.java | 36 +++++ .../sun/security/util/SecurityConstants.java | 141 +++++++++++++----- 12 files changed, 200 insertions(+), 52 deletions(-) create mode 100644 jdk/src/share/classes/sun/awt/AWTPermissionFactory.java create mode 100644 jdk/src/share/classes/sun/security/util/PermissionFactory.java diff --git a/jdk/src/share/classes/java/awt/Dialog.java b/jdk/src/share/classes/java/awt/Dialog.java index 4660e6ea07c..b897183ca8b 100644 --- a/jdk/src/share/classes/java/awt/Dialog.java +++ b/jdk/src/share/classes/java/awt/Dialog.java @@ -856,7 +856,7 @@ public class Dialog extends Window { if (type == ModalityType.TOOLKIT_MODAL) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION); + sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION); } } modalityType = type; diff --git a/jdk/src/share/classes/java/awt/MouseInfo.java b/jdk/src/share/classes/java/awt/MouseInfo.java index dce20bc0b84..8905ecaee9c 100644 --- a/jdk/src/share/classes/java/awt/MouseInfo.java +++ b/jdk/src/share/classes/java/awt/MouseInfo.java @@ -76,7 +76,7 @@ public class MouseInfo { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.WATCH_MOUSE_PERMISSION); + security.checkPermission(SecurityConstants.AWT.WATCH_MOUSE_PERMISSION); } Point point = new Point(0, 0); diff --git a/jdk/src/share/classes/java/awt/Robot.java b/jdk/src/share/classes/java/awt/Robot.java index c9a32e2d01d..d262910a220 100644 --- a/jdk/src/share/classes/java/awt/Robot.java +++ b/jdk/src/share/classes/java/awt/Robot.java @@ -167,7 +167,7 @@ public class Robot { private void checkRobotAllowed() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.CREATE_ROBOT_PERMISSION); + security.checkPermission(SecurityConstants.AWT.CREATE_ROBOT_PERMISSION); } } @@ -466,7 +466,7 @@ public class Robot { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission( - SecurityConstants.READ_DISPLAY_PIXELS_PERMISSION); + SecurityConstants.AWT.READ_DISPLAY_PIXELS_PERMISSION); } } diff --git a/jdk/src/share/classes/java/awt/SystemTray.java b/jdk/src/share/classes/java/awt/SystemTray.java index 2aa172108b1..91cffdce9f2 100644 --- a/jdk/src/share/classes/java/awt/SystemTray.java +++ b/jdk/src/share/classes/java/awt/SystemTray.java @@ -490,7 +490,7 @@ public class SystemTray { static void checkSystemTrayAllowed() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.ACCESS_SYSTEM_TRAY_PERMISSION); + security.checkPermission(SecurityConstants.AWT.ACCESS_SYSTEM_TRAY_PERMISSION); } } diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index aaa6afdd5a0..129b1f0102d 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -2025,7 +2025,7 @@ public abstract class Toolkit { } SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.ALL_AWT_EVENTS_PERMISSION); + security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION); } synchronized (this) { SelectiveAWTEventListener selectiveListener = @@ -2094,7 +2094,7 @@ public abstract class Toolkit { } SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.ALL_AWT_EVENTS_PERMISSION); + security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION); } synchronized (this) { @@ -2165,7 +2165,7 @@ public abstract class Toolkit { public AWTEventListener[] getAWTEventListeners() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.ALL_AWT_EVENTS_PERMISSION); + security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION); } synchronized (this) { EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); @@ -2217,7 +2217,7 @@ public abstract class Toolkit { public AWTEventListener[] getAWTEventListeners(long eventMask) { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.ALL_AWT_EVENTS_PERMISSION); + security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION); } synchronized (this) { EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index a342f37879f..c526107f4e8 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -1581,7 +1581,7 @@ public class Window extends Container implements Accessible { if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION); + sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION); } } modalExclusionType = exclusionType; @@ -2129,7 +2129,7 @@ public class Window extends Container implements Accessible { public final void setAlwaysOnTop(boolean alwaysOnTop) throws SecurityException { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkPermission(SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); + security.checkPermission(SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); } boolean oldAlwaysOnTop; diff --git a/jdk/src/share/classes/java/lang/SecurityManager.java b/jdk/src/share/classes/java/lang/SecurityManager.java index ea0dd5ea998..9006588fa08 100644 --- a/jdk/src/share/classes/java/lang/SecurityManager.java +++ b/jdk/src/share/classes/java/lang/SecurityManager.java @@ -1341,7 +1341,7 @@ class SecurityManager { throw new NullPointerException("window can't be null"); } try { - checkPermission(SecurityConstants.TOPLEVEL_WINDOW_PERMISSION); + checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION); return true; } catch (SecurityException se) { // just return false @@ -1391,7 +1391,7 @@ class SecurityManager { * @see #checkPermission(java.security.Permission) checkPermission */ public void checkSystemClipboardAccess() { - checkPermission(SecurityConstants.ACCESS_CLIPBOARD_PERMISSION); + checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } /** @@ -1412,7 +1412,7 @@ class SecurityManager { * @see #checkPermission(java.security.Permission) checkPermission */ public void checkAwtEventQueueAccess() { - checkPermission(SecurityConstants.CHECK_AWT_EVENTQUEUE_PERMISSION); + checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION); } /* diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 8f90a02a2a9..78715b886be 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -412,7 +412,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission( - SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); + SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); } } catch (SecurityException se) { // There is no permission to show popups over the task bar diff --git a/jdk/src/share/classes/sun/awt/AWTPermissionFactory.java b/jdk/src/share/classes/sun/awt/AWTPermissionFactory.java new file mode 100644 index 00000000000..73d7e2c5cac --- /dev/null +++ b/jdk/src/share/classes/sun/awt/AWTPermissionFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright 2009 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.awt; + +import java.awt.AWTPermission; +import sun.security.util.PermissionFactory; + +/** + * A factory object for AWTPermission objects. + */ + +public class AWTPermissionFactory + implements PermissionFactory +{ + @Override + public AWTPermission newPermission(String name) { + return new AWTPermission(name); + } +} diff --git a/jdk/src/share/classes/sun/security/provider/PolicyFile.java b/jdk/src/share/classes/sun/security/provider/PolicyFile.java index 768ddd9ce63..324e745f375 100644 --- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java +++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java @@ -54,7 +54,6 @@ import java.net.SocketPermission; import java.net.NetPermission; import java.util.PropertyPermission; import java.util.concurrent.atomic.AtomicReference; -import java.awt.AWTPermission; /* import javax.security.auth.AuthPermission; import javax.security.auth.kerberos.ServicePermission; @@ -1023,8 +1022,6 @@ public class PolicyFile extends java.security.Policy { return new NetPermission(name, actions); } else if (claz.equals(AllPermission.class)) { return SecurityConstants.ALL_PERMISSION; - } else if (claz.equals(AWTPermission.class)) { - return new AWTPermission(name, actions); /* } else if (claz.equals(ReflectPermission.class)) { return new ReflectPermission(name, actions); diff --git a/jdk/src/share/classes/sun/security/util/PermissionFactory.java b/jdk/src/share/classes/sun/security/util/PermissionFactory.java new file mode 100644 index 00000000000..10356051fa3 --- /dev/null +++ b/jdk/src/share/classes/sun/security/util/PermissionFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright 2009 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.security.util; + +import java.security.Permission; + +/** + * A factory object that creates Permission objects. + */ + +public interface PermissionFactory { + T newPermission(String name); +} diff --git a/jdk/src/share/classes/sun/security/util/SecurityConstants.java b/jdk/src/share/classes/sun/security/util/SecurityConstants.java index 43e2cd3d792..89c6fd7fdea 100644 --- a/jdk/src/share/classes/sun/security/util/SecurityConstants.java +++ b/jdk/src/share/classes/sun/security/util/SecurityConstants.java @@ -25,12 +25,12 @@ package sun.security.util; -import java.io.FilePermission; -import java.awt.AWTPermission; -import java.util.PropertyPermission; -import java.lang.RuntimePermission; import java.net.SocketPermission; import java.net.NetPermission; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.Permission; +import java.security.BasicPermission; import java.security.SecurityPermission; import java.security.AllPermission; import javax.security.auth.AuthPermission; @@ -71,45 +71,118 @@ public final class SecurityConstants { // sun.security.provider.PolicyFile public static final AllPermission ALL_PERMISSION = new AllPermission(); - // java.lang.SecurityManager - public static final AWTPermission TOPLEVEL_WINDOW_PERMISSION = - new AWTPermission("showWindowWithoutWarningBanner"); + /** + * Permission type used when AWT is not present. + */ + private static class FakeAWTPermission extends BasicPermission { + private static final long serialVersionUID = -1L; + public FakeAWTPermission(String name) { + super(name); + } + public String toString() { + return "(\"java.awt.AWTPermission\" \"" + getName() + "\")"; + } + } - // java.lang.SecurityManager - public static final AWTPermission ACCESS_CLIPBOARD_PERMISSION = - new AWTPermission("accessClipboard"); + /** + * Permission factory used when AWT is not present. + */ + private static class FakeAWTPermissionFactory + implements PermissionFactory + { + @Override + public FakeAWTPermission newPermission(String name) { + return new FakeAWTPermission(name); + } + } - // java.lang.SecurityManager - public static final AWTPermission CHECK_AWT_EVENTQUEUE_PERMISSION = - new AWTPermission("accessEventQueue"); + /** + * AWT Permissions used in the JDK. + */ + public static class AWT { + private AWT() { } - // java.awt.Dialog - public static final AWTPermission TOOLKIT_MODALITY_PERMISSION = - new AWTPermission("toolkitModality"); + /** + * The class name of the factory to create java.awt.AWTPermission objects. + */ + private static final String AWTFactory = "sun.awt.AWTPermissionFactory"; - // java.awt.Robot - public static final AWTPermission READ_DISPLAY_PIXELS_PERMISSION = - new AWTPermission("readDisplayPixels"); + /** + * The PermissionFactory to create AWT permissions (or fake permissions + * if AWT is not present). + */ + private static final PermissionFactory factory = permissionFactory(); - // java.awt.Robot - public static final AWTPermission CREATE_ROBOT_PERMISSION = - new AWTPermission("createRobot"); + private static PermissionFactory permissionFactory() { + Class c = AccessController + .doPrivileged(new PrivilegedAction>() { + public Class run() { + try { + return Class.forName(AWTFactory, true, null); + } catch (ClassNotFoundException e) { + // not available + return null; + } + }}); + if (c != null) { + // AWT present + try { + return (PermissionFactory)c.newInstance(); + } catch (InstantiationException x) { + throw new InternalError(x.getMessage()); + } catch (IllegalAccessException x) { + throw new InternalError(x.getMessage()); + } + } else { + // AWT not present + return new FakeAWTPermissionFactory(); + } + } - // java.awt.MouseInfo - public static final AWTPermission WATCH_MOUSE_PERMISSION = - new AWTPermission("watchMousePointer"); + private static Permission newAWTPermission(String name) { + return factory.newPermission(name); + } - // java.awt.Window - public static final AWTPermission SET_WINDOW_ALWAYS_ON_TOP_PERMISSION = - new AWTPermission("setWindowAlwaysOnTop"); + // java.lang.SecurityManager + public static final Permission TOPLEVEL_WINDOW_PERMISSION = + newAWTPermission("showWindowWithoutWarningBanner"); - // java.awt.Toolkit - public static final AWTPermission ALL_AWT_EVENTS_PERMISSION = - new AWTPermission("listenToAllAWTEvents"); + // java.lang.SecurityManager + public static final Permission ACCESS_CLIPBOARD_PERMISSION = + newAWTPermission("accessClipboard"); - // java.awt.SystemTray - public static final AWTPermission ACCESS_SYSTEM_TRAY_PERMISSION = - new AWTPermission("accessSystemTray"); + // java.lang.SecurityManager + public static final Permission CHECK_AWT_EVENTQUEUE_PERMISSION = + newAWTPermission("accessEventQueue"); + + // java.awt.Dialog + public static final Permission TOOLKIT_MODALITY_PERMISSION = + newAWTPermission("toolkitModality"); + + // java.awt.Robot + public static final Permission READ_DISPLAY_PIXELS_PERMISSION = + newAWTPermission("readDisplayPixels"); + + // java.awt.Robot + public static final Permission CREATE_ROBOT_PERMISSION = + newAWTPermission("createRobot"); + + // java.awt.MouseInfo + public static final Permission WATCH_MOUSE_PERMISSION = + newAWTPermission("watchMousePointer"); + + // java.awt.Window + public static final Permission SET_WINDOW_ALWAYS_ON_TOP_PERMISSION = + newAWTPermission("setWindowAlwaysOnTop"); + + // java.awt.Toolkit + public static final Permission ALL_AWT_EVENTS_PERMISSION = + newAWTPermission("listenToAllAWTEvents"); + + // java.awt.SystemTray + public static final Permission ACCESS_SYSTEM_TRAY_PERMISSION = + newAWTPermission("accessSystemTray"); + } // java.net.URL public static final NetPermission SPECIFY_HANDLER_PERMISSION = From 04890be7bb003b072e764348c310db96eb04c870 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Mon, 5 Oct 2009 23:42:48 +0100 Subject: [PATCH 15/22] 6885204: JSSE should not require Kerberos to be present Reviewed-by: wetmore, alanb --- .../https/DelegateHttpsURLConnection.java | 7 +++-- .../net/www/protocol/https/HttpsClient.java | 9 ++++-- .../classes/sun/security/ssl/CipherSuite.java | 16 +++++++--- .../classes/sun/security/ssl/JsseJce.java | 29 ++++++++++++++++++- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java b/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java index 7192405745f..e0512a33b87 100644 --- a/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java +++ b/jdk/src/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2009 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 @@ -116,7 +116,10 @@ class VerifierWrapper implements javax.net.ssl.HostnameVerifier { try { String serverName; Principal principal = getPeerPrincipal(session); - if (principal instanceof KerberosPrincipal) { + // X.500 principal or Kerberos principal. + // (Use ciphersuite check to determine whether Kerberos is present.) + if (session.getCipherSuite().startsWith("TLS_KRB5") && + principal instanceof KerberosPrincipal) { serverName = HostnameChecker.getServerName((KerberosPrincipal)principal); } else { diff --git a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java index d21425680c8..8bbcb4de312 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2009 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 @@ -461,12 +461,16 @@ final class HttpsClient extends HttpClient } Certificate[] peerCerts = null; + String cipher = session.getCipherSuite(); try { HostnameChecker checker = HostnameChecker.getInstance( HostnameChecker.TYPE_TLS); Principal principal = getPeerPrincipal(); - if (principal instanceof KerberosPrincipal) { + // X.500 principal or Kerberos principal. + // (Use ciphersuite check to determine whether Kerberos is present.) + if (cipher.startsWith("TLS_KRB5") && + principal instanceof KerberosPrincipal) { if (!checker.match(host, (KerberosPrincipal)principal)) { throw new SSLPeerUnverifiedException("Hostname checker" + " failed for Kerberos"); @@ -499,7 +503,6 @@ final class HttpsClient extends HttpClient // ignore } - String cipher = session.getCipherSuite(); if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) { return; } else if ((hostnameVerifier != null) && diff --git a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java index bb1ffa0909d..6ca15478f8e 100644 --- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 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 @@ -74,7 +74,7 @@ final class CipherSuite implements Comparable { // Flag indicating if CipherSuite availability can change dynamically. // This is the case when we rely on a JCE cipher implementation that // may not be available in the installed JCE providers. - // It is true because we do not have a Java ECC implementation. + // It is true because we might not have an ECC or Kerberos implementation. final static boolean DYNAMIC_AVAILABILITY = true; private final static boolean ALLOW_ECC = Debug.getBooleanProperty @@ -278,14 +278,22 @@ final class CipherSuite implements Comparable { KeyExchange(String name, boolean allowed) { this.name = name; this.allowed = allowed; - this.alwaysAvailable = allowed && (name.startsWith("EC") == false); + this.alwaysAvailable = allowed && + (!name.startsWith("EC")) && (!name.startsWith("KRB")); } boolean isAvailable() { if (alwaysAvailable) { return true; } - return allowed && JsseJce.isEcAvailable(); + + if (name.startsWith("EC")) { + return (allowed && JsseJce.isEcAvailable()); + } else if (name.startsWith("KRB")) { + return (allowed && JsseJce.isKerberosAvailable()); + } else { + return allowed; + } } public String toString() { diff --git a/jdk/src/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/share/classes/sun/security/ssl/JsseJce.java index 017efd03ac2..779214308d3 100644 --- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java +++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2009 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 @@ -64,6 +64,29 @@ final class JsseJce { // If yes, then all the EC based crypto we need is available. private static volatile Boolean ecAvailable; + // Flag indicating whether Kerberos crypto is available. + // If true, then all the Kerberos-based crypto we need is available. + private final static boolean kerberosAvailable; + static { + boolean temp; + try { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { + // Test for Kerberos using the bootstrap class loader + Class.forName("sun.security.krb5.PrincipalName", true, + null); + return null; + } + }); + temp = true; + + } catch (Exception e) { + temp = false; + } + kerberosAvailable = temp; + } + static { // force FIPS flag initialization // Because isFIPS() is synchronized and cryptoProvider is not modified @@ -187,6 +210,10 @@ final class JsseJce { ecAvailable = null; } + static boolean isKerberosAvailable() { + return kerberosAvailable; + } + /** * Return an JCE cipher implementation for the specified algorithm. */ From 9f6fbc5544f818afece1278a044d711f57220203 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 5 Oct 2009 18:15:32 -0700 Subject: [PATCH 16/22] 6612680: Remove classloader dependency on jkernel Add a new sun.misc.BootClassLoaderHook that DownloadManager will implement Reviewed-by: alanb, forax, igor --- jdk/make/sun/jkernel/Makefile | 4 - .../classes/java/awt/color/ICC_Profile.java | 11 +- .../share/classes/java/lang/ClassLoader.java | 37 +---- .../share/classes/java/util/zip/ZipEntry.java | 17 +- .../classes/sun/jkernel/DownloadManager.java | 77 ++++++++- .../classes/sun/misc/BootClassLoaderHook.java | 153 ++++++++++++++++++ jdk/src/share/classes/sun/misc/Launcher.java | 35 ++-- jdk/src/share/classes/sun/misc/VM.java | 5 - jdk/src/share/native/sun/misc/VM.c | 11 -- 9 files changed, 260 insertions(+), 90 deletions(-) create mode 100644 jdk/src/share/classes/sun/misc/BootClassLoaderHook.java diff --git a/jdk/make/sun/jkernel/Makefile b/jdk/make/sun/jkernel/Makefile index 047efeae5aa..97f2f38aca5 100644 --- a/jdk/make/sun/jkernel/Makefile +++ b/jdk/make/sun/jkernel/Makefile @@ -35,10 +35,6 @@ include $(BUILDDIR)/common/Defs.gmk # _OPT = $(CC_HIGHEST_OPT) -# This re-directs all the class files to a separate location -CLASSDESTDIR = $(TEMPDIR)/classes - - # # Java source files # diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java index 44f28508788..78ba43d4bc4 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java @@ -58,6 +58,8 @@ import java.util.StringTokenizer; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.misc.BootClassLoaderHook; + /** * A representation of color profile data for device independent and * device dependent color spaces based on the International Color @@ -1850,11 +1852,10 @@ public class ICC_Profile implements Serializable { f = new File(fullPath); if (!f.isFile()) { //make sure file was installed in the kernel mode - try { - //kernel uses platform independent paths => - // should not use platform separator char - sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName); - } catch (IOException ioe) {} + BootClassLoaderHook hook = BootClassLoaderHook.getHook(); + if (hook.getHook() != null) { + hook.prefetchFile("lib/cmm/"+fileName); + } } } diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index 9fec9b570a0..bd59d95667a 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -51,6 +51,7 @@ import java.util.Vector; import java.util.Hashtable; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; +import sun.misc.BootClassLoaderHook; import sun.misc.ClassFileTransformer; import sun.misc.CompoundEnumeration; import sun.misc.Resource; @@ -58,7 +59,6 @@ import sun.misc.URLClassPath; import sun.misc.VM; import sun.reflect.Reflection; import sun.security.util.SecurityConstants; -import sun.jkernel.DownloadManager; /** * A class loader is an object that is responsible for loading classes. The @@ -1300,21 +1300,7 @@ public abstract class ClassLoader { * Find resources from the VM's built-in classloader. */ private static URL getBootstrapResource(String name) { - try { - // If this is a known JRE resource, ensure that its bundle is - // downloaded. If it isn't known, we just ignore the download - // failure and check to see if we can find the resource anyway - // (which is possible if the boot class path has been modified). - if (sun.misc.VM.isBootedKernelVM()) { - sun.jkernel.DownloadManager.getBootClassPathEntryForResource( - name); - } - } catch (NoClassDefFoundError e) { - // This happens while Java itself is being compiled; DownloadManager - // isn't accessible when this code is first invoked. It isn't an - // issue, as if we can't find DownloadManager, we can safely assume - // that additional code is not available for download. - } + BootClassLoaderHook.preLoadResource(name); URLClassPath ucp = getBootstrapClassPath(); Resource res = ucp.getResource(name); return res != null ? res.getURL() : null; @@ -1831,24 +1817,7 @@ public abstract class ClassLoader { // Invoked in the java.lang.Runtime class to implement load and loadLibrary. static void loadLibrary(Class fromClass, String name, boolean isAbsolute) { - try { - if (VM.isBootedKernelVM() && !DownloadManager.isJREComplete() && - !DownloadManager.isCurrentThreadDownloading()) { - DownloadManager.downloadFile("bin/" + - System.mapLibraryName(name)); - // it doesn't matter if the downloadFile call returns false -- - // it probably just means that this is a user library, as - // opposed to a JRE library - } - } catch (IOException e) { - throw new UnsatisfiedLinkError("Error downloading library " + - name + ": " + e); - } catch (NoClassDefFoundError e) { - // This happens while Java itself is being compiled; DownloadManager - // isn't accessible when this code is first invoked. It isn't an - // issue, as if we can't find DownloadManager, we can safely assume - // that additional code is not available for download. - } + BootClassLoaderHook.preLoadLibrary(name); ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); if (sys_paths == null) { diff --git a/jdk/src/share/classes/java/util/zip/ZipEntry.java b/jdk/src/share/classes/java/util/zip/ZipEntry.java index 0e2ddaec3fb..8da5a4f54ad 100644 --- a/jdk/src/share/classes/java/util/zip/ZipEntry.java +++ b/jdk/src/share/classes/java/util/zip/ZipEntry.java @@ -26,6 +26,7 @@ package java.util.zip; import java.util.Date; +import sun.misc.BootClassLoaderHook; /** * This class is used to represent a ZIP file entry. @@ -109,12 +110,16 @@ class ZipEntry implements ZipConstants, Cloneable { * @see #getTime() */ public void setTime(long time) { - // fix for bug 6625963: we bypass time calculations while Kernel is - // downloading bundles, since they aren't necessary and would cause - // the Kernel core to depend upon the (very large) time zone data - if (sun.misc.VM.isBootedKernelVM() && - sun.jkernel.DownloadManager.isCurrentThreadDownloading()) { - this.time = sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME; + // Same value as defined in sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME + // to avoid direct reference to DownoadManager class. Need to revisit + // if this is needed any more (see comment in the DownloadManager class) + final int KERNEL_STATIC_MODTIME = 10000000; + BootClassLoaderHook hook = BootClassLoaderHook.getHook(); + if (hook != null && hook.isCurrentThreadPrefetching()) { + // fix for bug 6625963: we bypass time calculations while Kernel is + // downloading bundles, since they aren't necessary and would cause + // the Kernel core to depend upon the (very large) time zone data + this.time = KERNEL_STATIC_MODTIME; } else { this.time = javaToDosTime(time); } diff --git a/jdk/src/share/classes/sun/jkernel/DownloadManager.java b/jdk/src/share/classes/sun/jkernel/DownloadManager.java index e945380ebce..b93f51c68b4 100644 --- a/jdk/src/share/classes/sun/jkernel/DownloadManager.java +++ b/jdk/src/share/classes/sun/jkernel/DownloadManager.java @@ -31,6 +31,7 @@ import java.util.concurrent.*; import java.util.jar.*; import java.util.zip.*; import sun.misc.Launcher; +import sun.misc.BootClassLoaderHook; /** * Handles the downloading of additional JRE components. The bootstrap class @@ -39,7 +40,7 @@ import sun.misc.Launcher; * *@author Ethan Nicholas */ -public class DownloadManager { +public class DownloadManager extends BootClassLoaderHook { public static final String KERNEL_DOWNLOAD_URL_PROPERTY = "kernel.download.url"; public static final String KERNEL_DOWNLOAD_ENABLED_PROPERTY = @@ -1023,7 +1024,8 @@ public class DownloadManager { /** * Returns true if the current thread is in the process of - * downloading a bundle. This is called by ClassLoader.loadLibrary(), so + * downloading a bundle. This is called by DownloadManager.loadLibrary() + * that is called by System.loadLibrary(), so * that when we run into a library required by the download process itself, * we don't call back into DownloadManager in an attempt to download it * (which would lead to infinite recursion). @@ -1614,6 +1616,77 @@ public class DownloadManager { static native int getCurrentProcessId(); + private DownloadManager() { + } + + // Invoked by jkernel VM after the VM is initialized + static void setBootClassLoaderHook() { + if (!isJREComplete()) { + sun.misc.BootClassLoaderHook.setHook(new DownloadManager()); + } + } + + // Implementation of the BootClassLoaderHook interface + public String loadBootstrapClass(String name) { + // Check for download before we look for it. If + // DownloadManager ends up downloading it, it will add it to + // our search path before we proceed to the findClass(). + return DownloadManager.getBootClassPathEntryForClass(name); + } + + public boolean loadLibrary(String name) { + try { + if (!DownloadManager.isJREComplete() && + !DownloadManager.isCurrentThreadDownloading()) { + return DownloadManager.downloadFile("bin/" + + System.mapLibraryName(name)); + // it doesn't matter if the downloadFile call returns false -- + // it probably just means that this is a user library, as + // opposed to a JRE library + } + } catch (IOException e) { + throw new UnsatisfiedLinkError("Error downloading library " + + name + ": " + e); + } catch (NoClassDefFoundError e) { + // This happens while Java itself is being compiled; DownloadManager + // isn't accessible when this code is first invoked. It isn't an + // issue, as if we can't find DownloadManager, we can safely assume + // that additional code is not available for download. + } + return false; + } + + public boolean prefetchFile(String name) { + try { + return sun.jkernel.DownloadManager.downloadFile(name); + } catch (IOException ioe) { + return false; + } + } + + public String getBootstrapResource(String name) { + try { + // If this is a known JRE resource, ensure that its bundle is + // downloaded. If it isn't known, we just ignore the download + // failure and check to see if we can find the resource anyway + // (which is possible if the boot class path has been modified). + return DownloadManager.getBootClassPathEntryForResource(name); + } catch (NoClassDefFoundError e) { + // This happens while Java itself is being compiled; DownloadManager + // isn't accessible when this code is first invoked. It isn't an + // issue, as if we can't find DownloadManager, we can safely assume + // that additional code is not available for download. + return null; + } + } + + public File[] getAdditionalBootstrapPaths() { + return DownloadManager.getAdditionalBootStrapPaths(); + } + + public boolean isCurrentThreadPrefetching() { + return DownloadManager.isCurrentThreadDownloading(); + } public static void main(String[] arg) throws Exception { AccessController.checkPermission(new AllPermission()); diff --git a/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java new file mode 100644 index 00000000000..28c187ead73 --- /dev/null +++ b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java @@ -0,0 +1,153 @@ +/* + * Copyright 2009 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.misc; + +import java.io.File; +import java.io.IOException; + +/** + * BootClassLoaderHook defines an interface for a hook to inject + * into the bootstrap class loader. + * + * In jkernel build, the sun.jkernel.DownloadManager is set as + * a BootClassLoaderHook by the jkernel VM after the VM is initialized. + * + * In other JDK builds, no hook is set. + */ +public abstract class BootClassLoaderHook { + private static BootClassLoaderHook bootLoaderHook = null; + public static synchronized BootClassLoaderHook getHook() { + return bootLoaderHook; + } + + public static synchronized void setHook(BootClassLoaderHook hook) { + if (!VM.isBooted()) { + throw new InternalError("hook can only be set after VM is booted"); + } + if (bootLoaderHook != null) { + throw new InternalError("hook should not be reinitialized"); + } + bootLoaderHook = hook; + } + + protected BootClassLoaderHook() { + } + + /** + * A method to be invoked before a class loader loads + * a bootstrap class. + * + * @param classname the binary name of the class + */ + public static void preLoadClass(String classname) { + BootClassLoaderHook hook = getHook(); + if (hook != null) { + hook.loadBootstrapClass(classname); + } + } + + /** + * A method to be invoked before a class loader loads + * a resource. + * + * @param resourcename the resource name + */ + public static void preLoadResource(String resourcename) { + BootClassLoaderHook hook = getHook(); + if (hook != null) { + hook.getBootstrapResource(resourcename); + } + } + + /** + * A method to be invoked before a library is loaded. + * + * @param libname the name of the library + */ + public static void preLoadLibrary(String libname) { + BootClassLoaderHook hook = getHook(); + if (hook != null) { + hook.loadLibrary(libname); + } + } + + private static final File[] EMPTY_FILE_ARRAY = new File[0]; + + /** + * Returns bootstrap class paths added by the hook. + */ + public static File[] getBootstrapPaths() { + BootClassLoaderHook hook = getHook(); + if (hook != null) { + return hook.getBootstrapPaths(); + } else { + return EMPTY_FILE_ARRAY; + } + } + + /** + * Returns a pathname of a JAR or class that the hook loads + * per this loadClass request; or null. + * + * @param classname the binary name of the class + */ + public abstract String loadBootstrapClass(String className); + + /** + * Returns a pathname of a resource file that the hook loads + * per this getResource request; or null. + * + * @param resourceName the resource name + */ + public abstract String getBootstrapResource(String resourceName); + + /** + * Returns true if the hook successfully performs an operation per + * this loadLibrary request; or false if it fails. + * + * @param libname the name of the library + */ + public abstract boolean loadLibrary(String libname); + + /** + * Returns additional boot class paths added by the hook that + * should be searched by the boot class loader. + */ + public abstract File[] getAdditionalBootstrapPaths(); + + /** + * Returns true if the current thread is in the process of doing + * a prefetching operation. + */ + public abstract boolean isCurrentThreadPrefetching(); + + /** + * Returns true if the hook successfully prefetches the specified file. + * + * @param name a platform independent pathname + */ + public abstract boolean prefetchFile(String name); +} diff --git a/jdk/src/share/classes/sun/misc/Launcher.java b/jdk/src/share/classes/sun/misc/Launcher.java index 2793f14f05d..5ebd10fbd19 100644 --- a/jdk/src/share/classes/sun/misc/Launcher.java +++ b/jdk/src/share/classes/sun/misc/Launcher.java @@ -50,8 +50,6 @@ import java.security.CodeSource; import sun.security.action.GetPropertyAction; import sun.security.util.SecurityConstants; import sun.net.www.ParseUtil; -import sun.jkernel.Bundle; -import sun.jkernel.DownloadManager; /** * This class is used by the system to launch the main application. @@ -248,12 +246,7 @@ public class Launcher { } protected Class findClass(String name) throws ClassNotFoundException { - if (VM.isBootedKernelVM()) { - // Check for download before we look for it. If - // DownloadManager ends up downloading it, it will add it to - // our search path before we proceed to the findClass(). - DownloadManager.getBootClassPathEntryForClass(name); - } + BootClassLoaderHook.preLoadClass(name); return super.findClass(name); } @@ -321,9 +314,7 @@ public class Launcher { public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (VM.isBootedKernelVM()) { - DownloadManager.getBootClassPathEntryForClass(name); - } + BootClassLoaderHook.preLoadClass(name); int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); @@ -421,19 +412,17 @@ public class Launcher { } bootstrapClassPath = new URLClassPath(urls, factory); - if (VM.isBootedKernelVM()) { - final File[] additionalBootStrapPaths = - DownloadManager.getAdditionalBootStrapPaths(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - for (int i=0; iGetStaticFieldID(env, cls, "kernelVM", "Z"); - if (fid != 0) { - (*env)->SetStaticBooleanField(env, cls, fid, info.is_kernel_jvm); - } else { - sprintf(errmsg, "Static kernelVM boolean field not found"); - JNU_ThrowInternalError(env, errmsg); - } - } } } From bd9e7da356c1f011dfb5c6fdafad2cd962ac3d9d Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 6 Oct 2009 13:31:41 -0700 Subject: [PATCH 17/22] 5062288: (reflect) Core reflection uses raw types when it could be using wildcards Reviewed-by: alanb --- jdk/src/share/classes/java/lang/Class.java | 70 +++++++++---------- jdk/src/share/classes/java/lang/Package.java | 2 +- .../java/lang/reflect/AccessibleObject.java | 2 +- .../java/lang/reflect/Constructor.java | 28 ++++---- .../classes/java/lang/reflect/Field.java | 28 ++++---- .../classes/java/lang/reflect/Method.java | 42 +++++------ .../classes/java/lang/reflect/Proxy.java | 4 +- .../java/lang/reflect/ReflectAccess.java | 28 ++++---- .../sun/reflect/LangReflectAccess.java | 28 ++++---- .../AnnotationInvocationHandler.java | 18 ++--- .../reflect/annotation/AnnotationParser.java | 70 ++++++++++--------- .../reflect/annotation/AnnotationType.java | 14 ++-- 12 files changed, 168 insertions(+), 166 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 46414ad8491..111c78ce188 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -265,7 +265,7 @@ public final } /** Called after security checks have been made. */ - private static native Class forName0(String name, boolean initialize, + private static native Class forName0(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException; @@ -339,7 +339,7 @@ public final ); } try { - Class[] empty = {}; + Class[] empty = {}; final Constructor c = getConstructor0(empty, Member.DECLARED); // Disable accessibility checks on the constructor // since we have to do the security check here anyway @@ -361,7 +361,7 @@ public final // Security check (same as in java.lang.reflect.Constructor) int modifiers = tmpConstructor.getModifiers(); if (!Reflection.quickCheckMemberAccess(this, modifiers)) { - Class caller = Reflection.getCallerClass(3); + Class caller = Reflection.getCallerClass(3); if (newInstanceCallerCache != caller) { Reflection.ensureMemberAccess(caller, this, null, modifiers); newInstanceCallerCache = caller; @@ -377,7 +377,7 @@ public final } } private volatile transient Constructor cachedConstructor; - private volatile transient Class newInstanceCallerCache; + private volatile transient Class newInstanceCallerCache; /** @@ -638,7 +638,7 @@ public final if (getGenericSignature() != null) return (TypeVariable>[])getGenericInfo().getTypeParameters(); else - return (TypeVariable>[])new TypeVariable[0]; + return (TypeVariable>[])new TypeVariable[0]; } @@ -901,7 +901,7 @@ public final MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(), getFactory()); - Class returnType = toClass(typeInfo.getReturnType()); + Class returnType = toClass(typeInfo.getReturnType()); Type [] parameterTypes = typeInfo.getParameterTypes(); Class[] parameterClasses = new Class[parameterTypes.length]; @@ -996,12 +996,12 @@ public final } - private static Class toClass(Type o) { + private static Class toClass(Type o) { if (o instanceof GenericArrayType) return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()), 0) .getClass(); - return (Class)o; + return (Class)o; } /** @@ -1042,7 +1042,7 @@ public final * Loop over all declared constructors; match number * of and type of parameters. */ - for(Constructor c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) { + for(Constructor c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) { Class[] candidateParamClasses = c.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; @@ -1304,12 +1304,12 @@ public final // has already been ok'd by the SecurityManager. return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction[]>() { public Class[] run() { - List list = new ArrayList(); - Class currentClass = Class.this; + List> list = new ArrayList>(); + Class currentClass = Class.this; while (currentClass != null) { - Class[] members = currentClass.getDeclaredClasses(); + Class[] members = currentClass.getDeclaredClasses(); for (int i = 0; i < members.length; i++) { if (Modifier.isPublic(members[i].getModifiers())) { list.add(members[i]); @@ -2191,7 +2191,7 @@ public final return name; } if (!name.startsWith("/")) { - Class c = this; + Class c = this; while (c.isArray()) { c = c.getComponentType(); } @@ -2565,12 +2565,12 @@ public final // out concrete implementations inherited from superclasses at // the end. MethodArray inheritedMethods = new MethodArray(); - Class[] interfaces = getInterfaces(); + Class[] interfaces = getInterfaces(); for (int i = 0; i < interfaces.length; i++) { inheritedMethods.addAll(interfaces[i].privateGetPublicMethods()); } if (!isInterface()) { - Class c = getSuperclass(); + Class c = getSuperclass(); if (c != null) { MethodArray supers = new MethodArray(); supers.addAll(c.privateGetPublicMethods()); @@ -2632,16 +2632,16 @@ public final return res; } // Direct superinterfaces, recursively - Class[] interfaces = getInterfaces(); + Class[] interfaces = getInterfaces(); for (int i = 0; i < interfaces.length; i++) { - Class c = interfaces[i]; + Class c = interfaces[i]; if ((res = c.getField0(name)) != null) { return res; } } // Direct superclass, recursively if (!isInterface()) { - Class c = getSuperclass(); + Class c = getSuperclass(); if (c != null) { if ((res = c.getField0(name)) != null) { return res; @@ -2653,7 +2653,7 @@ public final private static Method searchMethods(Method[] methods, String name, - Class[] parameterTypes) + Class[] parameterTypes) { Method res = null; String internedName = name.intern(); @@ -2670,7 +2670,7 @@ public final } - private Method getMethod0(String name, Class[] parameterTypes) { + private Method getMethod0(String name, Class[] parameterTypes) { // Note: the intent is that the search algorithm this routine // uses be equivalent to the ordering imposed by // privateGetPublicMethods(). It fetches only the declared @@ -2687,7 +2687,7 @@ public final } // Search superclass's methods if (!isInterface()) { - Class c = getSuperclass(); + Class c = getSuperclass(); if (c != null) { if ((res = c.getMethod0(name, parameterTypes)) != null) { return res; @@ -2695,9 +2695,9 @@ public final } } // Search superinterfaces' methods - Class[] interfaces = getInterfaces(); + Class[] interfaces = getInterfaces(); for (int i = 0; i < interfaces.length; i++) { - Class c = interfaces[i]; + Class c = interfaces[i]; if ((res = c.getMethod0(name, parameterTypes)) != null) { return res; } @@ -2706,7 +2706,7 @@ public final return null; } - private Constructor getConstructor0(Class[] parameterTypes, + private Constructor getConstructor0(Class[] parameterTypes, int which) throws NoSuchMethodException { Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); @@ -2775,9 +2775,9 @@ public final private native Field[] getDeclaredFields0(boolean publicOnly); private native Method[] getDeclaredMethods0(boolean publicOnly); private native Constructor[] getDeclaredConstructors0(boolean publicOnly); - private native Class[] getDeclaredClasses0(); + private native Class[] getDeclaredClasses0(); - private static String argumentTypesToString(Class[] argTypes) { + private static String argumentTypesToString(Class[] argTypes) { StringBuilder buf = new StringBuilder(); buf.append("("); if (argTypes != null) { @@ -2785,7 +2785,7 @@ public final if (i > 0) { buf.append(", "); } - Class c = argTypes[i]; + Class c = argTypes[i]; buf.append((c == null) ? "null" : c.getName()); } } @@ -2858,7 +2858,7 @@ public final } // Retrieves the desired assertion status of this class from the VM - private static native boolean desiredAssertionStatus0(Class clazz); + private static native boolean desiredAssertionStatus0(Class clazz); /** * Returns true if and only if this class was declared as an enum in the @@ -2979,7 +2979,7 @@ public final getName() + " is not an enum type"); Map m = new HashMap(2 * universe.length); for (T constant : universe) - m.put(((Enum)constant).name(), constant); + m.put(((Enum)constant).name(), constant); enumConstantDirectory = m; } return enumConstantDirectory; @@ -3077,8 +3077,8 @@ public final } // Annotations cache - private transient Map annotations; - private transient Map declaredAnnotations; + private transient Map, Annotation> annotations; + private transient Map, Annotation> declaredAnnotations; private synchronized void initAnnotationsIfNecessary() { clearCachesOnClassRedefinition(); @@ -3090,10 +3090,10 @@ public final if (superClass == null) { annotations = declaredAnnotations; } else { - annotations = new HashMap(); + annotations = new HashMap, Annotation>(); superClass.initAnnotationsIfNecessary(); - for (Map.Entry e : superClass.annotations.entrySet()) { - Class annotationClass = e.getKey(); + for (Map.Entry, Annotation> e : superClass.annotations.entrySet()) { + Class annotationClass = e.getKey(); if (AnnotationType.getInstance(annotationClass).isInherited()) annotations.put(annotationClass, e.getValue()); } diff --git a/jdk/src/share/classes/java/lang/Package.java b/jdk/src/share/classes/java/lang/Package.java index 63cad6b1e4a..80d40ae871e 100644 --- a/jdk/src/share/classes/java/lang/Package.java +++ b/jdk/src/share/classes/java/lang/Package.java @@ -320,7 +320,7 @@ public class Package implements java.lang.reflect.AnnotatedElement { * @param class the class to get the package of. * @return the package of the class. It may be null if no package * information is available from the archive or codebase. */ - static Package getPackage(Class c) { + static Package getPackage(Class c) { String name = c.getName(); int i = name.lastIndexOf('.'); if (i != -1) { diff --git a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java index 7934ebe9484..1f94a4c5a15 100644 --- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java +++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java @@ -131,7 +131,7 @@ public class AccessibleObject implements AnnotatedElement { throws SecurityException { if (obj instanceof Constructor && flag == true) { - Constructor c = (Constructor)obj; + Constructor c = (Constructor)obj; if (c.getDeclaringClass() == Class.class) { throw new SecurityException("Can not make a java.lang.Class" + " constructor accessible"); diff --git a/jdk/src/share/classes/java/lang/reflect/Constructor.java b/jdk/src/share/classes/java/lang/reflect/Constructor.java index ae812ad72f5..3ec31e3e605 100644 --- a/jdk/src/share/classes/java/lang/reflect/Constructor.java +++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java @@ -64,8 +64,8 @@ public final private Class clazz; private int slot; - private Class[] parameterTypes; - private Class[] exceptionTypes; + private Class[] parameterTypes; + private Class[] exceptionTypes; private int modifiers; // Generics and annotations support private transient String signature; @@ -80,7 +80,7 @@ public final // always succeed (it is not affected by the granting or revoking // of permissions); we speed up the check in the common case by // remembering the last Class for which the check succeeded. - private volatile Class securityCheckCache; + private volatile Class securityCheckCache; // Generics infrastructure // Accessor for factory @@ -113,8 +113,8 @@ public final * package via sun.reflect.LangReflectAccess. */ Constructor(Class declaringClass, - Class[] parameterTypes, - Class[] checkedExceptions, + Class[] parameterTypes, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -307,11 +307,11 @@ public final */ public boolean equals(Object obj) { if (obj != null && obj instanceof Constructor) { - Constructor other = (Constructor)obj; + Constructor other = (Constructor)obj; if (getDeclaringClass() == other.getDeclaringClass()) { /* Avoid unnecessary cloning */ - Class[] params1 = parameterTypes; - Class[] params2 = other.parameterTypes; + Class[] params1 = parameterTypes; + Class[] params2 = other.parameterTypes; if (params1.length == params2.length) { for (int i = 0; i < params1.length; i++) { if (params1[i] != params2[i]) @@ -357,14 +357,14 @@ public final } sb.append(Field.getTypeName(getDeclaringClass())); sb.append("("); - Class[] params = parameterTypes; // avoid clone + Class[] params = parameterTypes; // avoid clone for (int j = 0; j < params.length; j++) { sb.append(Field.getTypeName(params[j])); if (j < (params.length - 1)) sb.append(","); } sb.append(")"); - Class[] exceptions = exceptionTypes; // avoid clone + Class[] exceptions = exceptionTypes; // avoid clone if (exceptions.length > 0) { sb.append(" throws "); for (int k = 0; k < exceptions.length; k++) { @@ -452,7 +452,7 @@ public final sb.append(" throws "); for (int k = 0; k < exceptions.length; k++) { sb.append((exceptions[k] instanceof Class)? - ((Class)exceptions[k]).getName(): + ((Class)exceptions[k]).getName(): exceptions[k].toString()); if (k < (exceptions.length - 1)) sb.append(","); @@ -518,7 +518,7 @@ public final { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(2); + Class caller = Reflection.getCallerClass(2); if (securityCheckCache != caller) { Reflection.ensureMemberAccess(caller, clazz, null, modifiers); securityCheckCache = caller; @@ -625,9 +625,9 @@ public final return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map declaredAnnotations; + private transient Map, Annotation> declaredAnnotations; - private synchronized Map declaredAnnotations() { + private synchronized Map, Annotation> declaredAnnotations() { if (declaredAnnotations == null) { declaredAnnotations = AnnotationParser.parseAnnotations( annotations, sun.misc.SharedSecrets.getJavaLangAccess(). diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java index 5a3e9e9ab7d..7a39f096373 100644 --- a/jdk/src/share/classes/java/lang/reflect/Field.java +++ b/jdk/src/share/classes/java/lang/reflect/Field.java @@ -58,12 +58,12 @@ import sun.reflect.annotation.AnnotationParser; public final class Field extends AccessibleObject implements Member { - private Class clazz; + private Class clazz; private int slot; // This is guaranteed to be interned by the VM in the 1.4 // reflection implementation private String name; - private Class type; + private Class type; private int modifiers; // Generics and annotations support private transient String signature; @@ -81,8 +81,8 @@ class Field extends AccessibleObject implements Member { // More complicated security check cache needed here than for // Class.newInstance() and Constructor.newInstance() - private Class securityCheckCache; - private Class securityCheckTargetClassCache; + private Class securityCheckCache; + private Class securityCheckTargetClassCache; // Generics infrastructure @@ -112,9 +112,9 @@ class Field extends AccessibleObject implements Member { * instantiation of these objects in Java code from the java.lang * package via sun.reflect.LangReflectAccess. */ - Field(Class declaringClass, + Field(Class declaringClass, String name, - Class type, + Class type, int modifiers, int slot, String signature, @@ -964,10 +964,10 @@ class Field extends AccessibleObject implements Member { private void doSecurityCheck(Object obj) throws IllegalAccessException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(4); - Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) - ? clazz - : obj.getClass()); + Class caller = Reflection.getCallerClass(4); + Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) + ? clazz + : obj.getClass()); synchronized (this) { if ((securityCheckCache == caller) @@ -987,10 +987,10 @@ class Field extends AccessibleObject implements Member { /* * Utility routine to paper over array type names */ - static String getTypeName(Class type) { + static String getTypeName(Class type) { if (type.isArray()) { try { - Class cl = type; + Class cl = type; int dimensions = 0; while (cl.isArray()) { dimensions++; @@ -1025,9 +1025,9 @@ class Field extends AccessibleObject implements Member { return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map declaredAnnotations; + private transient Map, Annotation> declaredAnnotations; - private synchronized Map declaredAnnotations() { + private synchronized Map, Annotation> declaredAnnotations() { if (declaredAnnotations == null) { declaredAnnotations = AnnotationParser.parseAnnotations( annotations, sun.misc.SharedSecrets.getJavaLangAccess(). diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java index fc9e467ae48..b9793c7754b 100644 --- a/jdk/src/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/share/classes/java/lang/reflect/Method.java @@ -61,14 +61,14 @@ import java.util.Map; public final class Method extends AccessibleObject implements GenericDeclaration, Member { - private Class clazz; + private Class clazz; private int slot; // This is guaranteed to be interned by the VM in the 1.4 // reflection implementation private String name; - private Class returnType; - private Class[] parameterTypes; - private Class[] exceptionTypes; + private Class returnType; + private Class[] parameterTypes; + private Class[] exceptionTypes; private int modifiers; // Generics and annotations support private transient String signature; @@ -85,8 +85,8 @@ public final // More complicated security check cache needed here than for // Class.newInstance() and Constructor.newInstance() - private Class securityCheckCache; - private Class securityCheckTargetClassCache; + private Class securityCheckCache; + private Class securityCheckTargetClassCache; // Generics infrastructure @@ -114,11 +114,11 @@ public final * instantiation of these objects in Java code from the java.lang * package via sun.reflect.LangReflectAccess. */ - Method(Class declaringClass, + Method(Class declaringClass, String name, - Class[] parameterTypes, - Class returnType, - Class[] checkedExceptions, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -355,8 +355,8 @@ public final if (!returnType.equals(other.getReturnType())) return false; /* Avoid unnecessary cloning */ - Class[] params1 = parameterTypes; - Class[] params2 = other.parameterTypes; + Class[] params1 = parameterTypes; + Class[] params2 = other.parameterTypes; if (params1.length == params2.length) { for (int i = 0; i < params1.length; i++) { if (params1[i] != params2[i]) @@ -410,14 +410,14 @@ public final sb.append(Field.getTypeName(getReturnType()) + " "); sb.append(Field.getTypeName(getDeclaringClass()) + "."); sb.append(getName() + "("); - Class[] params = parameterTypes; // avoid clone + Class[] params = parameterTypes; // avoid clone for (int j = 0; j < params.length; j++) { sb.append(Field.getTypeName(params[j])); if (j < (params.length - 1)) sb.append(","); } sb.append(")"); - Class[] exceptions = exceptionTypes; // avoid clone + Class[] exceptions = exceptionTypes; // avoid clone if (exceptions.length > 0) { sb.append(" throws "); for (int k = 0; k < exceptions.length; k++) { @@ -590,10 +590,10 @@ public final { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(1); - Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) - ? clazz - : obj.getClass()); + Class caller = Reflection.getCallerClass(1); + Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) + ? clazz + : obj.getClass()); boolean cached; synchronized (this) { @@ -702,9 +702,9 @@ public final return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map declaredAnnotations; + private transient Map, Annotation> declaredAnnotations; - private synchronized Map declaredAnnotations() { + private synchronized Map, Annotation> declaredAnnotations() { if (declaredAnnotations == null) { declaredAnnotations = AnnotationParser.parseAnnotations( annotations, sun.misc.SharedSecrets.getJavaLangAccess(). @@ -731,7 +731,7 @@ public final public Object getDefaultValue() { if (annotationDefault == null) return null; - Class memberType = AnnotationType.invocationHandlerReturnType( + Class memberType = AnnotationType.invocationHandlerReturnType( getReturnType()); Object result = AnnotationParser.parseMemberValue( memberType, ByteBuffer.wrap(annotationDefault), diff --git a/jdk/src/share/classes/java/lang/reflect/Proxy.java b/jdk/src/share/classes/java/lang/reflect/Proxy.java index 07b7e85df56..258c64aff69 100644 --- a/jdk/src/share/classes/java/lang/reflect/Proxy.java +++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java @@ -350,7 +350,7 @@ public class Proxy implements java.io.Serializable { throw new IllegalArgumentException("interface limit exceeded"); } - Class proxyClass = null; + Class proxyClass = null; /* collect interface names to use as key for proxy class cache */ String[] interfaceNames = new String[interfaces.length]; @@ -364,7 +364,7 @@ public class Proxy implements java.io.Serializable { * interface to the same Class object. */ String interfaceName = interfaces[i].getName(); - Class interfaceClass = null; + Class interfaceClass = null; try { interfaceClass = Class.forName(interfaceName, false, loader); } catch (ClassNotFoundException e) { diff --git a/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java b/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java index ff09637a934..28f1b63230f 100644 --- a/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java +++ b/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java @@ -33,9 +33,9 @@ import sun.reflect.ConstructorAccessor; package to instantiate objects in this package. */ class ReflectAccess implements sun.reflect.LangReflectAccess { - public Field newField(Class declaringClass, + public Field newField(Class declaringClass, String name, - Class type, + Class type, int modifiers, int slot, String signature, @@ -50,11 +50,11 @@ class ReflectAccess implements sun.reflect.LangReflectAccess { annotations); } - public Method newMethod(Class declaringClass, + public Method newMethod(Class declaringClass, String name, - Class[] parameterTypes, - Class returnType, - Class[] checkedExceptions, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -76,8 +76,8 @@ class ReflectAccess implements sun.reflect.LangReflectAccess { } public Constructor newConstructor(Class declaringClass, - Class[] parameterTypes, - Class[] checkedExceptions, + Class[] parameterTypes, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -102,29 +102,29 @@ class ReflectAccess implements sun.reflect.LangReflectAccess { m.setMethodAccessor(accessor); } - public ConstructorAccessor getConstructorAccessor(Constructor c) { + public ConstructorAccessor getConstructorAccessor(Constructor c) { return c.getConstructorAccessor(); } - public void setConstructorAccessor(Constructor c, + public void setConstructorAccessor(Constructor c, ConstructorAccessor accessor) { c.setConstructorAccessor(accessor); } - public int getConstructorSlot(Constructor c) { + public int getConstructorSlot(Constructor c) { return c.getSlot(); } - public String getConstructorSignature(Constructor c) { + public String getConstructorSignature(Constructor c) { return c.getSignature(); } - public byte[] getConstructorAnnotations(Constructor c) { + public byte[] getConstructorAnnotations(Constructor c) { return c.getRawAnnotations(); } - public byte[] getConstructorParameterAnnotations(Constructor c) { + public byte[] getConstructorParameterAnnotations(Constructor c) { return c.getRawParameterAnnotations(); } diff --git a/jdk/src/share/classes/sun/reflect/LangReflectAccess.java b/jdk/src/share/classes/sun/reflect/LangReflectAccess.java index 9a893d2e73e..1a58057a734 100644 --- a/jdk/src/share/classes/sun/reflect/LangReflectAccess.java +++ b/jdk/src/share/classes/sun/reflect/LangReflectAccess.java @@ -33,9 +33,9 @@ import java.lang.reflect.*; public interface LangReflectAccess { /** Creates a new java.lang.reflect.Field. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Field newField(Class declaringClass, + public Field newField(Class declaringClass, String name, - Class type, + Class type, int modifiers, int slot, String signature, @@ -43,11 +43,11 @@ public interface LangReflectAccess { /** Creates a new java.lang.reflect.Method. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Method newMethod(Class declaringClass, + public Method newMethod(Class declaringClass, String name, - Class[] parameterTypes, - Class returnType, - Class[] checkedExceptions, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -58,8 +58,8 @@ public interface LangReflectAccess { /** Creates a new java.lang.reflect.Constructor. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ public Constructor newConstructor(Class declaringClass, - Class[] parameterTypes, - Class[] checkedExceptions, + Class[] parameterTypes, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -74,24 +74,24 @@ public interface LangReflectAccess { /** Gets the ConstructorAccessor object for a java.lang.reflect.Constructor */ - public ConstructorAccessor getConstructorAccessor(Constructor c); + public ConstructorAccessor getConstructorAccessor(Constructor c); /** Sets the ConstructorAccessor object for a java.lang.reflect.Constructor */ - public void setConstructorAccessor(Constructor c, + public void setConstructorAccessor(Constructor c, ConstructorAccessor accessor); /** Gets the "slot" field from a Constructor (used for serialization) */ - public int getConstructorSlot(Constructor c); + public int getConstructorSlot(Constructor c); /** Gets the "signature" field from a Constructor (used for serialization) */ - public String getConstructorSignature(Constructor c); + public String getConstructorSignature(Constructor c); /** Gets the "annotations" field from a Constructor (used for serialization) */ - public byte[] getConstructorAnnotations(Constructor c); + public byte[] getConstructorAnnotations(Constructor c); /** Gets the "parameterAnnotations" field from a Constructor (used for serialization) */ - public byte[] getConstructorParameterAnnotations(Constructor c); + public byte[] getConstructorParameterAnnotations(Constructor c); // // Copying routines, needed to quickly fabricate new Field, diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index 3b5d8f74d27..85dd1424b60 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -40,17 +40,17 @@ import java.security.PrivilegedAction; * @since 1.5 */ class AnnotationInvocationHandler implements InvocationHandler, Serializable { - private final Class type; + private final Class type; private final Map memberValues; - AnnotationInvocationHandler(Class type, Map memberValues) { + AnnotationInvocationHandler(Class type, Map memberValues) { this.type = type; this.memberValues = memberValues; } public Object invoke(Object proxy, Method method, Object[] args) { String member = method.getName(); - Class[] paramTypes = method.getParameterTypes(); + Class[] paramTypes = method.getParameterTypes(); // Handle Object and Annotation methods if (member.equals("equals") && paramTypes.length == 1 && @@ -84,7 +84,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * if Cloneable had a public clone method. */ private Object cloneArray(Object array) { - Class type = array.getClass(); + Class type = array.getClass(); if (type == byte[].class) { byte[] byteArray = (byte[])array; @@ -151,7 +151,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * Translates a member value (in "dynamic proxy return form") into a string */ private static String memberValueToString(Object value) { - Class type = value.getClass(); + Class type = value.getClass(); if (!type.isArray()) // primitive, string, class, enum const, // or annotation return value.toString(); @@ -229,7 +229,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * two members are identical object references. */ private static boolean memberValueEquals(Object v1, Object v2) { - Class type = v1.getClass(); + Class type = v1.getClass(); // Check for primitive, string, class, enum const, annotation, // or ExceptionProxy @@ -301,7 +301,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * Computes hashCode of a member value (in "dynamic proxy return form") */ private static int memberValueHashCode(Object value) { - Class type = value.getClass(); + Class type = value.getClass(); if (!type.isArray()) // primitive, string, class, enum const, // or annotation return value.hashCode(); @@ -340,11 +340,11 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { return; } - Map memberTypes = annotationType.memberTypes(); + Map> memberTypes = annotationType.memberTypes(); for (Map.Entry memberValue : memberValues.entrySet()) { String name = memberValue.getKey(); - Class memberType = memberTypes.get(name); + Class memberType = memberTypes.get(name); if (memberType != null) { // i.e. member still exists Object value = memberValue.getValue(); if (!(memberType.isInstance(value) || diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java index 4bcb0d30542..8cef320b248 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java @@ -59,10 +59,10 @@ public class AnnotationParser { * @throws AnnotationFormatError if an annotation is found to be * malformed. */ - public static Map parseAnnotations( + public static Map, Annotation> parseAnnotations( byte[] rawAnnotations, ConstantPool constPool, - Class container) { + Class container) { if (rawAnnotations == null) return Collections.emptyMap(); @@ -76,17 +76,18 @@ public class AnnotationParser { } } - private static Map parseAnnotations2( + private static Map, Annotation> parseAnnotations2( byte[] rawAnnotations, ConstantPool constPool, - Class container) { - Map result = new LinkedHashMap(); + Class container) { + Map, Annotation> result = + new LinkedHashMap, Annotation>(); ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numAnnotations = buf.getShort() & 0xFFFF; for (int i = 0; i < numAnnotations; i++) { Annotation a = parseAnnotation(buf, constPool, container, false); if (a != null) { - Class klass = a.annotationType(); + Class klass = a.annotationType(); AnnotationType type = AnnotationType.getInstance(klass); if (type.retention() == RetentionPolicy.RUNTIME) if (result.put(klass, a) != null) @@ -123,7 +124,7 @@ public class AnnotationParser { public static Annotation[][] parseParameterAnnotations( byte[] rawAnnotations, ConstantPool constPool, - Class container) { + Class container) { try { return parseParameterAnnotations2(rawAnnotations, constPool, container); } catch(BufferUnderflowException e) { @@ -138,7 +139,7 @@ public class AnnotationParser { private static Annotation[][] parseParameterAnnotations2( byte[] rawAnnotations, ConstantPool constPool, - Class container) { + Class container) { ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numParameters = buf.get() & 0xFF; Annotation[][] result = new Annotation[numParameters][]; @@ -188,15 +189,15 @@ public class AnnotationParser { */ private static Annotation parseAnnotation(ByteBuffer buf, ConstantPool constPool, - Class container, + Class container, boolean exceptionOnMissingAnnotationClass) { int typeIndex = buf.getShort() & 0xFFFF; - Class annotationClass = null; + Class annotationClass = null; String sig = "[unknown]"; try { try { sig = constPool.getUTF8At(typeIndex); - annotationClass = parseSig(sig, container); + annotationClass = (Class)parseSig(sig, container); } catch (IllegalArgumentException ex) { // support obsolete early jsr175 format class files annotationClass = constPool.getClassAt(typeIndex); @@ -223,7 +224,7 @@ public class AnnotationParser { return null; } - Map memberTypes = type.memberTypes(); + Map> memberTypes = type.memberTypes(); Map memberValues = new LinkedHashMap(type.memberDefaults()); @@ -231,7 +232,7 @@ public class AnnotationParser { for (int i = 0; i < numMembers; i++) { int memberNameIndex = buf.getShort() & 0xFFFF; String memberName = constPool.getUTF8At(memberNameIndex); - Class memberType = memberTypes.get(memberName); + Class memberType = memberTypes.get(memberName); if (memberType == null) { // Member is no longer present in annotation type; ignore it @@ -252,7 +253,7 @@ public class AnnotationParser { * member -> value map. */ public static Annotation annotationForMap( - Class type, Map memberValues) + Class type, Map memberValues) { return (Annotation) Proxy.newProxyInstance( type.getClassLoader(), new Class[] { type }, @@ -286,14 +287,15 @@ public class AnnotationParser { * The member must be of the indicated type. If it is not, this * method returns an AnnotationTypeMismatchExceptionProxy. */ - public static Object parseMemberValue(Class memberType, ByteBuffer buf, + public static Object parseMemberValue(Class memberType, + ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { Object result = null; int tag = buf.get(); switch(tag) { case 'e': - return parseEnumValue(memberType, buf, constPool, container); + return parseEnumValue((Class>)memberType, buf, constPool, container); case 'c': result = parseClassValue(buf, constPool, container); break; @@ -361,7 +363,7 @@ public class AnnotationParser { */ private static Object parseClassValue(ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { int classIndex = buf.getShort() & 0xFFFF; try { try { @@ -379,7 +381,7 @@ public class AnnotationParser { } } - private static Class parseSig(String sig, Class container) { + private static Class parseSig(String sig, Class container) { if (sig.equals("V")) return void.class; SignatureParser parser = SignatureParser.make(); TypeSignature typeSig = parser.parseTypeSig(sig); @@ -389,7 +391,7 @@ public class AnnotationParser { Type result = reify.getResult(); return toClass(result); } - static Class toClass(Type o) { + static Class toClass(Type o) { if (o instanceof GenericArrayType) return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()), 0) @@ -409,9 +411,9 @@ public class AnnotationParser { * u2 const_name_index; * } enum_const_value; */ - private static Object parseEnumValue(Class enumType, ByteBuffer buf, + private static Object parseEnumValue(Class enumType, ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { int typeNameIndex = buf.getShort() & 0xFFFF; String typeName = constPool.getUTF8At(typeNameIndex); int constNameIndex = buf.getShort() & 0xFFFF; @@ -449,12 +451,12 @@ public class AnnotationParser { * If the array values do not match arrayType, an * AnnotationTypeMismatchExceptionProxy will be returned. */ - private static Object parseArray(Class arrayType, + private static Object parseArray(Class arrayType, ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { int length = buf.getShort() & 0xFFFF; // Number of array components - Class componentType = arrayType.getComponentType(); + Class componentType = arrayType.getComponentType(); if (componentType == byte.class) { return parseByteArray(length, buf, constPool); @@ -477,11 +479,11 @@ public class AnnotationParser { } else if (componentType == Class.class) { return parseClassArray(length, buf, constPool, container); } else if (componentType.isEnum()) { - return parseEnumArray(length, componentType, buf, + return parseEnumArray(length, (Class)componentType, buf, constPool, container); } else { assert componentType.isAnnotation(); - return parseAnnotationArray(length, componentType, buf, + return parseAnnotationArray(length, (Class )componentType, buf, constPool, container); } } @@ -660,8 +662,8 @@ public class AnnotationParser { private static Object parseClassArray(int length, ByteBuffer buf, ConstantPool constPool, - Class container) { - Object[] result = new Class[length]; + Class container) { + Object[] result = new Class[length]; boolean typeMismatch = false; int tag = 0; @@ -677,10 +679,10 @@ public class AnnotationParser { return typeMismatch ? exceptionProxy(tag) : result; } - private static Object parseEnumArray(int length, Class enumType, + private static Object parseEnumArray(int length, Class enumType, ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { Object[] result = (Object[]) Array.newInstance(enumType, length); boolean typeMismatch = false; int tag = 0; @@ -698,10 +700,10 @@ public class AnnotationParser { } private static Object parseAnnotationArray(int length, - Class annotationType, + Class annotationType, ByteBuffer buf, ConstantPool constPool, - Class container) { + Class container) { Object[] result = (Object[]) Array.newInstance(annotationType, length); boolean typeMismatch = false; int tag = 0; @@ -797,7 +799,7 @@ public class AnnotationParser { * it is needed. */ private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; - public static Annotation[] toArray(Map annotations) { + public static Annotation[] toArray(Map, Annotation> annotations) { return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY); } } diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java index f23263d8c05..6f7f0d0bb54 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java @@ -45,7 +45,7 @@ public class AnnotationType { * types. This matches the return value that must be used for a * dynamic proxy, allowing for a simple isInstance test. */ - private final Map memberTypes = new HashMap(); + private final Map> memberTypes = new HashMap>(); /** * Member name -> default value mapping. @@ -76,12 +76,12 @@ public class AnnotationType { * does not represent a valid annotation type */ public static synchronized AnnotationType getInstance( - Class annotationClass) + Class annotationClass) { AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess(). getAnnotationType(annotationClass); if (result == null) - result = new AnnotationType((Class) annotationClass); + result = new AnnotationType((Class) annotationClass); return result; } @@ -93,7 +93,7 @@ public class AnnotationType { * @throw IllegalArgumentException if the specified class object for * does not represent a valid annotation type */ - private AnnotationType(final Class annotationClass) { + private AnnotationType(final Class annotationClass) { if (!annotationClass.isAnnotation()) throw new IllegalArgumentException("Not an annotation type"); @@ -110,7 +110,7 @@ public class AnnotationType { if (method.getParameterTypes().length != 0) throw new IllegalArgumentException(method + " has params"); String name = method.getName(); - Class type = method.getReturnType(); + Class type = method.getReturnType(); memberTypes.put(name, invocationHandlerReturnType(type)); members.put(name, method); @@ -140,7 +140,7 @@ public class AnnotationType { * the specified type (which is assumed to be a legal member type * for an annotation). */ - public static Class invocationHandlerReturnType(Class type) { + public static Class invocationHandlerReturnType(Class type) { // Translate primitives to wrappers if (type == byte.class) return Byte.class; @@ -167,7 +167,7 @@ public class AnnotationType { * Returns member types for this annotation type * (member name -> type mapping). */ - public Map memberTypes() { + public Map> memberTypes() { return memberTypes; } From 07871a4920f721ec17a29fb681fb6ba790666db5 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 6 Oct 2009 15:14:59 -0700 Subject: [PATCH 18/22] 6888802: sun.misc.BootClassLoaderHook.getBootstrapPaths stack overflow Fixed sun.misc.BootClassLoaderHook.getBootstrapPaths calls hook.getAdditionalBootstrapPaths Reviewed-by: alanb, tbell --- .../classes/sun/misc/BootClassLoaderHook.java | 2 +- .../misc/BootClassLoaderHook/TestHook.java | 112 ++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/misc/BootClassLoaderHook/TestHook.java diff --git a/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java index 28c187ead73..dc9ecf963d7 100644 --- a/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java +++ b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java @@ -102,7 +102,7 @@ public abstract class BootClassLoaderHook { public static File[] getBootstrapPaths() { BootClassLoaderHook hook = getHook(); if (hook != null) { - return hook.getBootstrapPaths(); + return hook.getAdditionalBootstrapPaths(); } else { return EMPTY_FILE_ARRAY; } diff --git a/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java b/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java new file mode 100644 index 00000000000..f346ffd1554 --- /dev/null +++ b/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java @@ -0,0 +1,112 @@ +/* + * Copyright 2009 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. + */ + +import java.io.File; +import java.util.TreeSet; +import java.util.Set; +import sun.misc.BootClassLoaderHook; + +/* @test + * @bug 6888802 + * @summary Sanity test of BootClassLoaderHook interface + * + * @build TestHook + * @run main TestHook + */ + +public class TestHook extends BootClassLoaderHook { + + private static final TestHook hook = new TestHook(); + private static Set names = new TreeSet(); + private static final String LOGRECORD_CLASS = + "java.util.logging.LogRecord"; + private static final String NONEXIST_RESOURCE = + "non.exist.resource"; + private static final String LIBHELLO = "hello"; + + public static void main(String[] args) throws Exception { + BootClassLoaderHook.setHook(hook); + if (BootClassLoaderHook.getHook() == null) { + throw new RuntimeException("Null boot classloader hook "); + } + + testHook(); + + if (!names.contains(LOGRECORD_CLASS)) { + throw new RuntimeException("loadBootstrapClass for " + LOGRECORD_CLASS + " not called"); + } + + if (!names.contains(NONEXIST_RESOURCE)) { + throw new RuntimeException("getBootstrapResource for " + NONEXIST_RESOURCE + " not called"); + } + if (!names.contains(LIBHELLO)) { + throw new RuntimeException("loadLibrary for " + LIBHELLO + " not called"); + } + + Set copy = new TreeSet(); + copy.addAll(names); + for (String s : copy) { + System.out.println(" Loaded " + s); + } + + if (BootClassLoaderHook.getBootstrapPaths().length > 0) { + throw new RuntimeException("Unexpected returned value from getBootstrapPaths()"); + } + } + + private static void testHook() throws Exception { + Class.forName(LOGRECORD_CLASS); + ClassLoader.getSystemResource(NONEXIST_RESOURCE); + try { + System.loadLibrary(LIBHELLO); + } catch (UnsatisfiedLinkError e) { + } + } + + public String loadBootstrapClass(String className) { + names.add(className); + return null; + } + + public String getBootstrapResource(String resourceName) { + names.add(resourceName); + return null; + } + + public boolean loadLibrary(String libname) { + names.add(libname); + return false; + } + + public File[] getAdditionalBootstrapPaths() { + return new File[0]; + } + + public boolean isCurrentThreadPrefetching() { + return false; + } + + public boolean prefetchFile(String name) { + return false; + } +} From 9c32dec0bf5f36232ef75f80059dd2545b6dab68 Mon Sep 17 00:00:00 2001 From: Keith McGuigan Date: Tue, 6 Oct 2009 22:01:18 -0400 Subject: [PATCH 19/22] 6885916: Memory leak in inferencing verifier (libverify.so) Use the memory management already present to track allocated memory Reviewed-by: coleenp, acorn --- jdk/src/share/native/common/check_code.c | 61 ++++++++++++------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/jdk/src/share/native/common/check_code.c b/jdk/src/share/native/common/check_code.c index f76c8f81735..5561a0e2483 100644 --- a/jdk/src/share/native/common/check_code.c +++ b/jdk/src/share/native/common/check_code.c @@ -338,7 +338,8 @@ static void read_all_code(context_type *context, jclass cb, int num_methods, int** code_lengths, unsigned char*** code); static void verify_method(context_type *context, jclass cb, int index, int code_length, unsigned char* code); -static void free_all_code(int num_methods, int* lengths, unsigned char** code); +static void free_all_code(context_type* context, int num_methods, + unsigned char** code); static void verify_field(context_type *context, jclass cb, int index); static void verify_opcode_operands (context_type *, unsigned int inumber, int offset); @@ -813,11 +814,11 @@ VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len, /* Look at each method */ for (i = JVM_GetClassFieldsCount(env, cb); --i >= 0;) verify_field(context, cb, i); - num_methods = JVM_GetClassMethodsCount(env, cb); - read_all_code(context, cb, num_methods, &code_lengths, &code); - for (i = num_methods - 1; i >= 0; --i) + num_methods = JVM_GetClassMethodsCount(env, cb); + read_all_code(context, cb, num_methods, &code_lengths, &code); + for (i = num_methods - 1; i >= 0; --i) verify_method(context, cb, i, code_lengths[i], code[i]); - free_all_code(num_methods, code_lengths, code); + free_all_code(context, num_methods, code); result = CC_OK; } else { result = context->err_code; @@ -836,9 +837,6 @@ VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len, if (context->exceptions) free(context->exceptions); - if (context->code) - free(context->code); - if (context->constant_types) free(context->constant_types); @@ -895,41 +893,42 @@ static void read_all_code(context_type* context, jclass cb, int num_methods, int** lengths_addr, unsigned char*** code_addr) { - int* lengths = malloc(sizeof(int) * num_methods); - unsigned char** code = malloc(sizeof(unsigned char*) * num_methods); - - *(lengths_addr) = lengths; - *(code_addr) = code; - - if (lengths == 0 || code == 0) { - CCout_of_memory(context); - } else { + int* lengths; + unsigned char** code; int i; + + lengths = malloc(sizeof(int) * num_methods); + check_and_push(context, lengths, VM_MALLOC_BLK); + + code = malloc(sizeof(unsigned char*) * num_methods); + check_and_push(context, code, VM_MALLOC_BLK); + + *(lengths_addr) = lengths; + *(code_addr) = code; + for (i = 0; i < num_methods; ++i) { - lengths[i] = JVM_GetMethodIxByteCodeLength(context->env, cb, i); - if (lengths[i] != 0) { - code[i] = malloc(sizeof(unsigned char) * (lengths[i] + 1)); - if (code[i] == NULL) { - CCout_of_memory(context); + lengths[i] = JVM_GetMethodIxByteCodeLength(context->env, cb, i); + if (lengths[i] > 0) { + code[i] = malloc(sizeof(unsigned char) * (lengths[i] + 1)); + check_and_push(context, code[i], VM_MALLOC_BLK); + JVM_GetMethodIxByteCode(context->env, cb, i, code[i]); } else { - JVM_GetMethodIxByteCode(context->env, cb, i, code[i]); + code[i] = NULL; } - } else { - code[i] = NULL; - } } - } } static void -free_all_code(int num_methods, int* lengths, unsigned char** code) +free_all_code(context_type* context, int num_methods, unsigned char** code) { int i; for (i = 0; i < num_methods; ++i) { - free(code[i]); + if (code[i] != NULL) { + pop_and_free(context); + } } - free(lengths); - free(code); + pop_and_free(context); /* code */ + pop_and_free(context); /* lengths */ } /* Verify the code of one method */ From 67bff2db55036a175c6ec72f76f1e95be1948130 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Wed, 7 Oct 2009 17:23:02 +0100 Subject: [PATCH 20/22] 6887364: SetOutgoingIf.java fails if run on multihomed machine without PIv6 on all interfaces Reviewed-by: alanb --- .../net/MulticastSocket/SetOutgoingIf.java | 212 ++++++++++++------ 1 file changed, 147 insertions(+), 65 deletions(-) diff --git a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java index d793f196215..7aa546a5cf3 100644 --- a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java +++ b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java @@ -27,7 +27,6 @@ * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code */ import java.net.*; -import java.util.concurrent.*; import java.util.*; @@ -68,38 +67,61 @@ public class SetOutgoingIf { // We need 2 or more network interfaces to run the test // - List nics = new ArrayList(); + List netIfs = new ArrayList(); + int index = 1; for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) { // we should use only network interfaces with multicast support which are in "up" state - if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp()) - nics.add(nic); + if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp()) { + NetIf netIf = NetIf.create(nic); + + // now determine what (if any) type of addresses are assigned to this interface + for (InetAddress addr : Collections.list(nic.getInetAddresses())) { + if (addr instanceof Inet4Address) { + netIf.ipv4Address(true); + } else if (addr instanceof Inet6Address) { + netIf.ipv6Address(true); + } + } + if (netIf.ipv4Address() || netIf.ipv6Address()) { + netIf.index(index++); + netIfs.add(netIf); + debug("Using: " + nic); + } + } } - if (nics.size() <= 1) { + if (netIfs.size() <= 1) { System.out.println("Need 2 or more network interfaces to run. Bye."); return; } - // We will send packets to one ipv4, one ipv4-mapped, and one ipv6 + // We will send packets to one ipv4, and one ipv6 // multicast group using each network interface :- // 224.1.1.1 --| - // ::ffff:224.1.1.2 -----> using network interface #1 - // ff02::1:1 --| + // ff02::1:1 --|--> using network interface #1 // 224.1.2.1 --| - // ::ffff:224.1.2.2 -----> using network interface #2 - // ff02::1:2 --| + // ff02::1:2 --|--> using network interface #2 // and so on. // - List groups = new ArrayList(); - for (int i = 0; i < nics.size(); i++) { - InetAddress groupv4 = InetAddress.getByName("224.1." + (i+1) + ".1"); - InetAddress groupv4mapped = InetAddress.getByName("::ffff:224.1." + (i+1) + ".2"); - InetAddress groupv6 = InetAddress.getByName("ff02::1:" + (i+1)); - groups.add(groupv4); - groups.add(groupv4mapped); - groups.add(groupv6); + for (NetIf netIf : netIfs) { + int NetIfIndex = netIf.index(); + List groups = new ArrayList(); - // use a separated thread to send to those 3 groups - Thread sender = new Thread(new Sender(nics.get(i), groupv4, groupv4mapped, groupv6, PORT)); + if (netIf.ipv4Address()) { + InetAddress groupv4 = InetAddress.getByName("224.1." + NetIfIndex + ".1"); + groups.add(groupv4); + } + if (netIf.ipv6Address()) { + InetAddress groupv6 = InetAddress.getByName("ff02::1:" + NetIfIndex); + groups.add(groupv6); + } + + debug("Adding " + groups + " groups for " + netIf.nic().getName()); + netIf.groups(groups); + + // use a separated thread to send to those 2 groups + Thread sender = new Thread(new Sender(netIf, + groups, + PORT)); sender.setDaemon(true); // we want sender to stop when main thread exits sender.start(); } @@ -108,75 +130,135 @@ public class SetOutgoingIf { // from the expected network interface // byte[] buf = new byte[1024]; - for (InetAddress group : groups) { - MulticastSocket mcastsock = new MulticastSocket(PORT); - mcastsock.setSoTimeout(5000); // 5 second - DatagramPacket packet = new DatagramPacket(buf, 0, buf.length); + for (NetIf netIf : netIfs) { + NetworkInterface nic = netIf.nic(); + for (InetAddress group : netIf.groups()) { + MulticastSocket mcastsock = new MulticastSocket(PORT); + mcastsock.setSoTimeout(5000); // 5 second + DatagramPacket packet = new DatagramPacket(buf, 0, buf.length); - mcastsock.joinGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3)); + // the interface supports the IP multicast group + debug("Joining " + group + " on " + nic.getName()); + mcastsock.joinGroup(new InetSocketAddress(group, PORT), nic); - try { - mcastsock.receive(packet); - } catch (Exception e) { - // test failed if any exception - throw new RuntimeException(e); + try { + mcastsock.receive(packet); + debug("received packet on " + packet.getAddress()); + } catch (Exception e) { + // test failed if any exception + throw new RuntimeException(e); + } + + // now check which network interface this packet comes from + NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress()); + NetworkInterface shouldbe = nic; + if (!from.equals(shouldbe)) { + System.out.println("Packets on group " + + group + " should come from " + + shouldbe.getName() + ", but came from " + + from.getName()); + //throw new RuntimeException("Test failed."); + } + + mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nic); } - - // now check which network interface this packet comes from - NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress()); - NetworkInterface shouldbe = nics.get(groups.indexOf(group) / 3); - if (!from.equals(shouldbe)) { - System.out.println("Packets on group " - + group + " should come from " - + shouldbe.getName() + ", but came from " - + from.getName()); - //throw new RuntimeException("Test failed."); - } - - mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3)); } } + + private static boolean debug = true; + + static void debug(String message) { + if (debug) + System.out.println(message); + } } class Sender implements Runnable { - private NetworkInterface nic; - private InetAddress group1; - private InetAddress group2; - private InetAddress group3; + private NetIf netIf; + private List groups; private int port; - public Sender(NetworkInterface nic, - InetAddress groupv4, InetAddress groupv4mapped, InetAddress groupv6, - int port) { - this.nic = nic; - group1 = groupv4; - group2 = groupv4mapped; - group3 = groupv6; + public Sender(NetIf netIf, + List groups, + int port) { + this.netIf = netIf; + this.groups = groups; this.port = port; } public void run() { try { MulticastSocket mcastsock = new MulticastSocket(); - mcastsock.setNetworkInterface(nic); + mcastsock.setNetworkInterface(netIf.nic()); + List packets = new LinkedList(); byte[] buf = "hello world".getBytes(); - DatagramPacket packet1 = new DatagramPacket(buf, buf.length, - new InetSocketAddress(group1, port)); - DatagramPacket packet2 = new DatagramPacket(buf, buf.length, - new InetSocketAddress(group2, port)); - DatagramPacket packet3 = new DatagramPacket(buf, buf.length, - new InetSocketAddress(group3, port)); + for (InetAddress group : groups) { + packets.add(new DatagramPacket(buf, buf.length, new InetSocketAddress(group, port))); + } for (;;) { - mcastsock.send(packet1); - mcastsock.send(packet2); - mcastsock.send(packet3); + for (DatagramPacket packet : packets) + mcastsock.send(packet); - Thread.currentThread().sleep(1000); // sleep 1 second + Thread.sleep(1000); // sleep 1 second } } catch (Exception e) { throw new RuntimeException(e); } } } + +@SuppressWarnings("unchecked") +class NetIf { + private boolean ipv4Address; //false + private boolean ipv6Address; //false + private int index; + List groups = Collections.EMPTY_LIST; + private final NetworkInterface nic; + + private NetIf(NetworkInterface nic) { + this.nic = nic; + } + + static NetIf create(NetworkInterface nic) { + return new NetIf(nic); + } + + NetworkInterface nic() { + return nic; + } + + boolean ipv4Address() { + return ipv4Address; + } + + void ipv4Address(boolean ipv4Address) { + this.ipv4Address = ipv4Address; + } + + boolean ipv6Address() { + return ipv6Address; + } + + void ipv6Address(boolean ipv6Address) { + this.ipv6Address = ipv6Address; + } + + int index() { + return index; + } + + void index(int index) { + this.index = index; + } + + List groups() { + return groups; + } + + void groups(List groups) { + this.groups = groups; + } +} + From 1c6255de3e939f1ea70ec8357286f90fdb473749 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 7 Oct 2009 13:53:11 -0700 Subject: [PATCH 21/22] 6888888: new javah throws NullPointerException when building in jdk/make/java/nio Use the bootstrap javah during the build until bug-ID 6889255 is fixed Reviewed-by: jjg --- jdk/make/common/shared/Defs-java.gmk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jdk/make/common/shared/Defs-java.gmk b/jdk/make/common/shared/Defs-java.gmk index f9ed6353131..eb63179f6d3 100644 --- a/jdk/make/common/shared/Defs-java.gmk +++ b/jdk/make/common/shared/Defs-java.gmk @@ -165,6 +165,11 @@ else JAVADOC_CMD = $(JAVA_TOOLS_DIR)/javadoc $(JAVA_TOOLS_FLAGS:%=-J%) endif +#always use the bootstrap javah until bug-ID 6889255 is fixed. These +#five lines should be removed as part of that fix: +JAVAH_CMD = $(JAVA_TOOLS_DIR)/javah \ + $(JAVAHFLAGS) + # Override of what javac to use (see deploy workspace) ifdef JAVAC JAVAC_CMD = $(JAVAC) From debdf79d18c773fc2df717ec80364d4e4557e87b Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 7 Oct 2009 14:04:20 -0700 Subject: [PATCH 22/22] 6480728: Byte.valueOf(byte) returns a cached value but Byte.valueOf(String) 6655735: Integer.toString() and String.valueOf(int) contain slow delegations Reviewed-by: lancea --- jdk/src/share/classes/java/lang/Byte.java | 6 +++--- jdk/src/share/classes/java/lang/Double.java | 2 +- jdk/src/share/classes/java/lang/Float.java | 2 +- jdk/src/share/classes/java/lang/Integer.java | 2 +- jdk/src/share/classes/java/lang/Long.java | 2 +- jdk/src/share/classes/java/lang/Short.java | 6 +++--- jdk/src/share/classes/java/lang/String.java | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Byte.java b/jdk/src/share/classes/java/lang/Byte.java index 4725f3278b7..ce5adee7f53 100644 --- a/jdk/src/share/classes/java/lang/Byte.java +++ b/jdk/src/share/classes/java/lang/Byte.java @@ -201,7 +201,7 @@ public final class Byte extends Number implements Comparable { */ public static Byte valueOf(String s, int radix) throws NumberFormatException { - return new Byte(parseByte(s, radix)); + return valueOf(parseByte(s, radix)); } /** @@ -277,7 +277,7 @@ public final class Byte extends Number implements Comparable { if (i < MIN_VALUE || i > MAX_VALUE) throw new NumberFormatException( "Value " + i + " out of range from input " + nm); - return (byte)i; + return valueOf((byte)i); } /** @@ -374,7 +374,7 @@ public final class Byte extends Number implements Comparable { * base 10. */ public String toString() { - return String.valueOf((int)value); + return Integer.toString((int)value); } /** diff --git a/jdk/src/share/classes/java/lang/Double.java b/jdk/src/share/classes/java/lang/Double.java index 8efb241b808..ebc6fd3cada 100644 --- a/jdk/src/share/classes/java/lang/Double.java +++ b/jdk/src/share/classes/java/lang/Double.java @@ -629,7 +629,7 @@ public final class Double extends Number implements Comparable { * @see java.lang.Double#toString(double) */ public String toString() { - return String.valueOf(value); + return toString(value); } /** diff --git a/jdk/src/share/classes/java/lang/Float.java b/jdk/src/share/classes/java/lang/Float.java index eb133016f6b..c86b7bb1f9c 100644 --- a/jdk/src/share/classes/java/lang/Float.java +++ b/jdk/src/share/classes/java/lang/Float.java @@ -551,7 +551,7 @@ public final class Float extends Number implements Comparable { * @see java.lang.Float#toString(float) */ public String toString() { - return String.valueOf(value); + return Float.toString(value); } /** diff --git a/jdk/src/share/classes/java/lang/Integer.java b/jdk/src/share/classes/java/lang/Integer.java index 1c457c548e7..7aa03c07b5b 100644 --- a/jdk/src/share/classes/java/lang/Integer.java +++ b/jdk/src/share/classes/java/lang/Integer.java @@ -746,7 +746,7 @@ public final class Integer extends Number implements Comparable { * base 10. */ public String toString() { - return String.valueOf(value); + return toString(value); } /** diff --git a/jdk/src/share/classes/java/lang/Long.java b/jdk/src/share/classes/java/lang/Long.java index c5fd7ee5e29..2bb6da15923 100644 --- a/jdk/src/share/classes/java/lang/Long.java +++ b/jdk/src/share/classes/java/lang/Long.java @@ -761,7 +761,7 @@ public final class Long extends Number implements Comparable { * base 10. */ public String toString() { - return String.valueOf(value); + return toString(value); } /** diff --git a/jdk/src/share/classes/java/lang/Short.java b/jdk/src/share/classes/java/lang/Short.java index cf1551da8e5..b00e8b25cec 100644 --- a/jdk/src/share/classes/java/lang/Short.java +++ b/jdk/src/share/classes/java/lang/Short.java @@ -170,7 +170,7 @@ public final class Short extends Number implements Comparable { */ public static Short valueOf(String s, int radix) throws NumberFormatException { - return new Short(parseShort(s, radix)); + return valueOf(parseShort(s, radix)); } /** @@ -282,7 +282,7 @@ public final class Short extends Number implements Comparable { if (i < MIN_VALUE || i > MAX_VALUE) throw new NumberFormatException( "Value " + i + " out of range from input " + nm); - return (short)i; + return valueOf((short)i); } /** @@ -379,7 +379,7 @@ public final class Short extends Number implements Comparable { * base 10. */ public String toString() { - return String.valueOf((int)value); + return Integer.toString((int)value); } /** diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index e4327434c38..6aaf7684bf3 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2995,7 +2995,7 @@ public final class String * @see java.lang.Integer#toString(int, int) */ public static String valueOf(int i) { - return Integer.toString(i, 10); + return Integer.toString(i); } /** @@ -3009,7 +3009,7 @@ public final class String * @see java.lang.Long#toString(long) */ public static String valueOf(long l) { - return Long.toString(l, 10); + return Long.toString(l); } /**