From 7a1887e91ce50162dc6c89449f290ee34b28b9b0 Mon Sep 17 00:00:00 2001
From: Vinnie Ryan <vinnie@openjdk.org>
Date: Thu, 6 Oct 2016 17:33:57 +0100
Subject: [PATCH] 8158997: JNDI Protocols Switch

Reviewed-by: dfuchs
---
 .../jndi/cosnaming/CNBindingEnumeration.java  |  7 ++++-
 .../classes/com/sun/jndi/cosnaming/CNCtx.java | 26 ++++++++++++++--
 .../sun/jndi/cosnaming/ExceptionMapper.java   | 11 +++++--
 .../sun/jndi/toolkit/corba/CorbaUtils.java    | 31 +++++++++++++++++--
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java
index ae5c61d6fe7..7c6d58de772 100644
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java
+++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java
@@ -33,6 +33,8 @@ import java.util.Hashtable;
 
 import org.omg.CosNaming.*;
 
+import com.sun.jndi.toolkit.corba.CorbaUtils;
+
 /**
   * Implements the JNDI NamingEnumeration interface for COS
   * Naming. Gets hold of a list of bindings from the COS Naming Server
@@ -212,7 +214,10 @@ final class CNBindingEnumeration
         Name cname = CNNameParser.cosNameToName(bndg.binding_name);
 
         try {
-            obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env);
+            // Check whether object factory codebase is trusted
+            if (CorbaUtils.isObjectFactoryTrusted(obj)) {
+                obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env);
+            }
         } catch (NamingException e) {
             throw e;
         } catch (Exception e) {
diff --git a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java
index 3d77c3746b7..82078e3f0dc 100644
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java
+++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java
@@ -36,6 +36,8 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import org.omg.CosNaming.*;
 import org.omg.CosNaming.NamingContextPackage.*;
@@ -82,6 +84,19 @@ public class CNCtx implements javax.naming.Context {
     private static final String FED_PROP = "com.sun.jndi.cosnaming.federation";
     boolean federation = false;
 
+    /**
+     * Determines whether classes may be loaded from an arbitrary URL code base.
+     */
+    public static final boolean trustURLCodebase;
+    static {
+        // System property to control whether classes may be loaded from an
+        // arbitrary URL code base
+        PrivilegedAction<String> act = () -> System.getProperty(
+            "com.sun.jndi.cosnaming.object.trustURLCodebase", "false");
+        String trust = AccessController.doPrivileged(act);
+        trustURLCodebase = "true".equalsIgnoreCase(trust);
+    }
+
     // Reference counter for tracking _orb references
     OrbReuseTracker orbTracker = null;
     int enumCount;
@@ -534,12 +549,16 @@ public class CNCtx implements javax.naming.Context {
             if (name.size() == 0 )
                 return this; // %%% should clone() so that env can be changed
             NameComponent[] path = CNNameParser.nameToCosName(name);
+            java.lang.Object answer = null;
 
             try {
-                java.lang.Object answer = callResolve(path);
-
+                answer = callResolve(path);
                 try {
-                    return NamingManager.getObjectInstance(answer, name, this, _env);
+                    // Check whether object factory codebase is trusted
+                    if (CorbaUtils.isObjectFactoryTrusted(answer)) {
+                        answer = NamingManager.getObjectInstance(
+                            answer, name, this, _env);
+                    }
                 } catch (NamingException e) {
                     throw e;
                 } catch (Exception e) {
@@ -552,6 +571,7 @@ public class CNCtx implements javax.naming.Context {
                 javax.naming.Context cctx = getContinuationContext(cpe);
                 return cctx.lookup(cpe.getRemainingName());
             }
+            return answer;
     }
 
     /**
diff --git a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java
index a1e9fd66424..1f626d5da0d 100644
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java
+++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java
@@ -33,6 +33,8 @@ import org.omg.CosNaming.*;
 import org.omg.CosNaming.NamingContextPackage.*;
 import org.omg.CORBA.*;
 
+import com.sun.jndi.toolkit.corba.CorbaUtils;
+
 /**
   * A convenience class to map the COS Naming exceptions to the JNDI exceptions.
   * @author Raj Krishnamurthy
@@ -202,10 +204,13 @@ public final class ExceptionMapper {
             // Not a context, use object factory to transform object.
 
             Name cname = CNNameParser.cosNameToName(resolvedName);
-            java.lang.Object resolvedObj2;
+            java.lang.Object resolvedObj2 = null;
             try {
-                resolvedObj2 = NamingManager.getObjectInstance(resolvedObj,
-                    cname, ctx, ctx._env);
+                // Check whether object factory codebase is trusted
+                if (CorbaUtils.isObjectFactoryTrusted(resolvedObj)) {
+                    resolvedObj2 = NamingManager.getObjectInstance(resolvedObj,
+                        cname, ctx, ctx._env);
+                }
             } catch (NamingException ge) {
                 throw ge;
             } catch (Exception ge) {
diff --git a/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java b/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java
index 422857bcc1e..856ce9d24d2 100644
--- a/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java
+++ b/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java
@@ -36,11 +36,12 @@ import java.applet.Applet;
 
 import org.omg.CORBA.ORB;
 
-import javax.naming.Context;
-import javax.naming.ConfigurationException;
+import javax.naming.*;
 import javax.rmi.CORBA.Stub;
 import javax.rmi.PortableRemoteObject;
 
+import com.sun.jndi.cosnaming.CNCtx;
+
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URLDecoder;
@@ -182,6 +183,32 @@ public class CorbaUtils {
         return ORB.init(new String[0], orbProp);
     }
 
+    /**
+     * Check whether object factory code base is trusted.
+     * Classes may only be loaded from an arbitrary URL code base when
+     * the system property com.sun.jndi.rmi.object.trustURLCodebase
+     * has been set to "true".
+     */
+    public static boolean isObjectFactoryTrusted(Object obj)
+        throws NamingException {
+
+        // Extract Reference, if possible
+        Reference ref = null;
+        if (obj instanceof Reference) {
+            ref = (Reference) obj;
+        } else if (obj instanceof Referenceable) {
+            ref = ((Referenceable)(obj)).getReference();
+        }
+
+        if (ref != null && ref.getFactoryClassLocation() != null &&
+                !CNCtx.trustURLCodebase) {
+            throw new ConfigurationException(
+                "The object factory is untrusted. Set the system property" +
+                " 'com.sun.jndi.cosnaming.object.trustURLCodebase' to 'true'.");
+        }
+        return true;
+    }
+
     /**
      * Decode a URI string (according to RFC 2396).
      */