From 90a85f0fed34b0a7d6db93022074a39a17ad27b7 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Fri, 24 Apr 2009 17:05:14 +0000
Subject: [PATCH] Fix for issue where unit tests hang when the startTLS extended operation is used.
---
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java | 110 +++++++++++++++++++++++++++++++++----------------------
1 files changed, 66 insertions(+), 44 deletions(-)
diff --git a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
index 57b27e5..d0cd61f 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -50,6 +50,7 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
+import static org.opends.messages.CoreMessages.ERR_ENQUEUE_BIND_IN_PROGRESS;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConnectionHandler;
import org.opends.server.core.AbandonOperationBasis;
@@ -76,24 +77,9 @@
import org.opends.server.protocols.asn1.ASN1;
import org.opends.server.protocols.asn1.ASN1ByteChannelReader;
import org.opends.server.protocols.asn1.ASN1Writer;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteStringBuilder;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DN;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.IntermediateResponse;
-import org.opends.server.types.Operation;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SearchResultReference;
+import org.opends.server.types.*;
import org.opends.server.util.TimeThread;
-
+import static org.opends.server.util.ServerConstants.OID_START_TLS_REQUEST;
/**
@@ -200,9 +186,9 @@
private final RedirectingByteChannel saslChannel;
private final RedirectingByteChannel tlsChannel;
- private ConnectionSecurityProvider activeProvider = null;
- private ConnectionSecurityProvider tlsPendingProvider = null;
- private ConnectionSecurityProvider saslPendingProvider = null;
+ private volatile ConnectionSecurityProvider activeProvider = null;
+ private volatile ConnectionSecurityProvider tlsPendingProvider = null;
+ private volatile ConnectionSecurityProvider saslPendingProvider = null;
// Statistics for the processed operations
private OperationMonitor addMonitor;
@@ -1419,12 +1405,15 @@
*/
public boolean processDataRead()
{
- if (this.saslPendingProvider != null)
- {
- enableSASL();
- }
while (true)
{
+ if(bindOrStartTLSInProgress.get())
+ {
+ // We should wait for the bind or startTLS to finish before
+ // reading any more data off the socket.
+ return true;
+ }
+
try
{
int result = asn1Reader.processChannelData();
@@ -1541,6 +1530,14 @@
// terminated.
try
{
+ if(bindOrStartTLSInProgress.get() ||
+ (saslBindInProgress.get() &&
+ message.getProtocolOpType() != OP_TYPE_BIND_REQUEST))
+ {
+ throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+ ERR_ENQUEUE_BIND_IN_PROGRESS.get());
+ }
+
boolean result;
switch (message.getProtocolOpType())
{
@@ -1564,7 +1561,22 @@
return result;
case OP_TYPE_BIND_REQUEST:
if (keepStats) this.bindMonitor.start();
+ bindOrStartTLSInProgress.set(true);
+ if(message.getBindRequestProtocolOp().
+ getAuthenticationType() == AuthenticationType.SASL)
+ {
+ saslBindInProgress.set(true);
+ }
result = processBindRequest(message, opControls);
+ if(!result)
+ {
+ bindOrStartTLSInProgress.set(false);
+ if(message.getBindRequestProtocolOp().
+ getAuthenticationType() == AuthenticationType.SASL)
+ {
+ saslBindInProgress.set(false);
+ }
+ }
if (keepStats)
{
this.bindMonitor.stop();
@@ -1591,7 +1603,18 @@
return result;
case OP_TYPE_EXTENDED_REQUEST:
if (keepStats) this.extendedMonitor.start();
+ if(message.getExtendedRequestProtocolOp().getOID().equals(
+ OID_START_TLS_REQUEST))
+ {
+ bindOrStartTLSInProgress.set(true);
+ }
result = processExtendedRequest(message, opControls);
+ if(!result &&
+ message.getExtendedRequestProtocolOp().getOID().equals(
+ OID_START_TLS_REQUEST))
+ {
+ bindOrStartTLSInProgress.set(false);
+ }
if (keepStats)
{
this.extendedMonitor.stop();
@@ -2447,26 +2470,6 @@
/**
- * Sends a response to the client in the clear rather than through the
- * encrypted channel. This should only be used when processing the
- * StartTLS extended operation to send the response in the clear after
- * the TLS negotiation has already been initiated.
- *
- * @param operation
- * The operation for which to send the response in the clear.
- * @throws DirectoryException
- * If a problem occurs while sending the response in the
- * clear.
- */
- public void sendClearResponse(Operation operation)
- throws DirectoryException
- {
- sendLDAPMessage(operationToResponseLDAPMessage(operation));
- }
-
-
-
- /**
* Retrieves the length of time in milliseconds that this client
* connection has been idle. <BR>
* <BR>
@@ -2649,4 +2652,23 @@
this.moddnMonitor = OperationMonitor.getOperationMonitor(MODIFY_DN);
this.unbindMonitor = OperationMonitor.getOperationMonitor(UNBIND);
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void finishBindOrStartTLS()
+ {
+ if(this.tlsPendingProvider != null)
+ {
+ enableTLS();
+ }
+
+ if (this.saslPendingProvider != null)
+ {
+ enableSASL();
+ }
+
+ super.finishBindOrStartTLS();
+ }
}
--
Gitblit v1.10.0