]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/auth/ntlm/auth_ntlm.cc
Cleanup: zap CVS Id tags
[thirdparty/squid.git] / src / auth / ntlm / auth_ntlm.cc
index 7cfd741429139776cf3ddfb89d21ed040f18fe48..6b0caeb363da4df8df745fdeb0e3d565991676e2 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: auth_ntlm.cc,v 1.73 2007/08/03 01:57:30 amosjeffries Exp $
+ * $Id$
  *
  * DEBUG: section 29    NTLM Authenticator
  * AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
@@ -49,6 +48,7 @@
 /* TODO remove this include */
 #include "ntlmScheme.h"
 #include "wordlist.h"
+#include "SquidTime.h"
 
 static void
 authenticateNTLMReleaseServer(AuthUserRequest * auth_user_request);
@@ -198,11 +198,12 @@ AuthNTLMConfig::init(AuthConfig * scheme)
 }
 
 void
-AuthNTLMConfig::registerWithCacheManager(CacheManager & manager)
+AuthNTLMConfig::registerWithCacheManager(void)
 {
-    manager.registerAction("ntlmauthenticator",
-                           "NTLM User Authenticator Stats",
-                           authenticateNTLMStats, 0, 1);
+    CacheManager::GetInstance()->
+    registerAction("ntlmauthenticator",
+                   "NTLM User Authenticator Stats",
+                   authenticateNTLMStats, 0, 1);
 }
 
 bool
@@ -270,7 +271,7 @@ AuthNTLMConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, ht
 
     /* Need keep-alive */
     if (!request->flags.proxy_keepalive && request->flags.must_keepalive)
-       return;
+        return;
 
     /* New request, no user details */
     if (auth_user_request == NULL) {
@@ -279,7 +280,6 @@ AuthNTLMConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, ht
 
         if (!keep_alive) {
             /* drop the connection */
-            rep->header.delByName("keep-alive");
             request->flags.proxy_keepalive = 0;
         }
     } else {
@@ -292,7 +292,6 @@ AuthNTLMConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, ht
         case AUTHENTICATE_STATE_FAILED:
             /* here it makes sense to drop the connection, as auth is
              * tied to it, even if MAYBE the client could handle it - Kinkie */
-            rep->header.delByName("keep-alive");
             request->flags.proxy_keepalive = 0;
             /* fall through */
 
@@ -313,7 +312,6 @@ AuthNTLMConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, ht
             /* we're waiting for a response from the client. Pass it the blob */
             debugs(29, 9, "AuthNTLMConfig::fixHeader: Sending type:" << type << " header: 'NTLM " << ntlm_request->server_blob << "'");
             httpHeaderPutStrf(&rep->header, type, "NTLM %s", ntlm_request->server_blob);
-            request->flags.must_keepalive = 1;
             safe_free(ntlm_request->server_blob);
             break;
 
@@ -374,7 +372,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
     assert(auth_user->auth_type == AUTH_NTLM);
     ntlm_user = dynamic_cast<ntlm_user_t *>(auth_user_request->user());
 
-    assert(ntlm_request != NULL);
+    assert(ntlm_user != NULL);
 
     if (ntlm_request->authserver == NULL)
         ntlm_request->authserver = static_cast<helper_stateful_server*>(lastserver);
@@ -390,11 +388,18 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
     if (strncasecmp(reply, "TT ", 3) == 0) {
         /* we have been given a blob to send to the client */
         safe_free(ntlm_request->server_blob);
-        ntlm_request->server_blob = xstrdup(blob);
-        ntlm_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS;
-        auth_user_request->denyMessage("Authentication in progress");
-        debugs(29, 4, "authenticateNTLMHandleReply: Need to challenge the client with a server blob '" << blob << "'");
-        result = S_HELPER_RESERVE;
+        ntlm_request->request->flags.must_keepalive = 1;
+        if (ntlm_request->request->flags.proxy_keepalive) {
+            ntlm_request->server_blob = xstrdup(blob);
+            ntlm_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS;
+            auth_user_request->denyMessage("Authentication in progress");
+            debugs(29, 4, "authenticateNTLMHandleReply: Need to challenge the client with a server blob '" << blob << "'");
+            result = S_HELPER_RESERVE;
+        } else {
+            ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED;
+            auth_user_request->denyMessage("NTLM authentication requires a persistent connection");
+            result = S_HELPER_RELEASE;
+        }
     } else if (strncasecmp(reply, "AF ", 3) == 0) {
         /* we're finished, release the helper */
         ntlm_user->username(blob);
@@ -408,7 +413,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
         /* see if this is an existing user with a different proxy_auth
          * string */
         auth_user_hash_pointer *usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, ntlm_user->username()));
-       auth_user_t *local_auth_user = ntlm_request->user();
+        AuthUser *local_auth_user = ntlm_request->user();
         while (usernamehash && (usernamehash->user()->auth_type != AUTH_NTLM || strcmp(usernamehash->user()->username(), ntlm_user->username()) != 0))
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
         if (usernamehash) {
@@ -428,7 +433,7 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
          * existing user or a new user */
         local_auth_user->expiretime = current_time.tv_sec;
         authenticateNTLMReleaseServer(ntlm_request);
-       ntlm_request->auth_state = AUTHENTICATE_STATE_DONE;
+        ntlm_request->auth_state = AUTHENTICATE_STATE_DONE;
     } else if (strncasecmp(reply, "NA ", 3) == 0) {
         /* authentication failure (wrong password, etc.) */
         auth_user_request->denyMessage(blob);
@@ -454,6 +459,10 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
         fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply);
     }
 
+    if (ntlm_request->request) {
+        HTTPMSGUNLOCK(ntlm_request->request);
+        ntlm_request->request = NULL;
+    }
     r->handler(r->data, NULL);
     cbdataReferenceDone(r->data);
     authenticateStateFree(r);
@@ -475,7 +484,7 @@ AuthNTLMUserRequest::module_start(RH * handler, void *data)
     authenticateStateData *r = NULL;
     static char buf[8192];
     ntlm_user_t *ntlm_user;
-    auth_user_t *auth_user = user();
+    AuthUser *auth_user = user();
 
     assert(data);
     assert(handler);
@@ -526,8 +535,8 @@ authenticateNTLMReleaseServer(AuthUserRequest * auth_user_request)
      * yes, it is possible */
     assert(ntlm_request != NULL);
     if (ntlm_request->authserver) {
-       helperStatefulReleaseServer(ntlm_request->authserver);
-       ntlm_request->authserver = NULL;
+        helperStatefulReleaseServer(ntlm_request->authserver);
+        ntlm_request->authserver = NULL;
     }
 }
 
@@ -586,12 +595,12 @@ AuthNTLMUserRequest::authenticated() const
 }
 
 void
-AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type)
+AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type)
 {
     const char *proxy_auth, *blob;
 
     /* TODO: rename this!! */
-    auth_user_t *local_auth_user;
+    AuthUser *local_auth_user;
     ntlm_user_t *ntlm_user;
 
     local_auth_user = user();
@@ -603,19 +612,12 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
     /* Check that we are in the client side, where we can generate
      * auth challenges */
 
-    if (conn.getRaw() == NULL) {
+    if (conn == NULL || !cbdataReferenceValid(conn)) {
         auth_state = AUTHENTICATE_STATE_FAILED;
         debugs(29, 1, "AuthNTLMUserRequest::authenticate: attempt to perform authentication without a connection!");
         return;
     }
 
-    if (!request->flags.proxy_keepalive) {
-        debugs(29, 2, "AuthNTLMUserRequest::authenticate: attempt to perform authentication without a persistent connection!");
-        auth_state = AUTHENTICATE_STATE_FAILED;
-       request->flags.must_keepalive = 1;
-        return;
-    }
-
     if (waiting) {
         debugs(29, 1, "AuthNTLMUserRequest::authenticate: waiting for helper reply!");
         return;
@@ -633,7 +635,7 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
     blob = proxy_auth;
 
     /* if proxy_auth is actually NULL, we'd better not manipulate it. */
-    if(blob) {
+    if (blob) {
         while (xisspace(*blob) && *blob)
             blob++;
 
@@ -647,7 +649,7 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
     switch (auth_state) {
 
     case AUTHENTICATE_STATE_NONE:
-        /* we've recieved a ntlm request. pass to a helper */
+        /* we've received a ntlm request. pass to a helper */
         debugs(29, 9, "AuthNTLMUserRequest::authenticate: auth state ntlm none. Received blob: '" << proxy_auth << "'");
         auth_state = AUTHENTICATE_STATE_INITIAL;
         safe_free(client_blob);
@@ -655,7 +657,9 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
         conn->auth_type = AUTH_NTLM;
         assert(conn->auth_user_request == NULL);
         conn->auth_user_request = this;
-       AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn");
+        AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn");
+        this->request = request;
+        HTTPMSGLOCK(this->request);
         return;
 
         break;
@@ -675,14 +679,18 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
 
         client_blob = xstrdup (blob);
 
+        if (this->request)
+            HTTPMSGUNLOCK(this->request);
+        this->request = request;
+        HTTPMSGLOCK(this->request);
         return;
 
         break;
 
     case AUTHENTICATE_STATE_DONE:
-       fatal("AuthNTLMUserRequest::authenticate: unexpect auth state DONE! Report a bug to the squid developers.\n");
+        fatal("AuthNTLMUserRequest::authenticate: unexpect auth state DONE! Report a bug to the squid developers.\n");
 
-       break;
+        break;
 
     case AUTHENTICATE_STATE_FAILED:
         /* we've failed somewhere in authentication */
@@ -697,13 +705,14 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer
 }
 
 AuthNTLMUserRequest::AuthNTLMUserRequest() :
-        conn(NULL), auth_state(AUTHENTICATE_STATE_NONE),
+        /*conn(NULL),*/ auth_state(AUTHENTICATE_STATE_NONE),
         _theUser(NULL)
 {
     waiting=0;
     client_blob=0;
     server_blob=0;
     authserver=NULL;
+    request = NULL;
 }
 
 AuthNTLMUserRequest::~AuthNTLMUserRequest()
@@ -716,6 +725,10 @@ AuthNTLMUserRequest::~AuthNTLMUserRequest()
         helperStatefulReleaseServer(authserver);
         authserver = NULL;
     }
+    if (request) {
+        HTTPMSGUNLOCK(request);
+        request = NULL;
+    }
 }
 
 void