db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r126392 - in incubator/derby/code/trunk/java: drda/org/apache/derby/impl/drda engine/org/apache/derby/iapi/jdbc
Date Tue, 25 Jan 2005 17:13:37 GMT
Author: kmarsden
Date: Tue Jan 25 09:13:34 2005
New Revision: 126392

URL: http://svn.apache.org/viewcvs?view=rev&rev=126392
Log:
Fix for multiple EXCSAT's without reset of the connection.
contributed by kmarsden@sbcglobal.net

There are three kinds of EXCSAT's we might get

1) Initial Exchange attributes.   For this we need to initialize the
apprequester. Session state is set to ATTEXC (attributes exchanged) then
the AR must follow up with ACCSEC and SECCHK to get the connection.

2) Send of EXCSAT as ping or manager level adjustment. For this we just
ignore the EXCSAT objects that are already set.  JCC doesn't use this,
but it is in DRDA.

3) Send of EXCSAT for connection reset. (see parseEXCSAT2()) This is
treated just like ping and will be followed up
by an ACCSEC request if in fact it is a connection reset.
If we have already exchanged attributes once just
process any new manager levels and return (case 2 and 3 above)
 	
Before the XA checkin, 1 and 2 worked.  After the XA checkin 1 and 3
worked and with this patch 1, 2, and 3 all work.

I had to rearrange the code a bit to do this because in DRDAConnThread,
processCommands() the EXCSAT case just called parseDRDAConnection which
expected the ACCSEC and SECCHK codepoints in the correct order.

As a solution I
1) Moved the handling of the ACCSEC and SECCHK codepoints from
parseDRDAConnection up to  processCommands().

2) Put the security state in the Session object.  The session has
   4 states.

two existed before:
INIT 	- initial state
ATTEXC  - attributes exchanged
	   (After first EXSAT - ACCSEC required)

now there are two new ones:

SECACC   - security accessed (After successful ACCSEC - need SECCHK)
CHKSEC   - checked security. After successful SECCHK and connection.
           no more required security codepoits.

The session.getRequiredSecurityCodepoint() method is used by
process_commands to determine if the next codepoint must be ACCSEC or
SECCHK.

Also the patch includes the fix Dan suggested for jdk 131 for
BrokeredPreparedStatent.getStatement(). But how to call
Connection.prepareStatement is still an issue.

Modified:
   incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
   incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
   incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java
   incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java

Modified: incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java&r1=126391&p2=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java	(original)
+++ incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java	Tue
Jan 25 09:13:34 2005
@@ -560,12 +560,10 @@
 		else
 		{
 			// exchange attributes with application requester
-			if (exchangeServerAttributes())
-				session.state = Session.ATTEXC;
-			else
-				closeSession();
+			exchangeServerAttributes();
 		}
 	}
+
 	/**
 	 * Process DRDA commands we can receive once server attributes have been
 	 * exchanged.
@@ -577,11 +575,16 @@
 		DRDAStatement stmt = null;
 		int updateCount = 0;
 		boolean PRPSQLSTTfailed = false;
+		boolean checkSecurityCodepoint = session.requiresSecurityCodepoint();
 		do
 		{
 			correlationID = reader.readDssHeader();
 			int codePoint = reader.readLengthAndCodePoint();
 			int writerMark = writer.markDSSClearPoint();
+			
+			if (checkSecurityCodepoint)
+				verifyInOrderACCSEC_SECCHK(codePoint,session.getRequiredSecurityCodepoint());
+
 			switch(codePoint)
 			{
 				case CodePoint.CNTQRY:
@@ -801,7 +804,19 @@
 					}
 					break;
 				case CodePoint.EXCSAT:
-					parseDRDAConnection();
+					parseEXCSAT();
+					writeEXCSATRD();
+					finalizeChain();
+					break;
+				case CodePoint.ACCSEC:
+					int securityCheckCode = parseACCSEC();
+					writeACCSECRD(securityCheckCode); 
+					checkSecurityCodepoint = true;
+					break;
+				case CodePoint.SECCHK:
+					if(parseDRDAConnection())
+						// security all checked and connection ok
+						checkSecurityCodepoint = false;
 					break;
 				/* since we don't support sqlj, we won't get bind commands from jcc, we
 				 * might get it from ccc; just skip them.
@@ -916,11 +931,10 @@
 	/**
 	 * Exchange server attributes with application requester
 	 *
- 	 * @return true if the session was started successfully; false otherwise
-	 * @exception DRDAProtocolException, SQLException
+	 * @exception DRDAProtocolException
 	 */
-	private boolean exchangeServerAttributes()
-		throws  DRDAProtocolException, SQLException
+	private void exchangeServerAttributes()
+		throws  DRDAProtocolException
 	{
 		int codePoint;
 		correlationID = reader.readDssHeader();
@@ -944,10 +958,10 @@
 										  CodePoint.PRCCNVCD_EXCSAT_FIRST_AFTER_CONN);
 		}
 
-		// set up a new Application Requester to store information about the
-		// application requester for this session
-		
-		return parseDRDAConnection();
+		parseEXCSAT();
+		writeEXCSATRD();
+		finalizeChain();
+		session.setState(session.ATTEXC);
 	}
 	
 
@@ -956,49 +970,8 @@
 		int codePoint;
 		boolean sessionOK = true;
 
-		appRequester = new AppRequester();
-		parseEXCSAT();
-		writeEXCSATRD();
-		finalizeChain();
 
-		//we may have to do the access security more than once if we don't
-		//provide the requested security mechanism or we run into errors
-		//if we don't know the requested security mechanism
-		//we'll send our known security mechanisms and the requester will pick
-		//if he picks one that requires a security token then another ACCSEC 
-		//will flow
-		int securityCheckCode = 0;
-		boolean notdone = true;
-		while (notdone)
-		{
-			correlationID = reader.readDssHeader();
-			codePoint = reader.readLengthAndCodePoint();
-			verifyInOrderACCSEC_SECCHK(codePoint,CodePoint.ACCSEC);
-			securityCheckCode = parseACCSEC();
-			// need security token
-			if (securityCheckCode == 0  && 
-				database.securityMechanism == CodePoint.SECMEC_EUSRIDPWD &&
-				database.publicKeyIn == null)
-					securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING;
-
-			// shouldn't have security token
-			if (securityCheckCode == 0 &&
-				database.securityMechanism == CodePoint.SECMEC_USRIDPWD &&
-				database.publicKeyIn != null)
-					securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING;
-			if (SanityManager.DEBUG)
-				trace("** ACCSECRD securityCheckCode is: "+securityCheckCode);
-			writeACCSECRD(securityCheckCode);
-			// everything is O.K., we're done
-			if (securityCheckCode == 0) 
-			{
-				notdone = false;
-			}
-		}
-		correlationID = reader.readDssHeader();
-		codePoint = reader.readLengthAndCodePoint();
-		verifyInOrderACCSEC_SECCHK(codePoint,CodePoint.SECCHK);
-		securityCheckCode = parseSECCHK();
+		int securityCheckCode = parseSECCHK();
 		if (SanityManager.DEBUG)
 			trace("*** SECCHKRM securityCheckCode is: "+securityCheckCode);
 		writeSECCHKRM(securityCheckCode);
@@ -1231,6 +1204,31 @@
 		int codePoint;
 		String strVal;
 
+		// There are three kinds of EXCSAT's we might get.
+		// 1) Initial Exchange attributes.
+		//    For this we need to initialize the apprequester.
+		//    Session state is set to ATTEXC and then the AR must 
+		//    follow up with ACCSEC and SECCHK to get the connection.
+		//  2) Send of EXCSAT as ping or mangager level adjustment. 
+		//     (see parseEXCSAT2())
+		//     For this we just ignore the EXCSAT objects that
+		//     are already set.
+		//  3) Send of EXCSAT for connection reset. (see parseEXCSAT2())
+		//     This is treated just like ping and will be followed up 
+		//     by an ACCSEC request if in fact it is a connection reset.
+
+		// If we have already exchanged attributes once just 
+		// process any new manager levels and return (case 2 and 3 above)
+		if (appRequester != null)
+		{
+			parseEXCSAT2();
+			return;
+		}
+
+		// set up a new Application Requester to store information about the
+		// application requester for this session
+
+		appRequester = new AppRequester();
 
 		reader.markCollection();
 
@@ -1611,9 +1609,32 @@
 		database.securityMechanism = securityMechanism;
 		database.publicKeyIn = publicKeyIn;
 
+		// need security token
+		if (securityCheckCode == 0  && 
+			database.securityMechanism == CodePoint.SECMEC_EUSRIDPWD &&
+			database.publicKeyIn == null)
+			securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING;
+
+		// shouldn't have security token
+		if (securityCheckCode == 0 &&
+			database.securityMechanism == CodePoint.SECMEC_USRIDPWD &&
+			database.publicKeyIn != null)
+			securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING;
+		if (SanityManager.DEBUG)
+			trace("** ACCSECRD securityCheckCode is: "+securityCheckCode);
+		
+		// If the security check was successful set the session state to
+		// security accesseed.  Otherwise go back to attributes exchanged so we
+		// require another ACCSEC
+		if (securityCheckCode == 0)
+			session.setState(session.SECACC);
+		else
+			session.setState(session.ATTEXC);
+
 		return securityCheckCode;
 
 	}
+
 	/**
 	 * Parse OPNQRY
 	 * Instance Variables
@@ -2612,6 +2633,11 @@
 		{
 			securityCheckCode = verifyUserIdPassword();
 		}
+
+		// Security all checked 
+		if (securityCheckCode == 0)
+			session.setState(session.CHKSEC);
+		
 		return securityCheckCode;
 
 	}

Modified: incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java&r1=126391&p2=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java	(original)
+++ incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java	Tue
Jan 25 09:13:34 2005
@@ -39,6 +39,7 @@
 import org.apache.derby.impl.jdbc.Util;
 import org.apache.derby.impl.jdbc.EmbedConnection;
 import  org.apache.derby.iapi.jdbc.BrokeredConnection;
+import  org.apache.derby.iapi.jdbc.BrokeredPreparedStatement;
 import org.apache.derby.impl.jdbc.EmbedResultSet;
 import org.apache.derby.impl.jdbc.EmbedParameterSetMetaData;
 import org.apache.derby.iapi.services.sanity.SanityManager;
@@ -276,7 +277,7 @@
 		try {
 			Method sh =
 				rsstmt.getClass().getMethod("getResultSetHoldability", getResultSetHoldabilityParam);
-			holdValue =  ((Integer) sh.invoke(ps,null)).intValue();
+			holdValue =  ((Integer) sh.invoke(rsstmt,null)).intValue();
 		}
 		catch (Exception e) {
 			handleReflectionException(e);
@@ -518,9 +519,13 @@
 	 *
 	 * @return prepared statement
 	 */
-	protected PreparedStatement getPreparedStatement() 
+	protected PreparedStatement getPreparedStatement() throws SQLException
 	{
-		return ps;
+		if (ps instanceof BrokeredPreparedStatement)
+			return (PreparedStatement)(
+						   ((BrokeredPreparedStatement) ps).getStatement());
+		else
+			return ps;
 	}
 
 

Modified: incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java&r1=126391&p2=incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java	(original)
+++ incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Session.java	Tue Jan 25
09:13:34 2005
@@ -36,10 +36,12 @@
 class Session
 {
 
-	// session states
+	// session states	   
 	protected static final int INIT = 1;	// before exchange of server attributes
-	protected static final int ATTEXC = 2;	// after exchange of server attributes
-	protected static final int CLOSED = 3;	// session has ended
+	protected static final int ATTEXC = 2;	// after first exchange of server attributes
+	protected static final int SECACC = 3;	// after ACCSEC (Security Manager Accessed)
+	protected static final int CHKSEC = 4;	// after SECCHK  (Checked Security)
+	protected static final int CLOSED = 5;	// session has ended
 
 	// session types
 	protected static final int DRDA_SESSION = 1;
@@ -196,7 +198,50 @@
 		return (Database)dbtable.get(dbName);
 	}
 
+	/**
+	 * Get requried security checkpoint.
+	 * Used to verify EXCSAT/ACCSEC/SECCHK order.
+	 *
+	 *  @return next required Security checkpoint or -1 if 
+	 *          neither ACCSEC or SECCHK are required at this time.
+	 *
+	 */
+	protected int getRequiredSecurityCodepoint()
+	{
+		switch (state)
+		{
+			case ATTEXC:
+				// On initial exchange of attributes we require ACCSEC 
+				// to access security manager
+				return CodePoint.ACCSEC;
+			case SECACC:
+				// After security manager has been accessed successfully we
+				// require SECCHK to check security
+				return CodePoint.SECCHK;
+			default:
+				return -1;
+		}	 
+	}
+
+	/**
+	 * Check if a security codepoint is required
+	 *
+	 * @return true if ACCSEC or SECCHK are required at this time.
+	 */
+	protected boolean requiresSecurityCodepoint()
+	{
+		return (getRequiredSecurityCodepoint() != -1);
+	}
 
+	/**
+	 * Set Session state
+	 * 
+	 */
+	protected void setState(int s)
+	{
+		state = s;
+	}
+	
 	/**
 	 * Get session into initial state
 	 *

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java&r1=126391&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java
(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredCallableStatement.java
Tue Jan 25 09:13:34 2005
@@ -217,7 +217,7 @@
 	protected final CallableStatement getCallableStatement() throws SQLException {
 		return control.getRealCallableStatement();
 	}
-	protected final PreparedStatement getPreparedStatement() throws SQLException {
+	public final PreparedStatement getPreparedStatement() throws SQLException {
 		return getCallableStatement();
 	}
 	/**

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java&r1=126391&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java
(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredPreparedStatement.java
Tue Jan 25 09:13:34 2005
@@ -491,14 +491,14 @@
 	** Control methods.
 	*/
 
-	protected PreparedStatement getPreparedStatement() throws SQLException {
+	public PreparedStatement getPreparedStatement() throws SQLException {
 		return control.getRealPreparedStatement();
 	}
 
 	/**
 		Override the BrokeredStatement's getStatement() to always return a PreparedStatement.
 	*/
-	protected final Statement getStatement() throws SQLException {
+	public final Statement getStatement() throws SQLException {
 		return getPreparedStatement();
 	}
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java?view=diff&rev=126392&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java&r1=126391&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java&r2=126392
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java
(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredStatement.java
Tue Jan 25 09:13:34 2005
@@ -510,7 +510,7 @@
 		newStatement.setQueryTimeout(oldStatement.getQueryTimeout());
 	}
 
-	protected Statement getStatement() throws SQLException {
+	public Statement getStatement() throws SQLException {
 		return control.getRealStatement();
 	}
 	protected final ResultSet wrapResultSet(ResultSet rs) {

Mime
View raw message