You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by bp...@apache.org on 2018/03/12 01:32:24 UTC

svn commit: r1826481 - in /db/derby/code/trunk: ./ java/drda/org/apache/derby/drda/ java/drda/org/apache/derby/impl/drda/ java/shared/org/apache/derby/shared/common/reference/ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ java/test...

Author: bpendleton
Date: Mon Mar 12 01:32:23 2018
New Revision: 1826481

URL: http://svn.apache.org/viewvc?rev=1826481&view=rev
Log:
Merge revision 1826467 from 10.14 to trunk. Original commit message:

Remove support for COMMAND_TESTCONNECTION connectToDatabase feature.
It was never documented, and was never part of the regression tests.

A new regression test demonstrates that attempting to use this feature
now results in a "usage" response from the Network Server.

Also, change the Network Server's default security policy file, as well
as the template security policy file that we distribute with the
release and in the documentation. The new policy files do not use
the <<ALL FILES>> permission; instead they restrict the permission
to certain directories only.

Also, change the implementation of the Network Server's "sysinfo"
sub-command. Prior to this change, that feature would open each
jar file on the Network Server's class path, and would report on
whatever information it could find about that jar file. Now, the
only jar files that are opened and reported on are the known Derby
jar files; a table of those jar file names is compiled into the
sysinfo command. This causes sysinfo to return less information,
but it also means that it only needs the permission to access the
known Derby jar files on the classpath.

Modified:
    db/derby/code/trunk/   (props changed)
    db/derby/code/trunk/java/drda/org/apache/derby/drda/NetworkServerControl.java
    db/derby/code/trunk/java/drda/org/apache/derby/drda/server.policy
    db/derby/code/trunk/java/drda/org/apache/derby/drda/template.policy
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Property.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.policy
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/nast1.jar
    db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java

Propchange: db/derby/code/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 12 01:32:23 2018
@@ -1,3 +1,4 @@
+/db/derby/code/branches/10.14:1826467
 /db/derby/code/branches/10.7:1061570,1061578,1082235
 /db/derby/code/branches/10.8:1177474,1234973,1464951
 /db/derby/code/branches/10.9:1373148

Modified: db/derby/code/trunk/java/drda/org/apache/derby/drda/NetworkServerControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/drda/NetworkServerControl.java?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/drda/NetworkServerControl.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/drda/NetworkServerControl.java Mon Mar 12 01:32:23 2018
@@ -21,6 +21,7 @@
 
 package org.apache.derby.drda;
 
+import java.io.File;
 import java.io.PrintWriter;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -686,10 +687,14 @@ public class NetworkServerControl{
         // network codesources. Do not let the customer
         // override this
         //
-        String      derbyInstallURL = getCodeSourcePrefix( server );
+        URL    derbyInstallURL = getCodeSourceURL( server );
+        String derbyInstallStr = getCodeSourcePrefix( server, derbyInstallURL );
+        String derbyInstallPth = new File(derbyInstallURL.getFile())
+                                 .getParentFile().getAbsolutePath();
+
+        System.setProperty( Property.DERBY_INSTALL_URL, derbyInstallStr );
+        System.setProperty( Property.DERBY_INSTALL_PATH, derbyInstallPth );
 
-        System.setProperty( Property.DERBY_INSTALL_URL, derbyInstallURL );
-        
         //
         // Now install a SecurityManager, using the Basic policy file.
         //
@@ -790,7 +795,7 @@ public class NetworkServerControl{
      * same directory.
      * </p>
      */
-    private static  String  getCodeSourcePrefix( NetworkServerControlImpl server )
+    private static  URL  getCodeSourceURL( NetworkServerControlImpl server )
         throws Exception
     {
         // Note: This method is expected to run only when no security manager
@@ -801,9 +806,14 @@ public class NetworkServerControl{
             return null;
         }
         URL url = cs.getLocation();
-        if (url == null) {
-            return null;
-        }
+		return url;
+	}
+
+	private static String getCodeSourcePrefix(
+                NetworkServerControlImpl server,
+                URL url )
+		throws Exception
+	{
         // Replace in "file://some", but not in "file:///some".
         String extForm = url.toExternalForm().replaceFirst(
                 "^file://([^/].*)", "file:////$1");

Modified: db/derby/code/trunk/java/drda/org/apache/derby/drda/server.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/drda/server.policy?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/drda/server.policy (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/drda/server.policy Mon Mar 12 01:32:23 2018
@@ -32,17 +32,7 @@ grant codeBase "${derby.install.url}derb
   permission java.io.FilePermission "${derby.system.home}${/}-",
       "read,write,delete";
 
-  // This permission lets you backup and restore databases to and from
-  // arbitrary locations in your file system.
-  //
-  // This permission also lets you import/export data to and from arbitrary
-  // locations in your file system.
-  //
-  // You may want to restrict this access to specific directories.
-  //
-  permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
-
-  // Needed by sysinfo. The file permission is needed to check the existence of
+  // Needed by sysinfo. A file permission is needed to check the existence of
   // jars on the classpath. You can limit this permission to just the locations
   // which hold your jar files. This block is reproduced for all codebases
   // which include the sysinfo classes--the policy file syntax does not let you
@@ -54,9 +44,9 @@ grant codeBase "${derby.install.url}derb
   permission java.util.PropertyPermission "java.runtime.version", "read";
   permission java.util.PropertyPermission "java.fullversion", "read";
   permission java.lang.RuntimePermission "getProtectionDomain";
-  permission java.io.FilePermission "<<ALL FILES>>", "read";
   permission java.io.FilePermission "java.runtime.version", "read";
   permission java.io.FilePermission "java.fullversion", "read";
+  permission java.io.FilePermission "${derby.install.path}${/}-", "read";
 
   // Permissions needed for JMX based management and monitoring.
   //
@@ -160,7 +150,7 @@ grant codeBase "${derby.install.url}derb
       "control,monitor";
   permission org.apache.derby.shared.common.security.SystemPermission "engine", "usederbyinternals";
 
-  // Needed by sysinfo. The file permission is needed to check the existence of
+  // Needed by sysinfo. A file permission is needed to check the existence of
   // jars on the classpath. You can limit this permission to just the locations
   // which hold your jar files. This block is reproduced for all codebases
   // which include the sysinfo classes--the policy file syntax does not let you
@@ -172,15 +162,15 @@ grant codeBase "${derby.install.url}derb
   permission java.util.PropertyPermission "java.runtime.version", "read";
   permission java.util.PropertyPermission "java.fullversion", "read";
   permission java.lang.RuntimePermission "getProtectionDomain";
-  permission java.io.FilePermission "<<ALL FILES>>", "read";
   permission java.io.FilePermission "java.runtime.version", "read";
   permission java.io.FilePermission "java.fullversion", "read";
+  permission java.io.FilePermission "${derby.install.path}${/}-", "read";
 };
 
 
 grant codeBase "${derby.install.url}derbytools.jar"
 {
-  // Needed by sysinfo. The file permission is needed to check the existence of
+  // Needed by sysinfo. A file permission is needed to check the existence of
   // jars on the classpath. You can limit this permission to just the locations
   // which hold your jar files. This block is for all codebases which include
   // the sysinfo classes--the policy file syntax does not let you grant
@@ -201,7 +191,7 @@ grant codeBase "${derby.install.url}derb
 
 grant codeBase "${derby.install.url}derbyclient.jar"
 {
-  // Needed by sysinfo. The file permission is needed to check the existence of
+  // Needed by sysinfo. A file permission is needed to check the existence of
   // jars on the classpath. You can limit this permission to just the locations
   // which hold your jar files. This block is reproduced for all codebases
   // which include the sysinfo classes--the policy file syntax does not let you
@@ -213,7 +203,7 @@ grant codeBase "${derby.install.url}derb
   permission java.util.PropertyPermission "java.runtime.version", "read";
   permission java.util.PropertyPermission "java.fullversion", "read";
   permission java.lang.RuntimePermission "getProtectionDomain";
-  permission java.io.FilePermission "<<ALL FILES>>", "read";
+  permission java.io.FilePermission "${derby.install.path}${/}-", "read";
 
   // The following permission must be granted for Connection.abort(Executor) to
   // work.  Note that this permission must also be granted to outer

Modified: db/derby/code/trunk/java/drda/org/apache/derby/drda/template.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/drda/template.policy?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/drda/template.policy (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/drda/template.policy Mon Mar 12 01:32:23 2018
@@ -52,9 +52,13 @@ grant codeBase "${derby.install.url}derb
   // This permission also lets you import/export data to and from arbitrary
   // locations in your file system.
   //
-  // You may want to restrict this access to specific directories.
+  // NOTE: this permission is commented out. You should NOT grant blanket
+  // permission to the entire filesystem! If you choose to use this
+  // permission to allow the server to access files outside of the
+  // server's home directory, you should name those specific directories
+  // in the permisson (that is, do NOT specify ALL FILES).
   //
-  permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
+  // permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
 
   // Permissions needed for JMX based management and monitoring.
   //
@@ -155,9 +159,11 @@ grant codeBase "${derby.install.url}derb
   //
   // permission java.net.SocketPermission "*", "connect,resolve";
 
-  // Needed by sysinfo. The file permission is needed to check the existence of
-  // jars on the classpath. You can limit this permission to just the locations
-  // which hold your jar files.
+  // Needed by sysinfo. A file permission is needed to check the existence of
+  // jars on the classpath. Note that this permission is commented out! 
+  // You should limit this permission to just the locations which hold
+  // your jar files; do NOT grant blanket permission to read the entire
+  // filesystem.
   //
   // In this template file, this block of permissions is granted to
   // derbynet.jar under the assumption that derbynet.jar is the first jar file
@@ -171,13 +177,13 @@ grant codeBase "${derby.install.url}derb
   //    derbyclient.jar
   //    derbytools.jar
   //
+  // permission java.io.FilePermission "${derby.install.directory}${/}-", "read";
   permission java.util.PropertyPermission "user.*", "read";
   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "java.class.path", "read";
   permission java.util.PropertyPermission "java.runtime.version", "read";
   permission java.util.PropertyPermission "java.fullversion", "read";
   permission java.lang.RuntimePermission "getProtectionDomain";
-  permission java.io.FilePermission "<<ALL FILES>>", "read";
 };
 
 grant codeBase "${derby.install.url}derbytools.jar"

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java Mon Mar 12 01:32:23 2018
@@ -1821,11 +1821,11 @@ public final class NetworkServerControlI
                     consolePropertyMessage("DRDA_TraceDirectoryChange.I", traceDirectory);
                     break;
                 case COMMAND_TESTCONNECTION:
-                    databaseArg = reader.readCmdString();
-                    userArg = reader.readCmdString();
-                    passwordArg = reader.readCmdString();
+                    databaseArg = reader.readCmdString(); // This is ...
+                    userArg = reader.readCmdString(); // ... no longer ...
+                    passwordArg = reader.readCmdString(); // ... supported.
                     if (databaseArg != null)
-                        connectToDatabase(writer, databaseArg, userArg, passwordArg);
+                        sendMessage(writer, ERROR, "Usage: ping()");
                     else
                         sendOK(writer);
                     break;
@@ -3953,46 +3953,6 @@ public final class NetworkServerControlI
     
 
     /**
-     * Connect to a database to test whether a connection can be made
-     *
-     * @param writer    connection to send message to
-     * @param database  database directory to connect to
-     * @param user      user to use
-     * @param password  password to use
-     */
-    private void connectToDatabase(DDMWriter writer, String database, String user, 
-        String password) throws Exception
-    {
-        Properties p = new Properties();
-        if (user != null)
-            p.put("user", user);
-        if (password != null)
-            p.put("password", password);
-        try {
-            Class.forName(CLOUDSCAPE_DRIVER);
-        }
-        catch (Exception e) {
-            sendMessage(writer, ERROR, e.getMessage());
-            return;
-        }
-        try {
-            //Note, we add database to the url so that we can allow additional
-            //url attributes
-            Connection conn = getDriver().connect(Attribute.PROTOCOL+database, p);
-            // send warnings
-            SQLWarning warn = conn.getWarnings();
-            if (warn != null)
-                sendSQLMessage(writer, warn, SQLWARNING);
-            else
-                sendOK(writer);
-            conn.close();
-            return;
-        } catch (SQLException se) {
-            sendSQLMessage(writer, se, SQLERROR);
-        }
-    }
-
-    /**
      * Wrap SQL Error - display to console and raise exception
      *
      * @param messageKey    Derby SQL Exception message id

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Property.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Property.java?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Property.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Property.java Mon Mar 12 01:32:23 2018
@@ -416,6 +416,7 @@ public interface Property {
      * This property is the location of the derby jars.
      **/
     public static final String DERBY_INSTALL_URL = "derby.install.url";
+    public static final String DERBY_INSTALL_PATH = "derby.install.path";
 
     /**
      * This property is private to Derby.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.java?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.java Mon Mar 12 01:32:23 2018
@@ -22,6 +22,10 @@
 package org.apache.derbyTesting.functionTests.tests.derbynet;
 
 import java.io.File;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import javax.net.SocketFactory;
+import java.net.Socket;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.AccessController;
@@ -205,6 +209,138 @@ public class NetworkServerControlApiTest
         	// expected exception
         }
     }
+
+    /*
+     * CVE-2018-1313: Attempt to pass arguments to COMMAND_TESTCONNECTION
+     */
+    public void test_03_ping_args() throws Exception
+    {
+        String response = tryPingDbError("mydatabase", "myuser", "mypassword");
+        //System.out.println(response);
+        // This once said: XJ004:Database 'mydatabase' not found.
+        assertEquals("Usage", response.substring(0,5));
+
+        response = tryPingDbError("some/sorta/db","someone","somecredentials");
+        //System.out.println(response);
+        assertEquals("Usage", response.substring(0,5));
+
+        response = tryPingDbError("\\\\192.168.1.2\\guest\\db1","tata","tata");
+        //System.out.println(response);
+        assertEquals("Usage", response.substring(0,5));
+
+        response = tryPingDbError("my/nocred/db", "", "");
+        //System.out.println(response);
+        assertEquals("Usage", response.substring(0,5));
+
+        response = tryPingDbOK("", "scarface", "evildoer");
+        //System.out.println(response);
+        assertEquals("OK", response.substring(0,2));
+    }
+
+    private Socket privilegedClientSocket(final String host, int port)
+                        throws Exception
+    {
+        try {
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Socket>() {
+                public Socket run() throws Exception {
+                    return SocketFactory.getDefault().createSocket(
+                                InetAddress.getByName(host), port);
+                }
+            });
+        } catch (PrivilegedActionException pae) {
+            throw (Exception)pae.getCause();
+        }
+    }
+
+    private static String byteArrayToHex(byte[] ba, int l)
+    {
+        if (l < 0) return "STRING OF NEGATIVE LENGTH("+l+")";
+        StringBuilder sb = new StringBuilder(l * 2);
+        for (int i = 0; i < l; i++) sb.append(String.format("%02x", ba[i]));
+        return sb.toString();
+    }
+
+    private String tryPingDbError(String d, String u, String p)
+                    throws Exception
+    {
+        return tryPingDbTest(2, d, u, p); // Result 2: ERROR
+    }
+
+    private String tryPingDbOK(String d, String u, String p)
+                    throws Exception
+    {
+        return tryPingDbTest(0, d, u, p); // Result 0: OK
+    }
+
+    private String tryPingDbTest(int rc, String d, String u, String p)
+                    throws Exception
+    {
+        //System.out.println("database: '"+d+"' (len: "+d.length()+")");
+        //System.out.println("    user: '"+u+"' (len: "+u.length()+")");
+        //System.out.println("password: '"+p+"' (len: "+p.length()+")");
+
+        Socket clientSocket = privilegedClientSocket(
+                TestConfiguration.getCurrent().getHostName(),
+                TestConfiguration.getCurrent().getPort());
+        ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
+        DataOutputStream commandOs = new DataOutputStream(byteArrayOs);
+
+        byte[] msgBytes = "CMD:".getBytes("UTF8");
+        commandOs.write(msgBytes,0,msgBytes.length);
+        commandOs.writeByte((byte) 0); // default version: 02
+        commandOs.writeByte((byte) 2); // default version: 02
+        commandOs.writeByte((byte) 0); // default locale: 0
+        commandOs.writeByte((byte) 0); // default codeset: 0
+        commandOs.writeByte((byte) 4); // COMMAND_TESTCONNECTION
+
+        msgBytes = d.getBytes("UTF8");
+        commandOs.writeByte((byte)(msgBytes.length >> 8 ));
+        commandOs.writeByte((byte) msgBytes.length);
+        commandOs.write(msgBytes,0,msgBytes.length);
+
+        msgBytes = u.getBytes("UTF8");
+        commandOs.writeByte((byte)(msgBytes.length >> 8 ));
+        commandOs.writeByte((byte) msgBytes.length);
+        commandOs.write(msgBytes,0,msgBytes.length);
+
+        msgBytes = p.getBytes("UTF8");
+        commandOs.writeByte((byte)(msgBytes.length >> 8 ));
+        commandOs.writeByte((byte) msgBytes.length);
+        commandOs.write(msgBytes,0,msgBytes.length);
+
+        byteArrayOs.writeTo(clientSocket.getOutputStream());
+        commandOs.flush();
+        byteArrayOs.reset();
+        clientSocket.shutdownOutput();
+
+        byte[]result = new byte[1024];
+        int resultLen = clientSocket.getInputStream().read(result);
+
+        clientSocket.close();
+        
+        //System.out.println( "Result was " + resultLen + " bytes long");
+        //System.out.println( byteArrayToHex(result,resultLen) );
+        
+        if (resultLen < 0)
+            return "DISCONNECT";
+
+        String r = "RPY:";
+        int rl   = r.length();
+        assertTrue(resultLen > rl);
+        String header = new String(result, 0, rl, "UTF8");
+        assertEquals(r, header);
+        assertEquals(rc, result[rl++]); // 0: OK, 2: ERROR, 3: SQLERROR, etc.
+
+        if (rc == 0)
+            return "OK";
+
+        int l = ((result[rl++] & 0xff) << 8) + (result[rl++] & 0xff);
+        String response = new String(result, rl, l, "UTF8");
+
+        return response;
+    }
+
     
     /**
      * Wraps InitAddress.getByName in privilege block.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.policy?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.policy (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/NetworkServerControlApiTest.policy Mon Mar 12 01:32:23 2018
@@ -187,6 +187,10 @@ grant codeBase "${derbyTesting.testing}"
 
   // Needed by NetworkServerTestSetup when probing ports.
   permission java.net.SocketPermission "localhost", "listen";
+  permission java.net.SocketPermission "127.0.0.1", "accept,connect,resolve";
+  permission java.net.SocketPermission "localhost", "accept,connect,listen";
+  permission java.net.SocketPermission "${derbyTesting.clienthost}", "accept,connect";
+  permission java.net.SocketPermission "${derbyTesting.serverhost}", "accept,connect";
 };
 
 // JUnit jar file tries to read junit.properties in the user's

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/nast1.jar
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/nast1.jar?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
Binary files - no diff available.

Modified: db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java?rev=1826481&r1=1826480&r2=1826481&view=diff
==============================================================================
--- db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java (original)
+++ db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/sysinfo/Main.java Mon Mar 12 01:32:23 2018
@@ -23,6 +23,8 @@ package org.apache.derby.impl.tools.sysi
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -877,6 +879,31 @@ public static void getMainInfo (java.io.
         org.apache.derby.shared.common.info.ProductGenusNames.OPTIONAL_INFO,
     };
 
+	private static final String jarNames[] = 
+	{
+        "derby.jar",
+        "derbyclient.jar",
+        "derbynet.jar",
+        "derbyoptionaltools.jar",
+        "derbyrun.jar",
+        "derbyshared.jar",
+        "derbyTesting.jar",
+        "derbytools.jar",
+        "derbyLocale_cs.jar",
+        "derbyLocale_de_DE.jar",
+        "derbyLocale_es.jar",
+        "derbyLocale_ja_JP.jar",
+        "derbyLocale_ko_KR.jar",
+        "derbyLocale_pl.jar",
+        "derbyLocale_pt_BR.jar",
+        "derbyLocale_ru.jar",
+        "derbyLocale_fr.jar",
+        "derbyLocale_zh_CN.jar",
+        "derbyLocale_hu.jar",
+        "derbyLocale_zh_TW.jar",
+        "derbyLocale_it.jar"
+	};
+
     /**
      *  Get all the info we can obtain from the local execution context
      *  as to the availability of the Derby classes by attempting to load
@@ -908,9 +935,23 @@ public static void getMainInfo (java.io.
         {
 			if (classpath != null) {
 				String cp [] = parseClasspath(classpath);
+				List<String> jarNamesList = Arrays.asList(jarNames);
 				Vector<ZipInfoProperties> v = new Vector<ZipInfoProperties>();
 				for (int i = 0; i < cp.length; i++)
 				{
+                    boolean matches = false;
+                    String candidate = cp[i];
+                    for (String jarName : jarNames)
+                    {
+                        if (candidate.endsWith(jarName))
+                        {
+                            matches = true;
+                            break;
+                        }
+                    }
+                    if (!matches)
+                        continue;
+
 					ZipInfoProperties zip = null;
 					try {
 						zip = checkForInfo(cp[i]);