Hi,

As mentioned earlier, the sspi authentication can end up in an endless
loop, trying to authenticate over and over again.

To reproduce the problem:
* Get a Subversion client for Windows version 1.3.0, built with neon >
0.25.0.
* Set up an Apache server, Subversion repository and configure it to
authenticate with the mod_auth_sspi.so module. Configure it so that
authentication is done against a windows domain controller where the
user connecting with a client is known.
* connect with the Subversion client to the repository
$ svn ls -v https://server/svn/repo
should work

then, deactivate the user account on the domain controller
$ svn ls -v https://server/svn/repo
doesn't work. The Subversion client never returns, and the apache error
log on the repo server grows several kb every second (depending on the
network speed).

The only way to stop the Subversion client is to forcefully close the
command shell where it is running in.

Attached is a patch which will fix this issue.
The patch has already been tested by TSVN users, which means it now works.

Stefan

--
        ___
   oo  // \\      "De Chelonian Mobile"
  (_,\/ \_/ \     TortoiseSVN
    \ \_/_\_/>    The coolest Interface to (Sub)Version Control
    /_/   \_\     http://tortoisesvn.tigris.org

[[[
Fix endless authentication loop if the authentication fails.

* src/ne_sspi.c, src/ne_sspi.h:
  New public function to tell the lib that an authentication was
  successful.
  Return an error if the authentication is restarted without a
  successful authentication before.
* src/ne_auth.c:
  Call the new public function to tell the library about a successful
  authentication.
]]]
Index: src/ne_sspi.c
===================================================================
--- src/ne_sspi.c       (Revision 831)
+++ src/ne_sspi.c       (Arbeitskopie)
@@ -34,6 +34,7 @@
     char *serverName;
     CredHandle credentials;
     int continueNeeded;
+       int authfinished;
     char *mechanism;
     int ntlm;
     ULONG maxTokenSize;
@@ -371,6 +372,7 @@
     }
 
     sspiContext->ntlm = ntlm;
+       sspiContext->authfinished = 0;
     *context = sspiContext;
     return 0;
 }
@@ -429,7 +431,21 @@
     ne_free(sspiContext);
     return 0;
 }
+int ne_sspi_clear_context(void *context)
+{
+       int status;
+       SSPIContext *sspiContext;
 
+       if (initialized <= 0) {
+               return -1;
+       }
+
+       status = getContext(context, &sspiContext);
+       if (status) {
+               return status;
+       }
+       sspiContext->authfinished = 0;
+}
 /*
  * Processes received authentication tokens as well as supplies the
  * response token.
@@ -468,6 +484,7 @@
         SecBuffer inBuffer;
 
         if (!sspiContext->continueNeeded) {
+                       freeBuffer(&outBufferDesc);
             NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Got an unexpected token.\n");
             return -1;
         }
@@ -476,6 +493,7 @@
 
         status = base64ToBuffer(base64Token, &inBufferDesc);
         if (status) {
+                       freeBuffer(&outBufferDesc);
             return status;
         }
 
@@ -485,22 +503,38 @@
                                       sspiContext->serverName, contextFlags,
                                       &inBufferDesc, &(sspiContext->context),
                                       &outBufferDesc);
+               if (securityStatus == SEC_E_OK)
+               {
+                       sspiContext->authfinished = 1;
+               }
         freeBuffer(&inBufferDesc);
     } else {
         if (sspiContext->continueNeeded) {
+                       freeBuffer(&outBufferDesc);
             NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Expected a token from server.\n");
             return -1;
         }
+               if (sspiContext->authfinished && 
(sspiContext->credentials.dwLower || sspiContext->credentials.dwUpper)) {
+                       if (sspiContext->authfinished)
+                       {
+                               freeBuffer(&outBufferDesc);
+                               sspiContext->authfinished = 0;
+                               NE_DEBUG(NE_DBG_HTTPAUTH,"sspi: failing because 
starting over from failed try.\n");
+                               return -1;
+                       }
+                       sspiContext->authfinished = 0;
+               }
 
-        /* Reset any existing context since we are starting over */
-        resetContext(sspiContext);
+               /* Reset any existing context since we are starting over */
+               resetContext(sspiContext);
 
-        if (acquireCredentialsHandle
-            (&sspiContext->credentials, sspiContext->mechanism) != SEC_E_OK) {
-            NE_DEBUG(NE_DBG_HTTPAUTH,
-                     "sspi: acquireCredentialsHandle failed.\n");
-            return -1;
-        }
+               if (acquireCredentialsHandle
+                       (&sspiContext->credentials, sspiContext->mechanism) != 
SEC_E_OK) {
+                               freeBuffer(&outBufferDesc);
+                               NE_DEBUG(NE_DBG_HTTPAUTH,
+                                       "sspi: acquireCredentialsHandle 
failed.\n");
+                               return -1;
+               }
 
         securityStatus =
             initializeSecurityContext(&sspiContext->credentials, NULL,
Index: src/ne_sspi.h
===================================================================
--- src/ne_sspi.h       (Revision 831)
+++ src/ne_sspi.h       (Arbeitskopie)
@@ -38,6 +38,8 @@
 
 int ne_sspi_destroy_context(void *context);
 
+int ne_sspi_clear_context(void *context);
+
 int ne_sspi_get_mechanism(void *context, char const **mechanism);
 
 int ne_sspi_authenticate(void *context, const char *base64Token,
Index: src/ne_auth.c
===================================================================
--- src/ne_auth.c       (Revision 831)
+++ src/ne_auth.c       (Arbeitskopie)
@@ -1269,6 +1269,9 @@
            ret = sess->spec->fail_code;
        }
     }
+       else {
+               ne_sspi_clear_context(sess->sspi_context);
+       }
 
     return ret;
 }

_______________________________________________
neon mailing list
[email protected]
http://mailman.webdav.org/mailman/listinfo/neon

Reply via email to