changeset 498:68e8364feffc jdk7u21-b04

8005432: Update access to JAX-WS Summary: newly restricted the whole package com.sun.xml.internal; fix reviewed also by Alexander Fomin Reviewed-by: mullan, skoivu
author mkos
date Wed, 20 Feb 2013 22:42:04 +0100
parents 914a2fa3675d
children 238b59ffddce
files src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/ModelBuilder.java src/share/jaxws_classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java src/share/jaxws_classes/javax/xml/soap/MessageFactory.java src/share/jaxws_classes/javax/xml/soap/SAAJMetaFactory.java src/share/jaxws_classes/javax/xml/soap/SOAPConnectionFactory.java src/share/jaxws_classes/javax/xml/soap/SOAPFactory.java
diffstat 7 files changed, 169 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/ModelBuilder.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/ModelBuilder.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -235,7 +235,7 @@
                         String pkg = nav.getPackageName(ci.getClazz());
                         if(!registries.containsKey(pkg)) {
                             // insert the package's object factory
-                            C c = nav.findClass(pkg + ".ObjectFactory",ci.getClazz());
+                            C c = loadObjectFactory(ci, pkg);
                             if(c!=null)
                                 addRegistry(c,(Locatable)p);
                         }
@@ -264,6 +264,15 @@
         return r;
     }
 
+    private C loadObjectFactory(ClassInfoImpl<T, C, F, M> ci, String pkg) {
+        try {
+            return nav.findClass(pkg + ".ObjectFactory", ci.getClazz());
+        } catch (SecurityException ignored) {
+            // treat SecurityException in same way as ClassNotFoundException in this case
+            return null;
+        }
+    }
+
     /**
      * Checks the uniqueness of the type name.
      */
--- a/src/share/jaxws_classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package com.sun.xml.internal.ws.client;
 
 import com.sun.istack.internal.NotNull;
@@ -30,13 +29,11 @@
 import com.sun.xml.internal.ws.Closeable;
 import com.sun.xml.internal.ws.api.BindingID;
 import com.sun.xml.internal.ws.api.EndpointAddress;
-import com.sun.xml.internal.ws.api.WSBinding;
 import com.sun.xml.internal.ws.api.WSService;
 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
 import com.sun.xml.internal.ws.api.client.ServiceInterceptor;
 import com.sun.xml.internal.ws.api.client.ServiceInterceptorFactory;
-import com.sun.xml.internal.ws.api.model.SEIModel;
-import com.sun.xml.internal.ws.api.pipe.*;
+import com.sun.xml.internal.ws.api.pipe.Stubs;
 import com.sun.xml.internal.ws.api.server.Container;
 import com.sun.xml.internal.ws.api.server.ContainerResolver;
 import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
@@ -45,8 +42,8 @@
 import com.sun.xml.internal.ws.client.HandlerConfigurator.AnnotationConfigurator;
 import com.sun.xml.internal.ws.client.HandlerConfigurator.HandlerResolverImpl;
 import com.sun.xml.internal.ws.client.sei.SEIStub;
+import com.sun.xml.internal.ws.developer.UsesJAXBContextFeature;
 import com.sun.xml.internal.ws.developer.WSBindingProvider;
-import com.sun.xml.internal.ws.developer.UsesJAXBContextFeature;
 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
 import com.sun.xml.internal.ws.model.RuntimeModeler;
 import com.sun.xml.internal.ws.model.SOAPSEIModel;
@@ -59,7 +56,6 @@
 import com.sun.xml.internal.ws.util.JAXWSUtils;
 import com.sun.xml.internal.ws.util.ServiceConfigurationError;
 import com.sun.xml.internal.ws.util.ServiceFinder;
-import static com.sun.xml.internal.ws.util.xml.XmlUtil.createDefaultCatalogResolver;
 import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;
 import org.xml.sax.SAXException;
 
@@ -74,16 +70,17 @@
 import javax.xml.ws.handler.HandlerResolver;
 import javax.xml.ws.soap.AddressingFeature;
 import java.io.IOException;
+import java.lang.RuntimePermission;
 import java.lang.reflect.Proxy;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.security.*;
 import java.util.*;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 
+import static com.sun.xml.internal.ws.util.xml.XmlUtil.createDefaultCatalogResolver;
+
 /**
  * <code>Service</code> objects provide the client view of a Web service.
  *
@@ -578,7 +575,7 @@
         }
     }
 
-    private <T> T createEndpointIFBaseProxy(@Nullable WSEndpointReference epr,QName portName, Class<T> portInterface,
+    private <T> T createEndpointIFBaseProxy(@Nullable WSEndpointReference epr,QName portName, final Class<T> portInterface,
                                             WebServiceFeature[] webServiceFeatures, SEIPortInfo eif) {
         //fail if service doesnt have WSDL
         if (wsdlService == null)
@@ -592,14 +589,37 @@
         BindingImpl binding = eif.createBinding(webServiceFeatures,portInterface);
         SEIStub pis = new SEIStub(eif, binding, eif.model, epr);
 
-        T proxy = portInterface.cast(Proxy.newProxyInstance(portInterface.getClassLoader(),
-                new Class[]{portInterface, WSBindingProvider.class, Closeable.class}, pis));
+        T proxy = createProxy(portInterface, pis);
+
         if (serviceInterceptor != null) {
             serviceInterceptor.postCreateProxy((WSBindingProvider)proxy, portInterface);
         }
         return proxy;
     }
 
+    private <T> T createProxy(final Class<T> portInterface, final SEIStub pis) {
+
+        // accessClassInPackage privilege needs to be granted ...
+        RuntimePermission perm = new RuntimePermission("accessClassInPackage.com.sun." + "xml.internal.*");
+        PermissionCollection perms = perm.newPermissionCollection();
+        perms.add(perm);
+
+        return AccessController.doPrivileged(
+                new PrivilegedAction<T>() {
+                    @Override
+                    public T run() {
+                        Object proxy = Proxy.newProxyInstance(portInterface.getClassLoader(),
+                                new Class[]{portInterface, WSBindingProvider.class, Closeable.class}, pis);
+                        return portInterface.cast(proxy);
+                    }
+                },
+                new AccessControlContext(
+                        new ProtectionDomain[]{
+                                new ProtectionDomain(null, perms)
+                        })
+        );
+    }
+
     /**
      * Lists up the port names in WSDL. For error diagnostics.
      */
--- a/src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -43,20 +43,12 @@
         throws SOAPException
     {
         try {
-            Class spiClass;
-            if (classLoader == null) {
-                spiClass = Class.forName(className);
-            } else {
-                spiClass = classLoader.loadClass(className);
-            }
+            Class spiClass = safeLoadClass(className, classLoader);
             return spiClass.newInstance();
         } catch (ClassNotFoundException x) {
-            throw new SOAPException(
-                "Provider " + className + " not found", x);
+            throw new SOAPException("Provider " + className + " not found", x);
         } catch (Exception x) {
-            throw new SOAPException(
-                "Provider " + className + " could not be instantiated: " + x,
-                x);
+            throw new SOAPException("Provider " + className + " could not be instantiated: " + x, x);
         }
     }
 
@@ -73,11 +65,65 @@
      *                              a system property
      * @exception SOAPException if there is a SOAP error
      */
-    static Object find(String factId)
+    static Object find(String factoryId)
         throws SOAPException
     {
-        final ClassLoader classLoader;
-        final String factoryId = factId;
+        return find(factoryId, null, false);
+    }
+
+    /**
+     * Finds the implementation <code>Class</code> object for the given
+     * factory name, or if that fails, finds the <code>Class</code> object
+     * for the given fallback class name. The arguments supplied must be
+     * used in order. If using the first argument is successful, the second
+     * one will not be used.
+     * <P>
+     * This method is package private so that this code can be shared.
+     *
+     * @return the <code>Class</code> object of the specified message factory;
+     *         may be <code>null</code>
+     *
+     * @param factoryId             the name of the factory to find, which is
+     *                              a system property
+     * @param fallbackClassName     the implementation class name, which is
+     *                              to be used only if nothing else
+     *                              is found; <code>null</code> to indicate that
+     *                              there is no fallback class name
+     * @exception SOAPException if there is a SOAP error
+     */
+    static Object find(String factoryId, String fallbackClassName)
+        throws SOAPException
+    {
+        return find(factoryId, fallbackClassName, true);
+    }
+
+    /**
+     * Finds the implementation <code>Class</code> object for the given
+     * factory name, or if that fails, finds the <code>Class</code> object
+     * for the given default class name, but only if <code>tryFallback</code>
+     * is <code>true</code>.  The arguments supplied must be used in order
+     * If using the first argument is successful, the second one will not
+     * be used.  Note the default class name may be needed even if fallback
+     * is not to be attempted, so certain error conditions can be handled.
+     * <P>
+     * This method is package private so that this code can be shared.
+     *
+     * @return the <code>Class</code> object of the specified message factory;
+     *         may not be <code>null</code>
+     *
+     * @param factoryId             the name of the factory to find, which is
+     *                              a system property
+     * @param defaultClassName      the implementation class name, which is
+     *                              to be used only if nothing else
+     *                              is found; <code>null</code> to indicate
+     *                              that there is no default class name
+     * @param tryFallback           whether to try the default class as a
+     *                              fallback
+     * @exception SOAPException if there is a SOAP error
+     */
+    static Object find(String factoryId, String defaultClassName,
+            boolean tryFallback) throws SOAPException {
+        ClassLoader classLoader;
         try {
             classLoader = Thread.currentThread().getContextClassLoader();
         } catch (Exception x) {
@@ -99,7 +145,7 @@
             String javah=System.getProperty( "java.home" );
             String configFile = javah + File.separator +
                 "lib" + File.separator + "jaxm.properties";
-            final File f=new File( configFile );
+            File f=new File( configFile );
             if( f.exists()) {
                 Properties props=new Properties();
                 props.load( new FileInputStream(f));
@@ -134,49 +180,56 @@
         } catch( Exception ex ) {
         }
 
-        return null;
+        // If not found and fallback should not be tried, return a null result.
+        if (!tryFallback)
+            return null;
+
+        // We didn't find the class through the usual means so try the default
+        // (built in) factory if specified.
+        if (defaultClassName == null) {
+            throw new SOAPException(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+        return newInstance(defaultClassName, classLoader);
     }
 
     /**
-     * Finds the implementation <code>Class</code> object for the given
-     * factory name, or if that fails, finds the <code>Class</code> object
-     * for the given fallback class name. The arguments supplied must be
-     * used in order. If using the first argument is successful, the second
-     * one will not be used.
-     * <P>
-     * This method is package private so that this code can be shared.
-     *
-     * @return the <code>Class</code> object of the specified message factory;
-     *         may not be <code>null</code>
-     *
-     * @param factoryId             the name of the factory to find, which is
-     *                              a system property
-     * @param fallbackClassName     the implementation class name, which is
-     *                              to be used only if nothing else
-     *                              is found; <code>null</code> to indicate that
-     *                              there is no fallback class name
-     * @exception SOAPException if there is a SOAP error
+     * Loads the class, provided that the calling thread has an access to the
+     * class being loaded. If this is the specified default factory class and it
+     * is restricted by package.access we get a SecurityException and can do a
+     * Class.forName() on it so it will be loaded by the bootstrap class loader.
      */
-    static Object find(String factoryId, String fallbackClassName)
-        throws SOAPException
-    {
+    private static Class safeLoadClass(String className,
+            ClassLoader classLoader)
+            throws ClassNotFoundException {
+        try {
+            // make sure that the current thread has an access to the package of the given name.
+            SecurityManager s = System.getSecurityManager();
+            if (s != null) {
+                int i = className.lastIndexOf('.');
+                if (i != -1) {
+                    s.checkPackageAccess(className.substring(0, i));
+                }
+            }
 
-        Object obj = find(factoryId);
-        if (obj != null)
-            return obj;
+            if (classLoader == null)
+                return Class.forName(className);
+            else
+                return classLoader.loadClass(className);
+        } catch (SecurityException se) {
+            // (only) default implementation can be loaded
+            // using bootstrap class loader ...
+            if (isDefaultImplementation(className))
+                return Class.forName(className);
 
-        ClassLoader classLoader;
-        try {
-            classLoader = Thread.currentThread().getContextClassLoader();
-        } catch (Exception x) {
-            throw new SOAPException(x.toString(), x);
+            throw se;
         }
+    }
 
-        if (fallbackClassName == null) {
-            throw new SOAPException(
-                "Provider for " + factoryId + " cannot be found", null);
-        }
-
-        return newInstance(fallbackClassName, classLoader);
+    private static boolean isDefaultImplementation(String className) {
+        return MessageFactory.DEFAULT_MESSAGE_FACTORY.equals(className) ||
+                SOAPFactory.DEFAULT_SOAP_FACTORY.equals(className) ||
+                SOAPConnectionFactory.DEFAULT_SOAP_CONNECTION_FACTORY.equals(className) ||
+                SAAJMetaFactory.DEFAULT_META_FACTORY_CLASS.equals(className);
     }
 }
--- a/src/share/jaxws_classes/javax/xml/soap/MessageFactory.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/javax/xml/soap/MessageFactory.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -66,7 +66,7 @@
  */
 public abstract class MessageFactory {
 
-    static private final String DEFAULT_MESSAGE_FACTORY
+    static final String DEFAULT_MESSAGE_FACTORY
         = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl";
 
     static private final String MESSAGE_FACTORY_PROPERTY
@@ -99,11 +99,14 @@
     public static MessageFactory newInstance()
         throws SOAPException {
         try {
-            MessageFactory factory = (MessageFactory)
-                FactoryFinder.find(MESSAGE_FACTORY_PROPERTY);
+            MessageFactory factory = (MessageFactory) FactoryFinder.find(
+                    MESSAGE_FACTORY_PROPERTY,
+                    DEFAULT_MESSAGE_FACTORY,
+                    false);
 
-            if (factory != null)
+            if (factory != null) {
                 return factory;
+            }
 
             return newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
         } catch (Exception ex) {
--- a/src/share/jaxws_classes/javax/xml/soap/SAAJMetaFactory.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/javax/xml/soap/SAAJMetaFactory.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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,7 @@
 public abstract class SAAJMetaFactory {
     static private final String META_FACTORY_CLASS_PROPERTY =
         "javax.xml.soap.MetaFactory";
-    static private final String DEFAULT_META_FACTORY_CLASS =
+    static final String DEFAULT_META_FACTORY_CLASS =
         "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl";
 
     /**
--- a/src/share/jaxws_classes/javax/xml/soap/SOAPConnectionFactory.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/javax/xml/soap/SOAPConnectionFactory.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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,7 +38,7 @@
      * A constant representing the default value for a <code>SOAPConnection</code>
      * object. The default is the point-to-point SOAP connection.
      */
-    static private final String DEFAULT_SOAP_CONNECTION_FACTORY
+    static final String DEFAULT_SOAP_CONNECTION_FACTORY
         = "com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory";
 
     /**
--- a/src/share/jaxws_classes/javax/xml/soap/SOAPFactory.java	Tue Feb 19 17:13:52 2013 -0800
+++ b/src/share/jaxws_classes/javax/xml/soap/SOAPFactory.java	Wed Feb 20 22:42:04 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -54,6 +54,12 @@
         "javax.xml.soap.SOAPFactory";
 
     /**
+     * Class name of default <code>SOAPFactory</code> implementation.
+     */
+    static final String DEFAULT_SOAP_FACTORY
+        = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl";
+
+    /**
      * Creates a <code>SOAPElement</code> object from an existing DOM
      * <code>Element</code>. If the DOM <code>Element</code> that is passed in
      * as an argument is already a <code>SOAPElement</code> then this method
@@ -255,7 +261,7 @@
         throws SOAPException
     {
         try {
-            SOAPFactory factory = (SOAPFactory) FactoryFinder.find(SOAP_FACTORY_PROPERTY);
+            SOAPFactory factory = (SOAPFactory) FactoryFinder.find(SOAP_FACTORY_PROPERTY, DEFAULT_SOAP_FACTORY, false);
             if (factory != null)
                 return factory;
             return newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);