]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
auth_rewrite update:
authorhno <>
Sat, 10 Mar 2001 07:55:35 +0000 (07:55 +0000)
committerhno <>
Sat, 10 Mar 2001 07:55:35 +0000 (07:55 +0000)
Improved NTLMSSP debugging & reliability
Clearer acl.c logic, catches boundary cases.
"Fail open" configure option for NTLM to degrade gracefully
Should fix the compile issues on Solaris 8

Rob & kinkie.

20 files changed:
ChangeLog
configure.in
helpers/ntlm_auth/SMB/ntlm.h
helpers/ntlm_auth/SMB/ntlm_auth.c
helpers/ntlm_auth/SMB/smbval/md4.c
helpers/ntlm_auth/SMB/smbval/rfcnb-util.h
helpers/ntlm_auth/SMB/smbval/session.c
helpers/ntlm_auth/SMB/smbval/smbencrypt.c
helpers/ntlm_auth/SMB/smbval/smblib-priv.h
helpers/ntlm_auth/SMB/smbval/smblib.c
helpers/ntlm_auth/SMB/smbval/std-defines.h
helpers/ntlm_auth/SMB/smbval/std-includes.h
helpers/ntlm_auth/fakeauth/fakeauth_auth.c
helpers/ntlm_auth/fakeauth/ntlm.h
include/ntlmauth.h
src/HttpStatusLine.cc
src/acl.cc
src/auth/digest/auth_digest.h
src/auth/ntlm/auth_ntlm.cc
src/authenticate.cc

index 7f7883cfcf61c8b533d3c0aa65f5c33c6a80e759..f52b65459f4ab4ba586db567d93387fab96da63a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,7 @@ Changes to squid-2.5
        - Major rewrite of proxy authentication to support other schemes
          than basic. First in the line is NTLM support but others can
          easily be added (digest is on the way). See Programmers Guide.
-         (Robert Collins & Chemolli Francesco)
+         (Robert Collins & Francesco Chemolli)
        - Reworked how request bodies are passed down to the protocols.
          Now all client side processing is inside client_side.c, and
          the pass and pump modules is no longer used.
index 382d9612f9f42f5d73f4e90385503d4ade77bf2c..83805aa1fab31a18049dbe8f510ca56f7676e1f8 100644 (file)
@@ -3,13 +3,13 @@ dnl  Configuration input file for Squid
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.221 2001/02/25 21:49:08 hno Exp $
+dnl  $Id: configure.in,v 1.222 2001/03/10 00:55:35 hno Exp $
 dnl
 dnl
 dnl
 AC_INIT(src/main.c)
 AC_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.221 $)dnl
+AC_REVISION($Revision: 1.222 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AC_CONFIG_AUX_DIR(cfgaux)
 
@@ -812,6 +812,16 @@ if test -n "$DIGEST_AUTH_HELPERS"; then
 fi
 AC_SUBST(DIGEST_AUTH_HELPERS)
 
+dnl Enable "NTLM fail open"
+AC_ARG_ENABLE(ntlm-fail-open,
+[  --enable-ntlm-fail-open Enable NTLM fail open, where a helper that fails one of the
+                           Authentication steps can allow squid to still authenticate
+                          the user.],
+[ if test "$enableval" = "yes" ; then
+    AC_DEFINE(NTLM_FAIL_OPEN)
+  fi
+])
+
 dnl Disable "unlinkd" code
 AC_ARG_ENABLE(unlinkd,
 [  --disable-unlinkd       Do not use unlinkd],
index df48fb2468fbd4a24371d341100a6543fd1cec62..69643675033afe56b728cdd943d93116456fca4e 100644 (file)
@@ -57,14 +57,23 @@ static char *__foo;
 #define debug(X...)            /* */
 #endif /* DEBUG */
 #else /* __GNUC__ */
-#define debug(char *format, ...) {}    /* Too lazy to write va_args stuff */
+static void 
+debug(char *format,...)
+{
+}
+
 #endif
 
 
 /* A couple of harmless helper macros */
 #define SEND(X) debug("sending '%s' to squid\n",X); printf(X); printf("\n");
+#ifdef __GNUC__
 #define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X,Y);\
          printf("\n");
+#else
+/* no gcc, no debugging. varargs macros are a gcc extension */
+#define SEND2 printf
+#endif
 
 extern int ntlm_errno;
 #define NTLM_NO_ERROR 0
index 111341ff63ac7f721c3a61ce9a54832a2ca424b6..fe10e9232d975a169027468c6db822dfd45e80cc 100644 (file)
 #include "ntlmauth.h"
 #include "ntlm.h"
 #include "util.h"
+#include "smbval/smblib-common.h"
+#include "smbval/rfcnb-error.h"
 
 /* these are part of rfcnb-priv.h and smblib-priv.h */
 extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len);
 extern int SMB_Get_Last_Error();
 extern int SMB_Get_Last_SMB_Err();
+extern int RFCNB_Get_Last_Error();
 
+#include <errno.h>
 
 #define BUFFER_SIZE 10240
 
@@ -100,6 +104,7 @@ send_bh_or_ld(char *bhmessage, ntlm_authenticate * failedauth, int authlen)
     if (last_ditch_enabled) {
        creds = fetch_credentials(failedauth, authlen);
        if (creds) {
+           lc(creds);
            SEND2("LD %s", creds);
        } else {
            SEND("NA last-ditch on, but no credentials");
@@ -122,14 +127,7 @@ void
 usage()
 {
     fprintf(stderr,
-       "%s usage:\n"
-       "%s [-b] [-f] domain\\controller [domain\\controller ...]\n"
-       "-b, if specified, enables load-balancing among controllers\n"
-       "-f, if specified, enables failover among controllers\n"
-       "-l, if specified, changes behavior on domain controller failyures to"
-       "\tlast-ditch\n\n" "You MUST specify at least one Domain Controller.\n"
-       "You can use either \\ or / as separator between the domain name \n"
-       "\tand the controller name\n",
+       "%s usage:\n%s [-b] [-f] domain\\controller [domain\\controller ...]\n-b, if specified, enables load-balancing among controllers\n-f, if specified, enables failover among controllers\n-l, if specified, changes behavior on domain controller failyures to\tlast-ditch\n\nYou MUST specify at least one Domain Controller.\nYou can use either \\ or / as separator between the domain name \n\tand the controller name\n",
        my_program_name, my_program_name);
 }
 
@@ -219,18 +217,26 @@ obtain_challenge()
     debug("obtain_challenge: getting new challenge\n");
     for (j = 0; j < numcontrollers; j++) {
        if (current_dc->status == DC_OK) {
-           debug("getting challenge from %s\%s\n", current_dc->domain, current_dc->controller);
+           debug("getting challenge from %s\\%s (attempt no. %d)\n",
+               current_dc->domain, current_dc->controller, j + 1);
            ch = make_challenge(current_dc->domain, current_dc->controller);
-           if (ch)
+           debug("make_challenge retuned %p\n", ch);
+           if (ch) {
+               debug("Got it\n");
                return ch;      /* All went OK, returning */
+           }
            /* Huston, we've got a problem. Take this DC out of the loop */
            debug("Marking DC as DEAD\n");
            current_dc->status = DC_DEAD;
            need_dc_resurrection = 1;
+       } else {
+           debug("controller %s\\%s not OK, skipping\n", current_dc->domain,
+               current_dc->controller);
        }
        if (failover_enabled == 0)      /* No failover. Just return */
            return NULL;
        /* Try with the next */
+       debug("moving on to next controller\n");
        current_dc = current_dc->next;
     }
     /* DC (all DCs if failover is enabled) failed. */
@@ -247,8 +253,13 @@ manage_request()
     char *ch2, *decoded, *cred;
     int plen;
 
-    if (fgets(buf, BUFFER_SIZE, stdin) == NULL)
-       exit(0);                /* BIIG buffer */
+    if (fgets(buf, BUFFER_SIZE, stdin) == NULL) {
+       fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
+           strerror(errno));
+       abort();
+       exit(1);                /* BIIG buffer */
+    }
+    debug("managing request\n");
     ch2 = memchr(buf, '\n', BUFFER_SIZE);      /* safer against overrun than strchr */
     if (ch2) {
        *ch2 = '\0';            /* terminate the string at newline. */
@@ -281,7 +292,8 @@ manage_request()
            return;
            /* notreached */
        case NTLM_CHALLENGE:
-           SEND("NA Got a challenge. We refuse to have our authority disputed");
+           SEND
+               ("NA Got a challenge. We refuse to have our authority disputed");
            return;
            /* notreached */
        case NTLM_AUTHENTICATE:
@@ -289,79 +301,81 @@ manage_request()
            plen = strlen(buf) * 3 / 4;         /* we only need it here. Optimization */
            cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
            if (cred == NULL) {
-               int errorclass, errorcode;
-#ifdef DEBUG
-               SMB_Get_Error_Msg(SMB_Get_Last_SMB_Err(),
-                   error_messages_buffer, BUFFER_SIZE);
-               debug("Authentication failure. SMB error: %d: %s\n. Class=%d, "
-                   "Code=%d\n",
-                   SMB_Get_Last_SMB_Err(), error_messages_buffer,
-                   SMB_Get_Last_SMB_Err() & 0xff, SMB_Get_Last_SMB_Err() >> 16);
-#endif
-               /* This is kind of a special case, which happens when the
-                * client sends credentials in a domain which is not trusted
-                * by the domain we're using when authenticating. Unfortunately,
-                * it can't currently be accommodated in the current framework so
-                * I'll leave it hanging here, waiting for the general framework
-                * to be expanded to better accommodate the generale case. */
-               errorclass = SMB_Get_Last_SMB_Err() & 0xff;
-               errorcode = SMB_Get_Last_SMB_Err() >> 16;
-               if (errorclass == 1 && errorcode == 5) {
-                   SEND("NA Wrong password or untrusted domain");
+               int smblib_err, smb_errorclass, smb_errorcode, nb_error;
+               /* there was an error. We have two errno's to look at.
+                * libntlmssp's erno is insufficient, we'll have to look at
+                * the actual SMB library error codes, to acually figure
+                * out what's happening. The thing has braindamaged interfacess..*/
+               smblib_err = SMB_Get_Last_Error();
+               smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err());
+               smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err());
+               nb_error = RFCNB_Get_Last_Error();
+               debug
+                   ("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
+                   smblib_err, smb_errorclass, smb_errorcode, nb_error);
+               /* Should I use smblib_err? Actually it seems I can do as well
+                * without it.. */
+               if (nb_error != 0) {    /* netbios-level error */
+                   send_bh_or_ld("NetBios error!",
+                       (ntlm_authenticate *) decoded, plen);
+                   fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
+                       RFCNB_Error_Strings[abs(nb_error)]);
                    return;
                }
-               switch (ntlm_errno) {
-               case NTLM_LOGON_ERROR:
-                   SEND("NA authentication failure");
-                   /* I must have been drugged when I wrote the following two lines */
-                   /* dc_disconnect();
-                    * current_dc = current_dc->next; */
-                   return;
-               case NTLM_SERVER_ERROR:
-                   send_bh_or_ld("BH Domain Controller Error", (ntlm_authenticate *) decoded, plen);
-                   /* SEND("BH Domain Controller Error"); */
-                   /* we don't really need to disconnect NOW.
-                    * Besides, we asked squid to force a reconnect. This way, if we
-                    * have authentications in flight, we might even succeed.
+               switch (smb_errorclass) {
+               case SMBC_SUCCESS:
+                   debug("Huh? Got a SMB success code but could check auth..");
+                   SEND("NA Authentication failed");
+                   /*
+                    * send_bh_or_ld("SMB success, but no creds. Internal error?",
+                    * (ntlm_authenticate *) decoded, plen);
                     */
-                   /* dc_disconnect(); */
-
-                   SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000);
-                   debug("Last error was: %s, RFC errno=%d\n", smb_error_buffer,
-                       RFCNB_Get_Last_Errno());
-                   if (failover_enabled)
-                       current_dc = current_dc->next;
-                   return;
-               case NTLM_PROTOCOL_ERROR:
-                   send_bh_or_ld("BH Domain Controller communication error", (ntlm_authenticate *) decoded, plen);
-                   /* SEND("BH Domain Controller communication error"); */
-                   /* dc_disconnect(); */
-                   if (failover_enabled)
-                       current_dc = current_dc->next;
-                   return;
-               case NTLM_NOT_CONNECTED:
-                   send_bh_or_ld("BH Domain Controller (or network) died on us", (ntlm_authenticate *) decoded, plen);
-                   /* SEND("BH Domain Controller (or network) died on us"); */
-                   /* dc_disconnect(); */
-                   if (failover_enabled)
-                       current_dc = current_dc->next;
                    return;
-               case NTLM_BAD_PROTOCOL:
-                   send_bh_or_ld("BH Domain controller failure", (ntlm_authenticate *) decoded, plen);
-                   /* SEND("BH Domain controller failure"); */
-                   /* dc_disconnect(); *//* maybe we're overreacting? */
-                   SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000);
-                   debug("Last error was: %s. RFCNB errno=%d\n", smb_error_buffer,
-                       RFCNB_Get_Last_Errno());
-                   if (failover_enabled)
-                       current_dc = current_dc->next;
+               case SMBC_ERRDOS:
+                   /*this is the most important one for errors */
+                   debug("DOS error\n");
+                   switch (smb_errorcode) {
+                       /* two categories matter to us: those which could be
+                        * server errors, and those which are auth errors */
+                   case SMBD_noaccess: /* 5 */
+                       SEND("NA Access denied");
+                       return;
+                   case SMBD_badformat:
+                       SEND("NA bad format in authentication packet");
+                       return;
+                   case SMBD_badaccess:
+                       SEND("NA Bad access request");
+                       return;
+                   case SMBD_baddata:
+                       SEND("NA Bad Data");
+                       return;
+                   default:
+                       send_bh_or_ld("DOS Error",
+                           (ntlm_authenticate *) decoded, plen);
+                       return;
+                   }
+               case SMBC_ERRSRV:       /* server errors */
+                   debug("Server error");
+                   switch (smb_errorcode) {
+                       /* mostly same as above */
+                   case SMBV_badpw:
+                       SEND("NA Bad password");
+                       return;
+                   case SMBV_access:
+                       SEND("NA Server access error");
+                       return;
+                   default:
+                       send_bh_or_ld("Server Error",
+                           (ntlm_authenticate *) decoded, plen);
+                       return;
+                   }
+               case SMBC_ERRHRD:       /* hardware errors don't really matter */
+                   send_bh_or_ld("Domain Controller Hardware error",
+                       (ntlm_authenticate *) decoded, plen);
                    return;
-               default:
-                   send_bh_or_ld("BH Unhandled error while talking to Domain Controller", (ntlm_authenticate *) decoded, plen);
-                   /* SEND("BH Unhandled error while talking to Domain Controller"); */
-                   /* dc_disconnect(); *//* maybe we're overreacting? */
-                   if (failover_enabled)
-                       current_dc = current_dc->next;
+               case SMBC_ERRCMD:
+                   send_bh_or_ld("Domain Controller Command Error",
+                       (ntlm_authenticate *) decoded, plen);
                    return;
                }
            }
@@ -402,6 +416,10 @@ main(int argc, char *argv[])
 {
 
     debug("ntlm_auth build " __DATE__ ", " __TIME__ " starting up...\n");
+#ifdef DEBUG
+    debug("changing dir to /tmp\n");
+    chdir("/tmp");
+#endif
 
     my_program_name = argv[0];
     process_options(argc, argv);
@@ -425,7 +443,6 @@ main(int argc, char *argv[])
        }
     }
     while (1) {
-       debug("managing request\n");
        manage_request();
     }
     return 0;
index 4586c702484c3319b6d7ebadf6e2f3c9cd2d1cc8..9622aca51de56fe02bf04eb1c7b31cb615866477 100644 (file)
@@ -25,8 +25,7 @@
  * It assumes that a int is at least 32 bits long
  */
 #include <string.h>
-
-typedef unsigned int uint32;
+#include "std-defines.h"       /* for the types */
 
 static uint32 A, B, C, D;
 
index 66e93aec57b73ac9e7b636778766aa6bb697d4b6..123c9cba29bae020183701eb73d200de7237c7c3 100644 (file)
@@ -23,6 +23,8 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "std-includes.h"
+
 
 void RFCNB_CvtPad_Name(char *name1, char *name2);
 
index c69ced899d1f7143a9e7fb1e33fd83416639e480..126fe9a1d6cc14f8935acab481850b2942ae5ed1 100644 (file)
@@ -38,7 +38,7 @@ int RFCNB_saved_errno = 0;
 
 /* global data structures */
 
-static char *RFCNB_Error_Strings[] =
+char *RFCNB_Error_Strings[] =
 {
 
     "RFCNBE_OK: Routine completed successfully.",
index 4524b7ff30f2c1fc5088724c44640158659e3060..4cc7b5f591c8a68fe820fc10bab03092cd24d9ff 100644 (file)
 
 #include <string.h>
 #include <ctype.h>
-//#include <arpa/inet.h>
 #include <dirent.h>
 #include <string.h>
-//#include <sys/vfs.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
index 412dcca1efb3b7ddb41a1a384d096003cdb9c03f..8da4c703fd35f4e885297ad7a76905e2bbb29334 100644 (file)
 
 #include "std-defines.h"
 #include "smblib-common.h"
-#include <sys/types.h>
 #include <unistd.h>
 
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-
 #include "byteorder.h"         /* Hmmm ... hot good */
 
 #define max(a,b) (a < b ? b : a)
index 36d5c6d55502c1bb96c6a30356779bd1fd2a045d..506b3384e456d74f8c4ef7c193b46a927dd1b949 100644 (file)
@@ -1,3 +1,4 @@
+
 /* UNIX SMBlib NetBIOS implementation
  * 
  * Version 1.0
@@ -39,7 +40,7 @@ int SMBlib_SMB_Error;
 
 #include <signal.h>
 
-#define DEBUG
+/* #define DEBUG */
 
 SMB_State_Types SMBlib_State;
 
index a9968c55e3986feb691862e311e4be49edf31835..0be8bbb08776146e74015692b14b977dbe6263a5 100644 (file)
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define BOOL int
-typedef short int16;
+#include "squid_types.h"
+#define BOOL int16_t
+#define int16 int16_t
+#define uint16 u_int16_t
+#define int32 int32_t
+#define uint32 u_int32_t
 
 #include <netdb.h>
 #include <sys/types.h>
index 2426899a91f867531a30640e5c7b0969152fe659..d3ba62bc582c3fe31cb06d6e69dc8020b3eb86c8 100644 (file)
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define BOOL int
-typedef short int16;
+/* the types are provided by squid's configure preocess */
+#include "squid_types.h"
+#define BOOL int16_t
+#define int16 int16_t
 
 #include <netdb.h>
 #include <sys/types.h>
index e7603a241f1df15a6ac0f06785d15ecf17812094..32ea114a727e38965c0bd7ab1cba59d866d7ff04 100644 (file)
@@ -13,6 +13,8 @@
  */
 
 #include "config.h"
+#include "squid_types.h"
+#include "ntlmauth.h"
 
 #include "ntlm.h"
 #include "util.h"
@@ -111,7 +113,7 @@ ntlmMakeChallenge(struct ntlm_challenge *chal)
  * Check the vailidity of a request header. Return -1 on error.
  */
 int
-ntlmCheckHeader(struct ntlmhdr *hdr, int type)
+ntlmCheckHeader(ntlmhdr * hdr, int type)
 {
     /* 
      * Must be the correct security package and request type. The
@@ -262,7 +264,7 @@ main()
            printf("TT %s\n", data);
        } else if (strncasecmp(buf, "KK ", 3) == 0) {
            cleartext = (char *) uudecode(buf + 3);
-           if (!ntlmCheckHeader((struct ntlmhdr *) cleartext, NTLM_AUTHENTICATE)) {
+           if (!ntlmCheckHeader((ntlmhdr *) cleartext, NTLM_AUTHENTICATE)) {
                if (!ntlmDecodeAuth((struct ntlm_authenticate *) cleartext, user, 256)) {
                    lc(user);
                    printf("AF %s\n", user);
index 2cfb752252b32aa1d07f2653b1a356856676238b..8016628013c220ffe5e19de6afc52d8071a1bbe7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ntlm.h,v 1.2 2001/01/12 00:37:31 wessels Exp $
+ * $Id: ntlm.h,v 1.3 2001/03/10 00:55:39 hno Exp $
  *
  * AUTHOR: Andy Doran <ad@netbsd.org>
  *
 #define NTLM_AUTHENTICATE      3
 #define NTLM_ANY          0
 
-/* Header proceeding each request */
-typedef struct ntlmhdr {
-    char signature[8];         /* NTLMSSP */
-    int32_t type;              /* One of NTLM_* from above */
-} ntlmhdr;
-
-/* String header. String data resides at the end of the request */
-typedef struct strhdr {
-    int16_t len;               /* Length in bytes */
-    int16_t maxlen;            /* Allocated space in bytes */
-    int32_t offset;            /* Offset from start of request */
-} strhdr;
-
 /* Negotiation request sent by client */
 struct ntlm_negotiate {
     ntlmhdr hdr;               /* NTLM header */
@@ -102,7 +89,7 @@ struct ntlm_authenticate {
 
 char *ntlmGetString(ntlmhdr * hdr, strhdr * str, int flags);
 void ntlmMakeChallenge(struct ntlm_challenge *chal);
-int ntlmCheckHeader(struct ntlmhdr *hdr, int type);
+int ntlmCheckHeader(ntlmhdr * hdr, int type);
 int ntlmCheckNegotiation(struct ntlm_negotiate *neg);
 int ntlmAuthenticate(struct ntlm_authenticate *neg);
 
index 7120549725664b6556cfa4cf0542a9c3c6ec341d..2ca12a494085e6c2b399aa405e55098f05b9c7e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ntlmauth.h,v 1.3 2001/02/25 21:49:09 hno Exp $
+ * $Id: ntlmauth.h,v 1.4 2001/03/10 00:55:36 hno Exp $
  *
  * * * * * * * * Legal stuff * * * * * * *
  *
@@ -133,7 +133,7 @@ typedef struct _lstring {
  * among the different signature types. */
 typedef struct _ntlmhdr {
     char signature[8];         /* "NTLMSSP" */
-    int32_t type;              /* LSWAP(0x1) */
+    int32_t type;              /* One of the NTLM_* types above. */
 } ntlmhdr;
 
 /* Negotiation request sent by client */
index 0eb91da5082430c4cf702ebb5f89e3279b31beea..1f5ac756d8fb302dead5b5b36e8b8943e0c1a16f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpStatusLine.cc,v 1.23 2001/02/23 20:59:50 hno Exp $
+ * $Id: HttpStatusLine.cc,v 1.24 2001/03/10 00:55:36 hno Exp $
  *
  * DEBUG: section 57    HTTP Status-line
  * AUTHOR: Alex Rousskov
@@ -95,7 +95,7 @@ httpStatusLineParse(HttpStatusLine * sline, const char *start, const char *end)
     }
     if (!(start = strchr(start, ' ')))
        return 0;
-    sline->status = (http_status)atoi(++start);
+    sline->status = (http_status) atoi(++start);
     /* we ignore 'reason-phrase' */
     return 1;                  /* success */
 }
index d1983e3c1b454142b328262dec9fb8e7ce70ac19..bbd20c86e56586ec15214af03807be08c36a605d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.250 2001/03/03 10:39:30 hno Exp $
+ * $Id: acl.cc,v 1.251 2001/03/10 00:55:36 hno Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -574,8 +574,7 @@ aclParseTimeSpec(void *curlist)
                default:
                    debug(28, 0) ("%s line %d: %s\n",
                        cfg_filename, config_lineno, config_input_line);
-                   debug(28, 0) ("aclParseTimeSpec: Bad Day '%c'\n",
-                       *t);
+                   debug(28, 0) ("aclParseTimeSpec: Bad Day '%c'\n", *t);
                    break;
                }
            }
@@ -1101,8 +1100,7 @@ aclMatchUser(void *proxyauth_acl, char *user)
     Top = splay_splay(user, Top, (SPLAYCMP *) strcmp);
     /* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */
     debug(28, 7) ("aclMatchUser: returning %d,Top is %p, Top->data is %s\n",
-       !splayLastResult,
-       Top, (Top ? Top->data : "Unavailable"));
+       !splayLastResult, Top, (Top ? Top->data : "Unavailable"));
     data->names = Top;
     return !splayLastResult;
 }
@@ -1134,8 +1132,7 @@ aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data,
     while (link) {
        auth_match = link->data;
        if (auth_match->acl_data == data) {
-           debug(28, 4) ("aclCacheMatchAcl: cache hit on acl '%d'\n",
-               data);
+           debug(28, 4) ("aclCacheMatchAcl: cache hit on acl '%d'\n", data);
            return auth_match->matchrv;
        }
        link = link->next;
@@ -1184,7 +1181,8 @@ aclCacheMatchFlush(dlink_list * cache)
  */
 static int
 aclMatchProxyAuth(void *data, http_hdr_type headertype,
-    auth_user_request_t * auth_user_request, aclCheck_t * checklist, squid_acl acltype)
+    auth_user_request_t * auth_user_request, aclCheck_t * checklist,
+    squid_acl acltype)
 {
     /* checklist is used to register user name when identified, nothing else */
     const char *proxy_auth;
@@ -1209,7 +1207,14 @@ aclMatchProxyAuth(void *data, http_hdr_type headertype,
         */
        return 0;
     }
-    if (((proxy_auth == NULL) && (checklist->conn->auth_type == AUTH_UNKNOWN)) || (checklist->conn->auth_type == AUTH_BROKEN)) {
+    /*
+     * a note on proxy_auth logix here:
+     * proxy_auth==NULL -> unauthenticated request || already authenticated connection
+     * so we test for an authenticated connection when we recieve no authentication
+     * header.
+     */
+    if (((proxy_auth == NULL) && (!authenticateUserAuthenticated(auth_user_request)))
+       || (checklist->conn->auth_type == AUTH_BROKEN)) {
        /* no header or authentication failed/got corrupted - restart */
        checklist->conn->auth_type = AUTH_UNKNOWN;
        debug(28, 4) ("aclMatchProxyAuth: broken auth or no proxy_auth header. Requesting auth header.\n");
@@ -1226,11 +1231,14 @@ aclMatchProxyAuth(void *data, http_hdr_type headertype,
      * not had bungled connection oriented authentication happen on it. */
     debug(28, 9) ("aclMatchProxyAuth: header %s.\n", proxy_auth);
     if (auth_user_request == NULL) {
-       debug(28, 9) ("aclMatchProxyAuth: This is a new request on FD:%d\n", checklist->conn->fd);
-       if ((!checklist->request->auth_user_request) && (checklist->conn->auth_type == AUTH_UNKNOWN)) {
+       debug(28, 9) ("aclMatchProxyAuth: This is a new request on FD:%d\n",
+           checklist->conn->fd);
+       if ((!checklist->request->auth_user_request)
+           && (checklist->conn->auth_type == AUTH_UNKNOWN)) {
            /* beginning of a new request check */
            debug(28, 4) ("aclMatchProxyAuth: no connection authentication type\n");
-           if (!authenticateValidateUser(auth_user_request = authenticateGetAuthUser(proxy_auth))) {
+           if (!authenticateValidateUser(auth_user_request =
+                   authenticateGetAuthUser(proxy_auth))) {
                /* the decode might have left a username for logging, or a message to
                 * the user */
                if (authenticateUserRequestUsername(auth_user_request)) {
@@ -1254,7 +1262,9 @@ aclMatchProxyAuth(void *data, http_hdr_type headertype,
                authenticateAuthUserRequestLock(auth_user_request);
            } else {
                /* failed connection based authentication */
-               debug(28, 4) ("aclMatchProxyAuth: Aauth user request %d conn-auth user request %d conn type %d authentication failed.\n", auth_user_request, checklist->conn->auth_user_request, checklist->conn->auth_type);
+               debug(28, 4) ("aclMatchProxyAuth: Auth user request %d conn-auth user request %d conn type %d authentication failed.\n",
+                   auth_user_request, checklist->conn->auth_user_request,
+                   checklist->conn->auth_type);
                return -2;
            }
        }
@@ -1263,8 +1273,10 @@ aclMatchProxyAuth(void *data, http_hdr_type headertype,
     checklist->auth_user_request = NULL;
     if (!authenticateUserAuthenticated(auth_user_request)) {
        /* User not logged in. Log them in */
-       authenticateAuthUserRequestSetIp(auth_user_request, checklist->src_addr);
-       authenticateAuthenticateUser(auth_user_request, checklist->request, checklist->conn, headertype);
+       authenticateAuthUserRequestSetIp(auth_user_request,
+           checklist->src_addr);
+       authenticateAuthenticateUser(auth_user_request, checklist->request,
+           checklist->conn, headertype);
        switch (authenticateDirection(auth_user_request)) {
        case 1:
            /* this ACL check is finished. Unlock. */
@@ -1313,8 +1325,9 @@ aclMatchProxyAuth(void *data, http_hdr_type headertype,
        /* this ACL check completed */
        authenticateAuthUserRequestUnlock(auth_user_request);
        /* check to see if we have matched the user-acl before */
-       return aclCacheMatchAcl(&auth_user_request->auth_user->proxy_match_cache,
-           acltype, data, authenticateUserRequestUsername(auth_user_request));
+       return aclCacheMatchAcl(&auth_user_request->auth_user->
+           proxy_match_cache, acltype, data,
+           authenticateUserRequestUsername(auth_user_request));
     }
     /* this acl check completed */
     authenticateAuthUserRequestUnlock(auth_user_request);
@@ -1666,8 +1679,7 @@ aclMatchAcl(acl * ae, aclCheck_t * checklist)
     case ACL_REP_MIME_TYPE:
        if (!checklist->reply)
            return 0;
-       header = httpHeaderGetStr(&checklist->reply->header,
-           HDR_CONTENT_TYPE);
+       header = httpHeaderGetStr(&checklist->reply->header, HDR_CONTENT_TYPE);
        if (NULL == header)
            header = "";
        return aclMatchRegex(ae->data, header);
@@ -1736,20 +1748,17 @@ aclCheck(aclCheck_t * checklist)
        if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) {
            checklist->state[ACL_DST_IP] = ACL_LOOKUP_PENDING;
            ipcache_nbgethostbyname(checklist->request->host,
-               aclLookupDstIPDone,
-               checklist);
+               aclLookupDstIPDone, checklist);
            return;
        } else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) {
            checklist->state[ACL_DST_ASN] = ACL_LOOKUP_PENDING;
            ipcache_nbgethostbyname(checklist->request->host,
-               aclLookupDstIPforASNDone,
-               checklist);
+               aclLookupDstIPforASNDone, checklist);
            return;
        } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) {
            checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING;
            fqdncache_nbgethostbyaddr(checklist->src_addr,
-               aclLookupSrcFQDNDone,
-               checklist);
+               aclLookupSrcFQDNDone, checklist);
            return;
        } else if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) {
            ia = ipcacheCheckNumeric(checklist->request->host);
@@ -1760,8 +1769,7 @@ aclCheck(aclCheck_t * checklist)
            checklist->dst_addr = ia->in_addrs[0];
            checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING;
            fqdncache_nbgethostbyaddr(checklist->dst_addr,
-               aclLookupDstFQDNDone,
-               checklist);
+               aclLookupDstFQDNDone, checklist);
            return;
        } else if (checklist->state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) {
            debug(28, 3)
@@ -1927,9 +1935,7 @@ aclLookupProxyAuthDone(void *data, char *result)
 }
 
 aclCheck_t *
-aclChecklistCreate(const acl_access * A,
-    request_t * request,
-    const char *ident)
+aclChecklistCreate(const acl_access * A, request_t * request, const char *ident)
 {
     int i;
     aclCheck_t *checklist;
@@ -2302,10 +2308,7 @@ aclDumpTimeSpecList(acl_time_data * t)
            t->weekbits & ACL_THURSDAY ? 'H' : '-',
            t->weekbits & ACL_FRIDAY ? 'F' : '-',
            t->weekbits & ACL_SATURDAY ? 'A' : '-',
-           t->start / 60,
-           t->start % 60,
-           t->stop / 60,
-           t->stop % 60);
+           t->start / 60, t->start % 60, t->stop / 60, t->stop % 60);
        wordlistAdd(&W, buf);
        t = t->next;
     }
@@ -2662,8 +2665,7 @@ aclMatchArp(void *dataptr, struct in_addr c)
            arpReq.arp_ha.sa_data[2] & 0xff,
            arpReq.arp_ha.sa_data[3] & 0xff,
            arpReq.arp_ha.sa_data[4] & 0xff,
-           arpReq.arp_ha.sa_data[5] & 0xff,
-           ifr->ifr_name);
+           arpReq.arp_ha.sa_data[5] & 0xff, ifr->ifr_name);
        /* Do lookup */
        *Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
        /* Return if match, otherwise continue to other interfaces */
@@ -2703,8 +2705,7 @@ aclMatchArp(void *dataptr, struct in_addr c)
            arpReq.arp_ha.sa_data[1] == 0 &&
            arpReq.arp_ha.sa_data[2] == 0 &&
            arpReq.arp_ha.sa_data[3] == 0 &&
-           arpReq.arp_ha.sa_data[4] == 0 &&
-           arpReq.arp_ha.sa_data[5] == 0)
+           arpReq.arp_ha.sa_data[4] == 0 && arpReq.arp_ha.sa_data[5] == 0)
            return 0;
        debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n",
            arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff,
index d500c16653e4c0e561c9a2d611222644fef1e244..2f6e708c45c5a49dc17f2db55657e40ef5cae33f 100644 (file)
@@ -30,24 +30,15 @@ struct _digest_user_h {
 
 /* the digest_request structure is what follows the http_request around */
 struct _digest_request_h {
-    char *nonceb64;            // = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
-
-    char *cnonce;              // = "0a4f113b";
-
-    char *realm;               // = "testrealm@host.com";
-
-    char *pszPass;             // = "Circle Of Life";
-
-    char *algorithm;           // = "md5";
-
-    char nc[9];                        // = "00000001";
-
-    char *pszMethod;           // = "GET";
-
-    char *qop;                 // = "auth";
-
-    char *uri;                 // = "/dir/index.html";
-
+    char *nonceb64;            /* "dcd98b7102dd2f0e8b11d0f600bfb0c093" */
+    char *cnonce;              /* "0a4f113b" */
+    char *realm;               /* = "testrealm@host.com" */
+    char *pszPass;             /* = "Circle Of Life" */
+    char *algorithm;           /* = "md5" */
+    char nc[9];                        /* = "00000001" */
+    char *pszMethod;           /* = "GET" */
+    char *qop;                 /* = "auth" */
+    char *uri;                 /* = "/dir/index.html" */
     char *response;
     struct {
        unsigned int authinfo_sent:1;
index dd31a26b08cebf8c2c2f7cfe37a23fea0c70a954..cb8c67f6217fdbe9b7a4b60b66c4e1074ff7c3e0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: auth_ntlm.cc,v 1.7 2001/03/03 10:39:36 hno Exp $
+ * $Id: auth_ntlm.cc,v 1.8 2001/03/10 00:55:37 hno Exp $
  *
  * DEBUG: section 29    NTLM Authenticator
  * AUTHOR: Robert Collins
@@ -236,9 +236,7 @@ authNTLMInit(authScheme * scheme)
        /* TODO: In here send the initial YR to preinitialise the challenge cache */
        /* Think about this... currently we ask when the challenge is needed. Better? */
        if (!ntlminit) {
-           cachemgrRegister("ntlmauthenticator",
-               "User NTLM Authenticator Stats",
-               authenticateNTLMStats, 0, 1);
+           cachemgrRegister("ntlmauthenticator", "User NTLM Authenticator Stats", authenticateNTLMStats, 0, 1);
            ntlminit++;
        }
        CBDATA_INIT_TYPE(authenticateStateData);
@@ -255,9 +253,7 @@ authenticateNTLMActive()
 int
 authNTLMConfigured()
 {
-    if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) &&
-       (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1)
-       && (ntlmConfig->challengelifetime > -1)) {
+    if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) && (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1) && (ntlmConfig->challengelifetime > -1)) {
        debug(29, 9) ("authNTLMConfigured: returning configured\n");
        return 1;
     }
@@ -457,6 +453,40 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply)
                ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ);
                ntlm_request->authhelper = NULL;
                auth_user->flags.credentials_ok = 1;    /* login ok */
+#ifdef NTLM_FAIL_OPEN
+           } else if (strncasecmp(reply, "LD ", 3) == 0) {
+               /* This is a variant of BH, which rather than deny access
+                * allows the user through. The helper is starved and then refreshed
+                * via YR, all pending authentications are likely to fail also.
+                * It is meant for those helpers which occasionally fail for
+                * no reason at all (casus belli, NTLMSSP helper on NT domain,
+                * failing about 1 auth out of 1k.
+                * The code is a merge from the BH case with snippets of the AF
+                * case */
+               /* AF code: mark user as authenticated */
+               reply += 3;
+               assert(r->auth_user_request != NULL);
+               assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM);
+               auth_user_request = r->auth_user_request;
+               assert(auth_user_request->scheme_data != NULL);
+               ntlm_request = auth_user_request->scheme_data;
+               auth_user = auth_user_request->auth_user;
+               ntlm_user = auth_user_request->auth_user->scheme_data;
+               assert(ntlm_user != NULL);
+               result = S_HELPER_RELEASE;
+               /* we only expect OK when finishing the handshake */
+               assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE);
+               ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ);
+               helperstate = helperStatefulServerGetData(ntlm_request->authhelper);
+               ntlm_request->authhelper = NULL;
+               auth_user->flags.credentials_ok = 1;    /* login ok */
+               /* BH code: mark helper as broken */
+               /* Not a valid helper response to a YR request. Assert so the helper
+                * programmer will fix their bugs! */
+               assert(ntlm_request->auth_state != AUTHENTICATE_STATE_NEGOTIATE);
+               /* mark it for starving */
+               helperstate->starve = 1;
+#endif
            } else if (strncasecmp(reply, "NA ", 3) == 0) {
                /* TODO: only work with auth_user here if it exists */
                assert(r->auth_user_request != NULL);
@@ -556,6 +586,7 @@ authenticateNTLMStats(StoreEntry * sentry)
 int
 authenticateNTLMValidChallenge(ntlm_helper_state_t * helperstate)
 {
+    debug(29, 9) ("authenticateNTLMValidChallenge: Challenge is %s\n", helperstate->challenge ? "Valid" : "Invalid");
     if (helperstate->challenge == NULL)
        return 0;
     return 1;
@@ -568,10 +599,21 @@ authenticateNTLMChangeChallenge(ntlm_helper_state_t * helperstate)
     /* don't check for invalid challenges just for expiry choices */
     /* this is needed because we have to starve the helper until all old
      * requests have been satisfied */
-    if (helperstate->challengeuses > ntlmConfig->challengeuses)
+    if (!helperstate->renewed) {
+       /* first use, no challenge has been set. Without this check, it will
+        * loop forever */
+       debug(29, 5) ("authenticateNTLMChangeChallenge: first use\n");
+       return 0;
+    }
+    if (helperstate->challengeuses > ntlmConfig->challengeuses) {
+       debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig->challengeuses);
        return 1;
-    if (helperstate->renewed + ntlmConfig->challengelifetime >= squid_curtime)
+    }
+    if (helperstate->renewed + ntlmConfig->challengelifetime < squid_curtime) {
+       debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge exceeded max lifetime by %d seconds\n", squid_curtime - (helperstate->renewed + ntlmConfig->challengelifetime));
        return 1;
+    }
+    debug(29, 9) ("Challenge is to be reused\n");
     return 0;
 }
 
@@ -645,8 +687,7 @@ authenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, voi
         */
        server = helperStatefulDefer(ntlmauthenticators);
        helperstate = server ? helperStatefulServerGetData(server) : NULL;
-       while ((server != NULL) &&
-           authenticateNTLMChangeChallenge(helperstate)) {
+       while ((server != NULL) && authenticateNTLMChangeChallenge(helperstate)) {
            /* flag this helper for challenge changing */
            helperstate->starve = 1;
            /* and release the deferred request */
@@ -680,8 +721,7 @@ authenticateNTLMStart(auth_user_request_t * auth_user_request, RH * handler, voi
            /* increment the challenge uses */
            helperstate->challengeuses++;
            /* assign the challenge */
-           ntlm_request->authchallenge =
-               xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5);
+           ntlm_request->authchallenge = xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5);
            handler(data, NULL);
        }
 
@@ -815,13 +855,11 @@ authenticateProxyAuthCacheAddLink(const char *key, auth_user_t * auth_user)
 {
     auth_user_hash_pointer *proxy_auth_hash;
     ntlm_user_t *ntlm_user;
-    proxy_auth_hash =
-       memAllocate(MEM_AUTH_USER_HASH);
+    proxy_auth_hash = memAllocate(MEM_AUTH_USER_HASH);
     proxy_auth_hash->key = xstrdup(key);
     proxy_auth_hash->auth_user = auth_user;
     ntlm_user = auth_user->scheme_data;
-    dlinkAddTail(proxy_auth_hash, &proxy_auth_hash->link,
-       &ntlm_user->proxy_auth_list);
+    dlinkAddTail(proxy_auth_hash, &proxy_auth_hash->link, &ntlm_user->proxy_auth_list);
     hash_join(proxy_auth_cache, (hash_link *) proxy_auth_hash);
 }
 
@@ -858,8 +896,7 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques
     switch (ntlm_request->auth_state) {
     case AUTHENTICATE_STATE_NONE:
        /* we've recieved a negotiate request. pass to a helper */
-       debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n",
-           proxy_auth);
+       debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n", proxy_auth);
        if (auth_user->flags.credentials_ok == 2) {
            /* the authentication fialed badly... */
            return;
@@ -915,8 +952,7 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques
            assert(auth_user->auth_type == AUTH_NTLM);
            /* get the existing entries details */
            ntlm_user = auth_user->scheme_data;
-           debug(29, 9) ("Username to be used is %s\n",
-               ntlm_user->username);
+           debug(29, 9) ("Username to be used is %s\n", ntlm_user->username);
            auth_user->flags.credentials_ok = 1;        /* authenticated ok */
            /* on ntlm auth we do not unlock the auth_user until the
             * connection is dropped. Thank MS for this quirk */
@@ -940,11 +976,8 @@ authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, reques
            ntlm_request->authchallenge);
        /* see if this is an existing user with a different proxy_auth 
         * string */
-       if ((usernamehash = hash_lookup(proxy_auth_username_cache,
-                   ntlm_user->username))) {
-           while ((usernamehash->auth_user->auth_type !=
-                   auth_user->auth_type) && (usernamehash->next) &&
-               !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user))
+       if ((usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username))) {
+           while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user))
                usernamehash = usernamehash->next;
            if (usernamehash->auth_user->auth_type == auth_user->auth_type) {
                /*
index ea0d610b302170b927902eee0c8cf0e1d591f13c..0ab1d1fd9eafdeca743af1879195ec8e44920a6e 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: authenticate.cc,v 1.21 2001/02/07 18:56:51 hno Exp $
+ * $Id: authenticate.cc,v 1.22 2001/03/10 00:55:36 hno Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Duane Wessels
@@ -174,6 +174,7 @@ authenticateAuthUserNew(const char *scheme)
     temp_auth->auth_type = AUTH_UNKNOWN;
     temp_auth->references = 0;
     temp_auth->auth_module = authenticateAuthSchemeId(scheme) + 1;
+    temp_auth->usernamehash = NULL;
     return temp_auth;
 }
 
@@ -261,7 +262,8 @@ authenticateGetAuthUser(const char *proxy_auth)
 int
 authenticateUserAuthenticated(auth_user_request_t * auth_user_request)
 {
-    assert(authenticateValidateUser(auth_user_request));
+    if (!authenticateValidateUser(auth_user_request))
+       return 0;
     if (auth_user_request->auth_user->auth_module > 0)
        return authscheme_list[auth_user_request->auth_user->auth_module - 1].authenticated(auth_user_request);
     else