You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2016/05/02 18:12:09 UTC

[30/60] incubator-trafodion git commit: TRAFODION-1933 JDBC TYpe4 driver build scripts migrated to use maven instead of ant

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecPwd.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecPwd.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecPwd.java
new file mode 100644
index 0000000..60da5da
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecPwd.java
@@ -0,0 +1,274 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+ //
+ **********************************************************************/
+
+/**
+ * class SecPwd - builds the password key, encrypts password,
+ *                creates HMAC message based on password, rolename
+ *                process info and time stamp.  It also gets expiration
+ *                date of a certificate.
+ *
+ */
+
+package org.trafodion.jdbc.t4;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.sql.Connection;
+
+
+public class SecPwd {
+	 /**
+	  *
+      *
+      * @return SecPwd
+      */
+     public static SecPwd getInstance(Connection con, String directory, String fileName,
+    		 String serverName, boolean spjMode, byte[] procInfo) throws SecurityException
+     {
+    	 if (con == null)
+    		 throw new SecurityException(SecClientMsgKeys.INPUT_PARAMETER_IS_NULL, new Object[]{"connection"});
+    	 SecPwd secpwd = new SecPwd(directory, fileName, serverName, spjMode, procInfo);
+
+    		 SymCrypto.insert(con, secpwd);
+
+
+    	 return secpwd;
+     }
+
+     public static void removeInstance(Connection con)
+     {
+    	 SymCrypto.remove(con);
+     }
+
+	/**
+	 * Ctor for the SecPwd. There are two possible certificates: active
+	 * certificate and certificate that is going to be active.
+	 *
+	 * If autodownload is true, certificate will always come from the
+	 * server. In this case, only active certificate is used.
+	 *
+	 * If autodownload is false, active certificate is used to encrypt the
+	 * password. When there is a new certificate, it will be stored in
+	 * "certificate". As soon as this new certificate is activated on the
+	 * server, the current active certificate will become stale, and the new
+	 * certificate will be copied over and becomes the active certificate.
+	 *
+	 * If spjMode is true, the OS name is NONSTOP_KERNEL and the host name
+	 * is the same as the server name then just setSpj mode to true
+	 * and does nothing.
+	 *
+	 * @param directory
+	 *            specifies the directory to locate the certificate. The default
+	 *            value is %HOME% if set else %HOMEDRIVE%%HOMEPATH%.
+	 * @param fileName
+	 *            specifies the certificate that is in waiting. The default
+	 *            value is the first 5 characters of server name.
+	 * @param activeFileName
+	 *            specifies the current certificate in use. The default value is
+	 *            the first 5 character of server name + Active
+	 * @param spjMode
+	 *            true - and if os.name == NSK and the host name
+	 *            matches the local host - token case.  Certificate is not
+	 *            handled in this case.
+	 *            false - handles certificate
+	 * @param serverName
+	 *            server name for this certificate.
+	 * @throws SecurityException
+	 */
+	private SecPwd(String directory, String fileName, 
+			String serverName, boolean spjMode, byte[] procInfo) throws SecurityException {
+		String hostName = null;
+
+		try {
+			hostName = java.net.InetAddress.getLocalHost().getHostName();
+		} catch (java.net.UnknownHostException ex) {
+			throw new SecurityException(
+					SecClientMsgKeys.GET_LOCAL_HOST_NAME_FAILED, null);
+		}
+
+		// check USERID env variable for MXCI testing of SPJs.  If set use normal password
+		// encryption
+		if ((spjMode == true)  &&
+			//	((hostName.substring(0, 5)).compareToIgnoreCase(serverName.substring(0, 5)) == 0) &&
+				(System.getenv("USERID") == null))// token
+		{
+			m_spjMode = spjMode;
+		}
+		else // password
+		{
+			if (procInfo == null)
+				throw new SecurityException(SecClientMsgKeys.INPUT_PARAMETER_IS_NULL, new Object[]{"procInfo"});
+			// Stores procInfo with the time stamp for data message encryption used
+			m_procInfo = new byte [SecdefsCommon.PROCINFO_SIZE + SecdefsCommon.TIMESTAMP_SIZE];
+			System.arraycopy(procInfo, 0, m_procInfo, 0, (SecdefsCommon.PROCINFO_SIZE + SecdefsCommon.TIMESTAMP_SIZE));
+			directory = (directory != null) ? directory : System.getenv("HOME");
+			if (directory == null)
+			{
+				String hmdrive = System.getenv("HOMEDRIVE");
+				String hmpath = System.getenv("HOMEPATH");
+				if (hmdrive != null && hmpath != null)
+				{
+					directory = hmdrive + File.separator + hmpath;
+				}
+			    else
+			    {
+			    	directory = System.getProperty("user.home");
+			    	if (directory == null)
+			    		throw new SecurityException (SecClientMsgKeys.HOME_ENVIRONMENT_VAR_IS_NULL, null);
+			    }
+            }
+			fileName = (fileName != null) ? fileName : serverName + ".cer";
+
+			File dir = new File(directory);
+			if (dir.isDirectory() == false)
+				throw new SecurityException(SecClientMsgKeys.DIR_NOTFOUND, new Object[]{dir.getPath()});
+
+			certFile = new File(directory, fileName);
+		}
+	}
+
+	/**
+	 * Processes the active certificate when spjMode is false
+	 * else does nothing.  The certificate is processed by calling
+	 * the Security ctor to creates the password key and initializes it
+     * with password id.  Gets public key and the length of the public
+     * key from the certificate file.  Generates nonce and session key.
+	 * @throws SecurityException
+	 */
+	public void openCertificate() throws SecurityException {
+		if (m_spjMode == false) // do nothing for the token case
+			m_sec = new Security(certFile);
+	}
+
+	/** This method builds the password key which consists 4 bytes of password id,
+	 *  128 bytes of role name which would be 128 spaces when role name is null,
+	 *  32 bytes of the digest message calculated using the session key on the data made up of
+	 *  the procInfo and the encrypted data and 256 bytes (if the 2048 public key is used) or
+	 *  128 bytes (if the1024 public key is used) encrypted data calculated using the public key
+	 *  on the plain text made up of the session key, the nonce and the password.
+	 *  The password key is generated only when the spjMode is false.  When
+	 *  the spjMode is true, 26 bytes of the token is returned instead.
+	 * Builds password key
+	 * @param pwd
+	 * 		 	password to be encrypted
+	 * @param rolename
+	 * 			role name to build password key
+	 * @param procInfo
+	 * 			process information (PIN, CPU, segment name and time stamp)
+	 * @return pwdkey
+	 * 			returns the password key if spjMode is false
+	 *          returns the token when spjMode is true
+	 * @throws SecurityException
+	 */
+
+	public void encryptPwd(byte[] pwd, byte[] rolename, byte[] pwdkey) throws SecurityException {
+		// rolename is optional so can be NULL
+		if (pwd == null)
+			throw new SecurityException(SecClientMsgKeys.INPUT_PARAMETER_IS_NULL, new Object[]{"password"});
+		if (pwdkey == null)
+			throw new SecurityException(SecClientMsgKeys.INPUT_PARAMETER_IS_NULL, new Object[]{"password key"});
+		if (m_spjMode == true) // token
+		{
+			if (pwd.length != SecdefsCommon.TOKENSIZE)
+				throw new SecurityException(SecClientMsgKeys.BAD_TOKEN_LEN, null);
+			if ((pwd[0] != SecdefsCommon.USERTOKEN_ID_1)
+					|| (pwd[1] != SecdefsCommon.USERTOKEN_ID_2))
+				throw new SecurityException(
+						SecClientMsgKeys.INCORRECT_TOKEN_FORMAT, null);
+			ByteBuffer.wrap(pwd).get(pwdkey, 0, SecdefsCommon.TOKENSIZE);
+		}
+		else
+		{
+			m_sec.encryptPwd(pwd, rolename, m_procInfo, pwdkey);
+		}
+	}
+
+	/** Gets length of buffer for password encryption (public)
+	 * or the length of the token if it is the SPJ mode
+	 * @returns
+	 *     If the spjMode is false
+	 *        the length of the password key is returnd if success
+	 * 	      0 if failed
+	 *     If spjMode is true
+	 *     	  the length of the token is returned
+	 * @throws SecurityException
+	 */
+	public int getPwdEBufferLen() throws SecurityException {
+		if (m_spjMode == true)
+			return SecdefsCommon.TOKENSIZE;
+		else
+			return m_sec.getPwdEBufferLen();
+	}
+
+	/** Gets the expiration date of the certificate
+	 * @return an array of bytes
+	 * 			presents the certificate's
+	 * 			expiration day in the format YYMMDDHHMMSS
+	 * 			or a zero length byte array if the it is in the SPJ mode
+	 */
+	public byte[] getCertExpDate() {
+		if (m_spjMode == false)
+			return m_sec.getCertExpDate();
+		else
+			return new byte[0];
+	}
+
+	/**
+	 * When autodownload is on, client will download the certificate from server
+	 * when there is no certificate or certificate is stale.
+	 *
+	 * @param buf
+	 *            content of the certificate pushed from server.
+	 */
+	public void switchCertificate(byte[] buf) throws SecurityException {
+		FileChannel outChannel = null;
+		try {
+			outChannel = new FileOutputStream(certFile).getChannel();
+			outChannel.write(ByteBuffer.wrap(buf));
+		} catch (Exception e) {
+			throw new SecurityException(SecClientMsgKeys.ERR_WRITE_CERT_FILE, new Object[]{certFile});
+		} finally {
+			try {
+				if (outChannel != null)
+					outChannel.close();
+			} catch (Exception e) {
+			}
+		}
+		m_sec = new Security(certFile);
+	}
+
+	public byte[] getProcInfo()
+	{
+		return m_procInfo;
+	}
+
+	private Security m_sec;
+	private File certFile;
+	private boolean m_spjMode;
+	private byte[] m_procInfo;   //stores only 4 bytes pid + 4 bytes nid
+
+
+};

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecResourceBundle.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecResourceBundle.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecResourceBundle.java
new file mode 100644
index 0000000..5400d55
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecResourceBundle.java
@@ -0,0 +1,57 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+//
+**********************************************************************/
+
+package org.trafodion.jdbc.t4;
+
+import java.util.ResourceBundle;
+import java.text.MessageFormat;
+
+public class SecResourceBundle
+{
+
+    private static ResourceBundle rb = ResourceBundle.getBundle("secClient");
+
+    /**
+     * This method is used to obtain parameterized message text
+     *
+     */
+    static String obtainMessageText (String key, Object[] params) {
+        String pattern;
+        try {
+                pattern = rb.getString(key);
+        } catch (Exception e) {
+                return key;
+        }
+        if(pattern == null) {
+                return key;
+        }
+        String message;
+        try {
+                message = MessageFormat.format(pattern, params);
+        } catch (Exception e) {
+                return pattern;
+        }
+        return message;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecdefsCommon.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecdefsCommon.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecdefsCommon.java
new file mode 100644
index 0000000..f003588
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecdefsCommon.java
@@ -0,0 +1,84 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+//
+**********************************************************************/
+
+package org.trafodion.jdbc.t4;
+
+/**
+ * This class contains defines
+ *
+ */
+
+public class SecdefsCommon {
+
+     public static final int NONCE_RANDOM = 24;
+     public static final int NONCE_SEQNUM = 8;
+     public static final int NONCE_SIZE = (NONCE_RANDOM+NONCE_SEQNUM);
+     public static final int SESSION_KEYLEN = 32;
+     public static final int DIGEST_LENGTH = 32;
+     // AES block size used in data encryption
+     public static final int AES_BLOCKSIZE = 16;
+     public static final int KEY_REFRESH = 30;
+     public static final int TIMESTAMP_SIZE = 8;
+     public static final int ROLENAME_SIZE  = 128;
+     public static final int PROCINFO_SIZE =  8;
+     public static final int PWDID_SIZE = 4;
+     public static final int EXPDATESIZE = 12;
+     public static final int PWDKEY_SIZE_LESS_LOGINDATA = (PWDID_SIZE + ROLENAME_SIZE + DIGEST_LENGTH +  TIMESTAMP_SIZE);
+     // For public key encryption, the  number of bytes
+     // to be encrypted is 11 bytes less than the public key length
+     public static final int UNUSEDBYTES = 11;
+     public static final int TOKENSIZE = 68;
+     // User tokens begin with byte values 3,4.
+     public static final byte USERTOKEN_ID_1 = '\3'; 	// User token identifier, must be a sequence
+     public static final byte USERTOKEN_ID_2 = '\4';	// not allowed in password
+     public static final int DATA_BLOCK_BIT_SIZE = 128;  // data encryption block size in bits.  Java
+                                                         // supports block size of 128 bits for AES
+                                                         // algorithm using cryptographic key of 256 bits only.
+
+
+     // Structure used to describe layout of Encrypted data
+     // in login message
+     public static class LoginData {
+        //000 Session key
+        byte[] session_key = new byte[SecdefsCommon.SESSION_KEYLEN];
+        //032 Nonce
+        byte[] nonce = new byte[SecdefsCommon.NONCE_SIZE];
+        Byte password;            // 064 User's password
+     }            // 128 for 1024 or 256 for 2048
+
+//  Structure used to describe layout of password key
+
+    public static class PwdKey {
+       //000 Key identifier, binary values 1,2,3,4
+       //or 1,2,2,4 keys, optional mode only
+       byte[] id= new byte[SecdefsCommon.PWDID_SIZE];
+       //004 RolenameA
+       byte[] rolename = new byte[SecdefsCommon.ROLENAME_SIZE];
+       //132 Digest of server id and encrypted data
+       byte[] digest = new byte[SecdefsCommon.DIGEST_LENGTH];
+       // 164 time stamp
+       byte[]  ts = new byte[SecdefsCommon.TIMESTAMP_SIZE];
+       LoginData data;             //172 Encrypted data
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/Security.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/Security.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/Security.java
new file mode 100644
index 0000000..1a02021
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/Security.java
@@ -0,0 +1,319 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+//
+**********************************************************************/
+
+package org.trafodion.jdbc.t4;
+
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.Date;
+import java.security.NoSuchAlgorithmException;
+import java.io.File;
+import javax.crypto.SecretKey;
+
+
+
+class Security
+{
+      public static final Cipher cipher = org.trafodion.jdbc.t4.Cipher.getInstance();
+      public static final MessageDigest msgDigest = MessageDigest.getInstance();
+
+      /** Ctor - Creates the password key and initializes it with
+       * password id.  Gets public key and the length of the public key
+       * from the certificate file.  Generates nonce and session key.
+       * @param cert_file - fully qualified name of certificate file
+       * @throw SecurityException
+       */
+      public Security(File certFile) throws SecurityException
+      {
+         //   m_encrypted = 0;
+         m_pwdkey = new SecdefsCommon.PwdKey();
+         m_pwdkey.data = new SecdefsCommon.LoginData();
+         m_pwdkey.id[0] = '\1';
+         m_pwdkey.id[1] = '\2';
+         m_pwdkey.id[2] = '\3';
+         m_pwdkey.id[3] = '\4';
+
+         try {
+            m_keyObj = new Key();
+            m_cert = new Certificate(certFile);
+            m_keyObj.getPubKeyFromFile(m_cert.getCert());
+            generateSessionKey();
+         }catch (SecurityException se) {
+            throw se;
+         }
+      }
+
+    /** This method builds the password key which consists 4 bytes of password id,
+  	 *  128 bytes of role name which would be 128 spaces when role name is null,
+  	 *  32 bytes of the digest message calculated using the session key on the data made up of
+  	 *  the procInfo and the encrypted data and 256 bytes (if the 2048 public key is used) or
+  	 *  128 bytes (if the1024 public key is used) encrypted data calculated using the public key
+  	 *  on the plain text made up of the session key, the nonce and the password.
+  	 * Builds password key
+  	 * @param pwd
+  	 * 		 	password to be encrypted
+  	 * @param rolename
+  	 * 			role name to build password key
+  	 * @param procInfo
+  	 * 			process information (PIN, CPU, segment name and time stamp)
+  	 * @return pwdkey
+  	 * 			returned password key
+  	 * @throws SecurityException
+  	 */
+      public void encryptPwd(byte[] pwd, byte[] rolename, byte[] procInfo,
+                            byte[] pwdkey)
+                                 throws SecurityException
+      {
+         // Get public key length
+         int pubKeyLen = m_keyObj.getPubKeyLen();
+         int maxPlainTextLen = pubKeyLen - SecdefsCommon.UNUSEDBYTES;
+
+         // Password + nonce + session key can't be longer than the public
+         // key's length
+         if ((SecdefsCommon.NONCE_SIZE + SecdefsCommon.SESSION_KEYLEN
+                                       + pwd.length) > maxPlainTextLen)
+            throw new SecurityException(SecClientMsgKeys.
+                                   PWD_LENGTH_TOO_LONG, null);
+
+         byte[] to_encrypt = new byte[SecdefsCommon.SESSION_KEYLEN +
+                                      SecdefsCommon.NONCE_SIZE + pwd.length];
+         byte[] cipherText = new byte[pubKeyLen];
+         byte[] to_digest = new byte[SecdefsCommon.PROCINFO_SIZE +
+                              SecdefsCommon.TIMESTAMP_SIZE + pubKeyLen];
+         byte[] digestedMsg = new byte[SecdefsCommon.DIGEST_LENGTH];
+
+         try {
+            // Build password key
+            // Copy 4 bytes of id
+        	 System.arraycopy(m_pwdkey.id, 0, pwdkey, 0, SecdefsCommon.PWDID_SIZE);
+            // Copy rolename
+            if (rolename != null)
+            	System.arraycopy(rolename, 0, pwdkey, SecdefsCommon.PWDID_SIZE,
+            			          rolename.length);
+            // Copy 12 bytes of procInfo and 8 bytes of timestamp to
+            // password key store procInfo in the digest starting from
+            // digest[20]
+            System.arraycopy(procInfo, 0, pwdkey, (SecdefsCommon.PWDID_SIZE +
+            		        SecdefsCommon.ROLENAME_SIZE + SecdefsCommon.DIGEST_LENGTH -
+                            SecdefsCommon.PROCINFO_SIZE), (SecdefsCommon.PROCINFO_SIZE +
+                    		SecdefsCommon.TIMESTAMP_SIZE));
+
+            // Build plain text to encrypt
+            System.arraycopy(m_pwdkey.data.session_key, 0, to_encrypt, 0,
+            		        SecdefsCommon.SESSION_KEYLEN);
+            System.arraycopy(m_pwdkey.data.nonce, 0, to_encrypt,
+            		SecdefsCommon.SESSION_KEYLEN, SecdefsCommon.NONCE_SIZE);
+            System.arraycopy(pwd, 0, to_encrypt,
+            		(SecdefsCommon.SESSION_KEYLEN + SecdefsCommon.NONCE_SIZE), pwd.length);
+
+            // Encrypt the data
+            int cipherTextLen = cipher.encrypt(to_encrypt, cipherText,
+                             (java.security.Key)(m_keyObj.getPubKey()));
+
+            if(cipherTextLen != pubKeyLen)
+               throw new SecurityException(SecClientMsgKeys.
+                                           CIPHER_TEXT_LEN_NOT_EQUAL_KEY_LEN, null);
+
+            // Copy cipherText to pwdkey
+            System.arraycopy(cipherText, 0, pwdkey,
+            		SecdefsCommon.PWDKEY_SIZE_LESS_LOGINDATA, cipherTextLen);
+
+            // Create digest
+            // Get bytes from digest[20] on
+            System.arraycopy(pwdkey, (SecdefsCommon.PWDKEY_SIZE_LESS_LOGINDATA -
+                    SecdefsCommon.TIMESTAMP_SIZE - SecdefsCommon.PROCINFO_SIZE),
+                    to_digest, 0, (SecdefsCommon.PROCINFO_SIZE +
+                    		SecdefsCommon.TIMESTAMP_SIZE + cipherTextLen));
+
+            int mdLen = msgDigest.digest(m_pwdkey.data.session_key,
+                                 to_digest, digestedMsg);
+
+            if (mdLen != SecdefsCommon.DIGEST_LENGTH)
+               throw new SecurityException(SecClientMsgKeys.
+                                           BAD_MESSAGE_DIGEST_LEN, null);
+
+            // copy digestedMsg into pwdkey
+            System.arraycopy(digestedMsg, 0, pwdkey,
+            		(SecdefsCommon.PWDKEY_SIZE_LESS_LOGINDATA
+            		- SecdefsCommon.TIMESTAMP_SIZE - SecdefsCommon.DIGEST_LENGTH), mdLen );
+
+         }catch (SecurityException se) {
+             throw se;
+         }catch (Exception e) {
+        	 throw new SecurityException(SecClientMsgKeys.FAILED_BUILDING_PWDKEY, null);
+         }finally {
+            if (to_digest != null)
+               to_digest = null;
+            if (digestedMsg != null)
+               digestedMsg = null;
+            if (to_encrypt != null)
+               to_encrypt = null;
+         }
+      }
+
+      /** Encrypts the data using AES256 algorithm.
+	    *
+	    * @param  data - data to be encrypted
+	    * @return array of bytes of 2 bytes PIN,
+	    *         2 bytes of CPU, 8 bytes of seg_name
+	    *         and the encrypted data
+	    * @throw  SecurityException
+	    */
+
+	 public byte[] encryptData(byte[] data) throws SecurityException
+	 {
+		 //Creates a secret key from the session key
+		byte[] skey = new byte[SecdefsCommon.AES_BLOCKSIZE];
+		System.arraycopy(m_pwdkey.data.session_key, SecdefsCommon.AES_BLOCKSIZE,
+				skey, 0, SecdefsCommon.AES_BLOCKSIZE);
+		SecretKey seckey = Key.generateSymmetricKey(skey);
+		byte [] iv  = new byte [SecdefsCommon.AES_BLOCKSIZE];
+		System.arraycopy(m_pwdkey.data.nonce, SecdefsCommon.AES_BLOCKSIZE,
+				iv, 0, SecdefsCommon.AES_BLOCKSIZE);
+	    m_cipher = Cipher.getEASInstance("AES/CBC/PKCS5Padding");
+	    return Cipher.encryptData(data, seckey, iv, m_cipher);
+	 }
+
+      // Currently not implemented
+      // Generate message digest
+      // str - message to digest
+      // hmacMsg - Hashed message in bytes
+      // hmacMsgLen - Length of hashed message
+      public void HMAC_Message_Generate(byte[] str, byte[] hmacMsg,
+                                      int hmacMsgLen) throws SecurityException
+      {
+         // Not implemented yet
+      }
+
+      // Currently not implemented
+      // Verify message digest
+      // str - message digest
+      // length - message digest length
+      public boolean HMAC_Message_Verify(byte[] str) throws SecurityException
+      {
+         // Not implemented yet
+         return false;
+      }
+
+      /** increment the nonce sequence
+       *
+       */
+      public void incrementNonceSeq ()
+      {
+         m_nonceSeq++;
+      }
+
+      /** Gets length of buffer for password encryption (public)
+       * @Return pass word key length if success and 0 if failed
+       * @throw SecurityException
+       */
+      public int getPwdEBufferLen() throws SecurityException
+      {
+         int pubKLen = m_keyObj.getPubKeyLen();
+         if(pubKLen <= 0)
+            throw new SecurityException(SecClientMsgKeys.
+                                         PUBKEY_LENGTH_IS_ZERO, null);
+         else
+           return (pubKLen + SecdefsCommon.PWDKEY_SIZE_LESS_LOGINDATA);
+      }
+
+      /** Gets certificate's expiration date
+       * @Return an array of bytes represents the certificate's
+       * expiration day in the string format YYMMDDHHMMSS
+       */
+      public byte[] getCertExpDate()
+      {
+         return m_cert.getCertExpDate();
+      }
+
+      // Generates session key and nonce
+      private void generateSessionKey() throws SecurityException
+      {
+         //try {
+            SecureRandom random = new SecureRandom();
+            try {
+                random.setSeed(System.currentTimeMillis());
+
+                random.setSeed(Runtime.getRuntime().freeMemory());
+                random.setSeed(Runtime.getRuntime().totalMemory());
+                random.setSeed(Runtime.getRuntime().maxMemory());
+
+                String p = null;
+
+                p = System.getProperty("java.version", "unknown java version");
+                random.setSeed(p.getBytes());
+                p = System.getProperty("java.vendor", "unknown vendor");
+                random.setSeed(p.getBytes());
+                p = System.getProperty("os.name", "unknown os");
+                random.setSeed(p.getBytes());
+                p = System.getProperty("os.version", "unknown os version");
+                random.setSeed(p.getBytes());
+
+                // Add current time again
+
+                random.setSeed(System.currentTimeMillis());
+            }
+            catch(Exception e ) {
+                // Ignore
+            }
+            byte bytes[] = new byte[SecdefsCommon.SESSION_KEYLEN +
+                                    SecdefsCommon.NONCE_SIZE];
+            synchronized(random) {
+            	random.nextBytes(bytes);
+            }
+
+            // Assign bytes to members m_pwdkey.data.session_key
+            // and m_pwdkey.data.nonce
+
+            System.arraycopy(bytes, 0, m_pwdkey.data.session_key, 0, SecdefsCommon.SESSION_KEYLEN);
+            System.arraycopy(bytes, SecdefsCommon.SESSION_KEYLEN, m_pwdkey.data.nonce, 0, SecdefsCommon.NONCE_SIZE);
+
+            m_nonceSeq = (ByteBuffer.wrap(m_pwdkey.data.nonce)).getLong(
+            		                          SecdefsCommon.SESSION_KEYLEN -
+                                              SecdefsCommon.NONCE_SEQNUM);
+
+            // Set time when session key is generated
+            m_keyTime = (new Date()).getTime();
+         /*}catch (NoSuchAlgorithmException nae) {
+            throw new SecurityException(SecClientMsgKeys.SESSION_KEY_GENERATION_FAILED, null);
+         }*/
+      }
+
+      // encryption is required or not for replied message 0-yes, 1-no
+      //int m_encrypted;
+      // security option - mandatory - 1 or undocumented option - 0
+      // Time when session key is generated
+      private long m_keyTime;
+      // sequence nonce used in nonce increment
+      // Need to use 64 bit number type here
+      private long m_nonceSeq;
+      // certificate
+      private Certificate m_cert;
+      // key
+      private Key m_keyObj;
+      // password key
+      private SecdefsCommon.PwdKey m_pwdkey;
+      private javax.crypto.Cipher m_cipher;
+
+};

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecurityException.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecurityException.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecurityException.java
new file mode 100644
index 0000000..64d1a3d
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SecurityException.java
@@ -0,0 +1,47 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+//
+ **********************************************************************/
+package org.trafodion.jdbc.t4;
+
+import java.lang.String;
+import java.lang.Integer;
+import java.sql.SQLException;
+
+public class SecurityException extends SQLException
+{
+   private static final String SQLState = "38001";
+
+   public SecurityException(String key, Object[] params)
+   {
+	  // Get the text message from the file secClient.properties.
+	  // Parse the message for the error message and error number.
+      this((SecResourceBundle.obtainMessageText(key, params)).substring(6),
+    		  Integer.parseInt((SecResourceBundle.obtainMessageText(key, params)).substring(0, 5)));
+   }
+
+   public SecurityException(String errMsg, int errNum)
+   {
+	   super(errMsg, SQLState, errNum);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionMessage.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionMessage.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionMessage.java
new file mode 100644
index 0000000..8ee7c6c
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionMessage.java
@@ -0,0 +1,50 @@
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.UnsupportedCharsetException;
+
+class SetConnectionOptionMessage {
+	// ----------------------------------------------------------
+	static LogicalByteArray marshal(int dialogueId, short connectionOption, int optionValueNum, String optionValueStr,
+			InterfaceConnection ic) throws CharacterCodingException, UnsupportedCharsetException {
+		int wlength = Header.sizeOf();
+		LogicalByteArray buf;
+
+		byte[] optionValueBytes = ic.encodeString(optionValueStr, InterfaceUtilities.SQLCHARSETCODE_UTF8);
+
+		wlength += TRANSPORT.size_int; // dialogueId
+		wlength += TRANSPORT.size_short; // connectionOption
+		wlength += TRANSPORT.size_int; // optionValueNum
+		wlength += TRANSPORT.size_bytes(optionValueBytes); // optionValueStr
+
+		buf = new LogicalByteArray(wlength, Header.sizeOf(), ic.getByteSwap());
+
+		buf.insertInt(dialogueId);
+		buf.insertShort(connectionOption);
+		buf.insertInt(optionValueNum);
+		buf.insertString(optionValueBytes);
+
+		return buf;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionReply.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionReply.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionReply.java
new file mode 100644
index 0000000..fa3ecc0
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SetConnectionOptionReply.java
@@ -0,0 +1,45 @@
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.sql.SQLException;
+
+class SetConnectionOptionReply {
+	odbc_SQLSvc_SetConnectionOption_exc_ m_p1;
+	ERROR_DESC_LIST_def m_p2;
+
+	// -------------------------------------------------------------
+	SetConnectionOptionReply(LogicalByteArray buf, String addr, InterfaceConnection ic)
+			throws CharacterCodingException, UnsupportedCharsetException, SQLException {
+		buf.setLocation(Header.sizeOf());
+
+		m_p1 = new odbc_SQLSvc_SetConnectionOption_exc_();
+		m_p1.extractFromByteArray(buf, addr, ic);
+
+		if (m_p1.exception_nr == TRANSPORT.CEE_SUCCESS) {
+			m_p2 = new ERROR_DESC_LIST_def();
+			m_p2.extractFromByteArray(buf, ic);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SymCrypto.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SymCrypto.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SymCrypto.java
new file mode 100644
index 0000000..a0e10ad
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/SymCrypto.java
@@ -0,0 +1,87 @@
+/**********************************************************************
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+ //
+ **********************************************************************/
+
+/**
+ * class SymCrypto - Stores connections and correspondence SecPwd
+ *                   objects.
+ */
+
+package org.trafodion.jdbc.t4;
+
+import java.util.HashMap;
+import java.sql.Connection;
+
+public class SymCrypto
+{
+	static HashMap<Connection, SymCrypto> storage = new HashMap<Connection, SymCrypto> ();
+
+	/**
+	 * Ctor -
+	 * @param secpwd
+	 */
+	private SymCrypto(SecPwd secpwd)
+	{
+		m_secPwd = secpwd;
+	}
+
+	/**
+	 * Returns the SymCrypto object correspondence to the connection passed in
+	 * @param con
+	 * @return the value to which the SymCrypto object maps the connection passed in or
+	 *         null if the map contains no mapping for the connection.
+	 * @throws SecurityException
+	 */
+	public static SymCrypto getInstance(Connection con) throws SecurityException
+	{
+		if (con == null)
+			throw new SecurityException (SecClientMsgKeys.INPUT_PARAMETER_IS_NULL, new Object[]{"connection"});
+		return storage.get(con);
+	}
+
+	/**
+	 * Creates and SymCrypto object from the SecPwd object and inserts the connection
+	 * and the equivalent SymCRypto object into the hash table storage.  If the table previously
+	 * contained a mapping for the connection, the old value is replaced.
+	 * @param con - the JDBC connection
+	 * @param secpwd - the SecPwd object associated with the JDBC connection
+	 */
+	public static void insert(Connection con, SecPwd secpwd)
+	{
+		SymCrypto symcrypto = new SymCrypto(secpwd);
+		storage.put(con, symcrypto);
+	}
+
+	/**
+	 * Removed the mapping of this JDBC connection from the hash table if present
+	 * @param con - JDBC connection whose entry is to be removed from the hash table storage
+	 */
+	public static void remove(Connection con)
+	{
+		if (con != null)
+			storage.remove(con);
+	}
+
+	private SecPwd m_secPwd;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Address.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Address.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Address.java
new file mode 100644
index 0000000..6cc2085
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Address.java
@@ -0,0 +1,315 @@
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+/**********************************************************
+ * This class represents an address reference.
+ *
+ * @version 1.0
+ **********************************************************/
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.Properties;
+
+final class T4Address extends Address {
+
+	private static final String t4ConnectionPrefix = "jdbc:t4jdbc:";
+	private static final String urlPrefix = t4ConnectionPrefix + "//";
+	private static final int minT4ConnectionAddrLen = t4ConnectionPrefix.length() + 4;
+	private static final int AS_type = 1; // jdbc:subprotocol:subname
+
+	/**
+	 * The constructor.
+	 * 
+	 * @param addr
+	 *            The addr has two forms:
+	 * 
+	 * DriverManager getConnection addr parameter format for connecting via the
+	 * Fast JDBC Type 4 driver.
+	 * 
+	 * jdbc:subprotocol:subname
+	 * 
+	 * Where:
+	 * 
+	 * subprotocol = t4jdbc
+	 * 
+	 * subname = //<{IP Address|Machine Name}[:port]>/<properties>
+	 * 
+	 * Example: jdbc:t4jdbc://130.168.200.30:1433/database1
+	 * 
+	 */
+
+	// ----------------------------------------------------------
+	T4Address(T4Properties t4props, Locale locale, String addr) throws SQLException {
+		super(t4props, locale, addr);
+
+		if (addr == null) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_null_error", null);
+			throw se;
+		}
+
+		//
+		// We are now expecting addr = "//<{IP Address|Machine
+		// Name}[:port]>/<properties>"
+		//
+		m_type = AS_type;
+
+		//
+		// We don't recognize this address syntax
+		//
+		if (acceptsURL(addr) == false) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_parsing_error", addr);
+			SQLException se2 = HPT4Messages.createSQLException(m_t4props, m_locale, "unknown_prefix_error", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		//
+		// We are now expecting addr = "<{IP Address|Machine Name}[:port]>"
+		// Get the IP or Name
+		//
+		String IPorName = extractHostFromUrl(addr);
+		if (isIPAddress(IPorName)) {
+			m_ipAddress = IPorName;
+		} else {
+			m_machineName = IPorName;
+
+			//
+			// Get the port number if there is one.
+			//
+		}
+		m_portNumber = new Integer(extractPortFromUrl(addr));
+		m_properties = extractPropertiesFromString(addr);
+
+		m_url = recreateAddress();
+
+		validateAddress();
+		setInputOutput();
+	}
+
+	String recreateAddress() {
+		String addr = null;
+
+		addr = t4ConnectionPrefix + "//";
+
+		if (m_machineName != null) {
+			addr = addr + m_machineName;
+		} else if (m_ipAddress != null) {
+			addr = addr + m_ipAddress;
+
+		}
+		if (m_portNumber != null) {
+			addr = addr + ":" + m_portNumber;
+
+		}
+		addr = addr + "/";
+
+		return addr;
+	} // end recreateAddress
+
+	static boolean acceptsURL(String url) throws SQLException {
+		try {
+			return url.toLowerCase().startsWith(t4ConnectionPrefix);
+		} catch (Exception ex) {
+			throw new SQLException(ex.toString());
+		}
+	}
+
+	// ----------------------------------------------------------
+	String getUrl() {
+		return urlPrefix + getIPorName() + ':' + getPort().toString() + "/:";
+	} // end getProps()
+
+	// ----------------------------------------------------------
+	Properties getProps() {
+		return m_properties;
+	} // end getProps()
+
+	/**
+	 * Return the host value
+	 * 
+	 * @param url
+	 *            of format jdbc:t4jdbc://host:port/:[prop-name=prop-value]..
+	 * @return host string
+	 */
+	private String extractHostFromUrl(String url) throws SQLException {
+		if (url.length() < minT4ConnectionAddrLen) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_parsing_error", url);
+			SQLException se2 = HPT4Messages.createSQLException(m_t4props, m_locale, "min_address_length_error", null);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		int hostStartIndex = urlPrefix.length();
+		int hostEndIndex = -1;
+		if (isIPV6(url)) {
+			hostEndIndex = url.lastIndexOf(']', hostStartIndex); // IP6
+		} else {
+			hostEndIndex = url.indexOf(':', hostStartIndex); // IP4
+
+		}
+		if (hostEndIndex < 0) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_parsing_error", url);
+			SQLException se2 = HPT4Messages.createSQLException(m_t4props, m_locale, "address_format_error", url);
+
+			se.setNextException(se2);
+			throw se;
+		}
+
+		String host = url.substring(hostStartIndex, hostEndIndex);
+		if ((host == null) || (host.length() == 0)) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_parsing_error", url);
+			SQLException se2 = HPT4Messages.createSQLException(m_t4props, m_locale, "address_format_error", null);
+			SQLException se3 = HPT4Messages.createSQLException(m_t4props, m_locale, "missing_ip_or_name_error", null);
+			se.setNextException(se2);
+			se2.setNextException(se3);
+			throw se;
+		}
+
+		return host;
+	}
+
+	/**
+	 * Return the port value
+	 * 
+	 * @param url
+	 *            of format jdbc:t4jdbc://host:port/:[prop-name=prop-value]..
+	 * @return port string
+	 */
+	private String extractPortFromUrl(String url) throws SQLException {
+		int portStartIndex = url.indexOf(':', urlPrefix.length()) + 1;
+		int portEndIndex = url.indexOf('/', portStartIndex);
+		if (portEndIndex < 0) {
+			portEndIndex = url.length();
+
+		}
+		String port = url.substring(portStartIndex, portEndIndex);
+		if (port.length() < 1) {
+			throw new SQLException("Incorrect port value in the URL.");
+		}
+		;
+
+		int asPort;
+		try {
+			asPort = Integer.parseInt(port);
+		} catch (Exception e) {
+			throw new SQLException("Incorrect port value in the URL.");
+		}
+
+		if ((asPort < 0) || (asPort > 65535)) {
+			throw new SQLException("Port value out of range in the URL.");
+		}
+
+		return port;
+	}
+
+	/**
+	 * Checks if the url is of IP6 protocol
+	 */
+	private boolean isIPV6(String url) throws SQLException {
+		if (url == null) {
+			SQLException se = HPT4Messages.createSQLException(m_t4props, m_locale, "address_parsing_error", url);
+			SQLException se2 = HPT4Messages.createSQLException(m_t4props, m_locale, "address_format_2_error", null);
+			se.setNextException(se2);
+			throw se;
+
+		}
+		int hostStartIndex = urlPrefix.length();
+		return (url.charAt(hostStartIndex) == '[');
+	}
+
+	/**
+	 * Extracts the property name, value pair from a url String, seperated by ;
+	 * 
+	 * @param url
+	 *            of format jdbc:t4jdbc://host:port/:[prop-name=prop-value]..
+	 * @return Propeties object
+	 * @throws IOException
+	 */
+	private Properties extractPropertiesFromString(String url) throws SQLException {
+		int urLength = url.length();
+		int hostStartIndex = urlPrefix.length();
+		int propStartIndex = url.indexOf('/', hostStartIndex);
+		if (propStartIndex < 0) {
+			return null;
+		}
+
+		if (propStartIndex == urLength) {
+			return null;
+		}
+
+		if (url.charAt(propStartIndex) == '/') {
+			propStartIndex++;
+
+		}
+		if (propStartIndex == urLength) {
+			return null;
+		}
+
+		if (url.charAt(propStartIndex) == ':') {
+			propStartIndex++;
+
+		}
+		if (propStartIndex == urLength) {
+			return null;
+		}
+
+		String propStr = url.substring(propStartIndex);
+		if ((propStr == null) || (propStr.length() == 0)) {
+			return null;
+		}
+
+		Properties props = new Properties();
+		propStr = propStr.replace(';', '\n');
+		ByteArrayInputStream byteArrIPStream = new ByteArrayInputStream(propStr.getBytes());
+
+		try {
+			props.load(byteArrIPStream);
+		} catch (IOException ioex) {
+			throw new SQLException(ioex.getMessage());
+		}
+
+		return props;
+	}
+
+	/**
+	 * Checks the string is host or port.
+	 * 
+	 * @param IPorName
+	 * @return true if the address is a IP address
+	 */
+	private boolean isIPAddress(String IPorName) {
+		// Minimum length = 7; 1.1.1.1
+		if (IPorName.length() < 7)
+			return false;
+		//
+		// If first letter is a digit or ":" (i.e. IPv6), I'll assume it is an
+		// IP address
+		//
+		return (Character.isDigit(IPorName.charAt(0)) || (IPorName.charAt(1) == ':'));
+	}
+} // end class Address

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/72e17019/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Connection.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Connection.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Connection.java
new file mode 100644
index 0000000..d1ce34f
--- /dev/null
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Connection.java
@@ -0,0 +1,505 @@
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.logging.Level;
+
+class T4Connection {
+	protected Locale m_locale;
+	protected int m_dialogueId;
+	protected NCSAddress m_ncsAddress;
+	private InputOutput m_io;
+	private USER_DESC_def m_userDesc;
+	private CONNECTION_CONTEXT_def m_inContext;
+	private String m_sessionName;
+	InterfaceConnection m_ic;
+
+	static final int INCONTEXT_OPT1_SESSIONNAME = 0x80000000; // (2^31)
+	static final int INCONTEXT_OPT1_FETCHAHEAD = 0x40000000; // (2^30)
+	static final int INCONTEXT_OPT1_CERTIFICATE_TIMESTAMP = 0x20000000; //(2^29)
+	static final int INCONTEXT_OPT1_CLIENT_USERNAME = 0x10000000; //(2^28)
+
+	T4Connection(InterfaceConnection ic) throws SQLException {
+		if (ic == null) {
+			throwInternalException();
+
+		}
+		m_ic = ic;
+		m_locale = ic.getLocale();
+		m_dialogueId = ic.getDialogueId();
+		m_ncsAddress = ic.getNCSAddress();
+		m_userDesc = ic.getUserDescription();
+		m_inContext = ic.getInContext();
+		m_sessionName = ic.getSessionName();
+
+		if (m_dialogueId < 1 || m_ncsAddress == null || m_userDesc == null || m_inContext == null) {
+			throwInternalException();
+
+		}
+		m_io = m_ncsAddress.getInputOutput();
+		if (m_io == null) {
+			throwInternalException();
+		}
+		m_io.setDialogueId(m_dialogueId);
+		m_io.setConnectionIdleTimeout(ic.getConnectionTimeout());
+		// trace_connection - AM
+		m_io.setT4Connection(this);
+		m_io.openIO();
+		getInputOutput().setTimeout(ic.getLoginTimeout());
+		checkConnectionIdleTimeout();
+		resetConnectionIdleTimeout();
+	}
+
+	public void finalizer() {
+		closeTimers();
+	}
+
+	protected int getDialogueId() {
+		return m_dialogueId;
+	}
+
+	protected Locale getLocale() {
+		return m_locale;
+	}
+
+	protected String getSessionName() {
+		return this.m_sessionName;
+	}
+
+	protected NCSAddress getNCSAddress() {
+		return m_ncsAddress;
+	}
+
+	void closeTimers() {
+		if (m_io != null) {
+			m_io.closeTimers();
+		}
+	}
+
+	protected void reuse() {
+		resetConnectionIdleTimeout();
+	}
+
+	private void setConnectionIdleTimeout() {
+		m_io.startConnectionIdleTimeout();
+	}
+
+	private void resetConnectionIdleTimeout() {
+		m_io.resetConnectionIdleTimeout();
+	}
+
+	private void checkConnectionIdleTimeout() throws SQLException {
+		if (m_io.checkConnectionIdleTimeout()) {
+			try {
+				m_ic.close();
+			} catch (SQLException sqex) {
+				// ignores
+			}
+			throw HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "ids_s1_t00", null);
+		}
+	}
+
+	protected boolean connectionIdleTimeoutOccured() {
+		return m_io.checkConnectionIdleTimeout();
+	}
+
+	protected InputOutput getInputOutput() throws SQLException {
+		checkConnectionIdleTimeout();
+		resetConnectionIdleTimeout();
+		return m_io;
+	}
+
+	protected void throwInternalException() throws SQLException {
+		T4Properties tempP = null;
+
+		if (m_ic != null) {
+			tempP = m_ic.t4props_;
+
+		}
+		SQLException se = HPT4Messages.createSQLException(tempP, m_locale, "internal_error", null);
+		SQLException se2 = HPT4Messages.createSQLException(tempP, m_locale, "contact_hp_error", null);
+
+		se.setNextException(se2);
+		throw se;
+	}
+
+	// --------------------------------------------------------------------------------
+	protected LogicalByteArray getReadBuffer(short odbcAPI, LogicalByteArray wbuffer) throws SQLException {
+		// trace_connection - AM
+		if (m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+			Object p[] = T4LoggingUtilities.makeParams(m_ic.t4props_);
+			String temp = "LogicalByteArray";
+			m_ic.t4props_.t4Logger_.logp(Level.FINEST, "T4Connection", "getReadBuffer", temp, p);
+		}
+		LogicalByteArray rbuffer = m_io.doIO(odbcAPI, wbuffer);
+
+		return rbuffer;
+	}
+
+	// --------------------------------------------------------------------------------
+	/**
+	 * This class corresponds to the ODBC client driver function
+	 * odbc_SQLSvc_InitializeDialogue_pst_ as taken from odbccs_drvr.cpp.
+	 * @version 1.0
+	 * 
+	 * This method will make a connection to an ODBC server. The ODBC server's
+	 * locaiton This method will make a connection to an ODBC server. The ODBC
+	 * server's locaiton (i.e. ip address and port number), were provided by an
+	 * earlier call to the ODBC association server.
+	 * 
+	 * @param inContext
+	 *            a CONNETION_CONTEXT_def object containing connection
+	 *            information
+	 * @param userDesc
+	 *            a USER_DESC_def object containing user information
+	 * @param inContext
+	 *            a CONNECTION_CONTEXT_def object containing information for
+	 *            this connection
+	 * @param dialogueId
+	 *            a unique id identifing this connection as supplied by an
+	 *            earlier call to the association server
+	 * 
+	 * @retrun a InitializeDialogueReply class representing the reply from the
+	 *         ODBC server is returned
+	 * 
+	 * @exception A
+	 *                SQLException is thrown
+	 */
+
+	InitializeDialogueReply InitializeDialogue(boolean setTimestamp, boolean downloadCert) throws SQLException {
+		try {
+			int optionFlags1 = INCONTEXT_OPT1_CLIENT_USERNAME;
+			int optionFlags2 = 0;
+			
+			if(setTimestamp) {
+				optionFlags1 |= INCONTEXT_OPT1_CERTIFICATE_TIMESTAMP;
+			}
+
+			if (m_sessionName != null && m_sessionName.length() > 0) {
+				optionFlags1 |= INCONTEXT_OPT1_SESSIONNAME;
+			}
+
+			if (this.m_ic.t4props_.getFetchAhead()) {
+				optionFlags1 |= INCONTEXT_OPT1_FETCHAHEAD;
+			}
+
+			// trace_connection - AM
+			if (m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(m_ic.t4props_);
+				String temp = "m_dialogueId=" + m_dialogueId;
+				m_ic.t4props_.t4Logger_.logp(Level.FINEST, "T4Connection", "InitializeDialogue", temp, p);
+			}
+			LogicalByteArray wbuffer = InitializeDialogueMessage.marshal(m_userDesc, m_inContext, m_dialogueId,
+					optionFlags1, optionFlags2, m_sessionName, m_ic);
+
+			getInputOutput().setTimeout(m_ic.t4props_.getLoginTimeout());
+
+			LogicalByteArray rbuffer = getReadBuffer(TRANSPORT.SRVR_API_SQLCONNECT, wbuffer);
+
+			//
+			// Process output parameters
+			//
+			InitializeDialogueReply idr1 = new InitializeDialogueReply(rbuffer, m_ncsAddress.getIPorName(), m_ic, downloadCert);
+
+			return idr1;
+		} catch (SQLException se) {
+			throw se;
+		} catch (CharacterCodingException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"translation_of_parameter_failed", "InitializeDialogueMessage", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} catch (UnsupportedCharsetException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "unsupported_encoding", e
+					.getCharsetName());
+			se.initCause(e);
+			throw se;
+		}
+
+		catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"initialize_dialogue_message_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} // end catch
+	} // end InitializeDialogue
+
+	/**
+	 * This method will end a connection to an ODBC server. The ODBC server's
+	 * locaiton (i.e. ip address and port number), were provided by an earlier
+	 * call to the ODBC association server.
+	 * 
+	 * @retrun a TerminateDialogueReply class representing the reply from the
+	 *         ODBC server is returned
+	 * 
+	 * @exception A
+	 *                SQLException is thrown
+	 */
+	TerminateDialogueReply TerminateDialogue() throws SQLException {
+		try {
+			// trace_connection - AM
+			if (m_ic.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
+				Object p[] = T4LoggingUtilities.makeParams(m_ic.t4props_);
+				String temp = "m_dialogueId=" + m_dialogueId;
+				m_ic.t4props_.t4Logger_.logp(Level.FINEST, "T4Connection", "TerminateDialogue", temp, p);
+			}
+			LogicalByteArray wbuffer = TerminateDialogueMessage.marshal(m_dialogueId, this.m_ic);
+
+			//
+			// used m_ic instead of getInputOutput, because getInputOutput
+			// implicitly calls close at timeout, which will call
+			// TerminateDialogue
+			// which causes recursion.
+			//
+			// m_io.setTimeout(m_ic.t4props_.getCloseConnectionTimeout());
+			m_io.setTimeout(m_ic.t4props_.getLoginTimeout());
+
+			LogicalByteArray rbuffer = getReadBuffer(TRANSPORT.SRVR_API_SQLDISCONNECT, wbuffer);
+
+			//
+			// Process output parameters
+			//
+			TerminateDialogueReply tdr1 = new TerminateDialogueReply(rbuffer, m_ncsAddress.getIPorName(), m_ic);
+
+			//
+			// Send a close message and close the port if we don't have an
+			// error.
+			// If there is an error, it's up to the calling routine to decide
+			// what to do.
+			//
+			if (tdr1.m_p1.exception_nr == TRANSPORT.CEE_SUCCESS) {
+				m_io.CloseIO(wbuffer); // note, I'm re-using wbuffer
+
+			}
+
+			closeTimers();
+
+			return tdr1;
+		} // end try
+		catch (SQLException se) {
+			throw se;
+		} catch (CharacterCodingException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"translation_of_parameter_failed", "TerminateDialogMessage", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} catch (UnsupportedCharsetException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "unsupported_encoding", e
+					.getCharsetName());
+			se.initCause(e);
+			throw se;
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"terminate_dialogue_message_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} // end catch
+	} // end TerminateDialogue
+
+	/**
+	 * This method will send a set connection option command to the server.
+	 * 
+	 * @param connetionOption
+	 *            The connection option to be set
+	 * @param optionValueNum
+	 *            The number value of the option
+	 * @param optionValueStr
+	 *            The string value of the option
+	 * 
+	 * @retrun a SetConnectionOptionReply class representing the reply from the
+	 *         ODBC server is returned
+	 * 
+	 * @exception A
+	 *                SQLException is thrown
+	 */
+	SetConnectionOptionReply SetConnectionOption(short connectionOption, int optionValueNum, String optionValueStr)
+			throws SQLException {
+
+		if (optionValueStr == null) {
+			throwInternalException();
+
+		}
+		try {
+
+			LogicalByteArray wbuffer = SetConnectionOptionMessage.marshal(m_dialogueId, connectionOption,
+					optionValueNum, optionValueStr, this.m_ic);
+
+			getInputOutput().setTimeout(m_ic.t4props_.getNetworkTimeout());
+
+			LogicalByteArray rbuffer = getReadBuffer(TRANSPORT.SRVR_API_SQLSETCONNECTATTR, wbuffer);
+
+			SetConnectionOptionReply scor = new SetConnectionOptionReply(rbuffer, m_ncsAddress.getIPorName(), m_ic);
+
+			return scor;
+		} // end try
+		catch (SQLException se) {
+			throw se;
+		} catch (CharacterCodingException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"translation_of_parameter_failed", "SetConnectionOptionReply", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} catch (UnsupportedCharsetException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "unsupported_encoding", e
+					.getCharsetName());
+			se.initCause(e);
+			throw se;
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"set_connection_option_message_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} // end catch
+	} // end SetConnectionOption
+
+	/**
+	 * This method will send an End Transaction command, which does not return
+	 * any rowsets, to the ODBC server.
+	 * 
+	 * @param transactionOpt
+	 *            A transaction opt
+	 * 
+	 * @retrun A EndTransactionReply class representing the reply from the ODBC
+	 *         server is returned
+	 * 
+	 * @exception A
+	 *                SQLException is thrown
+	 */
+	EndTransactionReply EndTransaction(short transactionOpt) throws SQLException {
+
+		try {
+			LogicalByteArray wbuffer = EndTransactionMessage.marshal(m_dialogueId, transactionOpt, this.m_ic);
+
+			getInputOutput().setTimeout(m_ic.t4props_.getNetworkTimeout());
+
+			LogicalByteArray rbuffer = getReadBuffer(TRANSPORT.SRVR_API_SQLENDTRAN, wbuffer);
+
+			EndTransactionReply cr = new EndTransactionReply(rbuffer, m_ncsAddress.getIPorName(), m_ic);
+			return cr;
+		} // end try
+		catch (SQLException se) {
+			throw se;
+		} catch (CharacterCodingException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"translation_of_parameter_failed", "EndTransactionMessage", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} catch (UnsupportedCharsetException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "unsupported_encoding", e
+					.getCharsetName());
+			se.initCause(e);
+			throw se;
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "end_transaction_message_error",
+					e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} // end catch
+
+	} // end EndTransaction
+
+	/**
+	 * This method will send an get SQL catalogs command to the ODBC server.
+	 * 
+	 * @param stmtLabel
+	 *            a statement label for use by the ODBC server
+	 * @param APIType
+	 * @param catalogNm
+	 * @param schemaNm
+	 * @param tableNm
+	 * @param tableTypeList
+	 * @param columnNm
+	 * @param columnType
+	 * @param rowIdScope
+	 * @param nullable
+	 * @param uniqueness
+	 * @param accuracy
+	 * @param sqlType
+	 * @param metadataId
+	 * @param fkcatalogNm
+	 * @param fkschemaNm
+	 * @param fktableNm
+	 * 
+	 * @retrun a GetSQLCatalogsReply class representing the reply from the ODBC
+	 *         server is returned
+	 * 
+	 * @exception A
+	 *                SQLException is thrown
+	 */
+	GetSQLCatalogsReply GetSQLCatalogs(String stmtLabel, short APIType, String catalogNm, String schemaNm,
+			String tableNm, String tableTypeList, String columnNm, int columnType, int rowIdScope, int nullable,
+			int uniqueness, int accuracy, short sqlType, int metadataId, String fkcatalogNm, String fkschemaNm,
+			String fktableNm) throws SQLException {
+
+		if (stmtLabel == null) {
+			throwInternalException();
+
+		}
+		try {
+			LogicalByteArray wbuffer;
+
+			wbuffer = GetSQLCatalogsMessage.marshal(m_dialogueId, stmtLabel, APIType, catalogNm, schemaNm, tableNm,
+					tableTypeList, columnNm, columnType, rowIdScope, nullable, uniqueness, accuracy, sqlType,
+					metadataId, fkcatalogNm, fkschemaNm, fktableNm, m_ic);
+
+			getInputOutput().setTimeout(m_ic.t4props_.getNetworkTimeout());
+
+			LogicalByteArray rbuffer = getReadBuffer(TRANSPORT.SRVR_API_GETCATALOGS, wbuffer);
+
+			//
+			// Process output parameters
+			//
+			GetSQLCatalogsReply gscr = new GetSQLCatalogsReply(rbuffer, m_ncsAddress.getIPorName(), m_ic);
+
+			return gscr;
+		} // end try
+		catch (SQLException se) {
+			throw se;
+		} catch (CharacterCodingException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"translation_of_parameter_failed", "GetSQLCatalogsMessage", e.getMessage());
+			se.initCause(e);
+			throw se;
+		} catch (UnsupportedCharsetException e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale, "unsupported_encoding", e
+					.getCharsetName());
+			se.initCause(e);
+			throw se;
+		} catch (Exception e) {
+			SQLException se = HPT4Messages.createSQLException(m_ic.t4props_, m_locale,
+					"get_sql_catalogs_message_error", e.getMessage());
+
+			se.initCause(e);
+			throw se;
+		} // end catch
+
+	} // end GetSQLCatalogs
+
+}