[teiid-commits] teiid SVN: r3201 - in branches/7.4.x: build/kits/jboss-container/deploy/teiid and 6 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu May 26 11:47:41 EDT 2011


Author: shawkins
Date: 2011-05-26 11:47:40 -0400 (Thu, 26 May 2011)
New Revision: 3201

Modified:
   branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
   branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
   branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/odbc.xml
   branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/ssl.xml
   branches/7.4.x/engine/src/main/java/org/teiid/security/Credentials.java
   branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
   branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
   branches/7.4.x/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
   branches/7.4.x/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
   branches/7.4.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties
   branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
Log:
TEIID-1460 adding ssl support to odbc

Modified: branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml	2011-05-26 15:47:40 UTC (rev 3201)
@@ -229,7 +229,7 @@
     <bean name="OdbcSslConfiguration" class="org.teiid.transport.SSLConfiguration">
         <!-- can be one of disabled or enabled 
              disabled = no transport or message level security will be used
-             enabled = traffic will be secured using this configuration
+             enabled = traffic will be secured using this configuration if the client supports SSL
         -->
         <property name="mode">disabled</property>
         <property name="keystoreFilename">cert.keystore</property>

Modified: branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html	2011-05-26 15:47:40 UTC (rev 3201)
@@ -56,6 +56,7 @@
 	<LI><B>Cache Invalidation</B> - Prepared plan and result set caches have will invalidate entries based upon metadata and data changes respectively.  See the cache configuration maxStaleness setting and the Admin and Developer Guides for more.
 	<LI><B>Runtime Updates of Metadata</B> - ALTER statements have been added to change view/procedure/INSTEAD OF trigger (update procedure) definitions.  A CREATE TRIGGER statement is also available to add an INSTEAD OF trigger (update procedures) to views. 
 	System procedures were added to set extension metadata and stat values.  By default all effects of metadata updates happen only on running vdbs across the cluster.  To make the changes persistent see the Developers Guide Runtime Updates section.
+	<LI><B>ODBC SSL</B> - added support for SSL encrypted ODBC connections.
 </UL>
 
 <h2><a name="Compatibility">Compatibility Issues</a></h2>

Modified: branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/odbc.xml
===================================================================
--- branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/odbc.xml	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/odbc.xml	2011-05-26 15:47:40 UTC (rev 3201)
@@ -23,6 +23,11 @@
      <para>Before an application can use ODBC, you must first install the ODBC driver on same machine that 
      the application is running on and then create Data Source Name (DSN) that represents a connection profile for your Teiid VDB.
      </para>
+     
+     <warning><para>Teiid currently only supports plain text passward authentication for ODBC.  
+     If the client/server are not configured to use SSL, the password will be sent in plain text over the network.  
+     If you need secure passwords in transit and are not using SSL, then consider installing a security domain 
+     that will accept safe password values from the client (for example encrypted or hashed).</para></warning>
 
     <section id="install">
         <title>Installing the ODBC Driver Client</title>
@@ -145,7 +150,6 @@
                     listenes for ODBC requests on port 35432</para>
                     <para>In the <emphasis>User Name</emphasis> and <emphasis>Password</emphasis> edit boxes, supply the user name and password
                     for the Teiid runtime access.</para>
-                    <para>Leave <emphasis>SSL Mode</emphasis> to disabled. SSL connections are currently not supported.</para>
                     <para>Provide any description about the data source in the <emphasis>Description</emphasis> field.</para>
                 </listitem>
                 

Modified: branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/ssl.xml
===================================================================
--- branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/ssl.xml	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/documentation/client-developers-guide/src/main/docbook/en-US/content/ssl.xml	2011-05-26 15:47:40 UTC (rev 3201)
@@ -13,13 +13,13 @@
     <section id="default_security">
         <title>Default Security</title>
         
-        <para>If you are using a socket connection, then you may need to secure the channel more completely.</para>
-    
-        <para>By default all sensitive (non-data) messages between client and server 
+        <para>By default all JDBC/Admin sensitive (non-data) messages between client and server 
         are encrypted using a <ulink url="http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange">Diffy-Hellman</ulink> 
         key that is negotiated per connection. This 
         encryption is controlled by <code>clientEncryptionEnabled</code> property in <code>JdbcSslConfiguration</code> and 
         <code>AdminSslConfiguration</code> sections in the &jboss-beans; file.</para>
+        
+        <para>If you are using a socket connection, then you may need to secure the channel more completely - especially if using ODBC, which currently only supports plain text authentication.</para>
     </section>
     
     <section id="ssl_modes">

Modified: branches/7.4.x/engine/src/main/java/org/teiid/security/Credentials.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/security/Credentials.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/engine/src/main/java/org/teiid/security/Credentials.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -26,7 +26,9 @@
 
 public class Credentials implements Serializable {
     
-    private char[] credentials = null;
+	private static final long serialVersionUID = 7453114713211221240L;
+	
+	private char[] credentials = null;
     
     /**
      * Construct a new PasswordCredentials 

Modified: branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -85,7 +85,7 @@
 	void functionCallResponse(byte[] data);
 	void functionCallResponse(int data);
 	
-	void sslDenied();
+	void sendSslResponse();
 	
 	// unimplemented backend messages
 	

Modified: branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -637,7 +637,7 @@
 	
 	@Override
 	public void sslRequest() {
-		this.client.sslDenied();
+		this.client.sendSslResponse();
 	}
 	
 	private void setEncoding() {

Modified: branches/7.4.x/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
===================================================================
--- branches/7.4.x/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -23,11 +23,8 @@
 
 import java.util.Properties;
 
-import javax.net.ssl.SSLEngine;
-
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.DefaultChannelPipeline;
-import org.jboss.netty.handler.ssl.SslHandler;
 import org.teiid.common.buffer.StorageManager;
 import org.teiid.core.TeiidException;
 import org.teiid.jdbc.EmbeddedProfile;
@@ -66,12 +63,8 @@
 			public ChannelPipeline getPipeline() throws Exception {
 				ChannelPipeline pipeline = new DefaultChannelPipeline();
 
-				SSLEngine engine = config.getServerSSLEngine();
-			    if (engine != null) {
-			        pipeline.addLast("ssl", new SslHandler(engine)); //$NON-NLS-1$
-			    }
 			    pipeline.addLast("odbcFrontendProtocol", new PgFrontendProtocol(1 << 20)); //$NON-NLS-1$
-			    pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol(maxLobSize)); //$NON-NLS-1$
+			    pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol(maxLobSize, config)); //$NON-NLS-1$
 			    pipeline.addLast("handler", this); //$NON-NLS-1$
 			    return pipeline;
 			}			

Modified: branches/7.4.x/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- branches/7.4.x/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -28,6 +28,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.charset.Charset;
+import java.security.GeneralSecurityException;
 import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.ParameterMetaData;
@@ -41,13 +42,18 @@
 import java.util.List;
 import java.util.Properties;
 
+import javax.net.ssl.SSLEngine;
+
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.jboss.netty.channel.ChannelDownstreamHandler;
 import org.jboss.netty.channel.ChannelEvent;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.Channels;
 import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.ssl.SslHandler;
 import org.teiid.client.util.ResultsFuture;
 import org.teiid.core.util.ObjectConverterUtil;
 import org.teiid.core.util.ReaderInputStream;
@@ -59,6 +65,7 @@
 import org.teiid.logging.LogManager;
 import org.teiid.net.socket.ServiceInvocationStruct;
 import org.teiid.odbc.ODBCClientRemote;
+import org.teiid.runtime.RuntimePlugin;
 import org.teiid.transport.pg.PGbytea;
 
 /**
@@ -68,7 +75,25 @@
 @SuppressWarnings("nls")
 public class PgBackendProtocol implements ChannelDownstreamHandler, ODBCClientRemote {
 	
-    private final class ResultsWorkItem implements Runnable {
+    private final class SSLEnabler implements ChannelFutureListener {
+    	
+    	private SSLEngine engine;
+    	
+		public SSLEnabler(SSLEngine engine) {
+			this.engine = engine;
+		}
+
+		@Override
+		public void operationComplete(ChannelFuture future) throws Exception {
+			if (future.isSuccess()) {
+				SslHandler handler = new SslHandler(engine);
+				future.getChannel().getPipeline().addFirst("sslHandler", handler);
+				handler.handshake();
+			}
+		}
+	}
+
+	private final class ResultsWorkItem implements Runnable {
 		private final List<PgColInfo> cols;
 		private final String sql;
 		private final ResultSetImpl rs;
@@ -164,8 +189,11 @@
     
 	private volatile ResultsFuture<Boolean> nextFuture;
 
-    public PgBackendProtocol(int maxLobSize) {
+	private SSLConfiguration config;
+
+    public PgBackendProtocol(int maxLobSize, SSLConfiguration config) {
     	this.maxLobSize = maxLobSize;
+    	this.config = config;
     }
     
 	@Override
@@ -550,10 +578,23 @@
 	}	
 	
 	@Override
-	public void sslDenied() {
+	public void sendSslResponse() {
+		SSLEngine engine = null;
+		try {
+			engine = config.getServerSSLEngine();
+		} catch (IOException e) {
+			LogManager.logError(LogConstants.CTX_ODBC, e, RuntimePlugin.Util.getString("PgBackendProtocol.ssl_error"));
+		} catch (GeneralSecurityException e) {
+			LogManager.logError(LogConstants.CTX_ODBC, e, RuntimePlugin.Util.getString("PgBackendProtocol.ssl_error"));
+		}
 		ChannelBuffer buffer = ChannelBuffers.directBuffer(1);
-		buffer.writeByte('N');
-		Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());		
+		if (engine == null) {
+			buffer.writeByte('N');
+		} else {
+			this.message.getFuture().addListener(new SSLEnabler(engine));
+			buffer.writeByte('S');
+		}
+		Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
 	}
 	
 	private void sendErrorResponse(Throwable t) throws IOException {

Modified: branches/7.4.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- branches/7.4.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties	2011-05-26 15:47:40 UTC (rev 3201)
@@ -91,4 +91,6 @@
 metadata_loaded=VDB {0}.{1} model {2} metadata is currently being loaded.
 ambigious_name=Ambiguous VDB name specified. Only single occurrence of the "." is allowed in the VDB name. Also, when version based vdb name is specified, then a separate "version" connection option is not allowed:{0}.{1} 
 lo_not_supported=LO functions are not supported
-SSLConfiguration.no_anonymous=The anonymous cipher suite TLS_DH_anon_WITH_AES_128_CBC_SHA is not available.  Please change the transport to be non-SSL or use non-anonymous SSL.
\ No newline at end of file
+SSLConfiguration.no_anonymous=The anonymous cipher suite TLS_DH_anon_WITH_AES_128_CBC_SHA is not available.  Please change the transport to be non-SSL or use non-anonymous SSL.
+
+PgBackendProtocol.ssl_error=Could not initialize ODBC SSL.  non-SSL connections will still be allowed.
\ No newline at end of file

Modified: branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
===================================================================
--- branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java	2011-05-26 14:59:56 UTC (rev 3200)
+++ branches/7.4.x/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java	2011-05-26 15:47:40 UTC (rev 3201)
@@ -24,8 +24,13 @@
 
 import static org.junit.Assert.*;
 
+import java.io.IOException;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
 import java.nio.charset.Charset;
+import java.security.NoSuchAlgorithmException;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -33,6 +38,10 @@
 import java.sql.Statement;
 import java.util.Properties;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -44,37 +53,107 @@
 import org.teiid.jdbc.FakeServer;
 import org.teiid.jdbc.TeiidDriver;
 import org.teiid.jdbc.TestMMDatabaseMetaData;
+import org.teiid.net.socket.SocketUtil;
 
 @SuppressWarnings("nls")
 public class TestODBCSocketTransport {
-
-	static InetSocketAddress addr;
-	static ODBCSocketListener odbcTransport;
 	
-	@BeforeClass public static void oneTimeSetup() throws Exception {
-		SocketConfiguration config = new SocketConfiguration();
-		config.setSSLConfiguration(new SSLConfiguration());
-		addr = new InetSocketAddress(0);
-		config.setBindAddress(addr.getHostName());
-		config.setPortNumber(0);
-		odbcTransport = new ODBCSocketListener(config, BufferManagerFactory.getStandaloneBufferManager(), 0, 100000);
+public static class AnonSSLSocketFactory extends SSLSocketFactory {
 		
-		FakeServer server = new FakeServer();
-		server.setUseCallingThread(false);
-		server.deployVDB("parts", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb");
+		private SSLSocketFactory sslSocketFactory;
 		
-		TeiidDriver driver = new TeiidDriver();
-		driver.setEmbeddedProfile(server);
-		odbcTransport.setDriver(driver);
+		public AnonSSLSocketFactory() {
+			try {
+				sslSocketFactory = SSLContext.getDefault().getSocketFactory();
+			} catch (NoSuchAlgorithmException e) {
+				throw new RuntimeException();
+			}			
+		}
+
+		public Socket createSocket() throws IOException {
+			return sslSocketFactory.createSocket();
+		}
+
+		public Socket createSocket(InetAddress address, int port,
+				InetAddress localAddress, int localPort) throws IOException {
+			return sslSocketFactory.createSocket(address, port, localAddress,
+					localPort);
+		}
+
+		public Socket createSocket(InetAddress host, int port)
+				throws IOException {
+			return sslSocketFactory.createSocket(host, port);
+		}
+
+		public Socket createSocket(Socket s, String host, int port,
+				boolean autoClose) throws IOException {
+			SSLSocket socket = (SSLSocket)sslSocketFactory.createSocket(s, host, port, autoClose);
+			SocketUtil.addCipherSuite(socket, SocketUtil.ANON_CIPHER_SUITE);
+			return socket;
+		}
+
+		public Socket createSocket(String host, int port,
+				InetAddress localHost, int localPort) throws IOException,
+				UnknownHostException {
+			return sslSocketFactory.createSocket(host, port, localHost,
+					localPort);
+		}
+
+		public Socket createSocket(String host, int port) throws IOException,
+				UnknownHostException {
+			return sslSocketFactory.createSocket(host, port);
+		}
+
+		public String[] getDefaultCipherSuites() {
+			return sslSocketFactory.getDefaultCipherSuites();
+		}
+
+		public String[] getSupportedCipherSuites() {
+			return sslSocketFactory.getSupportedCipherSuites();
+		}
 		
 	}
 	
-	@AfterClass public static void oneTimeTearDown() throws Exception {
-		if (odbcTransport != null) {
+	static class FakeOdbcServer {
+		InetSocketAddress addr;
+		ODBCSocketListener odbcTransport;
+		
+		public void start() throws Exception {
+			SocketConfiguration config = new SocketConfiguration();
+			SSLConfiguration sslConfig = new SSLConfiguration();
+			sslConfig.setMode(SSLConfiguration.ENABLED);
+			sslConfig.setAuthenticationMode(SSLConfiguration.ANONYMOUS);
+			config.setSSLConfiguration(sslConfig);
+			addr = new InetSocketAddress(0);
+			config.setBindAddress(addr.getHostName());
+			config.setPortNumber(0);
+			odbcTransport = new ODBCSocketListener(config, BufferManagerFactory.getStandaloneBufferManager(), 0, 100000);
+			
+			FakeServer server = new FakeServer();
+			server.setUseCallingThread(false);
+			server.deployVDB("parts", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb");
+			
+			TeiidDriver driver = new TeiidDriver();
+			driver.setEmbeddedProfile(server);
+			odbcTransport.setDriver(driver);
+		}
+		
+		public void stop() {
 			odbcTransport.stop();
 		}
+		
 	}
 	
+	private static FakeOdbcServer odbcServer = new FakeOdbcServer();
+	
+	@BeforeClass public static void oneTimeSetup() throws Exception {
+		odbcServer.start();
+	}
+	
+	@AfterClass public static void oneTimeTearDown() throws Exception {
+		odbcServer.stop();
+	}
+	
 	Connection conn;
 	
 	@Before public void setUp() throws Exception {
@@ -82,7 +161,7 @@
 		Properties p = new Properties();
 		p.setProperty("user", "testuser");
 		p.setProperty("password", "testpassword");
-		conn = d.connect("jdbc:postgresql://"+addr.getHostName()+":" +odbcTransport.getPort()+"/parts", p);
+		conn = d.connect("jdbc:postgresql://"+odbcServer.addr.getHostName()+":" +odbcServer.odbcTransport.getPort()+"/parts", p);
 	}
 	
 	@After public void tearDown() throws Exception {
@@ -181,4 +260,18 @@
 		ResultSet rs = stmt.executeQuery("select has_function_privilege(100, 'foo')");
 		rs.next();
 	}
+	
+	@Test public void testSelectSsl() throws Exception {
+		conn.close();
+		Driver d = new Driver();
+		Properties p = new Properties();
+		p.setProperty("user", "testuser");
+		p.setProperty("password", "testpassword");
+		p.setProperty("ssl", "true");
+		p.setProperty("sslfactory", AnonSSLSocketFactory.class.getName());
+		conn = d.connect("jdbc:postgresql://"+odbcServer.addr.getHostName()+":" +odbcServer.odbcTransport.getPort()+"/parts", p);
+		Statement s = conn.createStatement();
+		assertTrue(s.execute("select * from tables order by name"));
+		TestMMDatabaseMetaData.compareResultSet("TestODBCSocketTransport/testSelect", s.getResultSet());
+	}
 }



More information about the teiid-commits mailing list