On 27/03/2013 10:16 a.m., Alex Rousskov wrote:
On 03/25/2013 09:59 PM, Amos Jeffries wrote:
"
Bug 3643: NTLM helpers stuck in reserved state by Safari

NTLM failures are not always cleaning up connection-auth credentials
properly. In particular they are not releasing the NTLM helpers when
the connection is closed between challenge and handshake completion.
Resulting in permanently reserved helpers locking up all access
through the proxy.

This change redesigns the connection authentication state management
to move the auth link/unlink operations into the connection state
manager objects instead of being managed by NTLM auth components.
As a result we are able to manage credentials from any auth scheme
consistently and terminate the connection properly on several
error conditions which the auth components are not easily aware of.

  Fix sponsored by Netbox Blue Pty (http://netboxblue.com/)
"

The bulk of the patch is symbol changes since we are moving the
credentials from a public member variable to  private one with accessors.

The core of the patch logics is contained in
ConnStateData::setConnectionAuth which performs error checking and
triggers termination of the connection in various ways determined by the
type of error that was encountered.

In summary:
  - once credentials are set they are baked into the connection state.
  - all following requests require a credentials token matching the state
one.
  - any request lacking credentials (or setting NULL) will terminate the
connection gracefully. It should end with an auth re-challenge, but that
specific detail does depend on ACLs.
  - any request with a new or altered auth token (injection attacks,
broken relay pinning) will terminate the connection immediately (expect
lost bytes).
  - any pinned server connection, and any pinned stateful auth helper is
unpined/released on credential errors.

Specific cases and handling are covered in greater detail in the patch
comments.

It also adds a stub file for client_side.h functionality.

Amos


-            if (conn->auth_user_request != NULL) {
-                *auth_user_request = conn->auth_user_request;
+            if (conn->getConnectionAuth() != NULL) {
+                *auth_user_request = conn->getConnectionAuth();
              } else {
                  /* failed connection based authentication */
                  debugs(29, 4, HERE << "Auth user request " <<
                         *auth_user_request << " conn-auth user request " <<
-                       conn->auth_user_request << " conn type " <<
-                       conn->auth_user_request->user()->auth_type << " 
authentication failed.");
+                       conn->getConnectionAuth() << " conn type " <<
+                       conn->getConnectionAuth()->user()->auth_type << " 
authentication failed.");
This is an old bug not introduced by this patch, but please note that
the last debugs() line above is always dereferencing a NULL pointer (and
the next-to-last line is always logging a nil pointer).

Fixed.


+    if (credentialsState == NULL) {
+        debugs(33, 2, HERE << "Adding connection-auth to " << clientConnection << " from 
" << by);
+        credentialsState = aur;
+        return;
+    }
The if-statement after the above implies that aur can be NULL. If aur is
NULL, the above code will not change anything. Should we check for that
before we claim that we are adding something or at least debugs() aur?

Here and elsewhere, please remove HERE from the new debugs() messages.

Done.


+private:
+    /// state of some credentials that can be used to perform authentication 
on this connection
+    Auth::UserRequest::Pointer credentialsState;
The words "state", "data", and "info" usually do not add to the
description or understanding of a member. How about renaming
"credentialsState" to just "credentials"?

"UserRequest" is not just the credentials. It is the credentials along with all the additional state information. ie how, when and if they validated, any protocol options line realm which are relevant, which helper was used if stateful, the HelperReply line details etc. whatever the potocol scheme is written to preserve. I think this is possibly one case where saying state is actually warranted.

Changed anyways with the method re-naming.


Please move the private section down, after the public/protected sections.

Done.

Also, can the description be simplified to just say "connection-based
credentials for this connection" or something similar?
Done.

Finally, why do getConnectionAuth() and setConnectionAuth() use the term
"connectionAuth" while the class member storing the same information is
called credentialsState? Can all three names be made consistent/similar?
I would drop "connection" from the accessor names because the
ConnStateData class itself determines their scope as "connection". For
example:

public:
     const Auth::UserRequest::Pointer &credentials() {...}
     void credentials(...);

private:
     Auth::UserRequest::Pointer credentials_;

Used getAuth() / setAuth() / auth_ since its more than just credentials.





+    Auth::UserRequest::Pointer getConnectionAuth() const { return 
credentialsState; };
Extra semicolon at the end.

Sigh. Thought I'd broken that bad habit finally. Thanks


The above method can return "const Auth::UserRequest::Pointer &" if you
want to avoid refcounting overheads during simple checks.


Seems to work so trying that.

+     * NP: once set the credentials are fixed until closure because for any 
change to be needed
+     * since something invalid has happened:
Please rephrase the "because ..." part. I am not sure what it means.

Done.


+    if (aur == NULL) {
+        debugs(33, 2, HERE << "WARNING: Closing " << clientConnection << " due to 
connection-auth erase from " << by);
+        credentialsState->releaseAuthServer();
+        credentialsState = NULL;
+        unpinConnection();
+        // XXX: need to test whether the connection re-auth challenge is sent. 
If not, how to trigger it from here.
+        // NP: the current situation seems to fix challenge loops in Safari 
without visible issues in others.
+        // we stop receiving more traffic but can leave teh Job running to 
terminate after the error or challenge is delivered.
+        stopReceiving("connection-auth removed");
+        return;
+    }
The code above does not close the connection as promised by the WARNING.
It only stops receiving more data from the client. Either the debugging
or the code that follows the debugging should be changed to be in sync.


Fixed.

+    // clobbered with alternative credentials
+    if (aur != credentialsState) {
+        debugs(33, 2, HERE << "ERROR: Closing " << clientConnection << " due to change of 
connection-auth from " << by);
+        credentialsState->releaseAuthServer();
+        credentialsState = NULL;
+        unpinConnection();
+        // this is a fatal type of problem. Close the connection immediately
+        clientConnection->close(); // XXX: need to send TCP RST packet if we 
can.
+        stopReceiving("connection-auth change attempted");
+        return;
+    }
IIRC, we should either stopReceiving() or close the connection. Doing
both is conceptually wrong because stopReceiving() implies that we
should keep sending if needed (which connection closure prohibits) and
because connection closure already implies that we will not receive
anything. Doing both may also lead to confusing double-closures.

For this case we need to close the connection ASAP and data loss of everything buffered for this connection is the desired outcome. The stopReceiving() is to both speed up the signalling that the client connection has closed, and produce a nice error message about why.
 Are you aware of any better way to exit ConnStateData with an error?

I'm trying both stopReceiving(); stopSending(); in this case, but neither results in TCP RST either. So we still have to call comm_reset_close() first.

NP: Comm::Connection::close() can be called any number of times and protects against repeated comm_close() cycles if that was what you mean?

Use comm_reset_close() to resolve the XXX?


Disclaimer: I do not know enough about authentication code to say
whether the primary changes in the patch are correct. The above can be
fixed without another round of reviews if nobody needs them, I guess.

It has now had ~6 months in use in a major high performance network with only one issue which was resolved by using stopReceiving() at the connection abort case discussed above.


I am also having second thoughts about whether the unpin and stopReceiving side effects matter when called from swanSong(). That comment and code was written for the mk1 patch which used deleteThis in the abort case (and crashed sometimes as a result). What do you think about just calling setAuth(NULL) there?



New patch attached for review with all the above changes.

Amos
=== modified file 'src/Makefile.am'
--- src/Makefile.am     2013-03-18 04:55:51 +0000
+++ src/Makefile.am     2013-03-19 04:38:43 +0000
@@ -1284,6 +1284,7 @@
        cache_cf.h \
        YesNoNone.h \
        tests/stub_cache_cf.cc \
+       tests/stub_client_side.cc \
        tests/stub_debug.cc \
        tests/stub_DelayId.cc \
        tests/stub_DiskIOModule.cc \

=== modified file 'src/auth/Acl.cc'
--- src/auth/Acl.cc     2012-09-19 17:16:56 +0000
+++ src/auth/Acl.cc     2013-03-27 08:09:54 +0000
@@ -26,7 +26,7 @@
         return ACCESS_DENIED;
     } else if (request->flags.sslBumped) {
         debugs(28, 5, "SslBumped request: It is an encapsulated request do not 
authenticate");
-        checklist->auth_user_request = checklist->conn() != NULL ? 
checklist->conn()->auth_user_request : request->auth_user_request;
+        checklist->auth_user_request = checklist->conn() != NULL ? 
checklist->conn()->getAuth() : request->auth_user_request;
         if (checklist->auth_user_request != NULL)
             return ACCESS_ALLOWED;
         else

=== modified file 'src/auth/AclProxyAuth.cc'
--- src/auth/AclProxyAuth.cc    2012-08-14 11:53:07 +0000
+++ src/auth/AclProxyAuth.cc    2013-03-27 08:10:24 +0000
@@ -163,7 +163,7 @@
         checklist->auth_user_request = NULL;
 
         if (checklist->conn() != NULL) {
-            checklist->conn()->auth_user_request = NULL;
+            checklist->conn()->setAuth(NULL, "proxy_auth ACL failure");
         }
     }
 

=== modified file 'src/auth/UserRequest.cc'
--- src/auth/UserRequest.cc     2013-03-18 04:55:51 +0000
+++ src/auth/UserRequest.cc     2013-03-27 11:34:55 +0000
@@ -221,7 +221,7 @@
 {}
 
 void
-Auth::UserRequest::onConnectionClose(ConnStateData *)
+Auth::UserRequest::releaseAuthServer()
 {}
 
 const char *
@@ -253,7 +253,7 @@
     else if (request != NULL && request->auth_user_request != NULL)
         return request->auth_user_request;
     else if (conn != NULL)
-        return conn->auth_user_request;
+        return conn->getAuth();
     else
         return NULL;
 }
@@ -303,7 +303,7 @@
 
         /* connection auth we must reset on auth errors */
         if (conn != NULL) {
-            conn->auth_user_request = NULL;
+            conn->setAuth(NULL, "HTTP request missing credentials");
         }
 
         *auth_user_request = NULL;
@@ -315,13 +315,13 @@
      * No check for function required in the if: its compulsory for conn based
      * auth modules
      */
-    if (proxy_auth && conn != NULL && conn->auth_user_request != NULL &&
-            authenticateUserAuthenticated(conn->auth_user_request) &&
-            conn->auth_user_request->connLastHeader() != NULL &&
-            strcmp(proxy_auth, conn->auth_user_request->connLastHeader())) {
+    if (proxy_auth && conn != NULL && conn->getAuth() != NULL &&
+            authenticateUserAuthenticated(conn->getAuth()) &&
+            conn->getAuth()->connLastHeader() != NULL &&
+            strcmp(proxy_auth, conn->getAuth()->connLastHeader())) {
         debugs(29, 2, "WARNING: DUPLICATE AUTH - authentication header on 
already authenticated connection!. AU " <<
-               conn->auth_user_request << ", Current user '" <<
-               conn->auth_user_request->username() << "' proxy_auth " <<
+               conn->getAuth() << ", Current user '" <<
+               conn->getAuth()->username() << "' proxy_auth " <<
                proxy_auth);
 
         /* remove this request struct - the link is already authed and it 
can't be to reauth. */
@@ -330,7 +330,7 @@
          * authenticateAuthenticate
          */
         assert(*auth_user_request == NULL);
-        conn->auth_user_request = NULL;
+        conn->setAuth(NULL, "changed credentials token");
     }
 
     /* we have a proxy auth header and as far as we know this connection has
@@ -342,20 +342,20 @@
             debugs(29, 9, HERE << "This is a new checklist test on:" << 
conn->clientConnection);
         }
 
-        if (proxy_auth && request->auth_user_request == NULL && conn != NULL 
&& conn->auth_user_request != NULL) {
+        if (proxy_auth && request->auth_user_request == NULL && conn != NULL 
&& conn->getAuth() != NULL) {
             Auth::Config * scheme = Auth::Config::Find(proxy_auth);
 
-            if (conn->auth_user_request->user() == NULL || 
conn->auth_user_request->user()->config != scheme) {
+            if (conn->getAuth()->user() == NULL || 
conn->getAuth()->user()->config != scheme) {
                 debugs(29, DBG_IMPORTANT, "WARNING: Unexpected change of 
authentication scheme from '" <<
-                       conn->auth_user_request->user()->config->type() <<
+                       
(conn->getAuth()->user()?conn->getAuth()->user()->config->type():"[no user]") <<
                        "' to '" << proxy_auth << "' (client " <<
                        src_addr << ")");
 
-                conn->auth_user_request = NULL;
+                conn->setAuth(NULL, "changed auth scheme");
             }
         }
 
-        if (request->auth_user_request == NULL && (conn == NULL || 
conn->auth_user_request == NULL)) {
+        if (request->auth_user_request == NULL && (conn == NULL || 
conn->getAuth() == NULL)) {
             /* beginning of a new request check */
             debugs(29, 4, HERE << "No connection authentication type");
 
@@ -378,15 +378,11 @@
             *auth_user_request = request->auth_user_request;
         } else {
             assert (conn != NULL);
-            if (conn->auth_user_request != NULL) {
-                *auth_user_request = conn->auth_user_request;
+            if (conn->getAuth() != NULL) {
+                *auth_user_request = conn->getAuth();
             } else {
                 /* failed connection based authentication */
-                debugs(29, 4, HERE << "Auth user request " <<
-                       *auth_user_request << " conn-auth user request " <<
-                       conn->auth_user_request << " conn type " <<
-                       conn->auth_user_request->user()->auth_type << " 
authentication failed.");
-
+                debugs(29, 4, HERE << "Auth user request " << 
*auth_user_request << " conn-auth missing and failed to authenticate.");
                 *auth_user_request = NULL;
                 return AUTH_ACL_CHALLENGE;
             }

=== modified file 'src/auth/UserRequest.h'
--- src/auth/UserRequest.h      2013-03-18 10:10:13 +0000
+++ src/auth/UserRequest.h      2013-03-19 04:38:43 +0000
@@ -155,7 +155,7 @@
     /* add the [Proxy-]Authentication-Info trailer */
     virtual void addAuthenticationInfoTrailer(HttpReply * rep, int accel);
 
-    virtual void onConnectionClose(ConnStateData *);
+    virtual void releaseAuthServer();
 
     /**
      * Called when squid is ready to put the request on hold and wait for a 
callback from the auth module

=== modified file 'src/auth/negotiate/UserRequest.cc'
--- src/auth/negotiate/UserRequest.cc   2013-03-18 04:55:51 +0000
+++ src/auth/negotiate/UserRequest.cc   2013-03-27 08:10:24 +0000
@@ -129,27 +129,6 @@
         debugs(29, 6, HERE << "No Negotiate auth server to release.");
 }
 
-/* clear any connection related authentication details */
-void
-Auth::Negotiate::UserRequest::onConnectionClose(ConnStateData *conn)
-{
-    assert(conn != NULL);
-
-    debugs(29, 8, HERE << "closing connection '" << conn << "' (this is '" << 
this << "')");
-
-    if (conn->auth_user_request == NULL) {
-        debugs(29, 8, HERE << "no auth_user_request");
-        return;
-    }
-
-    releaseAuthServer();
-
-    /* unlock the connection based lock */
-    debugs(29, 9, HERE << "Unlocking auth_user from the connection '" << conn 
<< "'.");
-
-    conn->auth_user_request = NULL;
-}
-
 void
 Auth::Negotiate::UserRequest::authenticate(HttpRequest * aRequest, 
ConnStateData * conn, http_hdr_type type)
 {
@@ -199,8 +178,8 @@
         user()->credentials(Auth::Pending);
         safe_free(client_blob);
         client_blob=xstrdup(blob);
-        assert(conn->auth_user_request == NULL);
-        conn->auth_user_request = this;
+        assert(conn->getAuth() == NULL);
+        conn->setAuth(this, "new Negotiate handshake request");
         request = aRequest;
         HTTPMSGLOCK(request);
         break;

=== modified file 'src/auth/negotiate/UserRequest.h'
--- src/auth/negotiate/UserRequest.h    2012-11-04 12:27:49 +0000
+++ src/auth/negotiate/UserRequest.h    2013-01-11 05:02:08 +0000
@@ -26,7 +26,6 @@
     virtual int authenticated() const;
     virtual void authenticate(HttpRequest * request, ConnStateData * conn, 
http_hdr_type type);
     virtual Direction module_direction();
-    virtual void onConnectionClose(ConnStateData *);
     virtual void module_start(AUTHCB *, void *);
 
     virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel);

=== modified file 'src/auth/ntlm/UserRequest.cc'
--- src/auth/ntlm/UserRequest.cc        2013-01-28 16:56:05 +0000
+++ src/auth/ntlm/UserRequest.cc        2013-03-27 08:10:24 +0000
@@ -123,26 +123,6 @@
 }
 
 void
-Auth::Ntlm::UserRequest::onConnectionClose(ConnStateData *conn)
-{
-    assert(conn != NULL);
-
-    debugs(29, 8, HERE << "closing connection '" << conn << "' (this is '" << 
this << "')");
-
-    if (conn->auth_user_request == NULL) {
-        debugs(29, 8, HERE << "no auth_user_request");
-        return;
-    }
-
-    releaseAuthServer();
-
-    /* unlock the connection based lock */
-    debugs(29, 9, HERE << "Unlocking auth_user from the connection '" << conn 
<< "'.");
-
-    conn->auth_user_request = NULL;
-}
-
-void
 Auth::Ntlm::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * 
conn, http_hdr_type type)
 {
     assert(this);
@@ -192,8 +172,8 @@
         user()->credentials(Auth::Pending);
         safe_free(client_blob);
         client_blob=xstrdup(blob);
-        assert(conn->auth_user_request == NULL);
-        conn->auth_user_request = this;
+        assert(conn->getAuth() == NULL);
+        conn->setAuth(this, "new NTLM handshake request");
         request = aRequest;
         HTTPMSGLOCK(request);
         break;

=== modified file 'src/auth/ntlm/UserRequest.h'
--- src/auth/ntlm/UserRequest.h 2012-11-04 12:27:49 +0000
+++ src/auth/ntlm/UserRequest.h 2013-01-11 05:02:08 +0000
@@ -26,14 +26,13 @@
     virtual int authenticated() const;
     virtual void authenticate(HttpRequest * request, ConnStateData * conn, 
http_hdr_type type);
     virtual Auth::Direction module_direction();
-    virtual void onConnectionClose(ConnStateData *);
     virtual void module_start(AUTHCB *, void *);
 
     virtual const char * connLastHeader();
 
     /* we need to store the helper server between requests */
     helper_stateful_server *authserver;
-    void releaseAuthServer(void); ///< Release authserver NTLM helpers 
properly when finished or abandoning.
+    virtual void releaseAuthServer(); ///< Release authserver NTLM helpers 
properly when finished or abandoning.
 
     /* our current blob to pass to the client */
     char *server_blob;

=== modified file 'src/client_side.cc'
--- src/client_side.cc  2013-03-18 04:55:51 +0000
+++ src/client_side.cc  2013-03-27 08:57:02 +0000
@@ -793,6 +793,88 @@
     deleteThis("ConnStateData::connStateClosed");
 }
 
+#if USE_AUTH
+void
+ConnStateData::setAuth(const Auth::UserRequest::Pointer &aur, const char *by)
+{
+    if (auth_ == NULL) {
+        if (aur != NULL) {
+            debugs(33, 2, "Adding connection-auth to " << clientConnection << 
" from " << by);
+            auth_ = aur;
+        }
+        return;
+    }
+
+    // clobered with self-pointer
+    // NP: something nasty is going on in Squid, but harmless.
+    if (aur == auth_) {
+        debugs(33, 2, "WARNING: Ignoring duplicate connection-auth for " << 
clientConnection << " from " << by);
+        return;
+    }
+
+    /*
+     * Connection-auth relies on a single set of credentials being preserved
+     * for all requests on a connection once they have been setup.
+     * There are several things which need to happen to preserve security
+     * when connection-auth credentials change unexpectedly or are unset.
+     *
+     * 1) auth helper released from any active state
+     *
+     * They can only be reserved by a handshake process which this
+     * connection can now never complete.
+     * This prevents helpers hanging when their connections close.
+     *
+     * 2) pinning is expected to be removed and server conn closed
+     *
+     * The upstream link is authenticated with the same credentials.
+     * Expecting the same level of consistency we should have received.
+     * This prevents upstream being faced with multiple or missing
+     * credentials after authentication.
+     *
+     * 3) the connection needs to close.
+     *
+     * This prevents attackers injecting requests into a connection,
+     * or gateways wrongly multiplexing users into a single connection.
+     *
+     * When credentials are missing closure needs to follow an auth
+     * challenge for best recovery by the client.
+     *
+     * When credentials change there is nothing we can do but abort as
+     * fast as possible. Sending TCP RST instead of an HTTP response
+     * is the best-case action.
+     */
+
+    // clobbered with nul-pointer
+    if (aur == NULL) {
+        debugs(33, 2, "WARNING: Graceful closure on " << clientConnection << " 
due to connection-auth erase from " << by);
+        auth_->releaseAuthServer();
+        auth_ = NULL;
+        unpinConnection();
+        // XXX: need to test whether the connection re-auth challenge is sent. 
If not, how to trigger it from here.
+        // NP: the current situation seems to fix challenge loops in Safari 
without visible issues in others.
+        // we stop receiving more traffic but can leave the Job running to 
terminate after the error or challenge is delivered.
+        stopReceiving("connection-auth removed");
+        return;
+    }
+
+    // clobbered with alternative credentials
+    if (aur != auth_) {
+        debugs(33, 2, "ERROR: Closing " << clientConnection << " due to change 
of connection-auth from " << by);
+        auth_->releaseAuthServer();
+        auth_ = NULL;
+        unpinConnection();
+        // this is a fatal type of problem.
+        // Close the connection immediately with TCP RST and abort both 
directions of traffic flow
+        comm_reset_close(clientConnection);
+        stopReceiving("connection-auth change attempted");
+        stopSending("connection-auth change attempted");
+        return;
+    }
+
+    /* NOT REACHABLE */
+}
+#endif
+
 // cleans up before destructor is called
 void
 ConnStateData::swanSong()
@@ -802,10 +884,14 @@
     clientdbEstablished(clientConnection->remote, -1); /* decrement */
     assert(areAllContextsForThisConnection());
     freeAllContexts();
+
 #if USE_AUTH
-    if (auth_user_request != NULL) {
-        debugs(33, 4, "ConnStateData::swanSong: freeing auth_user_request '" 
<< auth_user_request << "' (this is '" << this << "')");
-        auth_user_request->onConnectionClose(this);
+    if (getAuth() != NULL) {
+        debugs(33, 4, "freeing connection-auth credentials '" << getAuth() << 
"' (this is '" << this << "')");
+
+        // avoid setAuth(NULL) because of its side-effects, but ensure the 
helpers are released properly
+        auth_->releaseAuthServer();
+        auth_ = NULL;
     }
 #endif
 
@@ -2684,8 +2770,8 @@
                               !conn->port->allow_direct : 0;
 #if USE_AUTH
     if (request->flags.sslBumped) {
-        if (conn->auth_user_request != NULL)
-            request->auth_user_request = conn->auth_user_request;
+        if (conn->getAuth() != NULL)
+            request->auth_user_request = conn->getAuth();
     }
 #endif
 

=== modified file 'src/client_side.h'
--- src/client_side.h   2013-01-24 10:26:24 +0000
+++ src/client_side.h   2013-03-27 08:21:43 +0000
@@ -239,10 +239,20 @@
 
 #if USE_AUTH
     /**
-     * note this is ONLY connection based because NTLM and Negotiate is 
against HTTP spec.
-     * the user details for connection based authentication
-     */
-    Auth::UserRequest::Pointer auth_user_request;
+     * Fetch the user details for connection based authentication
+     * NOTE: this is ONLY connection based because NTLM and Negotiate is 
against HTTP spec.
+     */
+    const Auth::UserRequest::Pointer &getAuth() const { return auth_; }
+
+    /**
+     * Set the user details for connection-based authentication to use from 
now until connection closure.
+     *
+     * Any change to existing credentials shows that something invalid has 
happened. Such as:
+     * - NTLM/Negotiate auth was violated by the per-request headers missing a 
revalidation token
+     * - NTLM/Negotiate auth was violated by the per-request headers being for 
another user
+     * - SSL-Bump CONNECT tunnel with persistent credentials has ended
+     */
+    void setAuth(const Auth::UserRequest::Pointer &aur, const char *cause);
 #endif
 
     /**
@@ -383,7 +393,11 @@
     int connFinishedWithConn(int size);
     void clientAfterReadingRequests();
 
-private:
+#if USE_AUTH
+    /// some user details that can be used to perform authentication on this 
connection
+    Auth::UserRequest::Pointer auth_;
+#endif
+
     HttpParser parser_;
 
     // XXX: CBDATA plays with public/private and leaves the following 
'private' fields all public... :(

=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc  2013-03-26 10:33:10 +0000
+++ src/client_side_request.cc  2013-03-27 08:10:24 +0000
@@ -616,8 +616,8 @@
                                 http->request,
                                 NULL,
 #if USE_AUTH
-                                http->getConn() != NULL && 
http->getConn()->auth_user_request != NULL ?
-                                http->getConn()->auth_user_request : 
http->request->auth_user_request);
+                                http->getConn() != NULL && 
http->getConn()->getAuth() != NULL ?
+                                http->getConn()->getAuth() : 
http->request->auth_user_request);
 #else
                                 NULL);
 #endif
@@ -785,8 +785,8 @@
 
 #if USE_AUTH
     char const *proxy_auth_msg = "<null>";
-    if (http->getConn() != NULL && http->getConn()->auth_user_request != NULL)
-        proxy_auth_msg = 
http->getConn()->auth_user_request->denyMessage("<null>");
+    if (http->getConn() != NULL && http->getConn()->getAuth() != NULL)
+        proxy_auth_msg = http->getConn()->getAuth()->denyMessage("<null>");
     else if (http->request->auth_user_request != NULL)
         proxy_auth_msg = 
http->request->auth_user_request->denyMessage("<null>");
 #endif
@@ -849,8 +849,8 @@
 
 #if USE_AUTH
         error->auth_user_request =
-            http->getConn() != NULL && http->getConn()->auth_user_request != 
NULL ?
-            http->getConn()->auth_user_request : 
http->request->auth_user_request;
+            http->getConn() != NULL && http->getConn()->getAuth() != NULL ?
+            http->getConn()->getAuth() : http->request->auth_user_request;
 #endif
 
         readNextRequest = true;
@@ -1607,7 +1607,7 @@
 #if USE_AUTH
     // Preserve authentication info for the ssl-bumped request
     if (request->auth_user_request != NULL)
-        getConn()->auth_user_request = request->auth_user_request;
+        getConn()->setAuth(request->auth_user_request, "SSL-bumped CONNECT");
 #endif
 
     assert(sslBumpNeeded());
@@ -2089,7 +2089,7 @@
                                                 );
 #if USE_AUTH
         calloutContext->error->auth_user_request =
-            c != NULL && c->auth_user_request != NULL ? c->auth_user_request : 
request->auth_user_request;
+            c != NULL && c->getAuth() != NULL ? c->getAuth() : 
request->auth_user_request;
 #endif
         calloutContext->error->detailError(errDetail);
         calloutContext->readNextRequest = true;

=== modified file 'src/redirect.cc'
--- src/redirect.cc     2013-03-16 04:57:43 +0000
+++ src/redirect.cc     2013-03-27 08:09:54 +0000
@@ -301,8 +301,8 @@
                                     http->request,
                                     NULL,
 #if USE_AUTH
-                                    http->getConn() != NULL && 
http->getConn()->auth_user_request != NULL ?
-                                    http->getConn()->auth_user_request : 
http->request->auth_user_request);
+                                    http->getConn() != NULL && 
http->getConn()->getAuth() != NULL ?
+                                    http->getConn()->getAuth() : 
http->request->auth_user_request);
 #else
                                     NULL);
 #endif

=== modified file 'src/tests/Stub.list'
--- src/tests/Stub.list 2012-11-02 00:13:41 +0000
+++ src/tests/Stub.list 2013-01-11 04:59:49 +0000
@@ -17,6 +17,7 @@
        tests/stub_cache_manager.cc \
        tests/stub_cbdata.cc \
        tests/stub_client_db.cc \
+       tests/stub_client_side.cc \
        tests/stub_client_side_request.cc \
        tests/stub_comm.cc \
        tests/stub_debug.cc \

=== added file 'src/tests/stub_client_side.cc'
--- src/tests/stub_client_side.cc       1970-01-01 00:00:00 +0000
+++ src/tests/stub_client_side.cc       2013-03-27 08:10:24 +0000
@@ -0,0 +1,84 @@
+#include "squid.h"
+#include "client_side.h"
+
+#define STUB_API "client_side.cc"
+#include "tests/STUB.h"
+
+ClientSocketContext::ClientSocketContext() STUB
+ClientSocketContext::~ClientSocketContext() STUB
+bool ClientSocketContext::startOfOutput() const STUB_RETVAL(false)
+void ClientSocketContext::writeComplete(const Comm::ConnectionPointer &conn, 
char *bufnotused, size_t size, comm_err_t errflag) STUB
+void ClientSocketContext::keepaliveNextRequest() STUB
+void ClientSocketContext::pullData() STUB
+int64_t ClientSocketContext::getNextRangeOffset() const STUB_RETVAL(0)
+bool ClientSocketContext::canPackMoreRanges() const STUB_RETVAL(false)
+clientStream_status_t ClientSocketContext::socketState() 
STUB_RETVAL(STREAM_NONE)
+void ClientSocketContext::sendBody(HttpReply * rep, StoreIOBuffer bodyData) 
STUB
+void ClientSocketContext::sendStartOfMessage(HttpReply * rep, StoreIOBuffer 
bodyData) STUB
+size_t ClientSocketContext::lengthToSend(Range<int64_t> const &available) 
STUB_RETVAL(0)
+void ClientSocketContext::noteSentBodyBytes(size_t) STUB
+void ClientSocketContext::buildRangeHeader(HttpReply * rep) STUB
+clientStreamNode * ClientSocketContext::getTail() const STUB_RETVAL(NULL)
+clientStreamNode * ClientSocketContext::getClientReplyContext() const 
STUB_RETVAL(NULL)
+void ClientSocketContext::connIsFinished() STUB
+void ClientSocketContext::removeFromConnectionList(ConnStateData * conn) STUB
+void ClientSocketContext::deferRecipientForLater(clientStreamNode * node, 
HttpReply * rep, StoreIOBuffer receivedData) STUB
+bool ClientSocketContext::multipartRangeRequest() const STUB_RETVAL(false)
+void ClientSocketContext::registerWithConn() STUB
+void ClientSocketContext::noteIoError(const int xerrno) STUB
+void ClientSocketContext::writeControlMsg(HttpControlMsg &msg) STUB
+
+void ConnStateData::readSomeData() STUB
+int ConnStateData::getAvailableBufferLength() const STUB_RETVAL(0)
+bool ConnStateData::areAllContextsForThisConnection() const STUB_RETVAL(false)
+void ConnStateData::freeAllContexts() STUB
+void ConnStateData::notifyAllContexts(const int xerrno) STUB
+bool ConnStateData::clientParseRequests() STUB_RETVAL(false)
+void ConnStateData::readNextRequest() STUB
+bool ConnStateData::maybeMakeSpaceAvailable() STUB_RETVAL(false)
+void ConnStateData::addContextToQueue(ClientSocketContext * context) STUB
+int ConnStateData::getConcurrentRequestCount() const STUB_RETVAL(0)
+bool ConnStateData::isOpen() const STUB_RETVAL(false)
+void ConnStateData::checkHeaderLimits() STUB
+void ConnStateData::sendControlMsg(HttpControlMsg msg) STUB
+char *ConnStateData::In::addressToReadInto() const STUB_RETVAL(NULL)
+int64_t ConnStateData::mayNeedToReadMoreBody() const STUB_RETVAL(0)
+#if USE_AUTH
+void ConnStateData::setAuth(const Auth::UserRequest::Pointer &aur, const char 
*cause) STUB
+#endif
+bool ConnStateData::transparent() const STUB_RETVAL(false)
+bool ConnStateData::reading() const STUB_RETVAL(false)
+void ConnStateData::stopReading() STUB
+void ConnStateData::stopReceiving(const char *error) STUB
+void ConnStateData::stopSending(const char *error) STUB
+void ConnStateData::expectNoForwarding() STUB
+void ConnStateData::noteMoreBodySpaceAvailable(BodyPipe::Pointer) STUB
+void ConnStateData::noteBodyConsumerAborted(BodyPipe::Pointer) STUB
+bool ConnStateData::handleReadData(char *buf, size_t size) STUB_RETVAL(false)
+bool ConnStateData::handleRequestBodyData() STUB_RETVAL(false)
+void ConnStateData::pinConnection(const Comm::ConnectionPointer 
&pinServerConn, HttpRequest *request, CachePeer *peer, bool auth) STUB
+void ConnStateData::unpinConnection() STUB
+const Comm::ConnectionPointer 
ConnStateData::validatePinnedConnection(HttpRequest *request, const CachePeer 
*peer) STUB_RETVAL(NULL)
+void ConnStateData::clientPinnedConnectionClosed(const CommCloseCbParams &io) 
STUB
+void ConnStateData::clientReadRequest(const CommIoCbParams &io) STUB
+void ConnStateData::connStateClosed(const CommCloseCbParams &io) STUB
+void ConnStateData::requestTimeout(const CommTimeoutCbParams &params) STUB
+void ConnStateData::swanSong() STUB
+void ConnStateData::quitAfterError(HttpRequest *request) STUB
+#if USE_SSL
+void ConnStateData::httpsPeeked(Comm::ConnectionPointer serverConnection) STUB
+void ConnStateData::getSslContextStart() STUB
+void ConnStateData::getSslContextDone(SSL_CTX * sslContext, bool isNew) STUB
+void ConnStateData::sslCrtdHandleReplyWrapper(void *data, const HelperReply 
&reply) STUB
+void ConnStateData::sslCrtdHandleReply(const HelperReply &reply) STUB
+void ConnStateData::switchToHttps(HttpRequest *request, Ssl::BumpMode 
bumpServerMode) STUB
+void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties 
&certProperties) STUB
+bool ConnStateData::serveDelayedError(ClientSocketContext *context) 
STUB_RETVAL(false)
+#endif
+
+void setLogUri(ClientHttpRequest * http, char const *uri, bool cleanUrl) STUB
+const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char 
*end) STUB_RETVAL(NULL)
+int varyEvaluateMatch(StoreEntry * entry, HttpRequest * req) STUB_RETVAL(0)
+void clientOpenListenSockets(void) STUB
+void clientHttpConnectionsClose(void) STUB
+void httpRequestFree(void *) STUB

Reply via email to