Index: java/drda/org/apache/derby/impl/drda/Database.java =================================================================== --- java/drda/org/apache/derby/impl/drda/Database.java (revision 160383) +++ java/drda/org/apache/derby/impl/drda/Database.java (working copy) @@ -241,7 +241,10 @@ protected Connection makeConnection(Properties p) throws SQLException { p.put(Attribute.USERNAME_ATTR, userId); - p.put(Attribute.PASSWORD_ATTR, password); + + // take care of case of SECMEC_USRIDONL + if(password != null) + p.put(Attribute.PASSWORD_ATTR, password); Connection conn = DB2jServerImpl.getDriver().connect(Attribute.PROTOCOL + dbName + attrString, p); conn.setAutoCommit(false); Index: java/drda/org/apache/derby/impl/drda/DRDAConnThread.java =================================================================== --- java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (revision 160383) +++ java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (working copy) @@ -1556,10 +1556,13 @@ securityMechanism = reader.readNetworkShort(); if (SanityManager.DEBUG) trace("Security mechanism = " + securityMechanism); - if (securityMechanism != server.DEFAULT_SECURITY_MECHANISM) + // for plain text userid,password USRIDPWD, and USRIDONL + // no need of decryptionManager + if (securityMechanism != CodePoint.SECMEC_USRIDPWD && + securityMechanism != CodePoint.SECMEC_USRIDONL) { //this is the only other one we understand - if (securityMechanism != CodePoint.SECMEC_EUSRIDPWD) + if (securityMechanism != CodePoint.SECMEC_EUSRIDPWD) securityCheckCode = CodePoint.SECCHKCD_NOTSUPPORTED; else { @@ -1612,13 +1615,14 @@ if (securityCheckCode == 0 && database.securityMechanism == CodePoint.SECMEC_EUSRIDPWD && database.publicKeyIn == null) - securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING; + securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING_OR_INVALID; // shouldn't have security token if (securityCheckCode == 0 && - database.securityMechanism == CodePoint.SECMEC_USRIDPWD && + (database.securityMechanism == CodePoint.SECMEC_USRIDPWD || + database.securityMechanism == CodePoint.SECMEC_USRIDONL) && database.publicKeyIn != null) - securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING; + securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING_OR_INVALID; if (SanityManager.DEBUG) trace("** ACCSECRD securityCheckCode is: "+securityCheckCode); @@ -2468,6 +2472,7 @@ // these are the ones we know about writer.writeScalar2Bytes(CodePoint.SECMEC, CodePoint.SECMEC_USRIDPWD); writer.writeScalar2Bytes(CodePoint.SECMEC, CodePoint.SECMEC_EUSRIDPWD); + writer.writeScalar2Bytes(CodePoint.SECMEC, CodePoint.SECMEC_USRIDONL); } if (securityCheckCode != 0) { @@ -2535,7 +2540,7 @@ case CodePoint.SECTKN: if (database.securityMechanism != CodePoint.SECMEC_EUSRIDPWD) { - securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING; + securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING_OR_INVALID; reader.skipBytes(); } else if (database.decryptedUserId == null) { @@ -2612,12 +2617,16 @@ //check if we have a userid and password when we need it if (securityCheckCode == 0 && - database.securityMechanism == CodePoint.SECMEC_USRIDPWD) + (database.securityMechanism == CodePoint.SECMEC_USRIDPWD|| + database.securityMechanism == CodePoint.SECMEC_USRIDONL )) { if (database.userId == null) securityCheckCode = CodePoint.SECCHKCD_USERIDMISSING; - else if (database.password == null) + else if ( database.securityMechanism == CodePoint.SECMEC_USRIDPWD) + { + if (database.password == null) securityCheckCode = CodePoint.SECCHKCD_PASSWORDMISSING; + } //Note, we'll ignore encryptedUserId and encryptedPassword if they //are also set } Index: java/drda/org/apache/derby/impl/drda/CodePoint.java =================================================================== --- java/drda/org/apache/derby/impl/drda/CodePoint.java (revision 160383) +++ java/drda/org/apache/derby/impl/drda/CodePoint.java (working copy) @@ -709,7 +709,7 @@ //---------------------Security Check Codes --------------------------- static final int SECCHKCD_OK = 0; // Security info correct and acceptable static final int SECCHKCD_NOTSUPPORTED = 0x01; // SECMEC value not supported - static final int SECCHKCD_SECTKNMISSING = 0x0E; // SECTKN missing or invalid + static final int SECCHKCD_SECTKNMISSING_OR_INVALID = 0x0E; // SECTKN missing or invalid static final int SECCHKCD_PASSWORDMISSING = 0x10; // Password missing static final int SECCHKCD_USERIDMISSING = 0x12; // User Id missing static final int SECCHKCD_USERIDINVALID = 0x13; // Userid invalid Index: java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java =================================================================== --- java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java (revision 160383) +++ java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java (working copy) @@ -171,7 +171,6 @@ protected final static int DEFAULT_CCSID = 1208; protected final static byte SPACE_CHAR = 32; - protected final static int DEFAULT_SECURITY_MECHANISM = CodePoint.SECMEC_USRIDPWD; // Application Server manager levels - this needs to be in sync // with CodePoint.MGR_CODEPOINTS Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec.java =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec.java (revision 0) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec.java (revision 0) @@ -0,0 +1,219 @@ +/* + + Derby - Class org.apache.derbyTesting.functionTests.tests.derbynet.testSecMec + + Copyright 2003, 2004 The Apache Software Foundation or its licensors, as applicable. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + */ + +package org.apache.derbyTesting.functionTests.tests.derbynet; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.PreparedStatement; +import java.sql.CallableStatement; +import java.sql.Statement; +import java.sql.SQLException; +import java.sql.DriverManager; +import javax.sql.DataSource; + +import org.apache.derby.tools.JDBCDisplayUtil; +import org.apache.derby.tools.ij; +import org.apache.derby.drda.NetworkServerControl; +import org.apache.derbyTesting.functionTests.util.TestUtil; +import java.io.*; +import java.net.InetAddress; +import java.util.Hashtable; +import java.util.Properties; + +import java.lang.reflect.*; + +/** + * This class tests the security mechanisms supported by Network Server + * Network server supports SECMEC_EUSRIDPWD, SECMEC_USRIDPWD, SECMEC_USRIDONL + * Note - currently the SECMEC_EUSRIDPWD does not work with all versions of ibm142 + * because of the following reason + * The DiffieHelman algorithm that is used here uses a prime of 32bytes and this is not + * supported by Sun JCE , but is supported in ibm141 and some latest versions of ibm142 + * + */ +public class testSecMec extends dataSourcePermissions_net + +{ + + private static final int NETWORKSERVER_PORT = 20000; + + private static NetworkServerControl networkServer = null; + + public static void main(String[] args) throws Exception { + + // Load harness properties. + ij.getPropertyArg(args); + + // "runTest()" is going to try to connect to the database through + // the server at port NETWORKSERVER_PORT. Thus, we have to + // start the server on that port before calling runTest. + + try { + TestUtil.loadDriver(); + } catch (Exception e) { + e.printStackTrace(); + } + + // Start the NetworkServer on another thread + networkServer = new NetworkServerControl(InetAddress.getByName("localhost"),NETWORKSERVER_PORT); + networkServer.start(null); + + // Wait for the NetworkServer to start. + if (!isServerStarted(networkServer, 60)) + System.exit(-1); + + // Now, go ahead and run the test. + try { + testSecMec tester = new testSecMec(); + tester.runTest(); + + } catch (Exception e) { + // if we catch an exception of some sort, we need to make sure to + // close our streams before returning; otherwise, we can get + // hangs in the harness. SO, catching all exceptions here keeps + // us from exiting before closing the necessary streams. + System.out.println("FAIL - Exiting due to unexpected error: " + + e.getMessage()); + e.printStackTrace(); + } + + // Shutdown the server. + networkServer.shutdown(); + // how do we do this with the new api? + //networkServer.join(); + Thread.sleep(5000); + System.out.println("Completed testSecMec"); + + System.out.close(); + System.err.close(); + + } + + + // Indicates userid/encrypted password security mechanism. + static final short SECMEC_EUSRIDPWD = 0x09; + + // Indicates userid only security mechanism. + static final short SECMEC_USRIDONL = 0x04; + + // Indicates userid/encrypted password security mechanism. + static final short SECMEC_USRENCPWD = 0x07; + + // Indicates userid/new password security mechanism. + static final short SECMEC_USRIDNWPWD = 0x05; + + // Indicates userid/password security mechanism. + static final short SECMEC_USRIDPWD = 0x03; + + + /** + * Test cases for security mechanism + * --------------------------------------------------------------- + * T1 - default , no user PASS (for derbyclient) + * T2 - user only PASS (for derbyclient) + * T3 - user,password PASS (only for derbynet) + * T4 - user,password, security mechanism not set FAIL + * T5 - user,password, security mechanism set to SECMEC_USRIDPWD PASS + * T6 - user, security mechanism set to SECMEC_USRIDONL PASS + * T7 - user,password, security mechanism set to SECMEC_USRENCPWD FAIL + * Test with datasource as well as DriverManager + * T8 - user,password security mechanism set to SECMEC_USRIDONL PASS + * Test with datasource as well as DriverManager + */ + + protected void runTest() + { + // Test cases with get connection via drivermanager and using + // different security mechanisms. + // Network server supports SECMEC_USRIDPWD, SECMEC_USRIDONL,SECMEC_EUSRIDPWD + System.out.println("Checking security mechanism authentication with DriverManager"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true",null),"T1:"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=max"),"T2:"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;password=lee"),"T3:"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;password=lee;securityMechanism="+SECMEC_USRIDPWD),"T4:"); + // Disable because ibm142 doesnt support DiffieHelman prime of 32 bytes + // Also Sun JCE doesnt support it. + //getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;password=lee;securityMechanism="+SECMEC_EUSRIDPWD),"T5:"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;securityMechanism="+SECMEC_USRIDONL),"T6:"); + + // disable as ibm142 and sun jce doesnt support DH prime of 32 bytes + //getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;password=lee;securityMechanism="+SECMEC_USRENCPWD),"T7:"); + getConnectionUsingDriverManager(getJDBCUrl("wombat;create=true","user=neelima;password=lee;securityMechanism="+SECMEC_USRIDONL),"T8:"); + + getConnectionUsingDataSource(); + + } + + /* + * Get connection from datasource and also set security mechanism + */ + + public void getConnectionUsingDataSource() + { + // bug in jcc, throws error with null password + //testSecurityMechanism("sarah",null,new Short(SECMEC_USRIDONL),"SECMEC_USRIDONL:"); + testSecurityMechanism("john","sarah",new Short(SECMEC_USRIDPWD),"SECMEC_USRIDPWD:"); + + // Disable this test because ibm142, sun jce does not Diffie Helman prime of 32 bytes + // and so this security mechanism wont work in that case + //testSecurityMechanism("john","sarah",new Short(SECMEC_EUSRIDPWD),"SECMEC_EUSRIDPWD:"); + + } + + public void testSecurityMechanism(String user, String password,Short secmec,String msg) + { + Connection conn; + String securityMechanismProperty = "SecurityMechanism"; + Class[] argType = { Short.TYPE }; + String methodName = TestUtil.getSetterName(securityMechanismProperty); + Object[] args = new Short[1]; + args[0] = secmec; + + try { + DataSource ds = getDS("wombat", user,password); + Method sh = ds.getClass().getMethod(methodName, argType); + sh.invoke(ds, args); + conn = ds.getConnection(); + conn.close(); + System.out.println(msg +" OK"); + } + catch (Exception e) + { + System.out.println(msg +"EXCEPTION testSecurityMechanism() " + e.getMessage()); + } + } + + public void getConnectionUsingDriverManager(String dbUrl, String msg) + { + + try + { + DriverManager.getConnection(dbUrl); + System.out.println(msg +" "+dbUrl ); + } + catch(SQLException sqle) + { + System.out.println(msg +" "+dbUrl +" - EXCEPTION "+ sqle.getMessage()); + } + } + + +} Property changes on: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec.java ___________________________________________________________________ Name: svn:eol-style + native Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec_app.properties =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec_app.properties (revision 0) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec_app.properties (revision 0) @@ -0,0 +1,27 @@ +# +# This is the default system properties file for SQL and JAVA tests. +# +# *** DO NOT PUT PROPERTIES FOR THE DERBY SYSTEM IN THIS FILE. +# *** THEY BELONG IN default_derby.properties. +# +# This file will get handed to the test on the command line in a -p +# argument. +# +# This causes ij to load the driver and make an +# initial connection to the database. +# +# The .java test has to call util.getPropertyArg and util.startJBMS +# to process the property file. See any of the .java tests for this code. +# +# If you want to alter these to use a different driver, connect to a different +# database, or to not be used, override this file by creating +# a file _app.properties to be used instead of this file. +# +# +excludeJCC=1.1 +startServer=false +database=wombat;create=true +derby.optimizer.noTimeout=true +ij.defaultResourcePackage=/org/apache/derbyTesting/functionTests/tests/lang/ +ij.showNoConnectionsAtStart=true +ij.showNoCountForSelect=true Property changes on: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testSecMec_app.properties ___________________________________________________________________ Name: svn:eol-style + native Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests (working copy) @@ -141,6 +141,7 @@ readLengthAndCodePoint ACCSECRD // ACCSECRD readScalar2Bytes SECMEC 3// SECMEC readScalar2Bytes SECMEC 9// SECMEC +readScalar2Bytes SECMEC 4// SECMEC readScalar1Byte SECCHKCD 1// SECMEC endTest // @@ -296,6 +297,7 @@ readLengthAndCodePoint ACCSECRD // ACCSECRD readScalar2Bytes SECMEC 3// SECMEC readScalar2Bytes SECMEC 9// SECMEC +readScalar2Bytes SECMEC 4// SECMEC readScalar1Byte SECCHKCD 1// SECMEC // ok send one we support createDssRequest Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testclientij.sql =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testclientij.sql (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testclientij.sql (working copy) @@ -65,4 +65,7 @@ -- Should see message text select * from APP.notthere; +-- just user security mechanism +connect 'jdbc:derby://localhost:1527/my-db-name;create=true;user=usr;retrieveMessageText=true'; +connect 'jdbc:derby://localhost:1527/wombat' USER 'APP'; Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testij.sql =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testij.sql (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/testij.sql (working copy) @@ -40,4 +40,6 @@ connect 'jdbc:derby:net://localhost:1527/"./my-dbname;create=true":user=usr;password=pwd;retrieveMessagesFromServerOnGetMessage=true;'; +-- with no user +connect 'jdbc:derby:net://localhost:1527/wombat;create=true:retrieveMessagesFromServerOnGetMessage=true;'; Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/dataSourcePermissions_net.java =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/dataSourcePermissions_net.java (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/dataSourcePermissions_net.java (working copy) @@ -123,7 +123,7 @@ public void setProperties() { // Set required server properties. - System.setProperty("database", + System.setProperty("database", TestUtil.getJdbcUrlPrefix("localhost", NETWORKSERVER_PORT) + "wombat;create=true"); @@ -134,7 +134,7 @@ public String getJDBCUrl(String db, String attrs) { - String s = TestUtil.getJdbcUrlPrefix("localhost", NETWORKSERVER_PORT) + String s = TestUtil.getJdbcUrlPrefix("localhost", NETWORKSERVER_PORT) + db; if (attrs != null) if (TestUtil.isJCCFramework()) @@ -146,16 +146,16 @@ } - public javax.sql.DataSource getDS(String database, String user, String + public javax.sql.DataSource getDS(String database, String user, String password) { return getDS(database,user,password,null); } public javax.sql.DataSource getDS(String database, String user, String - password, Properties attrs) + password, Properties attrs) { - + if (attrs == null) attrs = new Properties(); attrs.setProperty("databaseName", database); @@ -166,9 +166,9 @@ attrs = addRequiredAttributes(attrs); return TestUtil.getDataSource(attrs); } - + public javax.sql.ConnectionPoolDataSource getCPDS(String database, String user, String password) { Properties attrs = new Properties(); attrs.setProperty("databaseName", database); @@ -221,7 +221,7 @@ } } - private static boolean isServerStarted(NetworkServerControl server, int ntries) + protected static boolean isServerStarted(NetworkServerControl server, int ntries) { for (int i = 1; i <= ntries; i ++) { @@ -247,9 +247,9 @@ testRetrieveMessageText(); } - /** + /** * Test property retrieveMessageText to retrieve message text - * Property defaults to true for Network Client but can be set to + * Property defaults to true for Network Client but can be set to * false to disable the procedure call. */ public void testRetrieveMessageText() throws SQLException @@ -268,7 +268,7 @@ conn = ds.getConnection(); checkMessageText(conn,"false"); conn.close(); - + // now try with retrieveMessageText = true ds = getDS("wombat", "EDWARD", "noodle"); args = new Boolean[] { new Boolean(true) }; @@ -287,7 +287,7 @@ public void checkMessageText(Connection conn, String retrieveMessageTextValue) throws SQLException { - System.out.println("** checkMessageText() with retrieveMessageText= " + + System.out.println("** checkMessageText() with retrieveMessageText= " + retrieveMessageTextValue); try { @@ -299,8 +299,8 @@ String sqlState = e.getSQLState(); if (sqlState == null || ! sqlState.equals(expectedSQLState)) { - System.out.println("Incorrect SQLState. Got: " + sqlState + - " should be: " + expectedSQLState); + System.out.println("Incorrect SQLState. Got: " + sqlState + + " should be: " + expectedSQLState); throw e; } if (retrieveMessageTextValue.equals("true") ) @@ -324,7 +324,7 @@ System.out.println("FAIL: Message Text should not have been retrieved"); throw e; } - + } } Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/copyfiles.ant =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/copyfiles.ant (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/copyfiles.ant (working copy) @@ -17,6 +17,7 @@ testij_app.properties testij_sed.properties testProtocol_app.properties +testSecMec_app.properties protocol.tests excsat_accsecrd1.inc excsat_accsecrd2.inc Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/testSecMec.out =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/testSecMec.out (revision 0) +++ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/testSecMec.out (revision 0) @@ -0,0 +1,9 @@ +Checking security mechanism authentication with DriverManager +T1: jdbc:derby:net://localhost:20000/wombat;create=true - EXCEPTION null userid not supported +T2: jdbc:derby:net://localhost:20000/wombat;create=true:user=max; - EXCEPTION null password not supported +T3: jdbc:derby:net://localhost:20000/wombat;create=true:user=neelima;password=lee; +T4: jdbc:derby:net://localhost:20000/wombat;create=true:user=neelima;password=lee;securityMechanism=3; +T6: jdbc:derby:net://localhost:20000/wombat;create=true:user=neelima;securityMechanism=4; +T8: jdbc:derby:net://localhost:20000/wombat;create=true:user=neelima;password=lee;securityMechanism=4; +SECMEC_USRIDPWD: OK +Completed testSecMec Property changes on: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/testSecMec.out ___________________________________________________________________ Name: svn:eol-style + native Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/testSecMec.out =================================================================== Index: java/testing/org/apache/derbyTesting/functionTests/master/testij.out =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/master/testij.out (revision 160386) +++ java/testing/org/apache/derbyTesting/functionTests/master/testij.out (working copy) @@ -35,4 +35,7 @@ connect 'jdbc:derby:net://localhost:1527/"./my-dbname;create=true":user=usr;password=pwd;'; ERROR 08006: DB2 SQL error: SQLCODE: -1, SQLSTATE: 08006, SQLERRMC: my-db-name08006.DDatabase 'my-db-name' shutdown.((server log XXX) ij(CONNECTION5)> connect 'jdbc:derby:net://localhost:1527/"./my-dbname;create=true":user=usr;password=pwd;retrieveMessagesFromServerOnGetMessage=true;'; +ij(CONNECTION6)> -- with no user +connect 'jdbc:derby:net://localhost:1527/wombat;create=true:retrieveMessagesFromServerOnGetMessage=true;'; +ERROR (no SQLState): null userid not supported ij(CONNECTION6)> Index: java/testing/org/apache/derbyTesting/functionTests/suites/derbynetmats.runall =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/suites/derbynetmats.runall (revision 160383) +++ java/testing/org/apache/derbyTesting/functionTests/suites/derbynetmats.runall (working copy) @@ -18,6 +18,7 @@ derbynet/testconnection.java derbynet/testij.java derbynet/timeslice.java +derbynet/testSecMec.java jdbcapi/autoGeneratedJdbc30.java jdbcapi/dbMetaDataJdbc30.java jdbcapi/metadata.java