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/core/DirectoryServer.java                                                        |   11 -
 opends/src/server/org/opends/server/api/ClientConnection.java                                                        |   71 ++++----
 opends/src/server/org/opends/server/core/ExtendedOperation.java                                                      |   10 -
 opends/src/server/org/opends/server/core/BindOperationBasis.java                                                     |   23 +-
 opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java |   55 ------
 opends/src/server/org/opends/server/core/ExtendedOperationBasis.java                                                 |   56 +-----
 opends/src/server/org/opends/server/extensions/TLSCapableConnection.java                                             |   37 ----
 opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java                                        |   25 ---
 opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java                                 |   41 -----
 opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java                                           |    4 
 opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java                                           |   34 ----
 opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java                                         |  110 ++++++++-----
 12 files changed, 131 insertions(+), 346 deletions(-)

diff --git a/opends/src/server/org/opends/server/api/ClientConnection.java b/opends/src/server/org/opends/server/api/ClientConnection.java
index bbe1a9e..1e43e23 100644
--- a/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -38,6 +38,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.opends.messages.Message;
 import org.opends.server.api.plugin.PluginResult;
@@ -92,10 +93,19 @@
   // The set of authentication information for this client connection.
   private AuthenticationInfo authenticationInfo;
 
-  // Indicates whether a bind is currently in progress on this client
-  // connection.  If so, then no other operations should be allowed
-  // until the bind completes.
-  private boolean bindInProgress;
+  /**
+   * Indicates whether a multistage SASL bind is currently in progress
+   * on this client connection.  If so, then no other operations
+   * should be allowed until the bind completes.
+   */
+  protected AtomicBoolean saslBindInProgress;
+
+  /**
+   * Indicates if a bind or start TLS request is currently in progress
+   * on this client connection. If so, then no further socket reads
+   * will occur until the request completes.
+   */
+  protected AtomicBoolean bindOrStartTLSInProgress;
 
   // Indicates whether any necessary finalization work has been done
   // for this client connection.
@@ -148,7 +158,8 @@
     connectTimeString  = TimeThread.getGMTTime();
     authenticationInfo = new AuthenticationInfo();
     saslAuthState      = null;
-    bindInProgress     = false;
+    saslBindInProgress = new AtomicBoolean(false);
+    bindOrStartTLSInProgress = new AtomicBoolean(false);
     persistentSearches = new CopyOnWriteArrayList<PersistentSearch>();
     sizeLimit          = DirectoryServer.getSizeLimit();
     timeLimit          = DirectoryServer.getTimeLimit();
@@ -695,36 +706,6 @@
 
 
   /**
-   * Indicates whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed
-   * until the bind has completed.
-   *
-   * @return  {@code true} if a bind operation is in progress on this
-   *          connection, or {@code false} if not.
-   */
-  public boolean bindInProgress()
-  {
-    return bindInProgress;
-  }
-
-
-
-  /**
-   * Specifies whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed
-   * until the bind has completed.
-   *
-   * @param  bindInProgress  Specifies whether a bind operation is in
-   *                         progress on this client connection.
-   */
-  public void setBindInProgress(boolean bindInProgress)
-  {
-    this.bindInProgress = bindInProgress;
-  }
-
-
-
-  /**
    * Indicates whether the user associated with this client connection
    * must change their password before they will be allowed to do
    * anything else.
@@ -1850,5 +1831,25 @@
    * @return An integer representing the SSF value of a connection.
    */
   public abstract int getSSF();
+
+  /**
+   * Indicates a bind or start TLS request processing is finished
+   * and the client connection may start processing data read from
+   * the socket again. This must be called after processing each
+   * bind request in a multistage SASL bind.
+   */
+  public void finishBindOrStartTLS()
+  {
+    bindOrStartTLSInProgress.set(false);
+  }
+
+  /**
+   * Indicates a multistage SASL bind operation is finished and the
+   * client connection may accept additional LDAP messages.
+   */
+  public void finishSaslBind()
+  {
+    saslBindInProgress.set(false);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/core/BindOperationBasis.java b/opends/src/server/org/opends/server/core/BindOperationBasis.java
index 01110df..44e8797 100644
--- a/opends/src/server/org/opends/server/core/BindOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/BindOperationBasis.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2007-2008 Sun Microsystems, Inc.
+ *      Copyright 2007-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 import org.opends.messages.Message;
@@ -728,11 +728,6 @@
 
     ClientConnection clientConnection = getClientConnection();
 
-    // Set a flag to indicate that a bind operation is in progress.  This should
-    // ensure that no new operations will be accepted for this client until the
-    // bind is complete.
-    clientConnection.setBindInProgress(true);
-
     // Wipe out any existing authentication for the client connection and create
     // a placeholder that will be used if the bind is successful.
     clientConnection.setUnauthenticated();
@@ -838,19 +833,21 @@
     }
     finally
     {
-      // If the bind processing is finished, then unset the "bind in progress"
-      // flag to allow other operations to be processed on the connection.
-      if (getResultCode() != ResultCode.SASL_BIND_IN_PROGRESS)
-      {
-        clientConnection.setBindInProgress(false);
-      }
-
       // Stop the processing timer.
       setProcessingStopTime();
 
       // Send the bind response to the client.
       clientConnection.sendResponse(this);
 
+      // If the bind processing is finished, then unset the "bind in progress"
+      // flag to allow other operations to be processed on the connection.
+      if (getResultCode() != ResultCode.SASL_BIND_IN_PROGRESS)
+      {
+        clientConnection.finishSaslBind();
+      }
+
+      clientConnection.finishBindOrStartTLS();
+
       // Log the bind response.
       logBindResponse(this);
 
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index 5a8ab3a..cddf0d2 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -211,7 +211,6 @@
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.ObjectClassType;
 import org.opends.server.types.OperatingSystem;
-import org.opends.server.types.OperationType;
 import org.opends.server.types.Privilege;
 import org.opends.server.types.RestoreConfig;
 import org.opends.server.types.ResultCode;
@@ -7248,17 +7247,7 @@
   public static void enqueueRequest(AbstractOperation operation)
          throws DirectoryException
   {
-    // See if a bind is already in progress on the associated connection.  If so
-    // then reject the operation.
     ClientConnection clientConnection = operation.getClientConnection();
-    if (clientConnection.bindInProgress() &&
-        (operation.getOperationType() != OperationType.BIND))
-    {
-      Message message = ERR_ENQUEUE_BIND_IN_PROGRESS.get();
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
-
     //Reject or accept the unauthenticated requests based on the configuration
     // settings.
     if ((directoryServer.rejectUnauthenticatedRequests ||
diff --git a/opends/src/server/org/opends/server/core/ExtendedOperation.java b/opends/src/server/org/opends/server/core/ExtendedOperation.java
index 455140c..d7bff6d 100644
--- a/opends/src/server/org/opends/server/core/ExtendedOperation.java
+++ b/opends/src/server/org/opends/server/core/ExtendedOperation.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 
@@ -94,13 +94,5 @@
    *                        the client.
    */
   public void setResponseValue(ByteString responseValue);
-
-  /**
-   * Indicates that the response for this extended operation has been sent from
-   * somewhere outside of this class.  This should only be used by the StartTLS
-   * extended operation for the case in which it needs to send a response in the
-   * clear after TLS negotiation has already started on the connection.
-   */
-  public void setResponseSent();
 }
 
diff --git a/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java b/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
index a50bc70..3764c5d 100644
--- a/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
@@ -76,9 +76,6 @@
   // The value for the response associated with this extended operation.
   private ByteString responseValue;
 
-  // Indicates whether a response has yet been sent for this operation.
-  private boolean responseSent;
-
   // The set of response controls for this extended operation.
   private List<Control> responseControls;
 
@@ -119,7 +116,6 @@
     responseValue    = null;
     responseControls = new ArrayList<Control>();
     cancelRequest    = null;
-    responseSent     = false;
 
     if (requestOID.equals(OID_CANCEL_REQUEST))
     {
@@ -524,17 +520,18 @@
       // Stop the processing timer.
       setProcessingStopTime();
 
-      // Send the response to the client, if it has not already been sent.
-      if (! responseSent)
+      // Send the response to the client.
+      if(cancelRequest == null || cancelResult == null ||
+          cancelResult.getResultCode() != ResultCode.CANCELED ||
+          cancelRequest.notifyOriginalRequestor() ||
+          DirectoryServer.notifyAbandonedOperations())
       {
-        responseSent = true;
-        if(cancelRequest == null || cancelResult == null ||
-            cancelResult.getResultCode() != ResultCode.CANCELED ||
-            cancelRequest.notifyOriginalRequestor() ||
-            DirectoryServer.notifyAbandonedOperations())
-        {
-          clientConnection.sendResponse(this);
-        }
+        clientConnection.sendResponse(this);
+      }
+
+      if(requestOID.equals(OID_START_TLS_REQUEST))
+      {
+        clientConnection.finishBindOrStartTLS();
       }
 
       // Log the extended response.
@@ -551,37 +548,6 @@
     }
   }
 
-
-
-  /**
-   * Sends an extended response to the client if none has already been sent.
-   * Note that extended operation handlers are strongly discouraged from using
-   * this method when it is not necessary because its use will prevent the
-   * response from being sent after post-operation plugin processing, which may
-   * impact the result that should be included.  Nevertheless, it may be needed
-   * in some special cases in which the response must be sent before the
-   * extended operation handler completes its processing (e.g., the StartTLS
-   * operation in which the response must be sent in the clear before actually
-   * enabling TLS protection).
-   */
-  public final void sendExtendedResponse()
-  {
-    if (! responseSent)
-    {
-      responseSent = true;
-      clientConnection.sendResponse(this);
-    }
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public final void setResponseSent()
-  {
-    this.responseSent = true;
-  }
-
   /**
    * {@inheritDoc}
    */
diff --git a/opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java b/opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java
index f3272de..2ea8332 100644
--- a/opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java
+++ b/opends/src/server/org/opends/server/extensions/RedirectingByteChannel.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 
 package org.opends.server.extensions;
@@ -38,7 +38,7 @@
  */
 public class RedirectingByteChannel implements ByteChannel {
     private final ByteChannel child;
-    private ByteChannel redirect = null;
+    private volatile ByteChannel redirect = null;
 
     private RedirectingByteChannel(ByteChannel child) {
         this.child = child;
diff --git a/opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java b/opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java
index 115a22f..9fbeab1 100644
--- a/opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/StartTLSExtendedOperation.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.extensions;
 
@@ -36,8 +36,6 @@
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ExtendedOperation;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.ResultCode;
 
@@ -169,27 +167,6 @@
     // TLS was successfully enabled on the client connection, but we need to
     // send the response in the clear.
     operation.setResultCode(ResultCode.SUCCESS);
-
-    try
-    {
-      tlsCapableConnection.sendClearResponse(operation);
-      operation.setResponseSent();
-      tlsCapableConnection.enableTLS();
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      logError(ERR_STARTTLS_ERROR_SENDING_CLEAR_RESPONSE.get(
-          getExceptionMessage(e)));
-
-      clientConnection.disconnect(DisconnectReason.SECURITY_PROBLEM, false,
-                                  ERR_STARTTLS_ERROR_SENDING_CLEAR_RESPONSE.get(
-                                  getExceptionMessage(e)));
-    }
   }
 }
 
diff --git a/opends/src/server/org/opends/server/extensions/TLSCapableConnection.java b/opends/src/server/org/opends/server/extensions/TLSCapableConnection.java
index c53ade0..9b942a0 100644
--- a/opends/src/server/org/opends/server/extensions/TLSCapableConnection.java
+++ b/opends/src/server/org/opends/server/extensions/TLSCapableConnection.java
@@ -22,16 +22,12 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.extensions;
 import org.opends.messages.MessageBuilder;
 
 
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Operation;
-
-
 
 /**
  * This interface defines a set of methods that must be implemented by a class
@@ -56,36 +52,5 @@
    *          connection, or <CODE>false</CODE> if it is not.
    */
   public boolean isTLSAvailable(MessageBuilder unavailableReason);
-
-
-
-  /**
-   * Installs the TLS connection security provider on this client connection.
-   * If an error occurs in the process, then the underlying client connection
-   * must be terminated and an exception must be thrown to indicate the
-   * underlying cause.
-   *
-   * @throws  DirectoryException  If the TLS connection security provider could
-   *                              not be enabled and the underlying connection
-   *                              has been closed.
-   */
-  public void enableTLS()
-         throws DirectoryException;
-
-
-  /**
-   * 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 SSL
-   * 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;
 }
 
diff --git a/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java b/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
index d8cd2b9..428d8a4 100644
--- a/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.internal;
 
@@ -2746,45 +2746,6 @@
 
 
   /**
-   * Indicates whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed
-   * until the bind has completed.
-   *
-   * @return  <CODE>true</CODE> if a bind operation is in progress on
-   *          this connection, or <CODE>false</CODE> if not.
-   */
-  @Override()
-  public boolean bindInProgress()
-  {
-    // For internal operations, we don't care if there are any binds
-    // in progress.
-    return false;
-  }
-
-
-
-  /**
-   * Specifies whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed
-   * until the bind has completed.
-   *
-   * @param  bindInProgress  Specifies whether a bind operation is in
-   *                         progress on this client connection.
-   */
-  @org.opends.server.types.PublicAPI(
-       stability=org.opends.server.types.StabilityLevel.PRIVATE,
-       mayInstantiate=false,
-       mayExtend=false,
-       mayInvoke=false)
-  @Override()
-  public void setBindInProgress(boolean bindInProgress)
-  {
-    // No implementation is required.
-  }
-
-
-
-  /**
    * Retrieves the set of operations in progress for this client
    * connection.  This list must not be altered by any caller.
    *
diff --git a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
index 9345d0f..49fa84b 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.jmx;
 import org.opends.messages.Message;
@@ -1026,38 +1026,6 @@
 
 
   /**
-   * Indicates whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed until the bind
-   * has completed.
-   *
-   * @return  <CODE>true</CODE> if a bind operation is in progress on this
-   *          connection, or <CODE>false</CODE> if not.
-   */
-  public boolean bindInProgress()
-  {
-    // For Jmx operations, we don't care if there are any binds in
-    // progress.
-    return false;
-  }
-
-
-
-  /**
-   * Specifies whether a bind operation is in progress on this client
-   * connection.  If so, then no new operations should be allowed until the bind
-   * has completed.
-   *
-   * @param  bindInProgress  Specifies whether a bind operation is in progress
-   *                         on this client connection.
-   */
-  public void setBindInProgress(boolean bindInProgress)
-  {
-    // No implementation is required.
-  }
-
-
-
-  /**
    * Retrieves the set of operations in progress for this client connection.
    * This list must not be altered by any caller.
    *
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();
+  }
 }
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
index c379d5f..c0239bc 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.internal;
 
@@ -1010,59 +1010,6 @@
 
 
 
-  /**
-   * Tests the <CODE>bindInProgress</CODE> method.
-   */
-  @Test()
-  public void testBindInProgress()
-  {
-    InternalClientConnection conn =
-         InternalClientConnection.getRootConnection();
-    assertFalse(conn.bindInProgress());
-  }
-
-
-
-  /**
-   * Tests the <CODE>setBindInProgress</CODE> method.
-   */
-  @Test()
-  public void testSetBindInProgress()
-  {
-    InternalClientConnection conn =
-         InternalClientConnection.getRootConnection();
-    conn.setBindInProgress(true);
-    assertFalse(conn.bindInProgress());
-  }
-
-
-
-  /**
-   * Tests the <CODE>getOperationsInProgress</CODE> method.
-   */
-  @Test()
-  public void testGetOperationsInProgress()
-  {
-    InternalClientConnection conn =
-         InternalClientConnection.getRootConnection();
-    Collection<Operation> opList = conn.getOperationsInProgress();
-    assertNotNull(opList);
-    assertTrue(opList.isEmpty());
-  }
-
-
-
-  /**
-   * Tests the <CODE>getOperationInProgress</CODE> method.
-   */
-  @Test()
-  public void testGetOperationInProgress()
-  {
-    InternalClientConnection conn =
-         InternalClientConnection.getRootConnection();
-    assertNull(conn.getOperationInProgress(0));
-  }
-
 
 
   /**

--
Gitblit v1.10.0