Mercurial > hg > openjdk > jdk7 > jdk
changeset 4323:49244980d692
Merge
author | asaha |
---|---|
date | Thu, 05 May 2011 22:29:05 -0700 |
parents | e6fdfb249e31 (diff) 631c23c29000 (current diff) |
children | 647b031200f0 |
files | src/share/classes/sun/security/util/SignatureFileManifest.java |
diffstat | 90 files changed, 2567 insertions(+), 708 deletions(-) [+] |
line wrap: on
line diff
--- a/make/com/sun/tools/attach/Makefile Thu May 05 14:02:17 2011 -0700 +++ b/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/make/sun/security/pkcs11/Makefile Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/lang/ProcessBuilder.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/lang/Runtime.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/net/NetworkInterface.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/nio/file/FileSystem.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/security/SignedObject.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/AbstractSet.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/ArrayList.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Collection.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Collections.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Deque.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/List.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/ListIterator.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Map.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Set.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/Vector.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/concurrent/BlockingDeque.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/concurrent/BlockingQueue.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/concurrent/ConcurrentMap.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/src/share/classes/javax/security/auth/kerberos/KerberosKey.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/src/share/classes/javax/swing/ImageIcon.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/java2d/pipe/DrawImage.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/src/share/classes/sun/misc/SharedSecrets.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/rmi/log/ReliableLog.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/rmi/server/Activation.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/jgss/krb5/Krb5Util.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/jgss/krb5/SubjectComber.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/krb5/Config.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/krb5/EncryptionKey.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/krb5/KrbAsRep.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/pkcs11/Config.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/pkcs11/Secmod.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/native/common/jdk_util.h Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/native/sun/font/layout/SunLayoutEngine.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/native/sun/java2d/loops/TransformHelper.c Thu May 05 14:02:17 2011 -0700 +++ b/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/src/share/native/sun/security/pkcs11/j2secmod.c Thu May 05 14:02:17 2011 -0700 +++ b/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/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/src/windows/classes/java/lang/ProcessEnvironment.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/krb5/internal/tools/Klist.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/mscapi/RSACipher.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/mscapi/RSAPublicKey.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/security/mscapi/RSASignature.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/classes/sun/tools/attach/WindowsAttachProvider.java Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/common/jdk_util_md.c Thu May 05 14:02:17 2011 -0700 +++ b/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/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/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/java2d/opengl/OGLFuncs_md.h Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/tools/attach/WindowsAttachProvider.c Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/tracing/dtrace/jvm_symbols_md.c Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/DllUtil.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/DllUtil.h Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/ShellFolder2.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/ThemeReader.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/awt_FileDialog.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/awt_Mlib.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/awt_TextArea.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/native/sun/windows/stdhdrs.h Thu May 05 14:02:17 2011 -0700 +++ b/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/src/windows/npt/npt_md.h Thu May 05 14:02:17 2011 -0700 +++ b/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/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/test/java/lang/ProcessBuilder/Basic.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/test/sun/security/krb5/auto/Context.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/test/sun/security/krb5/auto/KDC.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/test/sun/security/krb5/auto/LoginModuleOptions.java Thu May 05 14:02:17 2011 -0700 +++ b/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/test/sun/security/krb5/auto/SSL.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/test/sun/security/krb5/ktab/KeyTabIndex.java Thu May 05 14:02:17 2011 -0700 +++ b/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/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/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/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/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); + } + } + } +}