--- a/jdk/make/com/sun/tools/attach/Makefile Thu May 05 14:02:17 2011 -0700
+++ b/jdk/make/com/sun/tools/attach/Makefile Thu May 05 22:29:05 2011 -0700
@@ -48,6 +48,9 @@
ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS += -ldoor
endif
+ifeq ($(PLATFORM), windows)
+EXTRA_LIBS += psapi.lib
+endif
vpath %.c $(PLATFORM_SRC)/native/sun/tools/attach
--- a/jdk/make/sun/security/pkcs11/Makefile Thu May 05 14:02:17 2011 -0700
+++ b/jdk/make/sun/security/pkcs11/Makefile Thu May 05 22:29:05 2011 -0700
@@ -147,7 +147,7 @@
# Rules
#
CLASSDESTDIR = $(TEMPDIR)/classes
-JAVAHFLAGS += -classpath $(CLASSDESTDIR)
+JAVAHFLAGS += -Xbootclasspath/p:$(CLASSDESTDIR)
include $(BUILDDIR)/common/Mapfile-vers.gmk
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -395,7 +395,13 @@
private boolean succeeded = false;
private boolean commitSucceeded = false;
private String username;
+
+ // Encryption keys calculated from password. Assigned when storekey == true
+ // and useKeyTab == false (or true but not found)
private EncryptionKey[] encKeys = null;
+
+ KeyTab ktab = null;
+
private Credentials cred = null;
private PrincipalName principal = null;
@@ -663,28 +669,49 @@
(krb5PrincName.toString(),
PrincipalName.KRB_NT_PRINCIPAL);
}
+
+ /*
+ * Before dynamic KeyTab support (6894072), here we check if
+ * the keytab contains keys for the principal. If no, keytab
+ * will not be used and password is prompted for.
+ *
+ * After 6894072, we normally don't check it, and expect the
+ * keys can be populated until a real connection is made. The
+ * check is still done when isInitiator == true, where the keys
+ * will be used right now.
+ *
+ * Probably tricky relations:
+ *
+ * useKeyTab is config flag, but when it's true but the ktab
+ * does not contains keys for principal, we would use password
+ * and keep the flag unchanged (for reuse?). In this method,
+ * we use (ktab != null) to check whether keytab is used.
+ * After this method (and when storeKey == true), we use
+ * (encKeys == null) to check.
+ */
if (useKeyTab) {
- encKeys =
- EncryptionKey.acquireSecretKeys(principal, keyTabName);
-
- if (debug) {
- if (encKeys != null)
- System.out.println
- ("principal's key obtained from the keytab");
- else
- System.out.println
- ("Key for the principal " +
- principal +
- " not available in " +
- ((keyTabName == null) ?
- "default key tab" : keyTabName));
+ ktab = (keyTabName == null)
+ ? KeyTab.getInstance()
+ : KeyTab.getInstance(new File(keyTabName));
+ if (isInitiator) {
+ if (Krb5Util.keysFromJavaxKeyTab(ktab, principal).length
+ == 0) {
+ ktab = null;
+ if (debug) {
+ System.out.println
+ ("Key for the principal " +
+ principal +
+ " not available in " +
+ ((keyTabName == null) ?
+ "default key tab" : keyTabName));
+ }
+ }
}
-
}
KrbAsReqBuilder builder;
- // We can't get the key from the keytab so prompt
- if (encKeys == null) {
+
+ if (ktab == null) {
promptForPass(getPasswdFromSharedState);
builder = new KrbAsReqBuilder(principal, password);
if (isInitiator) {
@@ -693,9 +720,13 @@
// updated with PA info
cred = builder.action().getCreds();
}
- encKeys = builder.getKeys();
+ if (storeKey) {
+ encKeys = builder.getKeys();
+ // When encKeys is empty, the login actually fails.
+ // For compatibility, exception is thrown in commit().
+ }
} else {
- builder = new KrbAsReqBuilder(principal, encKeys);
+ builder = new KrbAsReqBuilder(principal, ktab);
if (isInitiator) {
cred = builder.action().getCreds();
}
@@ -705,10 +736,15 @@
if (debug) {
System.out.println("principal is " + principal);
HexDumpEncoder hd = new HexDumpEncoder();
- for (int i = 0; i < encKeys.length; i++) {
- System.out.println("EncryptionKey: keyType=" +
- encKeys[i].getEType() + " keyBytes (hex dump)=" +
- hd.encodeBuffer(encKeys[i].getBytes()));
+ if (ktab != null) {
+ System.out.println("Will use keytab");
+ } else if (storeKey) {
+ for (int i = 0; i < encKeys.length; i++) {
+ System.out.println("EncryptionKey: keyType=" +
+ encKeys[i].getEType() +
+ " keyBytes (hex dump)=" +
+ hd.encodeBuffer(encKeys[i].getBytes()));
+ }
}
}
@@ -989,8 +1025,8 @@
kerbTicket = Krb5Util.credsToTicket(cred);
}
- if (storeKey) {
- if (encKeys == null || encKeys.length <= 0) {
+ if (storeKey && encKeys != null) {
+ if (encKeys.length == 0) {
succeeded = false;
throw new LoginException("Null Server Key ");
}
@@ -1006,10 +1042,11 @@
}
}
- // Let us add the kerbClientPrinc,kerbTicket and kerbKey (if
+ // Let us add the kerbClientPrinc,kerbTicket and KeyTab/KerbKey (if
// storeKey is true)
- if (!princSet.contains(kerbClientPrinc))
+ if (!princSet.contains(kerbClientPrinc)) {
princSet.add(kerbClientPrinc);
+ }
// add the TGT
if (kerbTicket != null) {
@@ -1018,19 +1055,29 @@
}
if (storeKey) {
- for (int i = 0; i < kerbKeys.length; i++) {
- if (!privCredSet.contains(kerbKeys[i])) {
- privCredSet.add(kerbKeys[i]);
+ if (encKeys == null) {
+ if (!privCredSet.contains(ktab)) {
+ privCredSet.add(ktab);
+ // Compatibility; also add keys to privCredSet
+ for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) {
+ privCredSet.add(new Krb5Util.KeysFromKeyTab(key));
+ }
}
- encKeys[i].destroy();
- encKeys[i] = null;
- if (debug) {
- System.out.println("Added server's key"
- + kerbKeys[i]);
- System.out.println("\t\t[Krb5LoginModule] " +
- "added Krb5Principal " +
- kerbClientPrinc.toString()
- + " to Subject");
+ } else {
+ for (int i = 0; i < kerbKeys.length; i ++) {
+ if (!privCredSet.contains(kerbKeys[i])) {
+ privCredSet.add(kerbKeys[i]);
+ }
+ encKeys[i].destroy();
+ encKeys[i] = null;
+ if (debug) {
+ System.out.println("Added server's key"
+ + kerbKeys[i]);
+ System.out.println("\t\t[Krb5LoginModule] " +
+ "added Krb5Principal " +
+ kerbClientPrinc.toString()
+ + " to Subject");
+ }
}
}
}
@@ -1106,7 +1153,8 @@
while (it.hasNext()) {
Object o = it.next();
if (o instanceof KerberosTicket ||
- o instanceof KerberosKey) {
+ o instanceof KerberosKey ||
+ o instanceof KeyTab) {
it.remove();
}
}
@@ -1161,6 +1209,7 @@
} else {
// remove temp results for the next try
encKeys = null;
+ ktab = null;
principal = null;
}
username = null;
--- a/jdk/src/share/classes/java/lang/ProcessBuilder.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java Thu May 05 22:29:05 2011 -0700
@@ -938,6 +938,11 @@
* but at the very least the command must be a non-empty list of
* non-null strings.
*
+ * <p>A minimal set of system dependent environment variables may
+ * be required to start a process on some operating systems.
+ * As a result, the subprocess may inherit additional environment variable
+ * settings beyond those in the process builder's {@link #environment()}.
+ *
* <p>If there is a security manager, its
* {@link SecurityManager#checkExec checkExec}
* method is called with the first component of this object's
--- a/jdk/src/share/classes/java/lang/Runtime.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/lang/Runtime.java Thu May 05 22:29:05 2011 -0700
@@ -544,6 +544,11 @@
* <p>If <tt>envp</tt> is <tt>null</tt>, the subprocess inherits the
* environment settings of the current process.
*
+ * <p>A minimal set of system dependent environment variables may
+ * be required to start a process on some operating systems.
+ * As a result, the subprocess may inherit additional environment variable
+ * settings beyond those in the specified environment.
+ *
* <p>{@link ProcessBuilder#start()} is now the preferred way to
* start a process with a modified environment.
*
--- a/jdk/src/share/classes/java/net/NetworkInterface.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/net/NetworkInterface.java Thu May 05 22:29:05 2011 -0700
@@ -547,13 +547,8 @@
if (displayName != null) {
result += " (" + displayName + ")";
}
- result += " index: "+index+" addresses:\n";
- for (Enumeration e = getInetAddresses(); e.hasMoreElements(); ) {
- InetAddress addr = (InetAddress)e.nextElement();
- result += addr+";\n";
- }
return result;
}
+
private static native void init();
-
}
--- a/jdk/src/share/classes/java/nio/file/FileSystem.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/FileSystem.java Thu May 05 22:29:05 2011 -0700
@@ -391,6 +391,13 @@
* character is used to separate the subpatterns. Groups cannot be nested.
* </p></li>
*
+ * <li><p> Leading period<tt>/</tt>dot characters in file name are
+ * treated as regular characters in match operations. For example,
+ * the {@code "*"} glob pattern matches file name {@code ".login"}.
+ * The {@link Files#isHidden} method may be used to test whether a file
+ * is considered hidden.
+ * </p></li>
+ *
* <li><p> All other characters match themselves in an implementation
* dependent manner. This includes characters representing any {@link
* FileSystem#getSeparator name-separators}. </p></li>
--- a/jdk/src/share/classes/java/security/SignedObject.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/security/SignedObject.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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
@@ -249,10 +249,10 @@
* a stream.
*/
private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException
- {
- s.defaultReadObject();
- content = content.clone();
- signature = signature.clone();
+ throws java.io.IOException, ClassNotFoundException {
+ java.io.ObjectInputStream.GetField fields = s.readFields();
+ content = ((byte[])fields.get("content", null)).clone();
+ signature = ((byte[])fields.get("signature", null)).clone();
+ thealgorithm = (String)fields.get("thealgorithm", null);
}
}
--- a/jdk/src/share/classes/java/util/AbstractSet.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/AbstractSet.java Thu May 05 22:29:05 2011 -0700
@@ -156,9 +156,11 @@
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
* is not supported by this set
* @throws ClassCastException if the class of an element of this set
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this set contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
--- a/jdk/src/share/classes/java/util/ArrayList.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Thu May 05 22:29:05 2011 -0700
@@ -628,9 +628,11 @@
* @param c collection containing elements to be removed from this list
* @return {@code true} if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see Collection#contains(Object)
*/
@@ -646,9 +648,11 @@
* @param c collection containing elements to be retained in this list
* @return {@code true} if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see Collection#contains(Object)
*/
--- a/jdk/src/share/classes/java/util/Collection.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Collection.java Thu May 05 22:29:05 2011 -0700
@@ -60,7 +60,8 @@
* but is not required to, throw the exception if the collection to be added
* is empty.
*
- * <p>Some collection implementations have restrictions on the elements that
+ * <p><a name="optional-restrictions"/>
+ * Some collection implementations have restrictions on the elements that
* they may contain. For example, some implementations prohibit null elements,
* and some have restrictions on the types of their elements. Attempting to
* add an ineligible element throws an unchecked exception, typically
@@ -152,9 +153,11 @@
* @return <tt>true</tt> if this collection contains the specified
* element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this collection (optional)
+ * is incompatible with this collection
+ * (<a href="#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * collection does not permit null elements (optional)
+ * collection does not permit null elements
+ * (<a href="#optional-restrictions">optional</a>)
*/
boolean contains(Object o);
@@ -279,9 +282,11 @@
* @param o element to be removed from this collection, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the type of the specified element
- * is incompatible with this collection (optional)
+ * is incompatible with this collection
+ * (<a href="#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * collection does not permit null elements (optional)
+ * collection does not permit null elements
+ * (<a href="#optional-restrictions">optional</a>)
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this collection
*/
@@ -299,10 +304,13 @@
* in the specified collection
* @throws ClassCastException if the types of one or more elements
* in the specified collection are incompatible with this
- * collection (optional)
+ * collection
+ * (<a href="#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified collection contains one
* or more null elements and this collection does not permit null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="#optional-restrictions">optional</a>),
+ * or if the specified collection is null.
* @see #contains(Object)
*/
boolean containsAll(Collection<?> c);
@@ -346,10 +354,13 @@
* is not supported by this collection
* @throws ClassCastException if the types of one or more elements
* in this collection are incompatible with the specified
- * collection (optional)
+ * collection
+ * (<a href="#optional-restrictions">optional</a>)
* @throws NullPointerException if this collection contains one or more
* null elements and the specified collection does not support
- * null elements (optional), or if the specified collection is null
+ * null elements
+ * (<a href="#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
*/
@@ -367,10 +378,13 @@
* is not supported by this collection
* @throws ClassCastException if the types of one or more elements
* in this collection are incompatible with the specified
- * collection (optional)
+ * collection
+ * (<a href="#optional-restrictions">optional</a>)
* @throws NullPointerException if this collection contains one or more
* null elements and the specified collection does not permit null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
*/
--- a/jdk/src/share/classes/java/util/Collections.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Collections.java Thu May 05 22:29:05 2011 -0700
@@ -3746,9 +3746,10 @@
* @throws NullPointerException if either collection is {@code null}.
* @throws NullPointerException if one collection contains a {@code null}
* element and {@code null} is not an eligible element for the other collection.
- * (optional)
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if one collection contains an element that is
- * of a type which is ineligible for the other collection. (optional)
+ * of a type which is ineligible for the other collection.
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.5
*/
public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
--- a/jdk/src/share/classes/java/util/Deque.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Deque.java Thu May 05 22:29:05 2011 -0700
@@ -351,9 +351,11 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
+ * is incompatible with this deque
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
+ * deque does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean removeFirstOccurrence(Object o);
@@ -369,9 +371,11 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
+ * is incompatible with this deque
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
+ * deque does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean removeLastOccurrence(Object o);
@@ -527,9 +531,11 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
+ * is incompatible with this deque
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
+ * deque does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean remove(Object o);
@@ -542,9 +548,11 @@
* @param o element whose presence in this deque is to be tested
* @return <tt>true</tt> if this deque contains the specified element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this deque (optional)
+ * is incompatible with this deque
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
+ * deque does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean contains(Object o);
--- a/jdk/src/share/classes/java/util/List.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/List.java Thu May 05 22:29:05 2011 -0700
@@ -134,9 +134,11 @@
* @param o element whose presence in this list is to be tested
* @return <tt>true</tt> if this list contains the specified element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this list (optional)
+ * is incompatible with this list
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * list does not permit null elements (optional)
+ * list does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean contains(Object o);
@@ -245,9 +247,11 @@
* @param o element to be removed from this list, if present
* @return <tt>true</tt> if this list contained the specified element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this list (optional)
+ * is incompatible with this list
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * list does not permit null elements (optional)
+ * list does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this list
*/
@@ -265,10 +269,13 @@
* specified collection
* @throws ClassCastException if the types of one or more elements
* in the specified collection are incompatible with this
- * list (optional)
+ * list
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified collection contains one
* or more null elements and this list does not permit null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @see #contains(Object)
*/
boolean containsAll(Collection<?> c);
@@ -334,9 +341,11 @@
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
* is not supported by this list
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
@@ -354,9 +363,11 @@
* @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
* is not supported by this list
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
@@ -493,9 +504,11 @@
* @return the index of the first occurrence of the specified element in
* this list, or -1 if this list does not contain the element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this list (optional)
+ * is incompatible with this list
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * list does not permit null elements (optional)
+ * list does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
int indexOf(Object o);
@@ -510,9 +523,11 @@
* @return the index of the last occurrence of the specified element in
* this list, or -1 if this list does not contain the element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this list (optional)
+ * is incompatible with this list
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * list does not permit null elements (optional)
+ * list does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
int lastIndexOf(Object o);
--- a/jdk/src/share/classes/java/util/ListIterator.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/ListIterator.java Thu May 05 22:29:05 2011 -0700
@@ -173,9 +173,9 @@
/**
* Inserts the specified element into the list (optional operation).
- * The element is inserted immediately before the next element that
- * would be returned by {@link #next}, if any, and after the next
- * element that would be returned by {@link #previous}, if any. (If the
+ * The element is inserted immediately before the element that
+ * would be returned by {@link #next}, if any, and after the element
+ * that would be returned by {@link #previous}, if any. (If the
* list contains no elements, the new element becomes the sole element
* on the list.) The new element is inserted before the implicit
* cursor: a subsequent call to {@code next} would be unaffected, and a
--- a/jdk/src/share/classes/java/util/Map.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Map.java Thu May 05 22:29:05 2011 -0700
@@ -144,9 +144,11 @@
* @return <tt>true</tt> if this map contains a mapping for the specified
* key
* @throws ClassCastException if the key is of an inappropriate type for
- * this map (optional)
+ * this map
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key is null and this map
- * does not permit null keys (optional)
+ * does not permit null keys
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean containsKey(Object key);
@@ -162,9 +164,11 @@
* @return <tt>true</tt> if this map maps one or more keys to the
* specified value
* @throws ClassCastException if the value is of an inappropriate type for
- * this map (optional)
+ * this map
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified value is null and this
- * map does not permit null values (optional)
+ * map does not permit null values
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean containsValue(Object value);
@@ -187,9 +191,11 @@
* @return the value to which the specified key is mapped, or
* {@code null} if this map contains no mapping for the key
* @throws ClassCastException if the key is of an inappropriate type for
- * this map (optional)
+ * this map
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key is null and this map
- * does not permit null keys (optional)
+ * does not permit null keys
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
V get(Object key);
@@ -245,9 +251,11 @@
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this map
* @throws ClassCastException if the key is of an inappropriate type for
- * this map (optional)
+ * this map
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key is null and this
- * map does not permit null keys (optional)
+ * map does not permit null keys
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
V remove(Object key);
@@ -466,4 +474,5 @@
* @see #equals(Object)
*/
int hashCode();
+
}
--- a/jdk/src/share/classes/java/util/Set.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Set.java Thu May 05 22:29:05 2011 -0700
@@ -110,9 +110,11 @@
* @param o element whose presence in this set is to be tested
* @return <tt>true</tt> if this set contains the specified element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this set (optional)
+ * is incompatible with this set
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * set does not permit null elements (optional)
+ * set does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
*/
boolean contains(Object o);
@@ -236,9 +238,11 @@
* @param o object to be removed from this set, if present
* @return <tt>true</tt> if this set contained the specified element
* @throws ClassCastException if the type of the specified element
- * is incompatible with this set (optional)
+ * is incompatible with this set
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
- * set does not permit null elements (optional)
+ * set does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this set
*/
@@ -257,10 +261,13 @@
* specified collection
* @throws ClassCastException if the types of one or more elements
* in the specified collection are incompatible with this
- * set (optional)
+ * set
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified collection contains one
* or more null elements and this set does not permit null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @see #contains(Object)
*/
boolean containsAll(Collection<?> c);
@@ -302,9 +309,11 @@
* @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
* is not supported by this set
* @throws ClassCastException if the class of an element of this set
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this set contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
*/
@@ -322,9 +331,11 @@
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
* is not supported by this set
* @throws ClassCastException if the class of an element of this set
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this set contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
* @see #contains(Object)
--- a/jdk/src/share/classes/java/util/Vector.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java Thu May 05 22:29:05 2011 -0700
@@ -893,10 +893,13 @@
* @return true if this Vector changed as a result of the call
* @throws ClassCastException if the types of one or more elements
* in this vector are incompatible with the specified
- * collection (optional)
+ * collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this vector contains one or more null
* elements and the specified collection does not support null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @since 1.2
*/
public synchronized boolean removeAll(Collection<?> c) {
@@ -913,10 +916,13 @@
* @return true if this Vector changed as a result of the call
* @throws ClassCastException if the types of one or more elements
* in this vector are incompatible with the specified
- * collection (optional)
+ * collection
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this vector contains one or more null
* elements and the specified collection does not support null
- * elements (optional), or if the specified collection is null
+ * elements
+ * (<a href="Collection.html#optional-restrictions">optional</a>),
+ * or if the specified collection is null
* @since 1.2
*/
public synchronized boolean retainAll(Collection<?> c) {
--- a/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java Thu May 05 22:29:05 2011 -0700
@@ -400,8 +400,10 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this deque
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
boolean removeFirstOccurrence(Object o);
@@ -416,8 +418,10 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this deque
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
boolean removeLastOccurrence(Object o);
@@ -591,8 +595,10 @@
* @param o element to be removed from this deque, if present
* @return <tt>true</tt> if this deque changed as a result of the call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this deque
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
boolean remove(Object o);
@@ -604,8 +610,10 @@
* @param o object to be checked for containment in this deque
* @return <tt>true</tt> if this deque contains the specified element
* @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this deque
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
public boolean contains(Object o);
--- a/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java Thu May 05 22:29:05 2011 -0700
@@ -303,8 +303,10 @@
* @param o element to be removed from this queue, if present
* @return <tt>true</tt> if this queue changed as a result of the call
* @throws ClassCastException if the class of the specified element
- * is incompatible with this queue (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this queue
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
boolean remove(Object o);
@@ -316,8 +318,10 @@
* @param o object to be checked for containment in this queue
* @return <tt>true</tt> if this queue contains the specified element
* @throws ClassCastException if the class of the specified element
- * is incompatible with this queue (optional)
- * @throws NullPointerException if the specified element is null (optional)
+ * is incompatible with this queue
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
+ * @throws NullPointerException if the specified element is null
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
public boolean contains(Object o);
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java Thu May 05 22:29:05 2011 -0700
@@ -103,9 +103,11 @@
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this map
* @throws ClassCastException if the key or value is of an inappropriate
- * type for this map (optional)
+ * type for this map
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key or value is null,
- * and this map does not permit null keys or values (optional)
+ * and this map does not permit null keys or values
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
*/
boolean remove(Object key, Object value);
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Thu May 05 22:29:05 2011 -0700
@@ -631,9 +631,11 @@
* @param c collection containing elements to be removed from this list
* @return <tt>true</tt> if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="../Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
*/
@@ -671,9 +673,11 @@
* @param c collection containing elements to be retained in this list
* @return <tt>true</tt> if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list
- * is incompatible with the specified collection (optional)
+ * is incompatible with the specified collection
+ * (<a href="../Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
- * specified collection does not permit null elements (optional),
+ * specified collection does not permit null elements
+ * (<a href="../Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see #remove(Object)
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.security.auth.kerberos;
+
+import sun.misc.JavaxSecurityAuthKerberosAccess;
+import sun.security.krb5.EncryptionKey;
+import sun.security.krb5.PrincipalName;
+
+class JavaxSecurityAuthKerberosAccessImpl
+ implements JavaxSecurityAuthKerberosAccess {
+ public EncryptionKey[] keyTabGetEncryptionKeys(
+ KeyTab ktab, PrincipalName principal) {
+ return ktab.getEncryptionKeys(principal);
+ }
+}
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -35,14 +35,16 @@
* principal.<p>
*
* All Kerberos JAAS login modules that obtain a principal's password and
- * generate the secret key from it should use this class. Where available,
- * the login module might even read this secret key directly from a
- * Kerberos "keytab". Sometimes, such as when authenticating a server in
+ * generate the secret key from it should use this class.
+ * Sometimes, such as when authenticating a server in
* the absence of user-to-user authentication, the login module will store
* an instance of this class in the private credential set of a
* {@link javax.security.auth.Subject Subject} during the commit phase of the
* authentication process.<p>
*
+ * A Kerberos service using a keytab to read secret keys should use
+ * the {@link KeyTab} class, where latest keys can be read when needed.<p>
+ *
* It might be necessary for the application to be granted a
* {@link javax.security.auth.PrivateCredentialPermission
* PrivateCredentialPermission} if it needs to access the KerberosKey
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.security.auth.kerberos;
+
+import java.io.File;
+import java.util.Objects;
+import sun.misc.SharedSecrets;
+import sun.security.krb5.EncryptionKey;
+import sun.security.krb5.PrincipalName;
+import sun.security.krb5.RealmException;
+
+/**
+ * This class encapsulates a keytab file.
+ * <p>
+ * A Kerberos JAAS login module that obtains long term secret keys from a
+ * keytab file should use this class. The login module will store
+ * an instance of this class in the private credential set of a
+ * {@link javax.security.auth.Subject Subject} during the commit phase of the
+ * authentication process.
+ * <p>
+ * It might be necessary for the application to be granted a
+ * {@link javax.security.auth.PrivateCredentialPermission
+ * PrivateCredentialPermission} if it needs to access the KeyTab
+ * instance from a Subject. This permission is not needed when the
+ * application depends on the default JGSS Kerberos mechanism to access the
+ * KeyTab. In that case, however, the application will need an appropriate
+ * {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
+ * <p>
+ * The keytab file format is described at
+ * <a href="http://www.ioplex.com/utilities/keytab.txt">
+ * http://www.ioplex.com/utilities/keytab.txt</a>.
+ *
+ * @since 1.7
+ */
+public final class KeyTab {
+
+ /*
+ * Impl notes:
+ *
+ * This class is only a name, a permanent link to the keytab source
+ * (can be missing). Itself has no content. In order to read content,
+ * take a snapshot and read from it.
+ *
+ * The snapshot is of type sun.security.krb5.internal.ktab.KeyTab, which
+ * contains the content of the keytab file when the snapshot is taken.
+ * Itself has no refresh function and mostly an immutable class (except
+ * for the create/add/save methods only used by the ktab command).
+ */
+
+ // Source, null if using the default one. Note that the default name
+ // is maintained in snapshot, this field is never "resolved".
+ private final File file;
+
+ // Set up JavaxSecurityAuthKerberosAccess in SharedSecrets
+ static {
+ SharedSecrets.setJavaxSecurityAuthKerberosAccess(
+ new JavaxSecurityAuthKerberosAccessImpl());
+ }
+
+ private KeyTab(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Returns a {@code KeyTab} instance from a {@code File} object.
+ * <p>
+ * The result of this method is never null. This method only associates
+ * the returned {@code KeyTab} object with the file and does not read it.
+ * @param file the keytab {@code File} object, must not be null
+ * @return the keytab instance
+ * @throws NullPointerException if the {@code file} argument is null
+ */
+ public static KeyTab getInstance(File file) {
+ if (file == null) {
+ throw new NullPointerException("file must be non null");
+ }
+ return new KeyTab(file);
+ }
+
+ /**
+ * Returns the default {@code KeyTab} instance.
+ * <p>
+ * The result of this method is never null. This method only associates
+ * the returned {@code KeyTab} object with the default keytab file and
+ * does not read it.
+ * @return the default keytab instance.
+ */
+ public static KeyTab getInstance() {
+ return new KeyTab(null);
+ }
+
+ //Takes a snapshot of the keytab content
+ private sun.security.krb5.internal.ktab.KeyTab takeSnapshot() {
+ return sun.security.krb5.internal.ktab.KeyTab.getInstance(file);
+ }
+
+ /**
+ * Returns fresh keys for the given Kerberos principal.
+ * <p>
+ * Implementation of this method should make sure the returned keys match
+ * the latest content of the keytab file. The result is a newly created
+ * copy that can be modified by the caller without modifying the keytab
+ * object. The caller should {@link KerberosKey#destroy() destroy} the
+ * result keys after they are used.
+ * <p>
+ * Please note that the keytab file can be created after the
+ * {@code KeyTab} object is instantiated and its content may change over
+ * time. Therefore, an application should call this method only when it
+ * needs to use the keys. Any previous result from an earlier invocation
+ * could potentially be expired.
+ * <p>
+ * If there is any error (say, I/O error or format error)
+ * during the reading process of the KeyTab file, a saved result should be
+ * returned. If there is no saved result (say, this is the first time this
+ * method is called, or, all previous read attempts failed), an empty array
+ * should be returned. This can make sure the result is not drastically
+ * changed during the (probably slow) update of the keytab file.
+ * <p>
+ * Each time this method is called and the reading of the file succeeds
+ * with no exception (say, I/O error or file format error),
+ * the result should be saved for {@code principal}. The implementation can
+ * also save keys for other principals having keys in the same keytab object
+ * if convenient.
+ * <p>
+ * Any unsupported key read from the keytab is ignored and not included
+ * in the result.
+ *
+ * @param principal the Kerberos principal, must not be null.
+ * @return the keys (never null, may be empty)
+ * @throws NullPointerException if the {@code principal}
+ * argument is null
+ * @throws SecurityException if a security manager exists and the read
+ * access to the keytab file is not permitted
+ */
+ public KerberosKey[] getKeys(KerberosPrincipal principal) {
+ try {
+ EncryptionKey[] keys = takeSnapshot().readServiceKeys(
+ new PrincipalName(principal.getName()));
+ KerberosKey[] kks = new KerberosKey[keys.length];
+ for (int i=0; i<kks.length; i++) {
+ Integer tmp = keys[i].getKeyVersionNumber();
+ kks[i] = new KerberosKey(
+ principal,
+ keys[i].getBytes(),
+ keys[i].getEType(),
+ tmp == null ? 0 : tmp.intValue());
+ keys[i].destroy();
+ }
+ return kks;
+ } catch (RealmException re) {
+ return new KerberosKey[0];
+ }
+ }
+
+ EncryptionKey[] getEncryptionKeys(PrincipalName principal) {
+ return takeSnapshot().readServiceKeys(principal);
+ }
+
+ /**
+ * Checks if the keytab file exists. Implementation of this method
+ * should make sure that the result matches the latest status of the
+ * keytab file.
+ * <p>
+ * The caller can use the result to determine if it should fallback to
+ * another mechanism to read the keys.
+ * @return true if the keytab file exists; false otherwise.
+ * @throws SecurityException if a security manager exists and the read
+ * access to the keytab file is not permitted
+ */
+ public boolean exists() {
+ return !takeSnapshot().isMissing();
+ }
+
+ public String toString() {
+ return file == null ? "Default keytab" : file.toString();
+ }
+
+ /**
+ * Returns a hashcode for this KeyTab.
+ *
+ * @return a hashCode() for the <code>KeyTab</code>
+ */
+ public int hashCode() {
+ return Objects.hash(file);
+ }
+
+ /**
+ * Compares the specified Object with this KeyTab for equality.
+ * Returns true if the given object is also a
+ * <code>KeyTab</code> and the two
+ * <code>KeyTab</code> instances are equivalent.
+ *
+ * @param other the Object to compare to
+ * @return true if the specified object is equal to this KeyTab
+ */
+ public boolean equals(Object other) {
+ if (other == this)
+ return true;
+
+ if (! (other instanceof KeyTab)) {
+ return false;
+ }
+
+ KeyTab otherKtab = (KeyTab) other;
+ return Objects.equals(otherKtab.file, file);
+ }
+}
--- a/jdk/src/share/classes/javax/swing/ImageIcon.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/ImageIcon.java Thu May 05 22:29:05 2011 -0700
@@ -40,8 +40,7 @@
import sun.awt.AppContext;
import java.lang.reflect.Field;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
+import java.security.*;
/**
* An implementation of the Icon interface that paints Icons
@@ -81,32 +80,51 @@
ImageObserver imageObserver;
String description = null;
+ // Fields for twisted backward compatibility only. DO NOT USE.
protected final static Component component;
protected final static MediaTracker tracker;
static {
- component = new Component() {};
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
+ component = AccessController.doPrivileged(new PrivilegedAction<Component>() {
+ public Component run() {
try {
+ final Component component = createNoPermsComponent();
+
// 6482575 - clear the appContext field so as not to leak it
Field appContextField =
- Component.class.getDeclaredField("appContext");
+
+ Component.class.getDeclaredField("appContext");
appContextField.setAccessible(true);
appContextField.set(component, null);
- }
- catch (NoSuchFieldException e) {
+
+ return component;
+ } catch (Throwable e) {
+ // We don't care about component.
+ // So don't prevent class initialisation.
e.printStackTrace();
+ return null;
}
- catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- return null;
}
});
tracker = new MediaTracker(component);
}
+ private static Component createNoPermsComponent() {
+ // 7020198 - set acc field to no permissions and no subject
+ // Note, will have appContext set.
+ return AccessController.doPrivileged(
+ new PrivilegedAction<Component>() {
+ public Component run() {
+ return new Component() {
+ };
+ }
+ },
+ new AccessControlContext(new ProtectionDomain[]{
+ new ProtectionDomain(null, null)
+ })
+ );
+ }
+
/**
* Id used in loading images from MediaTracker.
*/
--- a/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java Thu May 05 22:29:05 2011 -0700
@@ -509,6 +509,9 @@
* edges thus has to be h*2+2 in length
*/
int edges[] = new int[(dy2-dy1)*2+2];
+ // It is important that edges[0]=edges[1]=0 when we call
+ // Transform in case it must return early and we would
+ // not want to render anything on an error condition.
helper.Transform(tmpmaskblit, srcData, tmpData,
AlphaComposite.Src, null,
itx, interpType,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/misc/JavaxSecurityAuthKerberosAccess.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import javax.security.auth.kerberos.KeyTab;
+import sun.security.krb5.EncryptionKey;
+import sun.security.krb5.PrincipalName;
+
+/**
+ * An unsafe tunnel to get non-public access to classes in the
+ * javax.security.auth.kerberos package.
+ */
+public interface JavaxSecurityAuthKerberosAccess {
+ /**
+ * Returns keys for a principal in a keytab.
+ * @return the keys, never null, can be empty.
+ */
+ public EncryptionKey[] keyTabGetEncryptionKeys(
+ KeyTab ktab, PrincipalName principal);
+}
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu May 05 22:29:05 2011 -0700
@@ -29,6 +29,7 @@
import java.io.Console;
import java.io.FileDescriptor;
import java.security.ProtectionDomain;
+import javax.security.auth.kerberos.KeyTab;
import java.security.AccessController;
@@ -51,6 +52,7 @@
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
private static JavaSecurityAccess javaSecurityAccess;
+ private static JavaxSecurityAuthKerberosAccess javaxSecurityAuthKerberosAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@@ -139,4 +141,16 @@
}
return javaSecurityAccess;
}
+
+ public static void setJavaxSecurityAuthKerberosAccess
+ (JavaxSecurityAuthKerberosAccess jsaka) {
+ javaxSecurityAuthKerberosAccess = jsaka;
+ }
+
+ public static JavaxSecurityAuthKerberosAccess
+ getJavaxSecurityAuthKerberosAccess() {
+ if (javaxSecurityAuthKerberosAccess == null)
+ unsafe.ensureClassInitialized(KeyTab.class);
+ return javaxSecurityAuthKerberosAccess;
+ }
}
--- a/jdk/src/share/classes/sun/rmi/log/ReliableLog.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java Thu May 05 22:29:05 2011 -0700
@@ -380,9 +380,7 @@
} catch (IOException e) {
throw e;
} catch (Exception e) {
- throw new IOException("snapshot failed with exception of type: " +
- e.getClass().getName() +
- ", message was: " + e.getMessage());
+ throw new IOException("snapshot failed", e);
}
lastSnapshot = System.currentTimeMillis();
} finally {
--- a/jdk/src/share/classes/sun/rmi/server/Activation.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/Activation.java Thu May 05 22:29:05 2011 -0700
@@ -30,6 +30,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -98,6 +99,7 @@
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import sun.rmi.log.LogHandler;
import sun.rmi.log.ReliableLog;
import sun.rmi.registry.RegistryImpl;
@@ -147,10 +149,10 @@
/** maps activation id to its respective group id */
private Map<ActivationID,ActivationGroupID> idTable =
- new HashMap<ActivationID,ActivationGroupID>();
+ new ConcurrentHashMap<>();
/** maps group id to its GroupEntry groups */
private Map<ActivationGroupID,GroupEntry> groupTable =
- new HashMap<ActivationGroupID,GroupEntry>();
+ new ConcurrentHashMap<>();
private byte majorVersion = MAJOR_VERSION;
private byte minorVersion = MINOR_VERSION;
@@ -236,9 +238,11 @@
groupSemaphore = getInt("sun.rmi.activation.groupThrottle", 3);
groupCounter = 0;
Runtime.getRuntime().addShutdownHook(shutdownHook);
+
+ // Use array size of 0, since the value from calling size()
+ // may be out of date by the time toArray() is called.
ActivationGroupID[] gids =
- groupTable.keySet().toArray(
- new ActivationGroupID[groupTable.size()]);
+ groupTable.keySet().toArray(new ActivationGroupID[0]);
synchronized (startupLock = new Object()) {
// all the remote methods briefly synchronize on startupLock
@@ -274,6 +278,23 @@
}
}
+ /**
+ * Previous versions used HashMap instead of ConcurrentHashMap.
+ * Replace any HashMaps found during deserialization with
+ * ConcurrentHashMaps.
+ */
+ private void readObject(ObjectInputStream ois)
+ throws IOException, ClassNotFoundException
+ {
+ ois.defaultReadObject();
+ if (! (groupTable instanceof ConcurrentHashMap)) {
+ groupTable = new ConcurrentHashMap<>(groupTable);
+ }
+ if (! (idTable instanceof ConcurrentHashMap)) {
+ idTable = new ConcurrentHashMap<>(idTable);
+ }
+ }
+
private static class SystemRegistryImpl extends RegistryImpl {
private static final String NAME = ActivationSystem.class.getName();
@@ -488,9 +509,7 @@
ActivationGroupID id = new ActivationGroupID(systemStub);
GroupEntry entry = new GroupEntry(id, desc);
// table insertion must take place before log update
- synchronized (groupTable) {
- groupTable.put(id, entry);
- }
+ groupTable.put(id, entry);
addLogRecord(new LogRegisterGroup(id, desc));
return id;
}
@@ -515,11 +534,7 @@
// remove entry before unregister so state is updated before
// logged
- synchronized (groupTable) {
- GroupEntry entry = getGroupEntry(id);
- groupTable.remove(id);
- entry.unregisterGroup(true);
- }
+ removeGroupEntry(id).unregisterGroup(true);
}
public ActivationDesc setActivationDesc(ActivationID id,
@@ -637,12 +652,7 @@
unexport(system);
// destroy all child processes (groups)
- GroupEntry[] groupEntries;
- synchronized (groupTable) {
- groupEntries = groupTable.values().
- toArray(new GroupEntry[groupTable.size()]);
- }
- for (GroupEntry groupEntry : groupEntries) {
+ for (GroupEntry groupEntry : groupTable.values()) {
groupEntry.shutdown();
}
@@ -693,10 +703,8 @@
}
// destroy all child processes (groups) quickly
- synchronized (groupTable) {
- for (GroupEntry groupEntry : groupTable.values()) {
- groupEntry.shutdownFast();
- }
+ for (GroupEntry groupEntry : groupTable.values()) {
+ groupEntry.shutdownFast();
}
}
}
@@ -708,13 +716,32 @@
private ActivationGroupID getGroupID(ActivationID id)
throws UnknownObjectException
{
- synchronized (idTable) {
- ActivationGroupID groupID = idTable.get(id);
- if (groupID != null) {
- return groupID;
+ ActivationGroupID groupID = idTable.get(id);
+ if (groupID != null) {
+ return groupID;
+ }
+ throw new UnknownObjectException("unknown object: " + id);
+ }
+
+ /**
+ * Returns the group entry for the group id, optionally removing it.
+ * Throws UnknownGroupException if the group is not registered.
+ */
+ private GroupEntry getGroupEntry(ActivationGroupID id, boolean rm)
+ throws UnknownGroupException
+ {
+ if (id.getClass() == ActivationGroupID.class) {
+ GroupEntry entry;
+ if (rm) {
+ entry = groupTable.remove(id);
+ } else {
+ entry = groupTable.get(id);
+ }
+ if (entry != null && !entry.removed) {
+ return entry;
}
}
- throw new UnknownObjectException("unknown object: " + id);
+ throw new UnknownGroupException("group unknown");
}
/**
@@ -724,15 +751,17 @@
private GroupEntry getGroupEntry(ActivationGroupID id)
throws UnknownGroupException
{
- if (id.getClass() == ActivationGroupID.class) {
- synchronized (groupTable) {
- GroupEntry entry = groupTable.get(id);
- if (entry != null && !entry.removed) {
- return entry;
- }
- }
- }
- throw new UnknownGroupException("group unknown");
+ return getGroupEntry(id, false);
+ }
+
+ /**
+ * Removes and returns the group entry for the group id. Throws
+ * UnknownGroupException if the group is not registered.
+ */
+ private GroupEntry removeGroupEntry(ActivationGroupID id)
+ throws UnknownGroupException
+ {
+ return getGroupEntry(id, true);
}
/**
@@ -744,11 +773,9 @@
throws UnknownObjectException
{
ActivationGroupID gid = getGroupID(id);
- synchronized (groupTable) {
- GroupEntry entry = groupTable.get(gid);
- if (entry != null) {
- return entry;
- }
+ GroupEntry entry = groupTable.get(gid);
+ if (entry != null && !entry.removed) {
+ return entry;
}
throw new UnknownObjectException("object's group removed");
}
@@ -882,9 +909,7 @@
}
// table insertion must take place before log update
- synchronized (idTable) {
- idTable.put(id, groupID);
- }
+ idTable.put(id, groupID);
if (addRecord) {
addLogRecord(new LogRegisterObject(id, desc));
@@ -901,10 +926,8 @@
restartSet.remove(id);
}
- // table insertion must take place before log update
- synchronized (idTable) {
- idTable.remove(id);
- }
+ // table removal must take place before log update
+ idTable.remove(id);
if (addRecord) {
addLogRecord(new LogUnregisterObject(id));
}
@@ -919,9 +942,7 @@
objects.entrySet())
{
ActivationID id = entry.getKey();
- synchronized (idTable) {
- idTable.remove(id);
- }
+ idTable.remove(id);
ObjectEntry objEntry = entry.getValue();
objEntry.removed = true;
}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -29,7 +29,6 @@
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import sun.security.krb5.*;
-import javax.security.auth.kerberos.*;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.AccessController;
@@ -43,40 +42,23 @@
* @since 1.4
*/
public class Krb5AcceptCredential
- extends KerberosKey
implements Krb5CredElement {
private static final long serialVersionUID = 7714332137352567952L;
private Krb5NameElement name;
- /**
- * We cache an EncryptionKey representation of this key because many
- * Krb5 operation require a key in that form. At some point we might do
- * away with EncryptionKey altogether and use the base class
- * KerberosKey everywhere.
- */
- private EncryptionKey[] krb5EncryptionKeys;
+ private Krb5Util.ServiceCreds screds;
- private Krb5AcceptCredential(Krb5NameElement name, KerberosKey[] keys) {
+ private Krb5AcceptCredential(Krb5NameElement name, Krb5Util.ServiceCreds creds) {
/*
* Initialize this instance with the data from the acquired
* KerberosKey. This class needs to be a KerberosKey too
* hence we can't just store a reference.
*/
- super(keys[0].getPrincipal(),
- keys[0].getEncoded(),
- keys[0].getKeyType(),
- keys[0].getVersionNumber());
this.name = name;
- // Cache this for later use by the sun.security.krb5 package.
- krb5EncryptionKeys = new EncryptionKey[keys.length];
- for (int i = 0; i < keys.length; i++) {
- krb5EncryptionKeys[i] = new EncryptionKey(keys[i].getEncoded(),
- keys[i].getKeyType(),
- new Integer(keys[i].getVersionNumber()));
- }
+ this.screds = creds;
}
static Krb5AcceptCredential getInstance(final GSSCaller caller, Krb5NameElement name)
@@ -86,12 +68,12 @@
name.getKrb5PrincipalName().getName());
final AccessControlContext acc = AccessController.getContext();
- KerberosKey[] keys;
+ Krb5Util.ServiceCreds creds = null;
try {
- keys = AccessController.doPrivileged(
- new PrivilegedExceptionAction<KerberosKey[]>() {
- public KerberosKey[] run() throws Exception {
- return Krb5Util.getKeys(
+ creds = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Krb5Util.ServiceCreds>() {
+ public Krb5Util.ServiceCreds run() throws Exception {
+ return Krb5Util.getServiceCreds(
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
serverPrinc, acc);
}});
@@ -103,17 +85,17 @@
throw ge;
}
- if (keys == null || keys.length == 0)
+ if (creds == null)
throw new GSSException(GSSException.NO_CRED, -1,
- "Failed to find any Kerberos Key");
+ "Failed to find any Kerberos credentails");
if (name == null) {
- String fullName = keys[0].getPrincipal().getName();
+ String fullName = creds.getName();
name = Krb5NameElement.getInstance(fullName,
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
}
- return new Krb5AcceptCredential(name, keys);
+ return new Krb5AcceptCredential(name, creds);
}
/**
@@ -171,7 +153,7 @@
}
EncryptionKey[] getKrb5EncryptionKeys() {
- return krb5EncryptionKeys;
+ return screds.getEKeys();
}
/**
@@ -193,13 +175,6 @@
* destroy in the base class.
*/
public void destroy() throws DestroyFailedException {
- if (krb5EncryptionKeys != null) {
- for (int i = 0; i < krb5EncryptionKeys.length; i++) {
- krb5EncryptionKeys[i].destroy();
- }
- krb5EncryptionKeys = null;
- }
-
- super.destroy();
+ screds.destroy();
}
}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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 @@
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import java.security.AccessControlContext;
@@ -38,7 +39,13 @@
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.KrbException;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import sun.misc.SharedSecrets;
+import sun.security.krb5.PrincipalName;
/**
* Utilities for obtaining and converting Kerberos tickets.
*
@@ -75,7 +82,7 @@
// 1. Try to find service ticket in acc subject
Subject accSubj = Subject.getSubject(acc);
- KerberosTicket ticket = (KerberosTicket) SubjectComber.find(accSubj,
+ KerberosTicket ticket = SubjectComber.find(accSubj,
serverPrincipal, clientPrincipal, KerberosTicket.class);
if (ticket != null) {
@@ -87,7 +94,7 @@
// 2. Try to get ticket from login
try {
loginSubj = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
- ticket = (KerberosTicket) SubjectComber.find(loginSubj,
+ ticket = SubjectComber.find(loginSubj,
serverPrincipal, clientPrincipal, KerberosTicket.class);
if (ticket != null) {
return ticket; // found it
@@ -102,13 +109,13 @@
// Try to get TGT to acquire service ticket
// 3. Try to get TGT from acc subject
- KerberosTicket tgt = (KerberosTicket) SubjectComber.find(accSubj,
+ KerberosTicket tgt = SubjectComber.find(accSubj,
tgsPrincipal, clientPrincipal, KerberosTicket.class);
boolean fromAcc;
if (tgt == null && loginSubj != null) {
// 4. Try to get TGT from login subject
- tgt = (KerberosTicket) SubjectComber.find(loginSubj,
+ tgt = SubjectComber.find(loginSubj,
tgsPrincipal, clientPrincipal, KerberosTicket.class);
fromAcc = false;
} else {
@@ -145,14 +152,14 @@
// Try to get ticket from acc's Subject
Subject accSubj = Subject.getSubject(acc);
- KerberosTicket ticket = (KerberosTicket)
+ KerberosTicket ticket =
SubjectComber.find(accSubj, serverPrincipal, clientPrincipal,
KerberosTicket.class);
// Try to get ticket from Subject obtained from GSSUtil
if (ticket == null && !GSSUtil.useSubjectCredsOnly(caller)) {
Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
- ticket = (KerberosTicket) SubjectComber.find(subject,
+ ticket = SubjectComber.find(subject,
serverPrincipal, clientPrincipal, KerberosTicket.class);
}
return ticket;
@@ -182,37 +189,152 @@
return subject;
}
+ // A special KerberosKey, used as keys read from a KeyTab object.
+ // Each time new keys are read from KeyTab objects in the private
+ // credentials set, old ones are removed and new ones added.
+ public static class KeysFromKeyTab extends KerberosKey {
+ public KeysFromKeyTab(KerberosKey key) {
+ super(key.getPrincipal(), key.getEncoded(),
+ key.getKeyType(), key.getVersionNumber());
+ }
+ }
+
/**
- * Retrieves the keys for the specified server principal from
- * the Subject in the specified AccessControlContext.
- * If the ticket can not be found in the Subject, and if
- * useSubjectCredsOnly is false, then obtain keys from
- * a LoginContext.
+ * Credentials of a service, the private secret to authenticate its
+ * identity, which can be:
+ * 1. Some KerberosKeys (generated from password)
+ * 2. A KeyTab (for a typical service)
+ * 3. A TGT (for a user2user service. Not supported yet)
*
- * NOTE: This method is used by JSSE Kerberos Cipher Suites
+ * Note that some creds can coexist. For example, a user2user service
+ * can use its keytab (or keys) if the client can successfully obtain a
+ * normal service ticket, otherwise, it can uses the TGT (actually, the
+ * session key of the TGT) if the client can only acquire a service ticket
+ * of ENC-TKT-IN-SKEY style.
*/
- public static KerberosKey[] getKeys(GSSCaller caller,
+ public static class ServiceCreds {
+ private KerberosPrincipal kp;
+ private List<KeyTab> ktabs;
+ private List<KerberosKey> kk;
+ private Subject subj;
+ //private KerberosTicket tgt; // user2user, not supported yet
+
+ private static ServiceCreds getInstance(
+ Subject subj, String serverPrincipal) {
+
+ ServiceCreds sc = new ServiceCreds();
+ sc.subj = subj;
+
+ for (KerberosPrincipal p: subj.getPrincipals(KerberosPrincipal.class)) {
+ if (serverPrincipal == null ||
+ p.getName().equals(serverPrincipal)) {
+ sc.kp = p;
+ serverPrincipal = p.getName();
+ break;
+ }
+ }
+ if (sc.kp == null) {
+ // Compatibility with old behavior: even when there is no
+ // KerberosPrincipal, we can find one from KerberosKeys
+ List<KerberosKey> keys = SubjectComber.findMany(
+ subj, null, null, KerberosKey.class);
+ if (!keys.isEmpty()) {
+ sc.kp = keys.get(0).getPrincipal();
+ serverPrincipal = sc.kp.getName();
+ if (DEBUG) {
+ System.out.println(">>> ServiceCreds: no kp?"
+ + " find one from kk: " + serverPrincipal);
+ }
+ } else {
+ return null;
+ }
+ }
+ sc.ktabs = SubjectComber.findMany(
+ subj, null, null, KeyTab.class);
+ sc.kk = SubjectComber.findMany(
+ subj, serverPrincipal, null, KerberosKey.class);
+ if (sc.ktabs.isEmpty() && sc.kk.isEmpty()) {
+ return null;
+ }
+ return sc;
+ }
+
+ public String getName() {
+ return kp.getName();
+ }
+
+ public KerberosKey[] getKKeys() {
+ if (ktabs.isEmpty()) {
+ return kk.toArray(new KerberosKey[kk.size()]);
+ } else {
+ List<KerberosKey> keys = new ArrayList<>();
+ for (KeyTab ktab: ktabs) {
+ for (KerberosKey k: ktab.getKeys(kp)) {
+ keys.add(k);
+ }
+ }
+ // Compatibility: also add keys to privCredSet. Remove old
+ // ones first, only remove those from keytab.
+ if (!subj.isReadOnly()) {
+ Set<Object> pcs = subj.getPrivateCredentials();
+ synchronized (pcs) {
+ Iterator<Object> iterator = pcs.iterator();
+ while (iterator.hasNext()) {
+ Object obj = iterator.next();
+ if (obj instanceof KeysFromKeyTab) {
+ KerberosKey key = (KerberosKey)obj;
+ if (Objects.equals(key.getPrincipal(), kp)) {
+ iterator.remove();
+ }
+ }
+ }
+ }
+ for (KerberosKey key: keys) {
+ subj.getPrivateCredentials().add(new KeysFromKeyTab(key));
+ }
+ }
+ return keys.toArray(new KerberosKey[keys.size()]);
+ }
+ }
+
+ public EncryptionKey[] getEKeys() {
+ KerberosKey[] kkeys = getKKeys();
+ EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
+ for (int i=0; i<ekeys.length; i++) {
+ ekeys[i] = new EncryptionKey(
+ kkeys[i].getEncoded(), kkeys[i].getKeyType(),
+ new Integer(kkeys[i].getVersionNumber()));
+ }
+ return ekeys;
+ }
+
+ public void destroy() {
+ kp = null;
+ ktabs = null;
+ kk = null;
+ }
+ }
+ /**
+ * Retrieves the ServiceCreds for the specified server principal from
+ * the Subject in the specified AccessControlContext. If not found, and if
+ * useSubjectCredsOnly is false, then obtain from a LoginContext.
+ *
+ * NOTE: This method is also used by JSSE Kerberos Cipher Suites
+ */
+ public static ServiceCreds getServiceCreds(GSSCaller caller,
String serverPrincipal, AccessControlContext acc)
throws LoginException {
Subject accSubj = Subject.getSubject(acc);
- List<KerberosKey> kkeys = (List<KerberosKey>)SubjectComber.findMany(
- accSubj, serverPrincipal, null, KerberosKey.class);
-
- if (kkeys == null && !GSSUtil.useSubjectCredsOnly(caller)) {
- Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
- kkeys = (List<KerberosKey>) SubjectComber.findMany(subject,
- serverPrincipal, null, KerberosKey.class);
+ ServiceCreds sc = null;
+ if (accSubj != null) {
+ sc = ServiceCreds.getInstance(accSubj, serverPrincipal);
}
-
- int len;
- if (kkeys != null && (len = kkeys.size()) > 0) {
- KerberosKey[] keys = new KerberosKey[len];
- kkeys.toArray(keys);
- return keys;
- } else {
- return null;
+ if (sc == null && !GSSUtil.useSubjectCredsOnly(caller)) {
+ Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
+ sc = ServiceCreds.getInstance(subject, serverPrincipal);
}
+ return sc;
}
public static KerberosTicket credsToTicket(Credentials serviceCreds) {
@@ -247,4 +369,17 @@
kerbTicket.getRenewTill(),
kerbTicket.getClientAddresses());
}
+
+ /**
+ * A helper method to get EncryptionKeys from a javax..KeyTab
+ * @param ktab the javax..KeyTab class
+ * @param cname the PrincipalName
+ * @return the EKeys, never null, might be empty
+ */
+ public static EncryptionKey[] keysFromJavaxKeyTab(
+ KeyTab ktab, PrincipalName cname) {
+ return SharedSecrets.getJavaxSecurityAuthKerberosAccess().
+ keyTabGetEncryptionKeys(ktab, cname);
+ }
+
}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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
@@ -33,10 +33,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import javax.security.auth.kerberos.KeyTab;
/**
- * This utility looks through the current Subject and retrieves a ticket or key
- * for the desired client/server principals.
+ * This utility looks through the current Subject and retrieves private
+ * credentials for the desired client/server principals.
*
* @author Ram Marti
* @since 1.4.2
@@ -52,58 +53,70 @@
private SubjectComber() { // Cannot create one of these
}
- static Object find(Subject subject, String serverPrincipal,
- String clientPrincipal, Class credClass) {
+ static <T> T find(Subject subject, String serverPrincipal,
+ String clientPrincipal, Class<T> credClass) {
- return findAux(subject, serverPrincipal, clientPrincipal, credClass,
+ return (T)findAux(subject, serverPrincipal, clientPrincipal, credClass,
true);
}
- static Object findMany(Subject subject, String serverPrincipal,
- String clientPrincipal, Class credClass) {
+ static <T> List<T> findMany(Subject subject, String serverPrincipal,
+ String clientPrincipal, Class<T> credClass) {
- return findAux(subject, serverPrincipal, clientPrincipal, credClass,
+ return (List<T>)findAux(subject, serverPrincipal, clientPrincipal, credClass,
false);
}
/**
- * Find the ticket or key for the specified client/server principals
+ * Find private credentials for the specified client/server principals
* in the subject. Returns null if the subject is null.
*
- * @return the ticket or key
+ * @return the private credentials
*/
- private static Object findAux(Subject subject, String serverPrincipal,
- String clientPrincipal, Class credClass, boolean oneOnly) {
+ private static <T> Object findAux(Subject subject, String serverPrincipal,
+ String clientPrincipal, Class<T> credClass, boolean oneOnly) {
if (subject == null) {
return null;
} else {
- List<Object> answer = (oneOnly ? null : new ArrayList<Object>());
+ List<T> answer = (oneOnly ? null : new ArrayList<T>());
- if (credClass == KerberosKey.class) {
- // We are looking for a KerberosKey credentials for the
- // serverPrincipal
- Iterator<KerberosKey> iterator =
- subject.getPrivateCredentials(KerberosKey.class).iterator();
+ if (credClass == KeyTab.class) { // Principal un-related
+ // We are looking for credentials unrelated to serverPrincipal
+ Iterator<T> iterator =
+ subject.getPrivateCredentials(credClass).iterator();
while (iterator.hasNext()) {
- KerberosKey key = iterator.next();
- if (serverPrincipal == null ||
- serverPrincipal.equals(key.getPrincipal().getName())) {
+ T t = iterator.next();
+ if (DEBUG) {
+ System.out.println("Found " + credClass.getSimpleName());
+ }
+ if (oneOnly) {
+ return t;
+ } else {
+ answer.add(t);
+ }
+ }
+ } else if (credClass == KerberosKey.class) {
+ // We are looking for credentials for the serverPrincipal
+ Iterator<T> iterator =
+ subject.getPrivateCredentials(credClass).iterator();
+ while (iterator.hasNext()) {
+ T t = iterator.next();
+ String name = ((KerberosKey)t).getPrincipal().getName();
+ if (serverPrincipal == null || serverPrincipal.equals(name)) {
if (DEBUG) {
- System.out.println("Found key for "
- + key.getPrincipal() + "(" +
- key.getKeyType() + ")");
+ System.out.println("Found " +
+ credClass.getSimpleName() + " for " + name);
}
if (oneOnly) {
- return key;
+ return t;
} else {
if (serverPrincipal == null) {
// Record name so that keys returned will all
// belong to the same principal
- serverPrincipal =
- key.getPrincipal().getName();
+ serverPrincipal = name;
}
- answer.add(key);
+ answer.add(t);
}
}
}
@@ -167,7 +180,7 @@
serverPrincipal =
ticket.getServer().getName();
}
- answer.add(ticket);
+ answer.add((T)ticket);
}
}
}
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Thu May 05 22:29:05 2011 -0700
@@ -110,7 +110,6 @@
public static synchronized void refresh() throws KrbException {
singleton = new Config();
- KeyTab.refresh();
KdcComm.initStatic();
}
--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -138,8 +138,7 @@
* @returns an array of secret keys or null if none were found.
*/
public static EncryptionKey[] acquireSecretKeys(PrincipalName princ,
- String keytab)
- throws KrbException, IOException {
+ String keytab) {
if (princ == null)
throw new IllegalArgumentException(
@@ -148,11 +147,6 @@
// KeyTab getInstance(keytab) will call KeyTab.getInstance()
// if keytab is null
KeyTab ktab = KeyTab.getInstance(keytab);
-
- if (ktab == null) {
- return null;
- }
-
return ktab.readServiceKeys(princ);
}
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Thu May 05 22:29:05 2011 -0700
@@ -37,6 +37,8 @@
import sun.security.util.*;
import java.io.IOException;
import java.util.Objects;
+import javax.security.auth.kerberos.KeyTab;
+import sun.security.jgss.krb5.Krb5Util;
/**
* This class encapsulates a AS-REP message that the KDC sends to the
@@ -90,29 +92,32 @@
}
/**
- * Called by KrbAsReqBuilder to resolve a AS-REP message using keys.
- * @param keys user provided keys, not null
+ * Called by KrbAsReqBuilder to resolve a AS-REP message using a keytab.
+ * @param ktab the keytab, not null
* @param asReq the original AS-REQ sent, used to validate AS-REP
+ * @param cname the user principal name, used to locate keys in ktab
*/
- void decryptUsingKeys(EncryptionKey[] keys, KrbAsReq asReq)
+ void decryptUsingKeyTab(KeyTab ktab, KrbAsReq asReq, PrincipalName cname)
throws KrbException, Asn1Exception, IOException {
EncryptionKey dkey = null;
int encPartKeyType = rep.encPart.getEType();
Integer encPartKvno = rep.encPart.kvno;
- try {
- dkey = EncryptionKey.findKey(encPartKeyType, encPartKvno, keys);
- } catch (KrbException ke) {
- if (ke.returnCode() == Krb5.KRB_AP_ERR_BADKEYVER) {
- // Fallback to no kvno. In some cases, keytab is generated
- // not by sysadmin but Java's ktab command
- dkey = EncryptionKey.findKey(encPartKeyType, keys);
+ try {
+ dkey = EncryptionKey.findKey(encPartKeyType, encPartKvno,
+ Krb5Util.keysFromJavaxKeyTab(ktab, cname));
+ } catch (KrbException ke) {
+ if (ke.returnCode() == Krb5.KRB_AP_ERR_BADKEYVER) {
+ // Fallback to no kvno. In some cases, keytab is generated
+ // not by sysadmin but Java's ktab command
+ dkey = EncryptionKey.findKey(encPartKeyType,
+ Krb5Util.keysFromJavaxKeyTab(ktab, cname));
+ }
}
- }
- if (dkey == null) {
- throw new KrbException(Krb5.API_INVALID_ARG,
- "Cannot find key for type/kvno to decrypt AS REP - " +
- EType.toString(encPartKeyType) + "/" + encPartKvno);
- }
+ if (dkey == null) {
+ throw new KrbException(Krb5.API_INVALID_ARG,
+ "Cannot find key for type/kvno to decrypt AS REP - " +
+ EType.toString(encPartKeyType) + "/" + encPartKvno);
+ }
decrypt(dkey, asReq);
}
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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
@@ -27,6 +27,8 @@
import java.io.IOException;
import java.util.Arrays;
+import javax.security.auth.kerberos.KeyTab;
+import sun.security.jgss.krb5.Krb5Util;
import sun.security.krb5.internal.HostAddresses;
import sun.security.krb5.internal.KDCOptions;
import sun.security.krb5.internal.KRBError;
@@ -42,13 +44,16 @@
* 1. Gather information to create AS-REQ
* 2. Create and send AS-REQ
* 3. Receive AS-REP and KRB-ERROR (-KRB_ERR_RESPONSE_TOO_BIG) and parse them
- * 4. Emit credentials and secret keys (for JAAS storeKey=true)
+ * 4. Emit credentials and secret keys (for JAAS storeKey=true with password)
*
* This class does not:
* 1. Deal with real communications (KdcComm does it, and TGS-REQ)
* a. Name of KDCs for a realm
* b. Server availability, timeout, UDP or TCP
* d. KRB_ERR_RESPONSE_TOO_BIG
+ * 2. Stores its own copy of password, this means:
+ * a. Do not change/wipe it before Builder finish
+ * b. Builder will not wipe it for you
*
* With this class:
* 1. KrbAsReq has only one constructor
@@ -70,19 +75,17 @@
private HostAddresses addresses;
// Secret source: can't be changed once assigned, only one (of the two
- // sources) can be set and should be non-null
- private EncryptionKey[] keys;
- private char[] password;
+ // sources) can be set to non-null
+ private final char[] password;
+ private final KeyTab ktab;
// Used to create a ENC-TIMESTAMP in the 2nd AS-REQ
- private EncryptionKey pakey;
private PAData[] paList; // PA-DATA from both KRB-ERROR and AS-REP.
// Used by getKeys() only.
// Only AS-REP should be enough per RFC,
// combined in case etypes are different.
// The generated and received:
- int[] eTypes;
private KrbAsReq req;
private KrbAsRep rep;
@@ -94,7 +97,7 @@
private State state;
// Called by other constructors
- private KrbAsReqBuilder(PrincipalName cname)
+ private void init(PrincipalName cname)
throws KrbException {
if (cname.getRealm() == null) {
cname.setRealm(Config.getInstance().getDefaultRealm());
@@ -114,14 +117,11 @@
* This argument will neither be modified nor stored by the method.
* @throws KrbException
*/
- public KrbAsReqBuilder(PrincipalName cname, EncryptionKey[] keys)
+ public KrbAsReqBuilder(PrincipalName cname, KeyTab ktab)
throws KrbException {
- this(cname);
- this.keys = new EncryptionKey[keys.length];
- for (int i=0; i<keys.length; i++) {
- this.keys[i] = (EncryptionKey)keys[i].clone();
- }
- eTypes = EType.getDefaults("default_tkt_enctypes", keys);
+ init(cname);
+ this.ktab = ktab;
+ this.password = null;
}
/**
@@ -137,30 +137,24 @@
*/
public KrbAsReqBuilder(PrincipalName cname, char[] pass)
throws KrbException {
- this(cname);
+ init(cname);
this.password = pass.clone();
- eTypes = EType.getDefaults("default_tkt_enctypes");
+ this.ktab = null;
}
/**
- * Retrieves an array of secret keys for the client. This is useful if
+ * Retrieves an array of secret keys for the client. This is used when
* the client supplies password but need keys to act as an acceptor
* (in JAAS words, isInitiator=true and storeKey=true)
- * @return original keys if initiated with keys, or generated keys if
- * password. In latter case, PA-DATA from server might be used to
- * generate keys. All "default_tkt_enctypes" keys will be generated,
- * Never null.
+ * @return generated keys from password. PA-DATA from server might be used.
+ * All "default_tkt_enctypes" keys will be generated, Never null.
+ * @throws IllegalStateException if not constructed from a password
* @throws KrbException
*/
public EncryptionKey[] getKeys() throws KrbException {
checkState(State.REQ_OK, "Cannot get keys");
- if (keys != null) {
- EncryptionKey[] result = new EncryptionKey[keys.length];
- for (int i=0; i<keys.length; i++) {
- result[i] = (EncryptionKey)keys[i].clone();
- }
- return result;
- } else {
+ if (password != null) {
+ int[] eTypes = EType.getDefaults("default_tkt_enctypes");
EncryptionKey[] result = new EncryptionKey[eTypes.length];
/*
@@ -205,6 +199,8 @@
}
}
return result;
+ } else {
+ throw new IllegalStateException("Required password not provided");
}
}
@@ -241,12 +237,22 @@
/**
* Build a KrbAsReq object from all info fed above. Normally this method
* will be called twice: initial AS-REQ and second with pakey
+ * @param key null (initial AS-REQ) or pakey (with preauth)
* @return the KrbAsReq object
* @throws KrbException
* @throws IOException
*/
- private KrbAsReq build() throws KrbException, IOException {
- return new KrbAsReq(pakey,
+ private KrbAsReq build(EncryptionKey key) throws KrbException, IOException {
+ int[] eTypes;
+ if (password != null) {
+ eTypes = EType.getDefaults("default_tkt_enctypes");
+ } else {
+ EncryptionKey[] ks = Krb5Util.keysFromJavaxKeyTab(ktab, cname);
+ eTypes = EType.getDefaults("default_tkt_enctypes",
+ ks);
+ for (EncryptionKey k: ks) k.destroy();
+ }
+ return new KrbAsReq(key,
options,
cname,
sname,
@@ -263,9 +269,10 @@
* @throws Asn1Exception
* @throws IOException
*/
- private KrbAsReqBuilder resolve() throws KrbException, Asn1Exception, IOException {
- if (keys != null) {
- rep.decryptUsingKeys(keys, req);
+ private KrbAsReqBuilder resolve()
+ throws KrbException, Asn1Exception, IOException {
+ if (ktab != null) {
+ rep.decryptUsingKeyTab(ktab, req, cname);
} else {
rep.decryptUsingPassword(password, req, cname);
}
@@ -292,9 +299,10 @@
private KrbAsReqBuilder send() throws KrbException, IOException {
boolean preAuthFailedOnce = false;
KdcComm comm = new KdcComm(cname.getRealmAsString());
+ EncryptionKey pakey = null;
while (true) {
try {
- req = build();
+ req = build(pakey);
rep = new KrbAsRep(comm.send(req.encoding()));
return this;
} catch (KrbException ke) {
@@ -308,7 +316,10 @@
preAuthFailedOnce = true;
KRBError kerr = ke.getError();
if (password == null) {
- pakey = EncryptionKey.findKey(kerr.getEType(), keys);
+ EncryptionKey[] ks = Krb5Util.keysFromJavaxKeyTab(ktab, cname);
+ pakey = EncryptionKey.findKey(kerr.getEType(), ks);
+ if (pakey != null) pakey = (EncryptionKey)pakey.clone();
+ for (EncryptionKey k: ks) k.destroy();
} else {
PAData.SaltAndParams snp = PAData.getSaltAndParams(
kerr.getEType(), kerr.getPA());
@@ -317,7 +328,7 @@
// does not recommend this
pakey = EncryptionKey.acquireSecretKey(password,
snp.salt == null ? cname.getSalt() : snp.salt,
- eTypes[0],
+ EType.getDefaults("default_tkt_enctypes")[0],
null);
} else {
pakey = EncryptionKey.acquireSecretKey(password,
@@ -369,15 +380,8 @@
*/
public void destroy() {
state = State.DESTROYED;
- if (keys != null) {
- for (EncryptionKey k: keys) {
- k.destroy();
- }
- keys = null;
- }
if (password != null) {
Arrays.fill(password, (char)0);
- password = null;
}
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java Thu May 05 22:29:05 2011 -0700
@@ -40,6 +40,7 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
+import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -50,92 +51,138 @@
* This class represents key table. The key table functions deal with storing
* and retrieving service keys for use in authentication exchanges.
*
+ * A KeyTab object is always constructed, if the file specified does not
+ * exist, it's still valid but empty. If there is an I/O error or file format
+ * error, it's invalid.
+ *
+ * The class is immutable on the read side (the write side is only used by
+ * the ktab tool).
+ *
* @author Yanni Zhang
*/
public class KeyTab implements KeyTabConstants {
- int kt_vno;
- private static KeyTab singleton = null;
+
private static final boolean DEBUG = Krb5.DEBUG;
- private static String name;
+ private static String defaultTabName = null;
+
+ // Attention: Currently there is no way to remove a keytab from this map,
+ // this might lead to a memory leak.
+ private static Map<String,KeyTab> map = new HashMap<>();
+
+ // KeyTab file does not exist. Note: a missing keytab is still valid
+ private boolean isMissing = false;
+
+ // KeyTab file is invalid, possibly an I/O error or a file format error.
+ private boolean isValid = true;
+
+ private final String tabName;
+ private long lastModified;
+ private int kt_vno;
+
private Vector<KeyTabEntry> entries = new Vector<>();
- private KeyTab(String filename) throws IOException, RealmException {
- init(filename);
- }
-
- public static KeyTab getInstance(String s) {
- name = parse(s);
- if (name == null) {
- return getInstance();
+ /**
+ * Constructs a KeyTab object.
+ *
+ * If there is any I/O error or format errot during the loading, the
+ * isValid flag is set to false, and all half-read entries are dismissed.
+ * @param filename path name for the keytab file, must not be null
+ */
+ private KeyTab(String filename) {
+ tabName = filename;
+ try {
+ lastModified = new File(tabName).lastModified();
+ KeyTabInputStream kis =
+ new KeyTabInputStream(new FileInputStream(filename));
+ load(kis);
+ kis.close();
+ } catch (FileNotFoundException e) {
+ entries.clear();
+ isMissing = true;
+ } catch (Exception ioe) {
+ entries.clear();
+ isValid = false;
}
- return getInstance(new File(name));
}
/**
- * Gets the single instance of KeyTab class.
- * @param file the key tab file.
- * @return single instance of KeyTab;
- * return null if error occurs while reading data out of the file.
+ * Read a keytab file. Returns a new object and save it into cache when
+ * new content (modified since last read) is available. If keytab file is
+ * invalid, the old object will be returned. This is a safeguard for
+ * partial-written keytab files or non-stable network. Please note that
+ * a missing keytab is valid, which is equivalent to an empty keytab.
+ *
+ * @param s file name of keytab, must not be null
+ * @return the keytab object, can be invalid, but never null.
*/
- public static KeyTab getInstance(File file) {
- try {
- if (!(file.exists())) {
- singleton = null;
- } else {
- String fname = file.getAbsolutePath();
- // Since this class deals with file I/O operations,
- // we want only one class instance existing.
- if (singleton != null) {
- File kfile = new File(singleton.name);
- String kname = kfile.getAbsolutePath();
- if (kname.equalsIgnoreCase(fname)) {
- if (DEBUG) {
- System.out.println("KeyTab instance already exists");
- }
- }
- } else {
- singleton = new KeyTab(fname);
- }
- }
- } catch (Exception e) {
- singleton = null;
- if (DEBUG) {
- System.out.println("Could not obtain an instance of KeyTab" +
- e.getMessage());
- }
+ private synchronized static KeyTab getInstance0(String s) {
+ long lm = new File(s).lastModified();
+ KeyTab old = map.get(s);
+ if (old != null && old.isValid() && old.lastModified == lm) {
+ return old;
}
- return singleton;
+ KeyTab ktab = new KeyTab(s);
+ if (ktab.isValid()) { // A valid new keytab
+ map.put(s, ktab);
+ return ktab;
+ } else if (old != null) { // An existing old one
+ return old;
+ } else {
+ return ktab; // first read is invalid
+ }
}
/**
- * Gets the single instance of KeyTab class.
- * @return single instance of KeyTab; return null if default keytab file
- * does not exist, or error occurs while reading data from the file.
+ * Gets a KeyTab object.
+ * @param s the key tab file name.
+ * @return the KeyTab object, never null.
+ */
+ public static KeyTab getInstance(String s) {
+ if (s == null) {
+ return getInstance();
+ } else {
+ return getInstance0(s);
+ }
+ }
+
+ /**
+ * Gets a KeyTab object.
+ * @param file the key tab file.
+ * @return the KeyTab object, never null.
+ */
+ public static KeyTab getInstance(File file) {
+ if (file == null) {
+ return getInstance();
+ } else {
+ return getInstance0(file.getPath());
+ }
+ }
+
+ /**
+ * Gets the default KeyTab object.
+ * @return the KeyTab object, never null.
*/
public static KeyTab getInstance() {
- try {
- name = getDefaultKeyTab();
- if (name != null) {
- singleton = getInstance(new File(name));
- }
- } catch (Exception e) {
- singleton = null;
- if (DEBUG) {
- System.out.println("Could not obtain an instance of KeyTab" +
- e.getMessage());
- }
- }
- return singleton;
+ return getInstance(getDefaultTabName());
+ }
+
+ public boolean isMissing() {
+ return isMissing;
+ }
+
+ public boolean isValid() {
+ return isValid;
}
/**
* The location of keytab file will be read from the configuration file
* If it is not specified, consider user.home as the keytab file's
* default location.
+ * @return never null
*/
- private static String getDefaultKeyTab() {
- if (name != null) {
- return name;
+ private static String getDefaultTabName() {
+ if (defaultTabName != null) {
+ return defaultTabName;
} else {
String kname = null;
try {
@@ -145,7 +192,7 @@
StringTokenizer st = new StringTokenizer(keytab_names, " ");
while (st.hasMoreTokens()) {
kname = parse(st.nextToken());
- if (kname != null) {
+ if (new File(kname).exists()) {
break;
}
}
@@ -165,19 +212,20 @@
new sun.security.action.GetPropertyAction("user.dir"));
}
- if (user_home != null) {
- kname = user_home + File.separator + "krb5.keytab";
- }
+ kname = user_home + File.separator + "krb5.keytab";
}
+ defaultTabName = kname;
return kname;
}
}
+ /**
+ * Parses some common keytab name formats
+ * @param name never null
+ * @return never null
+ */
private static String parse(String name) {
- String kname = null;
- if (name == null) {
- return null;
- }
+ String kname;
if ((name.length() >= 5) &&
(name.substring(0, 5).equalsIgnoreCase("FILE:"))) {
kname = name.substring(5);
@@ -194,18 +242,6 @@
return kname;
}
- private synchronized void init(String filename)
- throws IOException, RealmException {
-
- if (filename != null) {
- KeyTabInputStream kis =
- new KeyTabInputStream(new FileInputStream(filename));
- load(kis);
- kis.close();
- name = filename;
- }
- }
-
private void load(KeyTabInputStream kis)
throws IOException, RealmException {
@@ -234,14 +270,13 @@
* etypes that have been configured for use. If there are multiple
* keys with same etype, the one with the highest kvno is returned.
* @param service the PrincipalName of the requested service
- * @return an array containing all the service keys
+ * @return an array containing all the service keys, never null
*/
public EncryptionKey[] readServiceKeys(PrincipalName service) {
KeyTabEntry entry;
EncryptionKey key;
int size = entries.size();
ArrayList<EncryptionKey> keys = new ArrayList<>(size);
-
for (int i = size-1; i >= 0; i--) {
entry = entries.elementAt(i);
if (entry.service.match(service)) {
@@ -260,10 +295,7 @@
}
}
}
-
size = keys.size();
- if (size == 0)
- return null;
EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]);
// Sort keys according to default_tkt_enctypes
@@ -328,10 +360,13 @@
return false;
}
- public static String tabName() {
- return name;
+ public String tabName() {
+ return tabName;
}
+ /////////////////// THE WRITE SIDE ///////////////////////
+ /////////////// only used by ktab tool //////////////////
+
/**
* Adds a new entry in the key table.
* @param service the service which will have a new entry in the key table.
@@ -394,7 +429,7 @@
*/
public synchronized static KeyTab create()
throws IOException, RealmException {
- String dname = getDefaultKeyTab();
+ String dname = getDefaultTabName();
return create(dname);
}
@@ -408,8 +443,7 @@
new KeyTabOutputStream(new FileOutputStream(name));
kos.writeVersion(KRB5_KT_VNO);
kos.close();
- singleton = new KeyTab(name);
- return singleton;
+ return new KeyTab(name);
}
/**
@@ -417,7 +451,7 @@
*/
public synchronized void save() throws IOException {
KeyTabOutputStream kos =
- new KeyTabOutputStream(new FileOutputStream(name));
+ new KeyTabOutputStream(new FileOutputStream(tabName));
kos.writeVersion(kt_vno);
for (int i = 0; i < entries.size(); i++) {
kos.writeEntry(entries.elementAt(i));
@@ -490,13 +524,4 @@
kos.write16(KRB5_KT_VNO);
kos.close();
}
-
- public static void refresh() {
- if (singleton != null) {
- if (DEBUG) {
- System.out.println("Refreshing Keytab");
- }
- singleton = null;
- }
- }
}
--- a/jdk/src/share/classes/sun/security/pkcs11/Config.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/Config.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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
@@ -653,6 +653,13 @@
}
}
debug(keyword + ": " + lib);
+
+ // Check to see if full path is specified to prevent the DLL
+ // preloading attack
+ if (!(new File(lib)).isAbsolute()) {
+ throw new ConfigurationException(
+ "Absolute path required for library value: " + lib);
+ }
return lib;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
@@ -236,7 +236,8 @@
throw new IllegalStateException(e);
}
if (modules == null) {
- List<Module> modules = (List<Module>)nssGetModuleList(nssHandle);
+ List<Module> modules = (List<Module>)nssGetModuleList(nssHandle,
+ nssLibDir);
this.modules = Collections.unmodifiableList(modules);
}
return modules;
@@ -358,7 +359,7 @@
* A representation of one PKCS#11 slot in a PKCS#11 module.
*/
public static final class Module {
- // name of the native library
+ // path of the native library
final String libraryName;
// descriptive name used by NSS
final String commonName;
@@ -371,8 +372,10 @@
// trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
private Map<Bytes,TrustAttributes> trust;
- Module(String libraryName, String commonName, boolean fips, int slot) {
+ Module(String libraryDir, String libraryName, String commonName,
+ boolean fips, int slot) {
ModuleType type;
+
if ((libraryName == null) || (libraryName.length() == 0)) {
// must be softtoken
libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
@@ -397,7 +400,7 @@
+ "module: " + libraryName + ", " + commonName);
}
}
- this.libraryName = libraryName;
+ this.libraryName = (new File(libraryDir, libraryName)).getPath();
this.commonName = commonName;
this.slot = slot;
this.type = type;
@@ -752,6 +755,6 @@
private static native boolean nssInit(String functionName, long handle, String configDir);
- private static native Object nssGetModuleList(long handle);
+ private static native Object nssGetModuleList(long handle, String libDir);
}
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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
@@ -1285,11 +1285,12 @@
// check permission to access and use the secret key of the
// Kerberized "host" service
- if (kerberosKeys != null) {
-
+ if (kerberosKeys != null && kerberosKeys.length > 0) {
if (debug != null && Debug.isOn("handshake")) {
- System.out.println("Using Kerberos key: " +
- kerberosKeys[0]);
+ for (SecretKey k: kerberosKeys) {
+ System.out.println("Using Kerberos key: " +
+ k);
+ }
}
String serverPrincipal =
--- a/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. 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
@@ -40,7 +40,7 @@
import sun.security.ssl.Krb5Proxy;
/**
- * An implementatin of Krb5Proxy that simply delegates to the appropriate
+ * An implementation of Krb5Proxy that simply delegates to the appropriate
* Kerberos APIs.
*/
public class Krb5ProxyImpl implements Krb5Proxy {
@@ -62,7 +62,7 @@
@Override
public SecretKey[] getServerKeys(AccessControlContext acc)
throws LoginException {
- return Krb5Util.getKeys(GSSCaller.CALLER_SSL_SERVER, null, acc);
+ return Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc).getKKeys();
}
@Override
--- a/jdk/src/share/native/common/jdk_util.h Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/native/common/jdk_util.h Thu May 05 22:29:05 2011 -0700
@@ -28,6 +28,7 @@
#include "jni.h"
#include "jvm.h"
+#include "jdk_util_md.h"
#ifdef __cplusplus
extern "C" {
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu May 05 22:29:05 2011 -0700
@@ -1971,6 +1971,13 @@
return data->abortFlag;
}
+ if (cinfo->output_components <= 0 ||
+ cinfo->image_width > (0xffffffffu / (unsigned int)cinfo->output_components))
+ {
+ JNU_ThrowByName(env, "javax/imageio/IIOException",
+ "Invalid number of output components");
+ return data->abortFlag;
+ }
// Allocate a 1-scanline buffer
scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->output_components);
--- a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp Thu May 05 22:29:05 2011 -0700
@@ -186,7 +186,11 @@
jchar buffer[256];
jchar* chars = buffer;
if (len > 256) {
- chars = (jchar*)malloc(len * sizeof(jchar));
+ size_t size = len * sizeof(jchar);
+ if (size / sizeof(jchar) != len) {
+ return;
+ }
+ chars = (jchar*)malloc(size);
if (chars == 0) {
return;
}
--- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Thu May 05 22:29:05 2011 -0700
@@ -75,6 +75,94 @@
TransformInterpFunc *pBicubicFunc = BicubicInterp;
/*
+ * The dxydxy parameters of the inverse transform determine how
+ * quickly we step through the source image. For tiny scale
+ * factors (on the order of 1E-16 or so) the stepping distances
+ * are huge. The image has been scaled so small that stepping
+ * a single pixel in device space moves the sampling point by
+ * billions (or more) pixels in the source image space. These
+ * huge stepping values can overflow the whole part of the longs
+ * we use for the fixed point stepping equations and so we need
+ * a more robust solution. We could simply iterate over every
+ * device pixel, use the inverse transform to transform it back
+ * into the source image coordinate system and then test it for
+ * being in range and sample pixel-by-pixel, but that is quite
+ * a bit more expensive. Fortunately, if the scale factors are
+ * so tiny that we overflow our long values then the number of
+ * pixels we are planning to visit should be very tiny. The only
+ * exception to that rule is if the scale factor along one
+ * dimension is tiny (creating the huge stepping values), and
+ * the scale factor along the other dimension is fairly regular
+ * or an up-scale. In that case we have a lot of pixels along
+ * the direction of the larger axis to sample, but few along the
+ * smaller axis. Though, pessimally, with an added shear factor
+ * such a linearly tiny image could have bounds that cover a large
+ * number of pixels. Such odd transformations should be very
+ * rare and the absolute limit on calculations would involve a
+ * single reverse transform of every pixel in the output image
+ * which is not fast, but it should not cause an undue stall
+ * of the rendering software.
+ *
+ * The specific test we will use is to calculate the inverse
+ * transformed values of every corner of the destination bounds
+ * (in order to be user-clip independent) and if we can
+ * perform a fixed-point-long inverse transform of all of
+ * those points without overflowing we will use the fast
+ * fixed point algorithm. Otherwise we will use the safe
+ * per-pixel transform algorithm.
+ * The 4 corners are 0,0, 0,dsth, dstw,0, dstw,dsth
+ * Transformed they are:
+ * tx, ty
+ * tx +dxdy*H, ty +dydy*H
+ * tx+dxdx*W, ty+dydx*W
+ * tx+dxdx*W+dxdy*H, ty+dydx*W+dydy*H
+ */
+/* We reject coordinates not less than 1<<30 so that the distance between */
+/* any 2 of them is less than 1<<31 which would overflow into the sign */
+/* bit of a signed long value used to represent fixed point coordinates. */
+#define TX_FIXED_UNSAFE(v) (fabs(v) >= (1<<30))
+static jboolean
+checkOverflow(jint dxoff, jint dyoff,
+ SurfaceDataBounds *pBounds,
+ TransformInfo *pItxInfo,
+ jdouble *retx, jdouble *rety)
+{
+ jdouble x, y;
+
+ x = dxoff+pBounds->x1+0.5; /* Center of pixel x1 */
+ y = dyoff+pBounds->y1+0.5; /* Center of pixel y1 */
+ Transform_transform(pItxInfo, &x, &y);
+ *retx = x;
+ *rety = y;
+ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) {
+ return JNI_TRUE;
+ }
+
+ x = dxoff+pBounds->x2-0.5; /* Center of pixel x2-1 */
+ y = dyoff+pBounds->y1+0.5; /* Center of pixel y1 */
+ Transform_transform(pItxInfo, &x, &y);
+ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) {
+ return JNI_TRUE;
+ }
+
+ x = dxoff+pBounds->x1+0.5; /* Center of pixel x1 */
+ y = dyoff+pBounds->y2-0.5; /* Center of pixel y2-1 */
+ Transform_transform(pItxInfo, &x, &y);
+ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) {
+ return JNI_TRUE;
+ }
+
+ x = dxoff+pBounds->x2-0.5; /* Center of pixel x2-1 */
+ y = dyoff+pBounds->y2-0.5; /* Center of pixel y2-1 */
+ Transform_transform(pItxInfo, &x, &y);
+ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) {
+ return JNI_TRUE;
+ }
+
+ return JNI_FALSE;
+}
+
+/*
* Fill the edge buffer with pairs of coordinates representing the maximum
* left and right pixels of the destination surface that should be processed
* on each scanline, clipped to the bounds parameter.
@@ -82,21 +170,19 @@
* Only pixels that map back through the specified (inverse) transform to a
* source coordinate that falls within the (0, 0, sw, sh) bounds of the
* source image should be processed.
- * pEdgeBuf points to an array of jints that holds MAXEDGES*2 values.
- * If more storage is needed, then this function allocates a new buffer.
- * In either case, a pointer to the buffer actually used to store the
- * results is returned.
- * The caller is responsible for freeing the buffer if the return value
- * is not the same as the original pEdgeBuf passed in.
+ * pEdges points to an array of jints that holds 2 + numedges*2 values where
+ * numedges should match (pBounds->y2 - pBounds->y1).
+ * The first two jints in pEdges should be set to y1 and y2 and every pair
+ * of jints after that represent the xmin,xmax of all pixels in range of
+ * the transformed blit for the corresponding scanline.
*/
-static jint *
-calculateEdges(jint *pEdgeBuf,
+static void
+calculateEdges(jint *pEdges,
SurfaceDataBounds *pBounds,
TransformInfo *pItxInfo,
jlong xbase, jlong ybase,
juint sw, juint sh)
{
- jint *pEdges;
jlong dxdxlong, dydxlong;
jlong dxdylong, dydylong;
jlong drowxlong, drowylong;
@@ -111,10 +197,8 @@
dy1 = pBounds->y1;
dx2 = pBounds->x2;
dy2 = pBounds->y2;
- if ((dy2-dy1) > MAXEDGES) {
- pEdgeBuf = malloc(2 * (dy2-dy1) * sizeof (*pEdges));
- }
- pEdges = pEdgeBuf;
+ *pEdges++ = dy1;
+ *pEdges++ = dy2;
drowxlong = (dx2-dx1-1) * dxdxlong;
drowylong = (dx2-dx1-1) * dydxlong;
@@ -155,9 +239,21 @@
ybase += dydylong;
dy1++;
}
+}
- return pEdgeBuf;
-}
+static void
+Transform_SafeHelper(JNIEnv *env,
+ SurfaceDataOps *srcOps,
+ SurfaceDataOps *dstOps,
+ SurfaceDataRasInfo *pSrcInfo,
+ SurfaceDataRasInfo *pDstInfo,
+ NativePrimitive *pMaskBlitPrim,
+ CompositeInfo *pCompInfo,
+ TransformHelperFunc *pHelperFunc,
+ TransformInterpFunc *pInterpFunc,
+ RegionData *pClipInfo, TransformInfo *pItxInfo,
+ jint *pData, jint *pEdges,
+ jint dxoff, jint dyoff, jint sw, jint sh);
/*
* Class: sun_java2d_loops_TransformHelper
@@ -187,12 +283,14 @@
jint maxlinepix;
TransformHelperFunc *pHelperFunc;
TransformInterpFunc *pInterpFunc;
- jint edgebuf[MAXEDGES * 2];
+ jdouble xorig, yorig;
+ jint numedges;
jint *pEdges;
- jdouble x, y;
- jlong xbase, ybase;
- jlong dxdxlong, dydxlong;
- jlong dxdylong, dydylong;
+ jint edgebuf[2 + MAXEDGES * 2];
+ union {
+ jlong align;
+ jint data[LINE_SIZE];
+ } rgb;
#ifdef MAKE_STUBS
static int th_initialized;
@@ -269,39 +367,62 @@
if (srcOps->Lock(env, srcOps, &srcInfo, pHelperPrim->srcflags)
!= SD_SUCCESS)
{
+ /* edgeArray should already contain zeros for min/maxy */
return;
}
if (dstOps->Lock(env, dstOps, &dstInfo, pMaskBlitPrim->dstflags)
!= SD_SUCCESS)
{
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+ /* edgeArray should already contain zeros for min/maxy */
return;
}
Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
+ numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1);
+ if (numedges > MAXEDGES) {
+ pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges));
+ if (pEdges == NULL) {
+ SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
+ SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+ /* edgeArray should already contain zeros for min/maxy */
+ return;
+ }
+ } else {
+ pEdges = edgebuf;
+ }
+
Transform_GetInfo(env, itxform, &itxInfo);
- dxdxlong = DblToLong(itxInfo.dxdx);
- dydxlong = DblToLong(itxInfo.dydx);
- dxdylong = DblToLong(itxInfo.dxdy);
- dydylong = DblToLong(itxInfo.dydy);
- x = dxoff+dstInfo.bounds.x1+0.5; /* Center of pixel x1 */
- y = dyoff+dstInfo.bounds.y1+0.5; /* Center of pixel y1 */
- Transform_transform(&itxInfo, &x, &y);
- xbase = DblToLong(x);
- ybase = DblToLong(y);
-
- pEdges = calculateEdges(edgebuf, &dstInfo.bounds, &itxInfo,
- xbase, ybase, sx2-sx1, sy2-sy1);
if (!Region_IsEmpty(&clipInfo)) {
srcOps->GetRasInfo(env, srcOps, &srcInfo);
dstOps->GetRasInfo(env, dstOps, &dstInfo);
- if (srcInfo.rasBase && dstInfo.rasBase) {
- union {
- jlong align;
- jint data[LINE_SIZE];
- } rgb;
+ if (srcInfo.rasBase == NULL || dstInfo.rasBase == NULL) {
+ pEdges[0] = pEdges[1] = 0;
+ } else if (checkOverflow(dxoff, dyoff, &dstInfo.bounds,
+ &itxInfo, &xorig, &yorig))
+ {
+ Transform_SafeHelper(env, srcOps, dstOps,
+ &srcInfo, &dstInfo,
+ pMaskBlitPrim, &compInfo,
+ pHelperFunc, pInterpFunc,
+ &clipInfo, &itxInfo, rgb.data, pEdges,
+ dxoff, dyoff, sx2-sx1, sy2-sy1);
+ } else {
SurfaceDataBounds span;
+ jlong dxdxlong, dydxlong;
+ jlong dxdylong, dydylong;
+ jlong xbase, ybase;
+
+ dxdxlong = DblToLong(itxInfo.dxdx);
+ dydxlong = DblToLong(itxInfo.dydx);
+ dxdylong = DblToLong(itxInfo.dxdy);
+ dydylong = DblToLong(itxInfo.dydy);
+ xbase = DblToLong(xorig);
+ ybase = DblToLong(yorig);
+
+ calculateEdges(pEdges, &dstInfo.bounds, &itxInfo,
+ xbase, ybase, sx2-sx1, sy2-sy1);
Region_StartIteration(env, &clipInfo);
while (Region_NextIteration(&clipInfo, &span)) {
@@ -318,8 +439,8 @@
/* Note - process at most one scanline at a time. */
- dx1 = pEdges[(dy1 - dstInfo.bounds.y1) * 2];
- dx2 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 1];
+ dx1 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 2];
+ dx2 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 3];
if (dx1 < span.x1) dx1 = span.x1;
if (dx2 > span.x2) dx2 = span.x2;
@@ -376,21 +497,124 @@
}
SurfaceData_InvokeRelease(env, dstOps, &dstInfo);
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
+ } else {
+ pEdges[0] = pEdges[1] = 0;
}
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
if (!JNU_IsNull(env, edgeArray)) {
- (*env)->SetIntArrayRegion(env, edgeArray, 0, 1, &dstInfo.bounds.y1);
- (*env)->SetIntArrayRegion(env, edgeArray, 1, 1, &dstInfo.bounds.y2);
- (*env)->SetIntArrayRegion(env, edgeArray,
- 2, (dstInfo.bounds.y2 - dstInfo.bounds.y1)*2,
- pEdges);
+ (*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges);
}
if (pEdges != edgebuf) {
free(pEdges);
}
}
+static void
+Transform_SafeHelper(JNIEnv *env,
+ SurfaceDataOps *srcOps,
+ SurfaceDataOps *dstOps,
+ SurfaceDataRasInfo *pSrcInfo,
+ SurfaceDataRasInfo *pDstInfo,
+ NativePrimitive *pMaskBlitPrim,
+ CompositeInfo *pCompInfo,
+ TransformHelperFunc *pHelperFunc,
+ TransformInterpFunc *pInterpFunc,
+ RegionData *pClipInfo, TransformInfo *pItxInfo,
+ jint *pData, jint *pEdges,
+ jint dxoff, jint dyoff, jint sw, jint sh)
+{
+ SurfaceDataBounds span;
+ jint dx1, dx2;
+ jint dy1, dy2;
+ jint i, iy;
+
+ dy1 = pDstInfo->bounds.y1;
+ dy2 = pDstInfo->bounds.y2;
+ dx1 = pDstInfo->bounds.x1;
+ dx2 = pDstInfo->bounds.x2;
+ pEdges[0] = dy1;
+ pEdges[1] = dy2;
+ for (iy = dy1; iy < dy2; iy++) {
+ jint i = (iy - dy1) * 2;
+ /* row spans are set to max,min until we find a pixel in range below */
+ pEdges[i + 2] = dx2;
+ pEdges[i + 3] = dx1;
+ }
+
+ Region_StartIteration(env, pClipInfo);
+ while (Region_NextIteration(pClipInfo, &span)) {
+ dy1 = span.y1;
+ dy2 = span.y2;
+ while (dy1 < dy2) {
+ dx1 = span.x1;
+ dx2 = span.x2;
+ i = (dy1 - pDstInfo->bounds.y1) * 2;
+ while (dx1 < dx2) {
+ jdouble x, y;
+ jlong xlong, ylong;
+
+ x = dxoff + dx1 + 0.5;
+ y = dyoff + dy1 + 0.5;
+ Transform_transform(pItxInfo, &x, &y);
+ xlong = DblToLong(x);
+ ylong = DblToLong(y);
+
+ /* Process only pixels with centers in bounds
+ * Test double values to avoid overflow in conversion
+ * to long values and then also test the long values
+ * in case they rounded up and out of bounds during
+ * the conversion.
+ */
+ if (x >= 0 && y >= 0 && x < sw && y < sh &&
+ WholeOfLong(xlong) < sw &&
+ WholeOfLong(ylong) < sh)
+ {
+ void *pDst;
+
+ if (pEdges[i + 2] > dx1) {
+ pEdges[i + 2] = dx1;
+ }
+ if (pEdges[i + 3] <= dx1) {
+ pEdges[i + 3] = dx1 + 1;
+ }
+
+ /* Get IntArgbPre pixel data from source */
+ (*pHelperFunc)(pSrcInfo,
+ pData, 1,
+ xlong, 0,
+ ylong, 0);
+
+ /* Interpolate result pixels if needed */
+ if (pInterpFunc) {
+ (*pInterpFunc)(pData, 1,
+ FractOfLong(xlong-LongOneHalf), 0,
+ FractOfLong(ylong-LongOneHalf), 0);
+ }
+
+ /* Store/Composite interpolated pixels into dest */
+ pDst = PtrCoord(pDstInfo->rasBase,
+ dx1, pDstInfo->pixelStride,
+ dy1, pDstInfo->scanStride);
+ (*pMaskBlitPrim->funcs.maskblit)(pDst, pData,
+ 0, 0, 0,
+ 1, 1,
+ pDstInfo, pSrcInfo,
+ pMaskBlitPrim,
+ pCompInfo);
+ }
+
+ /* Increment to next input pixel */
+ dx1++;
+ }
+
+ /* Increment to next scanline */
+ dy1++;
+ }
+ }
+ Region_EndIteration(env, pClipInfo);
+}
+
#define BL_INTERP_V1_to_V2_by_F(v1, v2, f) \
(((v1)<<8) + ((v2)-(v1))*(f))
--- a/jdk/src/share/native/sun/security/pkcs11/j2secmod.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/share/native/sun/security/pkcs11/j2secmod.c Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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 @@
}
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList
- (JNIEnv *env, jclass thisClass, jlong jHandle)
+ (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jLibDir)
{
FPTR_GetDBModuleList getModuleList =
(FPTR_GetDBModuleList)findFunction(env, jHandle, "SECMOD_GetDefaultModuleList");
@@ -104,8 +104,8 @@
jList = (*env)->NewObject(env, jListClass, jListConstructor);
jModuleClass = (*env)->FindClass(env, "sun/security/pkcs11/Secmod$Module");
- jModuleConstructor = (*env)->GetMethodID
- (env, jModuleClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;ZI)V");
+ jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
while (list != NULL) {
module = list->module;
@@ -124,7 +124,8 @@
}
jFIPS = module->isFIPS;
for (i = 0; i < module->slotCount; i++ ) {
- jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor, jDllName, jCommonName, jFIPS, i);
+ jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
+ jLibDir, jDllName, jCommonName, jFIPS, i);
(*env)->CallVoidMethod(env, jList, jAdd, jModule);
}
list = list->next;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/common/jdk_util_md.h Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Currently, there are no unix specific functions defined.
--- a/jdk/src/windows/classes/java/lang/ProcessEnvironment.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/java/lang/ProcessEnvironment.java Thu May 05 22:29:05 2011 -0700
@@ -143,7 +143,7 @@
public void remove() { i.remove();}
};
}
- private static Map.Entry<String,String> checkedEntry (Object o) {
+ private static Map.Entry<String,String> checkedEntry(Object o) {
Map.Entry<String,String> e = (Map.Entry<String,String>) o;
nonNullString(e.getKey());
nonNullString(e.getValue());
@@ -285,7 +285,7 @@
return (Map<String,String>) theEnvironment.clone();
}
- // Only for use by Runtime.exec(...String[]envp...)
+ // Only for use by ProcessBuilder.environment(String[] envp)
static Map<String,String> emptyEnvironment(int capacity) {
return new ProcessEnvironment(capacity);
}
@@ -299,19 +299,46 @@
Collections.sort(list, entryComparator);
StringBuilder sb = new StringBuilder(size()*30);
- for (Map.Entry<String,String> e : list)
- sb.append(e.getKey())
- .append('=')
- .append(e.getValue())
- .append('\u0000');
- // Ensure double NUL termination,
- // even if environment is empty.
- if (sb.length() == 0)
+ int cmp = -1;
+
+ // Some versions of MSVCRT.DLL require SystemRoot to be set.
+ // So, we make sure that it is always set, even if not provided
+ // by the caller.
+ final String SYSTEMROOT = "SystemRoot";
+
+ for (Map.Entry<String,String> e : list) {
+ String key = e.getKey();
+ String value = e.getValue();
+ if (cmp < 0 && (cmp = nameComparator.compare(key, SYSTEMROOT)) > 0) {
+ // Not set, so add it here
+ addToEnvIfSet(sb, SYSTEMROOT);
+ }
+ addToEnv(sb, key, value);
+ }
+ if (cmp < 0) {
+ // Got to end of list and still not found
+ addToEnvIfSet(sb, SYSTEMROOT);
+ }
+ if (sb.length() == 0) {
+ // Environment was empty and SystemRoot not set in parent
sb.append('\u0000');
+ }
+ // Block is double NUL terminated
sb.append('\u0000');
return sb.toString();
}
+ // add the environment variable to the child, if it exists in parent
+ private static void addToEnvIfSet(StringBuilder sb, String name) {
+ String s = getenv(name);
+ if (s != null)
+ addToEnv(sb, name, s);
+ }
+
+ private static void addToEnv(StringBuilder sb, String name, String val) {
+ sb.append(name).append('=').append(val).append('\u0000');
+ }
+
static String toEnvironmentBlock(Map<String,String> map) {
return map == null ? null :
((ProcessEnvironment)map).toEnvironmentBlock();
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -30,12 +30,15 @@
package sun.security.krb5.internal.tools;
+import java.io.File;
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.*;
import java.io.IOException;
import java.util.Arrays;
+import javax.security.auth.kerberos.KerberosPrincipal;
import sun.security.util.Password;
+import javax.security.auth.kerberos.KeyTab;
/**
* Kinit tool for obtaining Kerberos v5 tickets.
@@ -153,7 +156,6 @@
System.out.println("Principal is " + principal);
}
char[] psswd = options.password;
- EncryptionKey[] skeys = null;
boolean useKeytab = options.useKeytabFile();
if (!useKeytab) {
if (princName == null) {
@@ -186,17 +188,9 @@
}
}
- // assert princName and principal are nonnull
- skeys = EncryptionKey.acquireSecretKeys(principal, ktabName);
-
- if (skeys == null || skeys.length == 0) {
- String msg = "No supported key found in keytab";
- if (princName != null) {
- msg += " for principal " + princName;
- }
- throw new KrbException(msg);
- }
- builder = new KrbAsReqBuilder(principal, skeys);
+ builder = new KrbAsReqBuilder(principal, ktabName == null
+ ? KeyTab.getInstance()
+ : KeyTab.getInstance(new File(ktabName)));
}
KDCOptions opt = new KDCOptions();
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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
@@ -95,16 +95,15 @@
}
break;
case 'k':
- if (klist.name == null) {
- klist.target = KeyTab.getInstance();
- klist.name = KeyTab.tabName();
- } else klist.target = KeyTab.getInstance(klist.name);
- if (klist.target != null) {
- klist.displayTab();
- } else {
+ try {
+ KeyTab ktab = KeyTab.getInstance(klist.name);
+ klist.target = ktab;
+ klist.name = ktab.tabName();
+ } catch (Exception e) {
klist.displayMessage("KeyTab");
System.exit(-1);
}
+ klist.displayTab();
break;
default:
if (klist.name != null) {
@@ -295,9 +294,10 @@
void displayMessage(String target) {
if (name == null) {
- name = "";
+ System.out.println("Default " + target + " not found.");
+ } else {
+ System.out.println(target + " " + name + " not found.");
}
- System.out.println(target + " " + name + " not found.");
}
/**
* Reformats the date from the form -
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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
@@ -321,7 +321,7 @@
* Lists key table name and entries in it.
*/
void listKt() {
- System.out.println("Keytab name: " + KeyTab.tabName());
+ System.out.println("Keytab name: " + table.tabName());
KeyTabEntry[] entries = table.getEntries();
if ((entries != null) && (entries.length > 0)) {
String[][] output = new String[entries.length+1][showTime?3:2];
--- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
@@ -25,6 +25,7 @@
package sun.security.mscapi;
+import java.math.BigInteger;
import java.security.*;
import java.security.Key;
import java.security.interfaces.*;
@@ -33,6 +34,8 @@
import javax.crypto.*;
import javax.crypto.spec.*;
+import sun.security.rsa.RSAKeyFactory;
+
/**
* RSA cipher implementation using the Microsoft Crypto API.
* Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
@@ -189,8 +192,38 @@
default:
throw new InvalidKeyException("Unknown mode: " + opmode);
}
+
if (!(key instanceof sun.security.mscapi.Key)) {
- throw new InvalidKeyException("Unsupported key type: " + key);
+ if (key instanceof java.security.interfaces.RSAPublicKey) {
+ java.security.interfaces.RSAPublicKey rsaKey =
+ (java.security.interfaces.RSAPublicKey) key;
+
+ // Convert key to MSCAPI format
+
+ BigInteger modulus = rsaKey.getModulus();
+ BigInteger exponent = rsaKey.getPublicExponent();
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to the nearest byte.
+ RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
+ exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
+
+ byte[] modulusBytes = modulus.toByteArray();
+ byte[] exponentBytes = exponent.toByteArray();
+
+ // Adjust key length due to sign bit
+ int keyBitLength = (modulusBytes[0] == 0)
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
+
+ byte[] keyBlob = RSASignature.generatePublicKeyBlob(
+ keyBitLength, modulusBytes, exponentBytes);
+
+ key = RSASignature.importPublicKey(keyBlob, keyBitLength);
+
+ } else {
+ throw new InvalidKeyException("Unsupported key type: " + key);
+ }
}
if (key instanceof PublicKey) {
@@ -358,6 +391,10 @@
if (key instanceof sun.security.mscapi.Key) {
return ((sun.security.mscapi.Key) key).bitLength();
+
+ } else if (key instanceof RSAKey) {
+ return ((RSAKey) key).getModulus().bitLength();
+
} else {
throw new InvalidKeyException("Unsupported key type: " + key);
}
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
@@ -91,7 +91,7 @@
if (exponent == null) {
publicKeyBlob = getPublicKeyBlob(hCryptKey);
- exponent = new BigInteger(getExponent(publicKeyBlob));
+ exponent = new BigInteger(1, getExponent(publicKeyBlob));
}
return exponent;
@@ -104,7 +104,7 @@
if (modulus == null) {
publicKeyBlob = getPublicKeyBlob(hCryptKey);
- modulus = new BigInteger(getModulus(publicKeyBlob));
+ modulus = new BigInteger(1, getModulus(publicKeyBlob));
}
return modulus;
--- a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Thu May 05 22:29:05 2011 -0700
@@ -379,11 +379,13 @@
/**
* Generates a public-key BLOB from a key's components.
*/
- private native byte[] generatePublicKeyBlob(
+ // used by RSACipher
+ static native byte[] generatePublicKeyBlob(
int keyBitLength, byte[] modulus, byte[] publicExponent);
/**
* Imports a public-key BLOB.
*/
- private native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize);
+ // used by RSACipher
+ static native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize);
}
--- a/jdk/src/windows/classes/sun/tools/attach/WindowsAttachProvider.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/classes/sun/tools/attach/WindowsAttachProvider.java Thu May 05 22:29:05 2011 -0700
@@ -126,16 +126,6 @@
* of the process list.
*/
private List<VirtualMachineDescriptor> listJavaProcesses() {
- // ensure that process status helper is loaded (psapi.dll)
- if (!isProcessStatusHelperInitialized) {
- synchronized (WindowsAttachProvider.class) {
- if (!isProcessStatusHelperInitialized) {
- initializeProcessStatusHelper();
- isProcessStatusHelperInitialized = true;
- }
- }
- }
-
ArrayList<VirtualMachineDescriptor> list =
new ArrayList<VirtualMachineDescriptor>();
@@ -172,12 +162,6 @@
return list;
}
- // indicates if psapi.dll has been initialized
- private static volatile boolean isProcessStatusHelperInitialized;
-
- // loads psapi
- private static native void initializeProcessStatusHelper();
-
// enumerates processes using psapi's EnumProcesses
private static native int enumProcesses(int[] processes, int max);
--- a/jdk/src/windows/native/common/jdk_util_md.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/common/jdk_util_md.c Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. 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
@@ -38,3 +38,25 @@
void* JDK_FindJvmEntry(const char* name) {
return (void*) GetProcAddress(jvm_handle, name);
}
+
+JNIEXPORT HMODULE JDK_LoadSystemLibrary(const char* name) {
+ HMODULE handle = NULL;
+ char path[MAX_PATH];
+ int ret;
+
+ if (GetSystemDirectory(path, sizeof(path)) != 0) {
+ strcat(path, "\\");
+ strcat(path, name);
+ handle = LoadLibrary(path);
+ }
+
+ if (handle == NULL) {
+ if (GetWindowsDirectory(path, sizeof(path)) != 0) {
+ strcat(path, "\\");
+ strcat(path, name);
+ handle = LoadLibrary(path);
+ }
+ }
+ return handle;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/native/common/jdk_util_md.h Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+#ifndef JDK_UTIL_MD_H
+#define JDK_UTIL_MD_H
+
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT HMODULE JDK_LoadSystemLibrary(const char* name);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* JDK_UTIL_MD_H */
--- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp Thu May 05 22:29:05 2011 -0700
@@ -117,7 +117,7 @@
{
typedef IDirect3D9 * WINAPI FnDirect3DCreate9(UINT SDKVersion);
- hLibD3D9 = ::LoadLibrary(TEXT("d3d9.dll"));
+ hLibD3D9 = JDK_LoadSystemLibrary("d3d9.dll");
if (hLibD3D9 == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no d3d9.dll");
return E_FAIL;
--- a/jdk/src/windows/native/sun/java2d/opengl/OGLFuncs_md.h Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/java2d/opengl/OGLFuncs_md.h Thu May 05 22:29:05 2011 -0700
@@ -29,6 +29,7 @@
#include <windows.h>
#include "J2D_GL/wglext.h"
#include "OGLFuncMacros.h"
+#include <jdk_util.h>
/**
* Core WGL functions
@@ -60,7 +61,7 @@
#define OGL_LIB_IS_UNINITIALIZED() \
(OGL_LIB_HANDLE == 0)
#define OGL_OPEN_LIB() \
- OGL_LIB_HANDLE = LoadLibrary(L"opengl32.dll")
+ OGL_LIB_HANDLE = JDK_LoadSystemLibrary("opengl32.dll")
#define OGL_CLOSE_LIB() \
FreeLibrary(OGL_LIB_HANDLE)
#define OGL_GET_PROC_ADDRESS(f) \
--- a/jdk/src/windows/native/sun/tools/attach/WindowsAttachProvider.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/tools/attach/WindowsAttachProvider.c Thu May 05 22:29:05 2011 -0700
@@ -25,6 +25,7 @@
#include <windows.h>
#include <stdlib.h>
#include <string.h>
+#include <Psapi.h>
#include "jni.h"
#include "jni_util.h"
@@ -97,41 +98,6 @@
/*
- * Process status helper library functions
- */
-static BOOL (WINAPI *_EnumProcesses) (DWORD *, DWORD, DWORD *);
-static BOOL (WINAPI *_EnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD);
-static DWORD (WINAPI *_GetModuleBaseName) (HANDLE, HMODULE, LPTSTR, DWORD);
-
-
-/*
- * Class: sun_tools_attach_WindowsAttachProvider
- * Method: initializeProcessStatusHelper
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_tools_attach_WindowsAttachProvider_initializeProcessStatusHelper(JNIEnv *env, jclass cls)
-{
- HINSTANCE psapi = LoadLibrary("PSAPI.DLL") ;
- if (psapi != NULL) {
- _EnumProcesses = (BOOL(WINAPI *)(DWORD *, DWORD, DWORD *))
- GetProcAddress(psapi, "EnumProcesses") ;
- _EnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD))
- GetProcAddress(psapi, "EnumProcessModules");
- _GetModuleBaseName = (DWORD(WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD))
- GetProcAddress(psapi, "GetModuleBaseNameA");
- }
-
- if ((_EnumProcesses == NULL) ||
- (_EnumProcessModules == NULL) ||
- (_GetModuleBaseName == NULL))
- {
- JNU_ThrowInternalError(env, "Unable to initialize process status helper library");
- }
-}
-
-
-/*
* Class: sun_tools_attach_WindowsAttachProvider
* Method: enumProcesses
* Signature: ([JI)I
@@ -147,7 +113,7 @@
size = max * sizeof(DWORD);
ptr = (DWORD*)malloc(size);
if (ptr != NULL) {
- BOOL res = (*_EnumProcesses)(ptr, size, &bytesReturned);
+ BOOL res = EnumProcesses(ptr, size, &bytesReturned);
if (res != 0) {
result = (jint)(bytesReturned / sizeof(DWORD));
(*env)->SetIntArrayRegion(env, arr, 0, (jsize)result, (jint*)ptr);
@@ -192,13 +158,13 @@
size = 1024 * sizeof(HMODULE);
ptr = (HMODULE*)malloc(size);
if (ptr != NULL) {
- BOOL res = (*_EnumProcessModules)(hProcess, ptr, size, &bytesReturned);
+ BOOL res = EnumProcessModules(hProcess, ptr, size, &bytesReturned);
if (res != 0) {
int count = bytesReturned / sizeof(HMODULE);
int i = 0;
while (i < count) {
char base[256];
- BOOL res = (*_GetModuleBaseName)(hProcess, ptr[i], base, sizeof(base));
+ BOOL res = GetModuleBaseName(hProcess, ptr[i], base, sizeof(base));
if (res != 0) {
if (strcmp(base, lib) == 0) {
result = JNI_TRUE;
--- a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Thu May 05 22:29:05 2011 -0700
@@ -32,13 +32,13 @@
/* kernel32 */
-typedef HINSTANCE (WINAPI* LoadLibraryFunc) (LPCTSTR);
+typedef HINSTANCE (WINAPI* GetModuleHandleFunc) (LPCTSTR);
typedef FARPROC (WINAPI* GetProcAddressFunc)(HMODULE, LPCSTR);
/* only on Windows 64-bit or 32-bit application running under WOW64 */
typedef BOOL (WINAPI *IsWow64ProcessFunc) (HANDLE, PBOOL);
-static LoadLibraryFunc _LoadLibrary;
+static GetModuleHandleFunc _GetModuleHandle;
static GetProcAddressFunc _GetProcAddress;
static IsWow64ProcessFunc _IsWow64Process;
@@ -70,7 +70,7 @@
#define MAX_PIPE_NAME_LENGTH 256
typedef struct {
- LoadLibraryFunc _LoadLibrary;
+ GetModuleHandleFunc _GetModuleHandle;
GetProcAddressFunc _GetProcAddress;
char jvmLib[MAX_LIBNAME_LENGTH]; /* "jvm.dll" */
char func1[MAX_FUNC_LENGTH];
@@ -96,7 +96,7 @@
HINSTANCE h;
EnqueueOperationFunc addr;
- h = pData->_LoadLibrary(pData->jvmLib);
+ h = pData->_GetModuleHandle(pData->jvmLib);
if (h == NULL) {
return ERR_OPEN_JVM_FAIL;
}
@@ -131,15 +131,10 @@
JNIEXPORT void JNICALL Java_sun_tools_attach_WindowsVirtualMachine_init
(JNIEnv *env, jclass cls)
{
- HINSTANCE h = LoadLibrary("kernel32");
- if (h != NULL) {
- _LoadLibrary = (LoadLibraryFunc) GetProcAddress(h, "LoadLibraryA");
- _GetProcAddress = (GetProcAddressFunc)GetProcAddress(h, "GetProcAddress");
- _IsWow64Process = (IsWow64ProcessFunc)GetProcAddress(h, "IsWow64Process");
- }
- if (_LoadLibrary == NULL || _GetProcAddress == NULL) {
- JNU_ThrowInternalError(env, "Unable to get address of LoadLibraryA or GetProcAddress");
- }
+ // All following APIs exist on Windows XP with SP2/Windows Server 2008
+ _GetModuleHandle = (GetModuleHandleFunc)GetModuleHandle;
+ _GetProcAddress = (GetProcAddressFunc)GetProcAddress;
+ _IsWow64Process = (IsWow64ProcessFunc)IsWow64Process;
}
@@ -375,7 +370,7 @@
/*
* Setup data to copy to target process
*/
- data._LoadLibrary = _LoadLibrary;
+ data._GetModuleHandle = _GetModuleHandle;
data._GetProcAddress = _GetProcAddress;
strcpy(data.jvmLib, "jvm");
--- a/jdk/src/windows/native/sun/tracing/dtrace/jvm_symbols_md.c Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/tracing/dtrace/jvm_symbols_md.c Thu May 05 22:29:05 2011 -0700
@@ -35,7 +35,7 @@
JvmSymbols* lookupJvmSymbols() {
JvmSymbols* syms = (JvmSymbols*)malloc(sizeof(JvmSymbols));
if (syms != NULL) {
- HINSTANCE jvm = LoadLibrary("jvm.dll");
+ HINSTANCE jvm = GetModuleHandle("jvm.dll");
if (jvm == NULL) {
free(syms);
return NULL;
--- a/jdk/src/windows/native/sun/windows/DllUtil.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/DllUtil.cpp Thu May 05 22:29:05 2011 -0700
@@ -25,6 +25,7 @@
#include "DllUtil.h"
+#include <jdk_util.h>
// Disable warning about using this in the initializer list.
#pragma warning( disable : 4355)
@@ -40,7 +41,7 @@
HMODULE DllUtil::GetModule()
{
if (!module) {
- module = ::LoadLibrary(name);
+ module = JDK_LoadSystemLibrary(name);
}
return module;
}
@@ -60,7 +61,7 @@
}
DwmAPI::DwmAPI() :
- DllUtil(_T("DWMAPI.DLL")),
+ DllUtil("DWMAPI.DLL"),
DwmIsCompositionEnabledFunction((DllUtil*)this, "DwmIsCompositionEnabled"),
DwmGetWindowAttributeFunction((DllUtil*)this, "DwmGetWindowAttribute")
{
--- a/jdk/src/windows/native/sun/windows/DllUtil.h Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/DllUtil.h Thu May 05 22:29:05 2011 -0700
@@ -43,7 +43,7 @@
FARPROC GetProcAddress(LPCSTR name);
protected:
- DllUtil(const TCHAR * name) : name(name), module(NULL) {}
+ DllUtil(const char * name) : name(name), module(NULL) {}
virtual ~DllUtil();
HMODULE GetModule();
@@ -68,7 +68,7 @@
};
private:
- const TCHAR * const name;
+ const char * const name;
HMODULE module;
};
--- a/jdk/src/windows/native/sun/windows/ShellFolder2.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/ShellFolder2.cpp Thu May 05 22:29:05 2011 -0700
@@ -120,15 +120,15 @@
return TRUE;
}
// Load libraries
- libShell32 = LoadLibrary(TEXT("shell32.dll"));
+ libShell32 = JDK_LoadSystemLibrary("shell32.dll");
if (libShell32 == NULL) {
return FALSE;
}
- libUser32 = LoadLibrary(TEXT("user32.dll"));
+ libUser32 = JDK_LoadSystemLibrary("user32.dll");
if (libUser32 == NULL) {
return FALSE;
}
- libComCtl32 = LoadLibrary(TEXT("comctl32.dll"));
+ libComCtl32 = JDK_LoadSystemLibrary("comctl32.dll");
if (libComCtl32 == NULL) {
return FALSE;
}
@@ -1021,7 +1021,8 @@
(JNIEnv* env, jclass cls, jstring libName, jint iconID,
jint cxDesired, jint cyDesired, jboolean useVGAColors)
{
- HINSTANCE libHandle = LoadLibrary(JNU_GetStringPlatformChars(env, libName, NULL));
+ const char *pLibName = env->GetStringUTFChars(libName, NULL);
+ HINSTANCE libHandle = (HINSTANCE)JDK_LoadSystemLibrary(pLibName);
if (libHandle != NULL) {
UINT fuLoad = (useVGAColors && !IS_WINXP) ? LR_VGACOLOR : 0;
return ptr_to_jlong(LoadImage(libHandle, MAKEINTRESOURCE(iconID),
--- a/jdk/src/windows/native/sun/windows/ThemeReader.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/ThemeReader.cpp Thu May 05 22:29:05 2011 -0700
@@ -150,7 +150,7 @@
BOOL InitThemes() {
static HMODULE hModThemes = NULL;
- hModThemes = LoadLibrary(TEXT("UXTHEME.DLL"));
+ hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
if(hModThemes) {
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
--- a/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp Thu May 05 22:29:05 2011 -0700
@@ -284,7 +284,7 @@
file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID);
if (file != NULL) {
LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL);
- _tcscpy(fileBuffer, tmp);
+ _tcsncpy(fileBuffer, tmp, bufferLimit - 2); // the fileBuffer is double null terminated string
JNU_ReleaseStringPlatformChars(env, file, tmp);
} else {
fileBuffer[0] = _T('\0');
--- a/jdk/src/windows/native/sun/windows/awt_Mlib.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Mlib.cpp Thu May 05 22:29:05 2011 -0700
@@ -43,12 +43,13 @@
mlibSysFnS_t tempSysFns;
mlib_status ret = MLIB_SUCCESS;
- /* Try to load library. Routine should find the library successfully
- * because this library is already loaded to the process space by
- * the System.loadLibrary() call. Here we just need to get handle to
- * initialize the pointers to required mlib routines.
+ /* Try to receive handle for the library. Routine should find
+ * the library successfully because this library is already
+ * loaded to the process space by the System.loadLibrary() call.
+ * Here we just need to get handle to initialize the pointers to
+ * required mlib routines.
*/
- hDLL = ::LoadLibrary(TEXT("mlib_image.dll"));
+ hDLL = ::GetModuleHandle(TEXT("mlib_image.dll"));
if (hDLL == NULL) {
return MLIB_FAILURE;
@@ -94,9 +95,6 @@
i++;
}
- if (ret != MLIB_SUCCESS) {
- ::FreeLibrary(hDLL);
- }
return ret;
}
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.cpp Thu May 05 22:29:05 2011 -0700
@@ -77,7 +77,7 @@
LPCTSTR AwtTextArea::GetClassName() {
static BOOL richedLibraryLoaded = FALSE;
if (!richedLibraryLoaded) {
- ::LoadLibrary(TEXT("RICHED20.DLL"));
+ JDK_LoadSystemLibrary("RICHED20.DLL");
richedLibraryLoaded = TRUE;
}
return RICHEDIT_CLASS;
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu May 05 22:29:05 2011 -0700
@@ -185,7 +185,7 @@
int shellVersion = 5; // WIN_2000
// MSDN: DllGetVersion should not be implicitly called, but rather
// loaded using GetProcAddress
- HMODULE hShell = LoadLibrary(TEXT("Shell32.dll"));
+ HMODULE hShell = JDK_LoadSystemLibrary("Shell32.dll");
if (hShell != NULL) {
DLLGETVERSIONPROC proc = (DLLGETVERSIONPROC)GetProcAddress(hShell, "DllGetVersion");
if (proc != NULL) {
--- a/jdk/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp Thu May 05 22:29:05 2011 -0700
@@ -63,7 +63,7 @@
bAlreadySet = TRUE;
- HMODULE hLibUser32Dll = ::LoadLibrary(TEXT("user32.dll"));
+ HMODULE hLibUser32Dll = JDK_LoadSystemLibrary("user32.dll");
if (hLibUser32Dll != NULL) {
SetProcessDPIAwareFunc *lpSetProcessDPIAware =
--- a/jdk/src/windows/native/sun/windows/stdhdrs.h Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/stdhdrs.h Thu May 05 22:29:05 2011 -0700
@@ -47,6 +47,7 @@
// standard Java headers
#include <jni.h>
#include <jni_util.h>
+#include <jdk_util.h>
} // extern "C"
--- a/jdk/src/windows/npt/npt_md.h Thu May 05 14:02:17 2011 -0700
+++ b/jdk/src/windows/npt/npt_md.h Thu May 05 22:29:05 2011 -0700
@@ -47,7 +47,7 @@
_handle = NULL; \
*(pnpt) = NULL; \
buf[0] = 0; \
- jvm = LoadLibrary("jvm.dll"); \
+ jvm = GetModuleHandle("jvm.dll"); \
if ( jvm == NULL ) NPT_ERROR("Cannot find jvm.dll"); \
GetModuleFileName(jvm, buf, FILENAME_MAX); \
lastSlash = strrchr(buf, '\\'); \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/BufferedImage/TinyScale.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,68 @@
+/*
+ * @test %W% %E%
+ * @bug 7016495
+ * @summary Test tiny scales of BufferedImage
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+
+public class TinyScale {
+ static double tinyscales[] = {
+ 1E-0,
+ 1E-1,
+ 1E-2,
+ 1E-3,
+ 1E-4,
+ 1E-5,
+ 1E-6,
+ 1E-7,
+ 1E-8,
+ 1E-9,
+ 1E-10,
+ 1E-11,
+ 1E-12,
+ 1E-13,
+ 1E-14,
+ 1E-15,
+ 1E-16,
+ 1E-17,
+ 1E-18,
+ 1E-19,
+ 1E-20,
+ 1E-21,
+ 1E-22,
+ 1E-23,
+ 1E-24,
+ 1E-25,
+ 1E-26,
+ 1E-27,
+ 1E-28,
+ 1E-29,
+ };
+
+ static void test(BufferedImage rendImg, BufferedImage drawImg, double s) {
+ Graphics2D g = drawImg.createGraphics();
+ g.transform(new AffineTransform(s, 0.0, -1.0, 1.0, 0.0, 0.0));
+ g.drawImage(rendImg,
+ -rendImg.getWidth() / 2,
+ -rendImg.getHeight() / 2,
+ null);
+ g.drawImage(rendImg, 0, 0, null);
+ g.dispose();
+ }
+
+ public static void main(String[] args) {
+ BufferedImage rendImg =
+ new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
+ BufferedImage drawImg =
+ new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+ for (double s: tinyscales) {
+ test(rendImg, drawImg, s);
+ for (int i = 0; args.length > 0 && i < 10; i++) {
+ test(rendImg, drawImg, Math.random()*s);
+ }
+ }
+ }
+}
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Thu May 05 22:29:05 2011 -0700
@@ -26,7 +26,7 @@
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
- * 4947220 7018606
+ * 4947220 7018606 7034570
* @summary Basic tests for Process and Environment Variable code
* @run main/othervm/timeout=300 Basic
* @author Martin Buchholz
@@ -1440,11 +1440,12 @@
// Check for sort order of environment variables on Windows.
//----------------------------------------------------------------
try {
+ String systemRoot = "SystemRoot=" + System.getenv("SystemRoot");
// '+' < 'A' < 'Z' < '_' < 'a' < 'z' < '~'
String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=",
- "+=+", "_=_", "~=~"};
+ "+=+", "_=_", "~=~", systemRoot};
String output = nativeEnv(envp);
- String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n_=_\n~=~\n";
+ String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n";
// On Windows, Java must keep the environment sorted.
// Order is random on Unix, so this test does the sort.
if (! Windows.is())
@@ -1453,6 +1454,21 @@
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
+ // Test Runtime.exec(...envp...)
+ // and check SystemRoot gets set automatically on Windows
+ //----------------------------------------------------------------
+ try {
+ if (Windows.is()) {
+ String systemRoot = "SystemRoot=" + System.getenv("SystemRoot");
+ String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=",
+ "+=+", "_=_", "~=~"};
+ String output = nativeEnv(envp);
+ String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n";
+ equal(output, expected);
+ }
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
// System.getenv() must be consistent with System.getenv(String)
//----------------------------------------------------------------
try {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/SignedObject/Correctness.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6618658
+ * @summary Deserialization allows creation of mutable SignedObject
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Signature;
+import java.security.SignedObject;
+
+
+public class Correctness {
+
+ public static void main(String[] args) throws Exception {
+
+ String SIGALG = "SHA1withRSA";
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ KeyPair kp = kpg.generateKeyPair();
+
+ SignedObject so1 = new SignedObject("Hello", kp.getPrivate(),
+ Signature.getInstance(SIGALG));
+
+ ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(byteOut);
+ out.writeObject(so1);
+ out.close();
+
+ byte[] data = byteOut.toByteArray();
+
+ SignedObject so2 = (SignedObject)new ObjectInputStream(
+ new ByteArrayInputStream(data)).readObject();
+
+ if (!so2.getObject().equals("Hello")) {
+ throw new Exception("Content changed");
+ }
+ if (!so2.getAlgorithm().equals(SIGALG)) {
+ throw new Exception("Signature algorithm unknown");
+ }
+ if (!so2.verify(kp.getPublic(), Signature.getInstance(SIGALG))) {
+ throw new Exception("Not verified");
+ }
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/Context.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/sun/security/krb5/auto/Context.java Thu May 05 22:29:05 2011 -0700
@@ -44,6 +44,7 @@
import com.sun.security.jgss.AuthorizationDataEntry;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import javax.security.auth.kerberos.KeyTab;
/**
* Context of a JGSS subject, encapsulating Subject and GSSContext.
@@ -107,15 +108,19 @@
return out;
}
+ public static Context fromUserPass(
+ String user, char[] pass, boolean storeKey) throws Exception {
+ return fromUserPass(null, user, pass, storeKey);
+ }
/**
* Logins with a username and a password, using Krb5LoginModule directly
* @param storeKey true if key should be saved, used on acceptor side
*/
- public static Context fromUserPass(String user, char[] pass, boolean storeKey)
- throws Exception {
+ public static Context fromUserPass(Subject s,
+ String user, char[] pass, boolean storeKey) throws Exception {
Context out = new Context();
out.name = user;
- out.s = new Subject();
+ out.s = s == null ? new Subject() : s;
Krb5LoginModule krb5 = new Krb5LoginModule();
Map<String, String> map = new HashMap<>();
Map<String, Object> shared = new HashMap<>();
@@ -198,12 +203,25 @@
* @throws java.lang.Exception
*/
public void startAsServer(final Oid mech) throws Exception {
+ startAsServer(null, mech);
+ }
+
+ /**
+ * Starts as a server with the specified service name
+ * @param name the service name
+ * @param mech GSS mech
+ * @throws java.lang.Exception
+ */
+ public void startAsServer(final String name, final Oid mech) throws Exception {
doAs(new Action() {
@Override
public byte[] run(Context me, byte[] dummy) throws Exception {
GSSManager m = GSSManager.getInstance();
me.x = (ExtendedGSSContext)m.createContext(m.createCredential(
- null,
+ name == null ? null :
+ (name.indexOf('@') < 0 ?
+ m.createName(name, null) :
+ m.createName(name, GSSName.NT_HOSTBASED_SERVICE)),
GSSCredential.INDEFINITE_LIFETIME,
mech,
GSSCredential.ACCEPT_ONLY));
@@ -230,6 +248,14 @@
}
/**
+ * Accesses the internal subject.
+ * @return the subject
+ */
+ public Subject s() {
+ return s;
+ }
+
+ /**
* Disposes the GSSContext within
* @throws org.ietf.jgss.GSSException
*/
@@ -297,7 +323,7 @@
} catch (Exception e) {
;// Don't care
}
- System.out.println("=====================================");
+ System.out.println("====== Private Credentials Set ======");
for (Object o : s.getPrivateCredentials()) {
System.out.println(" " + o.getClass());
if (o instanceof KerberosTicket) {
@@ -315,6 +341,8 @@
for (Object k : map.keySet()) {
System.out.println(" " + k + ": " + map.get(k));
}
+ } else {
+ System.out.println(" " + o);
}
}
if (x != null && x instanceof ExtendedGSSContext) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/DynamicKeytab.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6894072
+ * @run main/othervm DynamicKeytab
+ * @summary always refresh keytab
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.KrbException;
+import sun.security.krb5.internal.Krb5;
+
+public class DynamicKeytab {
+
+ Context c, s;
+ public static void main(String[] args)
+ throws Exception {
+ new DynamicKeytab().go();
+ }
+
+ void go() throws Exception {
+ OneKDC k = new OneKDC(null);
+ k.writeJAASConf();
+
+ new File(OneKDC.KTAB).delete();
+
+
+ // Starts with no keytab
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("com.sun.security.jgss.krb5.accept");
+
+ // Test 1: read new key 1 from keytab
+ k.addPrincipal(OneKDC.SERVER, "pass1".toCharArray());
+ k.writeKtab(OneKDC.KTAB);
+ connect();
+
+ // Test 2: service key cached, find 1 in keytab (now contains 1 and 2)
+ k.addPrincipal(OneKDC.SERVER, "pass2".toCharArray());
+ k.appendKtab(OneKDC.KTAB);
+ connect();
+
+ // Test 3: re-login. Now find 2 in keytab
+ c = Context.fromJAAS("client");
+ connect();
+
+ // Test 4: re-login, KDC use 3 this time.
+ c = Context.fromJAAS("client");
+ // Put 3 and 4 into keytab but keep the real key back to 3.
+ k.addPrincipal(OneKDC.SERVER, "pass3".toCharArray());
+ k.appendKtab(OneKDC.KTAB);
+ k.addPrincipal(OneKDC.SERVER, "pass4".toCharArray());
+ k.appendKtab(OneKDC.KTAB);
+ k.addPrincipal(OneKDC.SERVER, "pass3".toCharArray());
+ connect();
+
+ // Test 5: invalid keytab file, should ignore
+ new FileOutputStream(OneKDC.KTAB).write("BADBADBAD".getBytes());
+ connect();
+
+ // Test 6: delete keytab file, identical to revoke all
+ new File(OneKDC.KTAB).delete();
+ try {
+ connect();
+ throw new Exception("Should not success");
+ } catch (GSSException gsse) {
+ System.out.println(gsse);
+ KrbException ke = (KrbException)gsse.getCause();
+ // KrbApReq.authenticate(*) if (dkey == null)...
+ // This should have been Krb5.KRB_AP_ERR_NOKEY
+ if (ke.returnCode() != Krb5.API_INVALID_ARG) {
+ throw new Exception("Not expected failure code: " +
+ ke.returnCode());
+ }
+ }
+
+ // Test 7: 3 revoked, should fail (now contains only 5)
+ k.addPrincipal(OneKDC.SERVER, "pass5".toCharArray());
+ k.writeKtab(OneKDC.KTAB); // overwrite keytab, which means
+ // old key is revoked
+ try {
+ connect();
+ throw new Exception("Should not success");
+ } catch (GSSException gsse) {
+ System.out.println(gsse);
+ KrbException ke = (KrbException)gsse.getCause();
+ if (ke.returnCode() != Krb5.KRB_AP_ERR_BADKEYVER) {
+ throw new Exception("Not expected failure code: " +
+ ke.returnCode());
+ }
+ }
+
+ // Test 8: an empty KDC means revoke all
+ KDC.create("EMPTY.REALM").writeKtab(OneKDC.KTAB);
+ try {
+ connect();
+ throw new Exception("Should not success");
+ } catch (GSSException gsse) {
+ System.out.println(gsse);
+ KrbException ke = (KrbException)gsse.getCause();
+ // KrbApReq.authenticate(*) if (dkey == null)...
+ // This should have been Krb5.KRB_AP_ERR_NOKEY
+ if (ke.returnCode() != Krb5.API_INVALID_ARG) {
+ throw new Exception("Not expected failure code: " +
+ ke.returnCode());
+ }
+ }
+ }
+
+ void connect() throws Exception {
+ Thread.sleep(2000); // make sure ktab timestamp is different
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c, s);
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/KDC.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/sun/security/krb5/auto/KDC.java Thu May 05 22:29:05 2011 -0700
@@ -228,7 +228,33 @@
}
/**
- * Write all principals' keys from multiple KDCsinto one keytab file.
+ * Writes or appends KDC keys into a keytab. See doc for writeMultiKtab.
+ * @param append true if append, otherwise, overwrite.
+ */
+ private static void writeKtab0(String tab, boolean append, KDC... kdcs)
+ throws IOException, KrbException {
+ KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
+ for (KDC kdc: kdcs) {
+ for (String name : kdc.passwords.keySet()) {
+ char[] pass = kdc.passwords.get(name);
+ int kvno = 0;
+ if (Character.isDigit(pass[pass.length-1])) {
+ kvno = pass[pass.length-1] - '0';
+ }
+ ktab.addEntry(new PrincipalName(name,
+ name.indexOf('/') < 0 ?
+ PrincipalName.KRB_NT_UNKNOWN :
+ PrincipalName.KRB_NT_SRV_HST),
+ pass,
+ kvno,
+ true);
+ }
+ }
+ ktab.save();
+ }
+
+ /**
+ * Writes all principals' keys from multiple KDCs into one keytab file.
* Note that the keys for the krbtgt principals will not be written.
* <p>
* Attention: This method references krb5.conf settings. If you need to
@@ -252,17 +278,16 @@
*/
public static void writeMultiKtab(String tab, KDC... kdcs)
throws IOException, KrbException {
- KeyTab ktab = KeyTab.create(tab);
- for (KDC kdc: kdcs) {
- for (String name : kdc.passwords.keySet()) {
- ktab.addEntry(new PrincipalName(name,
- name.indexOf('/') < 0 ?
- PrincipalName.KRB_NT_UNKNOWN :
- PrincipalName.KRB_NT_SRV_HST),
- kdc.passwords.get(name), -1, true);
- }
- }
- ktab.save();
+ writeKtab0(tab, false, kdcs);
+ }
+
+ /**
+ * Appends all principals' keys from multiple KDCs to one keytab file.
+ * See writeMultiKtab for details.
+ */
+ public static void appendMultiKtab(String tab, KDC... kdcs)
+ throws IOException, KrbException {
+ writeKtab0(tab, true, kdcs);
}
/**
@@ -273,6 +298,13 @@
}
/**
+ * Appends keys in this KDC to a ktab.
+ */
+ public void appendKtab(String tab) throws IOException, KrbException {
+ KDC.appendMultiKtab(tab, this);
+ }
+
+ /**
* Adds a new principal to this realm with a given password.
* @param user the principal's name. For a service principal, use the
* form of host/f.q.d.n
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/KeyTabCompat.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6894072
+ * @compile -XDignore.symbol.file KeyTabCompat.java
+ * @run main/othervm KeyTabCompat
+ * @summary always refresh keytab
+ */
+
+import javax.security.auth.kerberos.KerberosKey;
+import sun.security.jgss.GSSUtil;
+
+/*
+ * There are 2 compat issues to check:
+ *
+ * 1. If there is only KerberosKeys in private credential set and no
+ * KerberosPrincipal. JAAS login should go on.
+ * 2. Even if KeyTab is used, user can still get KerberosKeys from
+ * private credentials set.
+ */
+public class KeyTabCompat {
+
+ public static void main(String[] args)
+ throws Exception {
+ OneKDC kdc = new OneKDC("aes128-cts");
+ kdc.writeJAASConf();
+ kdc.addPrincipal(OneKDC.SERVER, "pass1".toCharArray());
+ kdc.writeKtab(OneKDC.KTAB);
+
+ Context c, s;
+
+ // Part 1
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ s = Context.fromUserPass(OneKDC.USER2, OneKDC.PASS2, true);
+
+ s.s().getPrincipals().clear();
+
+ c.startAsClient(OneKDC.USER2, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ Context.handshake(c, s);
+
+ // Part 2
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ s.status();
+
+ if (s.s().getPrivateCredentials(KerberosKey.class).size() != 1) {
+ throw new Exception("There should be one KerberosKey");
+ }
+
+ Thread.sleep(2000); // make sure ktab timestamp is different
+
+ kdc.addPrincipal(OneKDC.SERVER, "pass2".toCharArray());
+ kdc.writeKtab(OneKDC.KTAB);
+
+ Context.handshake(c, s);
+ s.status();
+
+ if (s.s().getPrivateCredentials(KerberosKey.class).size() != 1) {
+ throw new Exception("There should be only one KerberosKey");
+ }
+
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/LoginModuleOptions.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/sun/security/krb5/auto/LoginModuleOptions.java Thu May 05 22:29:05 2011 -0700
@@ -28,7 +28,6 @@
* @summary Krb5LoginModule a little too restrictive, and the doc is not clear.
*/
import com.sun.security.auth.module.Krb5LoginModule;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
@@ -36,7 +35,6 @@
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
public class LoginModuleOptions {
@@ -61,10 +59,12 @@
// 1. ccache -> keytab
login(null, "useTicketCache", "true", "ticketCache", "krbcc_non_exists",
"useKeyTab", "true", "principal", "dummy");
+
// 2. keytab -> shared
login(null, "useKeyTab", "true", "principal", "dummy",
"keyTab", "ktab_non_exist",
"tryFirstPass", "true", NAME, OneKDC.USER, PWD, OneKDC.PASS);
+
// 3. shared -> callback
// 3.1. useFirstPass, no callback
boolean failed = false;
--- a/jdk/test/sun/security/krb5/auto/SSL.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/sun/security/krb5/auto/SSL.java Thu May 05 22:29:05 2011 -0700
@@ -48,7 +48,7 @@
public class SSL {
private static String krb5Cipher;
- private static final int LOOP_LIMIT = 1;
+ private static final int LOOP_LIMIT = 3;
private static int loopCount = 0;
private static volatile String server;
private static volatile int port;
@@ -98,13 +98,13 @@
fos.close();
f.deleteOnExit();
- final Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ Context c;
final Context s = Context.fromJAAS("ssl");
- c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
+ // There's no keytab file when server starts.
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
- new Thread(new Runnable() {
+ Thread server = new Thread(new Runnable() {
public void run() {
try {
s.doAs(new JsseServerAction(), null);
@@ -112,12 +112,57 @@
e.printStackTrace();
}
}
- }).start();
+ });
+ server.setDaemon(true);
+ server.start();
// Warm the server
Thread.sleep(2000);
+ // Now create the keytab
+
+ /*
+ // Add 3 versions of keys into keytab
+ KeyTab ktab = KeyTab.create(OneKDC.KTAB);
+ PrincipalName service = new PrincipalName(
+ "host/" + server, PrincipalName.KRB_NT_SRV_HST);
+ ktab.addEntry(service, "pass1".toCharArray(), 1);
+ ktab.addEntry(service, "pass2".toCharArray(), 2);
+ ktab.addEntry(service, "pass3".toCharArray(), 3);
+ ktab.save();
+
+ // and use the middle one as the real key
+ kdc.addPrincipal("host/" + server, "pass2".toCharArray());
+ */
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
c.doAs(new JsseClientAction(), null);
+
+ // Add another version of key, make sure it can be loaded
+ Thread.sleep(2000);
+ ktab = KeyTab.getInstance(OneKDC.KTAB);
+ ktab.addEntry(service, "pass4".toCharArray(), 4, true);
+ ktab.save();
+ kdc.addPrincipal("host/" + server, "pass4".toCharArray());
+
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
+ c.doAs(new JsseClientAction(), null);
+
+ // Revoke the old key
+ /*Thread.sleep(2000);
+ ktab = KeyTab.create(OneKDC.KTAB);
+ ktab.addEntry(service, "pass5".toCharArray(), 5, false);
+ ktab.save();
+
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
+ try {
+ c.doAs(new JsseClientAction(), null);
+ throw new Exception("Should fail this time.");
+ } catch (SSLException e) {
+ // Correct behavior.
+ }*/
}
// Following codes copied from
@@ -126,6 +171,7 @@
public byte[] run(Context s, byte[] input) throws Exception {
SSLSocketFactory sslsf =
(SSLSocketFactory) SSLSocketFactory.getDefault();
+ System.out.println("Connecting " + server + ":" + port);
SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(server, port);
// Enable only a KRB5 cipher suite.
@@ -154,6 +200,9 @@
System.out.println("Server is: " + peer.toString());
sslSocket.close();
+ // This line should not be needed. It's the server's duty to
+ // forget the old key
+ //sslSocket.getSession().invalidate();
return null;
}
}
@@ -165,6 +214,7 @@
SSLServerSocket sslServerSocket =
(SSLServerSocket) sslssf.createServerSocket(0); // any port
port = sslServerSocket.getLocalPort();
+ System.out.println("Listening on " + port);
// Enable only a KRB5 cipher suite.
String enabledSuites[] = {krb5Cipher};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/TwoPrinces.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6894072
+ * @compile -XDignore.symbol.file TwoPrinces.java
+ * @run main/othervm TwoPrinces
+ * @summary always refresh keytab
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class TwoPrinces {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ KDC k1 = KDC.create("R1");
+ k1.addPrincipal("u1", "hello".toCharArray());
+ k1.addPrincipalRandKey("krbtgt/R1");
+ k1.addPrincipalRandKey("host/same.host");
+
+ KDC k2 = KDC.create("R2");
+ k2.addPrincipal("u2", "hello".toCharArray());
+ k2.addPrincipalRandKey("krbtgt/R2");
+ k2.addPrincipalRandKey("host/same.host");
+
+ System.setProperty("java.security.krb5.conf", "krb5.conf");
+
+ // R1 is the default realm now
+ KDC.saveConfig("krb5.conf", k1, k2);
+ Config.refresh();
+
+ k1.writeKtab("ktab1");
+ k2.writeKtab("ktab2");
+
+ // A JAAS config file with 2 Krb5LoginModules, after commit, the
+ // subject with have principals and keytabs from both sides
+ System.setProperty("java.security.auth.login.config", "jaas.conf");
+ File f = new File("jaas.conf");
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write((
+ "me {\n"
+ + " com.sun.security.auth.module.Krb5LoginModule required"
+ + " isInitiator=true principal=\"host/same.host@R1\""
+ + " useKeyTab=true keyTab=ktab1 storeKey=true;\n"
+ + " com.sun.security.auth.module.Krb5LoginModule required"
+ + " isInitiator=true principal=\"host/same.host@R2\""
+ + " useKeyTab=true keyTab=ktab2 storeKey=true;\n"
+ + "};\n"
+ ).getBytes());
+ fos.close();
+
+ /*
+ * This server side context will be able to act as services in both
+ * realms. Please note that we still don't support a single instance
+ * of server to accept connections from two realms at the same time.
+ * Therefore, we must call startAsServer in a given realm to start
+ * working there. The same Subject never changes anyway.
+ */
+ Context s = Context.fromJAAS("me");
+
+ // Default realm still R1
+ s.startAsServer("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
+ Context c1 = Context.fromUserPass("u1", "hello".toCharArray(), false);
+ c1.startAsClient("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c1, s);
+
+ KDC.saveConfig("krb5.conf", k2, k1);
+ Config.refresh();
+
+ // Default realm now R2
+ s.startAsServer("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
+ Context c2 = Context.fromUserPass("u2", "hello".toCharArray(), false);
+ c2.startAsClient("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c2, s);
+ }
+}
--- a/jdk/test/sun/security/krb5/ktab/KeyTabIndex.java Thu May 05 14:02:17 2011 -0700
+++ b/jdk/test/sun/security/krb5/ktab/KeyTabIndex.java Thu May 05 22:29:05 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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
@@ -44,7 +44,6 @@
KeyTab.getInstance("ktab").getClass();
}
};
- KeyTab.refresh();
for (int i=0; i<10; i++) {
new Thread(t).start();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @see PublicKeyInterop.sh
+ */
+
+import java.security.*;
+import java.util.*;
+import javax.crypto.*;
+
+import sun.misc.HexDumpEncoder;
+
+/*
+ * Confirm interoperability of RSA public keys between SunMSCAPI and SunJCE
+ * security providers.
+ */
+public class PublicKeyInterop {
+
+ public static void main(String[] arg) throws Exception {
+ PrivateKey privKey = null;
+ Certificate cert = null;
+ KeyStore ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+ System.out.println("Loaded keystore: Windows-MY");
+
+ PublicKey myPuKey =
+ (PublicKey) ks.getCertificate("6888925").getPublicKey();
+ System.out.println("Public key is a " + myPuKey.getClass().getName());
+ PrivateKey myPrKey = (PrivateKey) ks.getKey("6888925", null);
+ System.out.println("Private key is a " + myPrKey.getClass().getName());
+ System.out.println();
+
+ byte[] plain = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05};
+ HexDumpEncoder hde = new HexDumpEncoder();
+ System.out.println("Plaintext:\n" + hde.encode(plain) + "\n");
+
+ Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ rsa.init(Cipher.ENCRYPT_MODE, myPuKey);
+ byte[] encrypted = rsa.doFinal(plain);
+ System.out.println("Encrypted plaintext using RSA Cipher from " +
+ rsa.getProvider().getName() + " JCE provider\n");
+ System.out.println(hde.encode(encrypted) + "\n");
+
+ Cipher rsa2 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
+ rsa2.init(Cipher.ENCRYPT_MODE, myPuKey);
+ byte[] encrypted2 = rsa2.doFinal(plain);
+ System.out.println("Encrypted plaintext using RSA Cipher from " +
+ rsa2.getProvider().getName() + " JCE provider\n");
+ System.out.println(hde.encode(encrypted2) + "\n");
+
+ Cipher rsa3 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
+ rsa3.init(Cipher.DECRYPT_MODE, myPrKey);
+ byte[] decrypted = rsa3.doFinal(encrypted);
+ System.out.println("Decrypted first ciphertext using RSA Cipher from " +
+ rsa3.getProvider().getName() + " JCE provider\n");
+ System.out.println(hde.encode(decrypted) + "\n");
+ if (! Arrays.equals(plain, decrypted)) {
+ throw new Exception("First decrypted ciphertext does not match " +
+ "original plaintext");
+ }
+
+ decrypted = rsa3.doFinal(encrypted2);
+ System.out.println("Decrypted second ciphertext using RSA Cipher from "
+ + rsa3.getProvider().getName() + " JCE provider\n");
+ System.out.println(hde.encode(decrypted) + "\n");
+ if (! Arrays.equals(plain, decrypted)) {
+ throw new Exception("Second decrypted ciphertext does not match " +
+ "original plaintext");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.sh Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 6888925
+# @run shell PublicKeyInterop.sh
+# @summary SunMSCAPI's Cipher can't use RSA public keys obtained from other
+# sources.
+#
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows* | CYGWIN* )
+
+ echo "Creating a temporary RSA keypair in the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -genkeypair \
+ -storetype Windows-My \
+ -keyalg RSA \
+ -alias 6888925 \
+ -dname "cn=6888925,c=US" \
+ -noprompt
+
+ echo
+ echo "Running the test..."
+ ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\PublicKeyInterop.java
+ ${TESTJAVA}/bin/java PublicKeyInterop
+
+ rc=$?
+
+ echo
+ echo "Removing the temporary RSA keypair from the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -delete \
+ -storetype Windows-My \
+ -alias 6888925
+
+ echo done.
+ exit $rc
+ ;;
+
+ * )
+ echo "This test is not intended for '$OS' - passing test"
+ exit 0
+ ;;
+esac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.cfg Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,10 @@
+#
+# Configuration file to allow the SunPKCS11 provider to utilize
+# the Solaris Cryptographic Framework, if it is available
+#
+
+name = Absolute
+
+description = SunPKCS11 using a relative path
+
+library = ./libpkcs11.so
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.java Thu May 05 22:29:05 2011 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * @test
+ * @bug 7003952
+ * @summary load DLLs and launch executables using fully qualified path
+ */
+import java.security.*;
+import java.lang.reflect.*;
+import sun.security.pkcs11.*;
+
+public class Absolute {
+
+ public static void main(String[] args) throws Exception {
+ Constructor cons;
+ try {
+ Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
+ cons = clazz.getConstructor(new Class[] {String.class});
+ } catch (Exception ex) {
+ System.out.println("Skipping test - no PKCS11 provider available");
+ return;
+ }
+
+ String config =
+ System.getProperty("test.src", ".") + "/Absolute.cfg";
+
+ try {
+ Object obj = cons.newInstance(new Object[] {config});
+ } catch (InvocationTargetException ite) {
+ Throwable cause = ite.getCause();
+ if (cause instanceof ProviderException) {
+ Throwable cause2 = cause.getCause();
+ if ((cause2 == null) ||
+ !cause2.getMessage().startsWith(
+ "Absolute path required for library value:")) {
+ // rethrow
+ throw (ProviderException) cause;
+ }
+ System.out.println("Caught expected Exception: \n" + cause2);
+ }
+ }
+ }
+}