---------------------
PatchSet 2019 
Date: 2005/10/30 16:48:08
Author: serassio
Branch: nt
Tag: (none) 
Log:
Renamed Windows native NTLM helper from NTLMSSP-WIN32 to mswin_sspi

Members: 
	helpers/ntlm_auth/Makefile.am:1.3.16.2->1.3.16.3 
	helpers/ntlm_auth/NTLMSSP-WIN32/.cvsignore:1.1.2.1->1.1.2.2(DEAD) 
	helpers/ntlm_auth/NTLMSSP-WIN32/Makefile.am:1.2.18.3->1.2.18.4(DEAD) 
	helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c:1.2.18.8->1.2.18.9(DEAD) 
	helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h:1.2.18.4->1.2.18.5(DEAD) 
	helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c:1.2.18.8->1.2.18.9(DEAD) 
	helpers/ntlm_auth/NTLMSSP-WIN32/readme.txt:1.2.18.4->1.2.18.5(DEAD) 
	helpers/ntlm_auth/mswin_sspi/.cvsignore:1.1->1.1.2.1 
	helpers/ntlm_auth/mswin_sspi/Makefile.am:1.1->1.1.2.1 
	helpers/ntlm_auth/mswin_sspi/libntlmssp.c:1.1->1.1.2.1 
	helpers/ntlm_auth/mswin_sspi/ntlm.h:1.1->1.1.2.1 
	helpers/ntlm_auth/mswin_sspi/ntlm_auth.c:1.1->1.1.2.1 
	helpers/ntlm_auth/mswin_sspi/readme.txt:1.1->1.1.2.1 

Index: squid3/helpers/ntlm_auth/Makefile.am
===================================================================
RCS file: /cvsroot/squid-sf//squid3/helpers/ntlm_auth/Makefile.am,v
retrieving revision 1.3.16.2
retrieving revision 1.3.16.3
diff -u -r1.3.16.2 -r1.3.16.3
--- squid3/helpers/ntlm_auth/Makefile.am	2 Jul 2005 10:16:22 -0000	1.3.16.2
+++ squid3/helpers/ntlm_auth/Makefile.am	30 Oct 2005 16:48:08 -0000	1.3.16.3
@@ -1,7 +1,7 @@
 #  Makefile for storage modules in the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.3.16.2 2005/07/02 10:16:22 serassio Exp $
+#  $Id: Makefile.am,v 1.3.16.3 2005/10/30 16:48:08 serassio Exp $
 #
 
-DIST_SUBDIRS	= fakeauth no_check SMB NTLMSSP-WIN32
+DIST_SUBDIRS	= fakeauth no_check SMB mswin_sspi
 SUBDIRS		= @NTLM_AUTH_HELPERS@
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/.cvsignore	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,4 +0,0 @@
-.cvsignore
-Makefile.in
-Makefile
-.deps
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/Makefile.am	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,16 +0,0 @@
-#
-#  Makefile for the Squid Object Cache server
-#
-#  $Id: Makefile.am,v 1.2.18.3 2005/08/21 18:41:05 serassio Exp $
-#
-
-libexec_PROGRAMS = win32_ntlm_auth
-
-win32_ntlm_auth_SOURCES = libntlmssp.c ntlm_auth.c ntlm.h
-
-INCLUDES      = -I. -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/src
-
-LDADD		= -L$(top_builddir)/lib -lntlmauth -lsspwin32 -lnetapi32 \
-		  -ladvapi32 -lmiscutil $(CRYPTLIB) $(XTRA_LIBS)
-
-EXTRA_DIST = readme.txt
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,379 +0,0 @@
-/*
- * (C) 2002 Guido Serassio <serassio@libero.it>
- * Based on previous work of Francesco Chemolli and Robert Collins
- * Distributed freely under the terms of the GNU General Public License,
- * version 2. See the file COPYING for licensing details
- *
- * 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.
- */
-
-typedef unsigned char uchar;
-
-#include "util.h"
-#include "ntlm.h"
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#include <lm.h>
-#include <ntsecapi.h>
-
-/* returns 1 on success, 0 on failure */
-int
-Valid_Group(char *UserName, char *Group)
-{
-    int result = FALSE;
-    WCHAR wszUserName[UNLEN+1];	// Unicode user name
-    WCHAR wszGroup[GNLEN+1];	// Unicode Group
-
-    LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
-    LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
-    DWORD dwLevel = 0;
-    DWORD dwFlags = LG_INCLUDE_INDIRECT;
-    DWORD dwPrefMaxLen = -1;
-    DWORD dwEntriesRead = 0;
-    DWORD dwTotalEntries = 0;
-    NET_API_STATUS nStatus;
-    DWORD i;
-    DWORD dwTotalCount = 0;
-
-/* Convert ANSI User Name and Group to Unicode */
-
-    MultiByteToWideChar(CP_ACP, 0, UserName,
-	strlen(UserName) + 1, wszUserName,
-	sizeof(wszUserName) / sizeof(wszUserName[0]));
-    MultiByteToWideChar(CP_ACP, 0, Group,
-	strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
-
-    /*
-     * Call the NetUserGetLocalGroups function 
-	 * specifying information level 0.
-	 * 
-	 * The LG_INCLUDE_INDIRECT flag specifies that the 
-	 * function should also return the names of the local 
-	 * groups in which the user is indirectly a member.
-	 */
-	nStatus = NetUserGetLocalGroups(NULL,
-	    wszUserName,
-	    dwLevel,
-	    dwFlags,
-	    (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
-	/*
-	 * If the call succeeds,
-	 */
-    if (nStatus == NERR_Success) {
-	if ((pTmpBuf = pBuf) != NULL) {
-	    for (i = 0; i < dwEntriesRead; i++) {
-		if (pTmpBuf == NULL) {
-		    result = FALSE;
-		    break;
-		}
-		if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) {
-		    result = TRUE;
-		    break;
-		}
-		pTmpBuf++;
-		dwTotalCount++;
-	    }
-	}
-    } else
-	    result = FALSE;
-/*
- * Free the allocated memory.
- */
-    if (pBuf != NULL)
-	NetApiBufferFree(pBuf);
-    return result;
-}
-
-
-char * AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
-{
-    size_t len;
-    static char * target;
-
-    len = LsaStr.Length/sizeof(WCHAR) + 1;
-
-    /* allocate buffer for str + null termination */
-    safe_free(target);
-    target = (char *)xmalloc(len);
-    if (target == NULL)
-	return NULL;
-
-    /* copy unicode buffer */
-    WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, NULL, NULL );
-
-    /* add null termination */
-    target[len-1] = '\0';
-    return target;
-}
-
-
-char * GetDomainName(void)
-
-{
-    LSA_HANDLE PolicyHandle;
-    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
-    NTSTATUS status;
-    PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo;
-    PWKSTA_INFO_100 pwkiWorkstationInfo;
-    DWORD netret;
-    char * DomainName = NULL;
-
-    /* 
-     * Always initialize the object attributes to all zeroes.
-     */ 
-    memset(&ObjectAttributes, '\0', sizeof(ObjectAttributes));
-
-    /* 
-     * You need the local workstation name. Use NetWkstaGetInfo at level
-     * 100 to retrieve a WKSTA_INFO_100 structure.
-     * 
-     * The wki100_computername field contains a pointer to a UNICODE
-     * string containing the local computer name.
-     */ 
-    netret = NetWkstaGetInfo(NULL, 100, (LPBYTE *)&pwkiWorkstationInfo);
-    if (netret == NERR_Success) {
-	/* 
-	 * We have the workstation name in:
-	 * pwkiWorkstationInfo->wki100_computername
-	 * 
-	 * Next, open the policy object for the local system using
-	 * the LsaOpenPolicy function.
-	 */ 
-	status = LsaOpenPolicy(
-                 NULL,
-                 &ObjectAttributes,
-                 GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION,
-                 &PolicyHandle
-                );
-	
-	/* 
-	 * Error checking.
-	 */ 
-	if (status) {
-	    debug("OpenPolicy Error: %ld\n", status);
-	} else {
-
-	    /* 
-	     * You have a handle to the policy object. Now, get the
-	     * domain information using LsaQueryInformationPolicy.
-	     */ 
-	    status = LsaQueryInformationPolicy(PolicyHandle,
-		PolicyPrimaryDomainInformation,
-		(void **)&ppdiDomainInfo);
-	    if (status) {
-		debug("LsaQueryInformationPolicy Error: %ld\n", status);
-	    } else  {
-
-		/* Get name in useable format */
-		DomainName = AllocStrFromLSAStr(ppdiDomainInfo->Name);
-
-		/* 
-		 * Check the Sid pointer, if it is null, the
-		 * workstation is either a stand-alone computer
-		 * or a member of a workgroup.
-		 */ 
-		if (ppdiDomainInfo->Sid) {
-
-		    /* 
-		     * Member of a domain. Display it in debug mode.
-		     */ 
-		    debug("Member of Domain %s\n",DomainName);
-		} else {
-		    DomainName = NULL;
-                }
-	    }
-	}
-
-	/* 
-	 * Clean up all the memory buffers created by the LSA and
-	 * Net* APIs.
-	 */ 
-	NetApiBufferFree(pwkiWorkstationInfo);
-	LsaFreeMemory((LPVOID)ppdiDomainInfo);
-    } else 
-	debug("NetWkstaGetInfo Error: %ld\n", netret);
-    return DomainName;
-}
-
-
-int ntlm_errno;
-
-
-/* returns NULL on failure, or a pointer to
- * the user's credentials (domain\\username)
- * upon success. WARNING. It's pointing to static storage.
- * In case of problem sets as side-effect ntlm_errno to one of the
- * codes defined in ntlm.h
- */
-char *
-ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
-{
-    int rv;
-    char domain[DNLEN+1];
-    char user[UNLEN+1];
-    static char credentials[DNLEN+UNLEN+2];	/* we can afford to waste */
-
-    lstring tmp;
-
-    if (!NTLM_LocalCall) {
-
-        tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain);
-
-        if (tmp.str == NULL || tmp.l == 0) {
-	    debug("No domain supplied. Returning no-auth\n");
-	    ntlm_errno = NTLM_BAD_REQUEST;
-	    return NULL;
-        }
-        if (Use_Unicode) {
-            /* copy unicode buffer */
-            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) tmp.str, tmp.l, domain, DNLEN, NULL, NULL );
-            /* add null termination */
-            domain[tmp.l / sizeof(WCHAR)] = '\0';
-        } else {
-            if (tmp.l > DNLEN) {
-	        debug("Domain string exceeds %d bytes, rejecting\n", DNLEN);
-	        ntlm_errno = NTLM_BAD_REQUEST;
-	        return NULL;
-            }
-            memcpy(domain, tmp.str, tmp.l);
-            domain[tmp.l] = '\0';
-        }
-        tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user);
-        if (tmp.str == NULL || tmp.l == 0) {
-	    debug("No username supplied. Returning no-auth\n");
-	    ntlm_errno = NTLM_BAD_REQUEST;
-	    return NULL;
-        }
-        if (Use_Unicode) {
-            /* copy unicode buffer */
-            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) tmp.str, tmp.l, user, UNLEN, NULL, NULL );
-            /* add null termination */
-            user[tmp.l / sizeof(WCHAR)] = '\0';
-        } else {
-            if (tmp.l > UNLEN) {
-	        debug("Username string exceeds %d bytes, rejecting\n", UNLEN);
-	        ntlm_errno = NTLM_BAD_REQUEST;
-	        return NULL;
-            }
-            memcpy(user, tmp.str, tmp.l);
-            user[tmp.l] = '\0';
-        }
-        debug("checking domain: '%s', user: '%s'\n", domain, user);
-
-    } else
-        debug("checking local user\n");
-
-    rv = SSP_ValidateCredentials(auth, auth_length, credentials);
-
-    debug("Login attempt had result %d\n", rv);
-
-    if (!rv) {			/* failed */
-	ntlm_errno = NTLM_SSPI_ERROR;
-	return NULL;
-    }
-    
-    if (UseAllowedGroup) {
-	if (!Valid_Group(credentials, NTAllowedGroup)) {
-	    ntlm_errno = NTLM_BAD_NTGROUP;
-	    debug("User %s not in allowed Group %s\n", credentials, NTAllowedGroup);
-	    return NULL;
-	}
-    }
-    if (UseDisallowedGroup) {
-	if (Valid_Group(credentials, NTDisAllowedGroup)) {
-	    ntlm_errno = NTLM_BAD_NTGROUP;
-	    debug("User %s is in denied Group %s\n", credentials, NTDisAllowedGroup);
-	    return NULL;
-	}
-    }
-
-    debug("credentials: %s\n", credentials);
-    return credentials;
-}
-
-
-const char *
-ntlm_make_negotiate(void)
-{
-    ntlm_negotiate ne;
-    const char *encoded;
-    memset(&ne, 0, sizeof(ntlm_negotiate));	/* reset */
-    memcpy(ne.signature, "NTLMSSP", 8);		/* set the signature */
-    ne.type = le32toh(NTLM_NEGOTIATE);	/* this is a challenge */
-    ne.flags = le32toh(
-	NEGOTIATE_ALWAYS_SIGN |
-	NEGOTIATE_USE_NTLM |
-	NEGOTIATE_USE_LM |
-	NEGOTIATE_ASCII |
-	0
-	);
-    encoded = base64_encode_bin((char *) &ne, NEGOTIATE_LENGTH);
-    debug("Negotiate packet not supplied - self generated\n");
-    return encoded;
-}
-
-
-void hex_dump(void *data, int size)
-{
-    /* dumps size bytes of *data to stdout. Looks like:
-     * [0000] 75 6E 6B 6E 6F 77 6E 20
-     *                  30 FF 00 00 00 00 39 00 unknown 0.....9.
-     * (in a single line of course)
-     */
-
-    if (debug_enabled) {
-        unsigned char *p = data;
-        unsigned char c;
-        int n;
-        char bytestr[4] = {0};
-        char addrstr[10] = {0};
-        char hexstr[ 16*3 + 5] = {0};
-        char charstr[16*1 + 5] = {0};
-        for(n=1;n<=size;n++) {
-            if (n%16 == 1) {
-                /* store address for this line */
-                snprintf(addrstr, sizeof(addrstr), "%.4x",
-                   ((unsigned int)p-(unsigned int)data) );
-            }
-            
-            c = *p;
-            if (isalnum(c) == 0) {
-                c = '.';
-            }
-
-            /* store hex str (for left side) */
-            snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
-            strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
-
-            /* store char str (for right side) */
-            snprintf(bytestr, sizeof(bytestr), "%c", c);
-            strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
-
-            if(n%16 == 0) { 
-                /* line completed */
-                fprintf(stderr, "[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
-                hexstr[0] = 0;
-                charstr[0] = 0;
-            } else if(n%8 == 0) {
-                /* half line: add whitespaces */
-                strncat(hexstr, "  ", sizeof(hexstr)-strlen(hexstr)-1);
-                strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
-            }
-            p++; /* next byte */
-        }
-
-        if (strlen(hexstr) > 0) {
-            /* print rest of buffer if not empty */
-            fprintf(stderr, "[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
-        }
-    }
-}
-
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,115 +0,0 @@
-/*
- * (C) 2002 Guido Serassio <serassio@libero.it>
- * Based on previous work of Francesco Chemolli, Robert Collins and Andrew Doran
- *
- * Distributed freely under the terms of the GNU General Public License,
- * version 2. See the file COPYING for licensing details
- *
- * 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.
- */
-
-#ifndef _NTLM_H_
-#define _NTLM_H_
-
-#include "sspwin32.h"
-#include <windows.h>
-#include <sspi.h>
-#include <security.h>
-#include "ntlmauth.h"
-#undef debug
-
-/************* CONFIGURATION ***************/
-/*
- * define this if you want debugging
- */
-#ifndef DEBUG
-#define DEBUG
-#endif
-
-#define FAIL_DEBUG 0
-
-/************* END CONFIGURATION ***************/
-
-#include <sys/types.h>
-
-extern int debug_enabled;
-#ifdef FAIL_DEBUG
-extern int fail_debug_enabled;
-#endif
-
-/* Debugging stuff */
-
-#ifdef __GNUC__			/* this is really a gcc-ism */
-#ifdef DEBUG
-#include <stdio.h>
-#include <unistd.h>
-static char *__foo;
-#define debug(X...) if (debug_enabled) { \
-                    fprintf(stderr,"ntlm-auth[%d](%s:%d): ", getpid(), \
-                    ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\
-                    __LINE__);\
-                    fprintf(stderr,X); }
-#else /* DEBUG */
-#define debug(X...)		/* */
-#endif /* DEBUG */
-#else /* __GNUC__ */
-static void
-debug(char *format,...) 
-{
-#ifdef DEBUG
-#ifdef _SQUID_MSWIN_
-    if (debug_enabled || fail_debug_enabled) {
-	va_list args;
-
-	va_start(args,format);
-	fprintf(stderr, "ntlm-auth[%d]: ",getpid());
-	vfprintf(stderr, format, args);
-	va_end(args);
-#ifdef FAIL_DEBUG
-        fail_debug_enabled = 0;
-#endif
-    }
-#endif /* _SQUID_MSWIN_ */
-#endif /* DEBUG */
-}
-#endif /* __GNUC__ */
-
-
-/* A couple of harmless helper macros */
-#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
-#ifdef __GNUC__
-#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
-#else
-/* no gcc, no debugging. varargs macros are a gcc extension */
-#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
-#endif
-
-extern char * NTAllowedGroup;
-extern char * NTDisAllowedGroup;
-extern int UseDisallowedGroup;
-extern int UseAllowedGroup;
-extern int ntlm_errno;
-
-#define NTLM_NO_ERROR 0
-#define NTLM_SSPI_ERROR 1
-#define NTLM_BAD_NTGROUP 2
-#define NTLM_BAD_REQUEST 3
-
-#define NEGOTIATE_LENGTH 16
-
-extern void uc(char *);
-
-extern const char * ntlm_make_negotiate(void);
-extern char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length);
-extern void hex_dump(void *, int);
-
-#define safe_free(x)	if (x) { free(x); x = NULL; }
-
-#endif /* _NTLM_H_ */
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,421 +0,0 @@
-/*
- * win32_ntlm_auth: helper for NTLM Authentication for Squid Cache
- *
- * (C)2002,2003 Guido Serassio - Acme Consulting S.r.l.
- *
- * Authors:
- *  Guido Serassio <guido.serassio@acmeconsulting.it>
- *  Acme Consulting S.r.l., Italy <http://www.acmeconsulting.it>
- *
- * With contributions from others mentioned in the change history section
- * below.
- *
- * Based on previous work of Francesco Chemolli and Robert Collins.
- *
- * Dependencies: Windows NT4 SP4 and later.
- *
- * This program is free software; you can redistribute it and/or modify
- * 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.
- *
- * History:
- *
- * Version 1.21
- * 21-02-2004 Guido Serassio
- *              Removed control of use of NTLM NEGOTIATE packet from
- *              command line, now the support is automatic.
- * Version 1.20
- * 30-11-2003 Guido Serassio
- *              Added support for NTLM local calls.
- *              Added control of use of NTLM NEGOTIATE packet from
- *              command line.
- *              Updated documentation.
- * Version 1.10
- * 07-09-2003 Guido Serassio
- *              Now is true NTLM authenticator.
- *              More debug info.
- *              Updated documentation.
- * Version 1.0
- * 29-06-2002 Guido Serassio
- *              First release.
- *
- *
- */
-
-#include "util.h"
-#if HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include "ntlm.h"
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
-#define BUFFER_SIZE 10240
-
-#ifdef NTLM_FAIL_OPEN
-int last_ditch_enabled = 0;
-#endif
-
-int debug_enabled = 0;
-int NTLM_packet_debug_enabled = 0;
-
-static int have_challenge;
-
-char * NTAllowedGroup;
-char * NTDisAllowedGroup;
-int UseDisallowedGroup = 0;
-int UseAllowedGroup = 0;
-#ifdef FAIL_DEBUG
-int fail_debug_enabled = 0;
-#endif
-
-/* makes a null-terminated string upper-case. Changes CONTENTS! */
-void
-uc(char *string)
-{
-    char *p = string, c;
-    while ((c = *p)) {
-	*p = toupper(c);
-	p++;
-    }
-}
-
-/* makes a null-terminated string lower-case. Changes CONTENTS! */
-static void
-lc(char *string)
-{
-    char *p = string, c;
-    while ((c = *p)) {
-	*p = tolower(c);
-	p++;
-    }
-}
-
-void
-helperfail(const char *reason)
-{
-#ifdef FAIL_DEBUG
-    fail_debug_enabled =1;
-#endif
-    SEND2("BH %s", reason);
-}
-
-/*
-  options:
-  -d enable debugging.
-  -v enable verbose NTLM packet debugging.
-  -l if specified, changes behavior on failures to last-ditch.
-  -A can specify a Windows Local Group name allowed to authenticate.
-  -D can specify a Windows Local Group name not allowed to authenticate.
- */
-char *my_program_name = NULL;
-
-void
-usage()
-{
-    fprintf(stderr,
-#ifdef NTLM_FAIL_OPEN
-	"Usage: %s [-d] [-v] [-A|D LocalUserGroup] [-l] [-h]\n"
-#else
-	"Usage: %s [-d] [-v] [-A|D LocalUserGroup] [-h]\n"
-#endif
-	" -d  enable debugging.\n"
-        " -v  enable verbose NTLM packet debugging.\n"
-#ifdef NTLM_FAIL_OPEN
-	" -l  if specified, changes behavior on failures to last-ditch\n"
-#endif
-	" -A  specify a Windows Local Group name allowed to authenticate\n"
-	" -D  specify a Windows Local Group name not allowed to authenticate\n"
-	" -h  this message\n\n",
-	my_program_name);
-}
-
-
-void
-process_options(int argc, char *argv[])
-{
-    int opt, had_error = 0;
-
-    opterr =0;
-#ifdef NTLM_FAIL_OPEN
-    while (-1 != (opt = getopt(argc, argv, "hdvlA:D:"))) {
-#else
-    while (-1 != (opt = getopt(argc, argv, "hdvA:D:"))) {
-#endif
-	switch (opt) {
-	case 'A':
-	    safe_free(NTAllowedGroup);
-	    NTAllowedGroup=xstrdup(optarg);
-	    UseAllowedGroup = 1;
-	    break;
-	case 'D':
-	    safe_free(NTDisAllowedGroup);
-	    NTDisAllowedGroup=xstrdup(optarg);
-	    UseDisallowedGroup = 1;
-	    break;
-#ifdef NTLM_FAIL_OPEN
-	case 'l':
-	    last_ditch_enabled = 1;
-	    break;
-#endif
-	case 'd':
-	    debug_enabled = 1;
-	    break;
-	case 'v':
-	    debug_enabled = 1;
-	    NTLM_packet_debug_enabled = 1;
-	    break;
-	case 'h':
-	    usage();
-	    exit(0);
-	case '?':
-	    opt = optopt;
-	    /* fall thru to default */
-	default:
-	    fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
-	    usage();
-	    had_error = 1;
-	}
-    }
-    if (had_error)
-	exit(1);
-}
-
-
-const char *
-obtain_challenge(ntlm_negotiate * nego, int nego_length)
-{
-    const char *ch = NULL;
-
-    debug("attempting SSPI challenge retrieval\n");
-    ch = SSP_MakeChallenge(nego, nego_length);
-    if (ch) {
-	debug("Got it\n");
-	return ch;		/* All went OK, returning */
-    }
-    return NULL;
-}
-
-
-int
-manage_request()
-{
-    ntlmhdr *fast_header;
-    char buf[BUFFER_SIZE];
-    char helper_command[3];
-    char *c, *decoded, *cred;
-    int plen;
-    int oversized = 0;
-    char * ErrorMessage;
-
-try_again:
-    if (fgets(buf, BUFFER_SIZE, stdin) == NULL) 
-        return 0;
-
-    c = memchr(buf, '\n', BUFFER_SIZE);	/* safer against overrun than strchr */
-    if (c) {
-	if (oversized) {
-	    helperfail("illegal request received");
-	    fprintf(stderr, "Illegal request received: '%s'\n", buf);
-	    return 1;
-	}
-	*c = '\0';
-    } else {
-	fprintf(stderr, "No newline in '%s'\n", buf);
-	oversized = 1;
-	goto try_again;
-    }
-    if ((strlen(buf) > 3) && NTLM_packet_debug_enabled) {
-        decoded = base64_decode(buf + 3);
-        strncpy(helper_command, buf, 2);
-        debug("Got '%s' from Squid with data:\n", helper_command);
-        hex_dump(decoded, ((strlen(buf) - 3) * 3) / 4);
-    } else
-        debug("Got '%s' from Squid\n", buf);
-    if (memcmp(buf, "YR", 2) == 0) {	/* refresh-request */
-	/* figure out what we got */
-        if (strlen(buf) > 3)
-            decoded = base64_decode(buf + 3);
-        else
-            decoded = base64_decode(ntlm_make_negotiate());
-	/* Note: we don't need to manage memory at this point, since
-	 *  base64_decode returns a pointer to static storage.
-	 */
-	if (!decoded) {		/* decoding failure, return error */
-	    SEND("NA Packet format error, couldn't base64-decode");
-	    return 1;
-	}
-	/* fast-track-decode request type. */
-	fast_header = (struct _ntlmhdr *) decoded;
-
-	/* sanity-check: it IS a NTLMSSP packet, isn't it? */
-	if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
-	    SEND("NA Broken authentication packet");
-	    return 1;
-	}
-	switch (fast_header->type) {
-	case NTLM_NEGOTIATE:
-	    /* Obtain challenge against SSPI */
-            if (strlen(buf) > 3)
-                plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
-            else
-                plen = NEGOTIATE_LENGTH;
-            if ((c = (char *) obtain_challenge((ntlm_negotiate *) decoded, plen)) != NULL )
-            {
-                if (NTLM_packet_debug_enabled) {
-                    printf("TT %s\n",c);
-                    decoded = base64_decode(c);
-	            debug("sending 'TT' to squid with data:\n");
-                    hex_dump(decoded, (strlen(c) * 3) / 4);
-                    if (NTLM_LocalCall)
-                        debug("NTLM Local Call detected\n");
-                } else {
-               	    SEND2("TT %s", c);
-                }
-                have_challenge = 1;
-            } else
-                helperfail("can't obtain challenge");
-	    return 1;
-	    /* notreached */
-	case NTLM_CHALLENGE:
-	    SEND
-		("NA Got a challenge. We refuse to have our authority disputed");
-	    return 1;
-	    /* notreached */
-	case NTLM_AUTHENTICATE:
-	    SEND("NA Got authentication request instead of negotiate request");
-	    return 1;
-	    /* notreached */
-	default:
-	    helperfail("unknown refresh-request packet type");
-	    return 1;
-	}
-	return 1;
-    }
-    if (memcmp(buf, "KK ", 3) == 0) {	/* authenticate-request */
-        if (!have_challenge) {
-	    helperfail("invalid challenge");
-	    return 1;
-        }
-	/* figure out what we got */
-	decoded = base64_decode(buf + 3);
-	/* Note: we don't need to manage memory at this point, since
-	 *  base64_decode returns a pointer to static storage.
-	 */
-
-	if (!decoded) {		/* decoding failure, return error */
-	    SEND("NA Packet format error, couldn't base64-decode");
-	    return 1;
-	}
-	/* fast-track-decode request type. */
-	fast_header = (struct _ntlmhdr *) decoded;
-
-	/* sanity-check: it IS a NTLMSSP packet, isn't it? */
-	if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
-	    SEND("NA Broken authentication packet");
-	    return 1;
-	}
-	switch (fast_header->type) {
-	case NTLM_NEGOTIATE:
-	    SEND("NA Invalid negotiation request received");
-	    return 1;
-	    /* notreached */
-	case NTLM_CHALLENGE:
-	    SEND
-		("NA Got a challenge. We refuse to have our authority disputed");
-	    return 1;
-	    /* notreached */
-	case NTLM_AUTHENTICATE:
-	    /* check against SSPI */
-	    plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
-	    cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
-            have_challenge = 0;
-	    if (cred == NULL) {
-#ifdef FAIL_DEBUG
-                fail_debug_enabled =1;
-#endif
-		switch (ntlm_errno) {
-		case NTLM_BAD_NTGROUP:
-		    SEND("NA Incorrect Group Membership");
-		    return 1;
-		case NTLM_BAD_REQUEST:
-		    SEND("NA Incorrect Request Format");
-		    return 1;
-		case NTLM_SSPI_ERROR:
-                    FormatMessage( 
-                    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-                    FORMAT_MESSAGE_FROM_SYSTEM | 
-                    FORMAT_MESSAGE_IGNORE_INSERTS,
-                    NULL,
-                    GetLastError(),
-                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-                    (LPTSTR) &ErrorMessage,
-                    0,
-                    NULL);
-                    if (ErrorMessage[strlen(ErrorMessage) - 1] == '\n')
-                        ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
-                    if (ErrorMessage[strlen(ErrorMessage) - 1] == '\r')
-                        ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
-		    SEND2("NA %s", ErrorMessage);
-                    LocalFree(ErrorMessage);
-		    return 1;
-		default:
-		    SEND("NA Unknown Error");
-		    return 1;
-		}
-	    }
-	    lc(cred);		/* let's lowercase them for our convenience */
-	    SEND2("AF %s", cred);
-	    return 1;
-	default:
-	    helperfail("unknown authentication packet type");
-	    return 1;
-	}
-	return 1;
-    } else {	/* not an auth-request */
-	helperfail("illegal request received");
-	fprintf(stderr, "Illegal request received: '%s'\n", buf);
-	return 1;
-    }
-    helperfail("detected protocol error");
-    return 1;
-/********* END ********/
-}
-
-int
-main(int argc, char *argv[])
-{
-    my_program_name = argv[0];
-
-    process_options(argc, argv);
-
-    debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name);
-    
-    if (LoadSecurityDll(SSP_NTLM) == NULL) {
-	fprintf(stderr, "FATAL, can't initialize SSPI, exiting.\n");
-	exit(1);
-    }
-    debug("SSPI initialized OK\n");
-
-    atexit(UnloadSecurityDll);
-
-    /* initialize FDescs */
-    setbuf(stdout, NULL);
-    setbuf(stderr, NULL);
-
-    while (manage_request()) {
-	/* everything is done within manage_request */
-    }
-    exit(0);
-}
--- squid3/helpers/ntlm_auth/NTLMSSP-WIN32/readme.txt	Wed Feb 14 13:35:26 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,70 +0,0 @@
-win32_ntlm_auth.exe
-
-Native Windows NTLM/NTLMv2 authenticator for Squid 2.5 with
-automatic support for NTLM NEGOTIATE packets.
-
-=====
-Usage
-=====
-
-win32_ntlm_auth [-d] [-v] [-A|D LocalUserGroup] [-h]
-
--d enables debugging.
--v enables verbose NTLM packet debugging.
--A specify a Windows Local Group name allowed to authenticate.
--D specify a Windows Local Group name not allowed to authenticate.
--h print program usage
-
-This is released under the GNU General Public License
-
-==============
-Allowing Users
-==============
-
-Users that are allowed to access the web proxy must have the Windows NT
-User Rights "logon from the network".
-Optionally the authenticator can verify the NT LOCAL group membership of 
-the user against the User Group specified in the Authenticator's command
-line. 
-This can be accomplished creating a local user group on the NT machine,
-grant the privilege, and adding users to it, it works only with MACHINE
-Local Groups, not Domain Local Groups.
-Better group checking is available with External Acl, see win32_check_group
-documentation.
-
-The use of NTLM NEGOTIATE packet allow full NTLM/NTLMv2 support, but
-Squid too must be configured to use NTLM NEGOTIATE, see squid.conf.
-
-Squid.conf typical minimal required changes:
-
-auth_param ntlm program c:/squid/libexec/win32_ntlm_auth.exe
-auth_param ntlm children 5
-auth_param ntlm max_challenge_reuses 0
-auth_param ntlm max_challenge_lifetime 2 minutes
-auth_param ntlm use_ntlm_negotiate on
-
-acl password proxy_auth REQUIRED
-
-http_access allow password
-http_access deny all
-
-When using "use_ntlm_negotiate on" 
-max_challenge_reuses and max_challenge_lifetime parameters must be specified
-but they are are ignored.
-
-Refer to Squid documentation for more details.
-
-Currently Internet Explorer has some problems with ftp:// URLs when handling
-internal Squid FTP icons. The following squid.conf ACL works around this:
-
-acl internal_icons urlpath_regex -i /squid-internal-static/icons/
-
-http_access allow our_networks internal_icons <== BEFORE authentication ACL !!!
-
-
-===============
-Contact details
-===============
-
-To contact the maintainer of this package, e-mail on squidnt@acmeconsulting.it.
-The latest version may be found on http://www.acmeconsulting.it/SquidNT.htm.
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/.cvsignore	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,4 @@
+.cvsignore
+Makefile.in
+Makefile
+.deps
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/Makefile.am	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,16 @@
+#
+#  Makefile for the Squid Object Cache server
+#
+#  $Id: Makefile.am,v 1.1.2.1 2005/10/30 16:48:08 serassio Exp $
+#
+
+libexec_PROGRAMS = mswin_ntlm_auth
+
+win32_ntlm_auth_SOURCES = libntlmssp.c ntlm_auth.c ntlm.h
+
+INCLUDES      = -I. -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/src
+
+LDADD		= -L$(top_builddir)/lib -lntlmauth -lsspwin32 -lnetapi32 \
+		  -ladvapi32 -lmiscutil $(CRYPTLIB) $(XTRA_LIBS)
+
+EXTRA_DIST = readme.txt
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/libntlmssp.c	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,379 @@
+/*
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli and Robert Collins
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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.
+ */
+
+typedef unsigned char uchar;
+
+#include "util.h"
+#include "ntlm.h"
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#include <lm.h>
+#include <ntsecapi.h>
+
+/* returns 1 on success, 0 on failure */
+int
+Valid_Group(char *UserName, char *Group)
+{
+    int result = FALSE;
+    WCHAR wszUserName[UNLEN+1];	// Unicode user name
+    WCHAR wszGroup[GNLEN+1];	// Unicode Group
+
+    LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
+    LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
+    DWORD dwLevel = 0;
+    DWORD dwFlags = LG_INCLUDE_INDIRECT;
+    DWORD dwPrefMaxLen = -1;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    NET_API_STATUS nStatus;
+    DWORD i;
+    DWORD dwTotalCount = 0;
+
+/* Convert ANSI User Name and Group to Unicode */
+
+    MultiByteToWideChar(CP_ACP, 0, UserName,
+	strlen(UserName) + 1, wszUserName,
+	sizeof(wszUserName) / sizeof(wszUserName[0]));
+    MultiByteToWideChar(CP_ACP, 0, Group,
+	strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
+
+    /*
+     * Call the NetUserGetLocalGroups function 
+	 * specifying information level 0.
+	 * 
+	 * The LG_INCLUDE_INDIRECT flag specifies that the 
+	 * function should also return the names of the local 
+	 * groups in which the user is indirectly a member.
+	 */
+	nStatus = NetUserGetLocalGroups(NULL,
+	    wszUserName,
+	    dwLevel,
+	    dwFlags,
+	    (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
+	/*
+	 * If the call succeeds,
+	 */
+    if (nStatus == NERR_Success) {
+	if ((pTmpBuf = pBuf) != NULL) {
+	    for (i = 0; i < dwEntriesRead; i++) {
+		if (pTmpBuf == NULL) {
+		    result = FALSE;
+		    break;
+		}
+		if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) {
+		    result = TRUE;
+		    break;
+		}
+		pTmpBuf++;
+		dwTotalCount++;
+	    }
+	}
+    } else
+	    result = FALSE;
+/*
+ * Free the allocated memory.
+ */
+    if (pBuf != NULL)
+	NetApiBufferFree(pBuf);
+    return result;
+}
+
+
+char * AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
+{
+    size_t len;
+    static char * target;
+
+    len = LsaStr.Length/sizeof(WCHAR) + 1;
+
+    /* allocate buffer for str + null termination */
+    safe_free(target);
+    target = (char *)xmalloc(len);
+    if (target == NULL)
+	return NULL;
+
+    /* copy unicode buffer */
+    WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, NULL, NULL );
+
+    /* add null termination */
+    target[len-1] = '\0';
+    return target;
+}
+
+
+char * GetDomainName(void)
+
+{
+    LSA_HANDLE PolicyHandle;
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS status;
+    PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo;
+    PWKSTA_INFO_100 pwkiWorkstationInfo;
+    DWORD netret;
+    char * DomainName = NULL;
+
+    /* 
+     * Always initialize the object attributes to all zeroes.
+     */ 
+    memset(&ObjectAttributes, '\0', sizeof(ObjectAttributes));
+
+    /* 
+     * You need the local workstation name. Use NetWkstaGetInfo at level
+     * 100 to retrieve a WKSTA_INFO_100 structure.
+     * 
+     * The wki100_computername field contains a pointer to a UNICODE
+     * string containing the local computer name.
+     */ 
+    netret = NetWkstaGetInfo(NULL, 100, (LPBYTE *)&pwkiWorkstationInfo);
+    if (netret == NERR_Success) {
+	/* 
+	 * We have the workstation name in:
+	 * pwkiWorkstationInfo->wki100_computername
+	 * 
+	 * Next, open the policy object for the local system using
+	 * the LsaOpenPolicy function.
+	 */ 
+	status = LsaOpenPolicy(
+                 NULL,
+                 &ObjectAttributes,
+                 GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION,
+                 &PolicyHandle
+                );
+	
+	/* 
+	 * Error checking.
+	 */ 
+	if (status) {
+	    debug("OpenPolicy Error: %ld\n", status);
+	} else {
+
+	    /* 
+	     * You have a handle to the policy object. Now, get the
+	     * domain information using LsaQueryInformationPolicy.
+	     */ 
+	    status = LsaQueryInformationPolicy(PolicyHandle,
+		PolicyPrimaryDomainInformation,
+		(void **)&ppdiDomainInfo);
+	    if (status) {
+		debug("LsaQueryInformationPolicy Error: %ld\n", status);
+	    } else  {
+
+		/* Get name in useable format */
+		DomainName = AllocStrFromLSAStr(ppdiDomainInfo->Name);
+
+		/* 
+		 * Check the Sid pointer, if it is null, the
+		 * workstation is either a stand-alone computer
+		 * or a member of a workgroup.
+		 */ 
+		if (ppdiDomainInfo->Sid) {
+
+		    /* 
+		     * Member of a domain. Display it in debug mode.
+		     */ 
+		    debug("Member of Domain %s\n",DomainName);
+		} else {
+		    DomainName = NULL;
+                }
+	    }
+	}
+
+	/* 
+	 * Clean up all the memory buffers created by the LSA and
+	 * Net* APIs.
+	 */ 
+	NetApiBufferFree(pwkiWorkstationInfo);
+	LsaFreeMemory((LPVOID)ppdiDomainInfo);
+    } else 
+	debug("NetWkstaGetInfo Error: %ld\n", netret);
+    return DomainName;
+}
+
+
+int ntlm_errno;
+
+
+/* returns NULL on failure, or a pointer to
+ * the user's credentials (domain\\username)
+ * upon success. WARNING. It's pointing to static storage.
+ * In case of problem sets as side-effect ntlm_errno to one of the
+ * codes defined in ntlm.h
+ */
+char *
+ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
+{
+    int rv;
+    char domain[DNLEN+1];
+    char user[UNLEN+1];
+    static char credentials[DNLEN+UNLEN+2];	/* we can afford to waste */
+
+    lstring tmp;
+
+    if (!NTLM_LocalCall) {
+
+        tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->domain);
+
+        if (tmp.str == NULL || tmp.l == 0) {
+	    debug("No domain supplied. Returning no-auth\n");
+	    ntlm_errno = NTLM_BAD_REQUEST;
+	    return NULL;
+        }
+        if (Use_Unicode) {
+            /* copy unicode buffer */
+            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) tmp.str, tmp.l, domain, DNLEN, NULL, NULL );
+            /* add null termination */
+            domain[tmp.l / sizeof(WCHAR)] = '\0';
+        } else {
+            if (tmp.l > DNLEN) {
+	        debug("Domain string exceeds %d bytes, rejecting\n", DNLEN);
+	        ntlm_errno = NTLM_BAD_REQUEST;
+	        return NULL;
+            }
+            memcpy(domain, tmp.str, tmp.l);
+            domain[tmp.l] = '\0';
+        }
+        tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user);
+        if (tmp.str == NULL || tmp.l == 0) {
+	    debug("No username supplied. Returning no-auth\n");
+	    ntlm_errno = NTLM_BAD_REQUEST;
+	    return NULL;
+        }
+        if (Use_Unicode) {
+            /* copy unicode buffer */
+            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) tmp.str, tmp.l, user, UNLEN, NULL, NULL );
+            /* add null termination */
+            user[tmp.l / sizeof(WCHAR)] = '\0';
+        } else {
+            if (tmp.l > UNLEN) {
+	        debug("Username string exceeds %d bytes, rejecting\n", UNLEN);
+	        ntlm_errno = NTLM_BAD_REQUEST;
+	        return NULL;
+            }
+            memcpy(user, tmp.str, tmp.l);
+            user[tmp.l] = '\0';
+        }
+        debug("checking domain: '%s', user: '%s'\n", domain, user);
+
+    } else
+        debug("checking local user\n");
+
+    rv = SSP_ValidateCredentials(auth, auth_length, credentials);
+
+    debug("Login attempt had result %d\n", rv);
+
+    if (!rv) {			/* failed */
+	ntlm_errno = NTLM_SSPI_ERROR;
+	return NULL;
+    }
+    
+    if (UseAllowedGroup) {
+	if (!Valid_Group(credentials, NTAllowedGroup)) {
+	    ntlm_errno = NTLM_BAD_NTGROUP;
+	    debug("User %s not in allowed Group %s\n", credentials, NTAllowedGroup);
+	    return NULL;
+	}
+    }
+    if (UseDisallowedGroup) {
+	if (Valid_Group(credentials, NTDisAllowedGroup)) {
+	    ntlm_errno = NTLM_BAD_NTGROUP;
+	    debug("User %s is in denied Group %s\n", credentials, NTDisAllowedGroup);
+	    return NULL;
+	}
+    }
+
+    debug("credentials: %s\n", credentials);
+    return credentials;
+}
+
+
+const char *
+ntlm_make_negotiate(void)
+{
+    ntlm_negotiate ne;
+    const char *encoded;
+    memset(&ne, 0, sizeof(ntlm_negotiate));	/* reset */
+    memcpy(ne.signature, "NTLMSSP", 8);		/* set the signature */
+    ne.type = le32toh(NTLM_NEGOTIATE);	/* this is a challenge */
+    ne.flags = le32toh(
+	NEGOTIATE_ALWAYS_SIGN |
+	NEGOTIATE_USE_NTLM |
+	NEGOTIATE_USE_LM |
+	NEGOTIATE_ASCII |
+	0
+	);
+    encoded = base64_encode_bin((char *) &ne, NEGOTIATE_LENGTH);
+    debug("Negotiate packet not supplied - self generated\n");
+    return encoded;
+}
+
+
+void hex_dump(void *data, int size)
+{
+    /* dumps size bytes of *data to stdout. Looks like:
+     * [0000] 75 6E 6B 6E 6F 77 6E 20
+     *                  30 FF 00 00 00 00 39 00 unknown 0.....9.
+     * (in a single line of course)
+     */
+
+    if (debug_enabled) {
+        unsigned char *p = data;
+        unsigned char c;
+        int n;
+        char bytestr[4] = {0};
+        char addrstr[10] = {0};
+        char hexstr[ 16*3 + 5] = {0};
+        char charstr[16*1 + 5] = {0};
+        for(n=1;n<=size;n++) {
+            if (n%16 == 1) {
+                /* store address for this line */
+                snprintf(addrstr, sizeof(addrstr), "%.4x",
+                   ((unsigned int)p-(unsigned int)data) );
+            }
+            
+            c = *p;
+            if (isalnum(c) == 0) {
+                c = '.';
+            }
+
+            /* store hex str (for left side) */
+            snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
+            strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
+
+            /* store char str (for right side) */
+            snprintf(bytestr, sizeof(bytestr), "%c", c);
+            strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
+
+            if(n%16 == 0) { 
+                /* line completed */
+                fprintf(stderr, "[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
+                hexstr[0] = 0;
+                charstr[0] = 0;
+            } else if(n%8 == 0) {
+                /* half line: add whitespaces */
+                strncat(hexstr, "  ", sizeof(hexstr)-strlen(hexstr)-1);
+                strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
+            }
+            p++; /* next byte */
+        }
+
+        if (strlen(hexstr) > 0) {
+            /* print rest of buffer if not empty */
+            fprintf(stderr, "[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
+        }
+    }
+}
+
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/ntlm.h	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,115 @@
+/*
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli, Robert Collins and Andrew Doran
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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.
+ */
+
+#ifndef _NTLM_H_
+#define _NTLM_H_
+
+#include "sspwin32.h"
+#include <windows.h>
+#include <sspi.h>
+#include <security.h>
+#include "ntlmauth.h"
+#undef debug
+
+/************* CONFIGURATION ***************/
+/*
+ * define this if you want debugging
+ */
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+#define FAIL_DEBUG 0
+
+/************* END CONFIGURATION ***************/
+
+#include <sys/types.h>
+
+extern int debug_enabled;
+#ifdef FAIL_DEBUG
+extern int fail_debug_enabled;
+#endif
+
+/* Debugging stuff */
+
+#ifdef __GNUC__			/* this is really a gcc-ism */
+#ifdef DEBUG
+#include <stdio.h>
+#include <unistd.h>
+static char *__foo;
+#define debug(X...) if (debug_enabled) { \
+                    fprintf(stderr,"ntlm-auth[%d](%s:%d): ", getpid(), \
+                    ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\
+                    __LINE__);\
+                    fprintf(stderr,X); }
+#else /* DEBUG */
+#define debug(X...)		/* */
+#endif /* DEBUG */
+#else /* __GNUC__ */
+static void
+debug(char *format,...) 
+{
+#ifdef DEBUG
+#ifdef _SQUID_MSWIN_
+    if (debug_enabled || fail_debug_enabled) {
+	va_list args;
+
+	va_start(args,format);
+	fprintf(stderr, "ntlm-auth[%d]: ",getpid());
+	vfprintf(stderr, format, args);
+	va_end(args);
+#ifdef FAIL_DEBUG
+        fail_debug_enabled = 0;
+#endif
+    }
+#endif /* _SQUID_MSWIN_ */
+#endif /* DEBUG */
+}
+#endif /* __GNUC__ */
+
+
+/* A couple of harmless helper macros */
+#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
+#ifdef __GNUC__
+#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
+#else
+/* no gcc, no debugging. varargs macros are a gcc extension */
+#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
+#endif
+
+extern char * NTAllowedGroup;
+extern char * NTDisAllowedGroup;
+extern int UseDisallowedGroup;
+extern int UseAllowedGroup;
+extern int ntlm_errno;
+
+#define NTLM_NO_ERROR 0
+#define NTLM_SSPI_ERROR 1
+#define NTLM_BAD_NTGROUP 2
+#define NTLM_BAD_REQUEST 3
+
+#define NEGOTIATE_LENGTH 16
+
+extern void uc(char *);
+
+extern const char * ntlm_make_negotiate(void);
+extern char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length);
+extern void hex_dump(void *, int);
+
+#define safe_free(x)	if (x) { free(x); x = NULL; }
+
+#endif /* _NTLM_H_ */
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/ntlm_auth.c	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,421 @@
+/*
+ * win32_ntlm_auth: helper for NTLM Authentication for Squid Cache
+ *
+ * (C)2002,2003 Guido Serassio - Acme Consulting S.r.l.
+ *
+ * Authors:
+ *  Guido Serassio <guido.serassio@acmeconsulting.it>
+ *  Acme Consulting S.r.l., Italy <http://www.acmeconsulting.it>
+ *
+ * With contributions from others mentioned in the change history section
+ * below.
+ *
+ * Based on previous work of Francesco Chemolli and Robert Collins.
+ *
+ * Dependencies: Windows NT4 SP4 and later.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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.
+ *
+ * History:
+ *
+ * Version 1.21
+ * 21-02-2004 Guido Serassio
+ *              Removed control of use of NTLM NEGOTIATE packet from
+ *              command line, now the support is automatic.
+ * Version 1.20
+ * 30-11-2003 Guido Serassio
+ *              Added support for NTLM local calls.
+ *              Added control of use of NTLM NEGOTIATE packet from
+ *              command line.
+ *              Updated documentation.
+ * Version 1.10
+ * 07-09-2003 Guido Serassio
+ *              Now is true NTLM authenticator.
+ *              More debug info.
+ *              Updated documentation.
+ * Version 1.0
+ * 29-06-2002 Guido Serassio
+ *              First release.
+ *
+ *
+ */
+
+#include "util.h"
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include "ntlm.h"
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#define BUFFER_SIZE 10240
+
+#ifdef NTLM_FAIL_OPEN
+int last_ditch_enabled = 0;
+#endif
+
+int debug_enabled = 0;
+int NTLM_packet_debug_enabled = 0;
+
+static int have_challenge;
+
+char * NTAllowedGroup;
+char * NTDisAllowedGroup;
+int UseDisallowedGroup = 0;
+int UseAllowedGroup = 0;
+#ifdef FAIL_DEBUG
+int fail_debug_enabled = 0;
+#endif
+
+/* makes a null-terminated string upper-case. Changes CONTENTS! */
+void
+uc(char *string)
+{
+    char *p = string, c;
+    while ((c = *p)) {
+	*p = toupper(c);
+	p++;
+    }
+}
+
+/* makes a null-terminated string lower-case. Changes CONTENTS! */
+static void
+lc(char *string)
+{
+    char *p = string, c;
+    while ((c = *p)) {
+	*p = tolower(c);
+	p++;
+    }
+}
+
+void
+helperfail(const char *reason)
+{
+#ifdef FAIL_DEBUG
+    fail_debug_enabled =1;
+#endif
+    SEND2("BH %s", reason);
+}
+
+/*
+  options:
+  -d enable debugging.
+  -v enable verbose NTLM packet debugging.
+  -l if specified, changes behavior on failures to last-ditch.
+  -A can specify a Windows Local Group name allowed to authenticate.
+  -D can specify a Windows Local Group name not allowed to authenticate.
+ */
+char *my_program_name = NULL;
+
+void
+usage()
+{
+    fprintf(stderr,
+#ifdef NTLM_FAIL_OPEN
+	"Usage: %s [-d] [-v] [-A|D LocalUserGroup] [-l] [-h]\n"
+#else
+	"Usage: %s [-d] [-v] [-A|D LocalUserGroup] [-h]\n"
+#endif
+	" -d  enable debugging.\n"
+        " -v  enable verbose NTLM packet debugging.\n"
+#ifdef NTLM_FAIL_OPEN
+	" -l  if specified, changes behavior on failures to last-ditch\n"
+#endif
+	" -A  specify a Windows Local Group name allowed to authenticate\n"
+	" -D  specify a Windows Local Group name not allowed to authenticate\n"
+	" -h  this message\n\n",
+	my_program_name);
+}
+
+
+void
+process_options(int argc, char *argv[])
+{
+    int opt, had_error = 0;
+
+    opterr =0;
+#ifdef NTLM_FAIL_OPEN
+    while (-1 != (opt = getopt(argc, argv, "hdvlA:D:"))) {
+#else
+    while (-1 != (opt = getopt(argc, argv, "hdvA:D:"))) {
+#endif
+	switch (opt) {
+	case 'A':
+	    safe_free(NTAllowedGroup);
+	    NTAllowedGroup=xstrdup(optarg);
+	    UseAllowedGroup = 1;
+	    break;
+	case 'D':
+	    safe_free(NTDisAllowedGroup);
+	    NTDisAllowedGroup=xstrdup(optarg);
+	    UseDisallowedGroup = 1;
+	    break;
+#ifdef NTLM_FAIL_OPEN
+	case 'l':
+	    last_ditch_enabled = 1;
+	    break;
+#endif
+	case 'd':
+	    debug_enabled = 1;
+	    break;
+	case 'v':
+	    debug_enabled = 1;
+	    NTLM_packet_debug_enabled = 1;
+	    break;
+	case 'h':
+	    usage();
+	    exit(0);
+	case '?':
+	    opt = optopt;
+	    /* fall thru to default */
+	default:
+	    fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
+	    usage();
+	    had_error = 1;
+	}
+    }
+    if (had_error)
+	exit(1);
+}
+
+
+const char *
+obtain_challenge(ntlm_negotiate * nego, int nego_length)
+{
+    const char *ch = NULL;
+
+    debug("attempting SSPI challenge retrieval\n");
+    ch = SSP_MakeChallenge(nego, nego_length);
+    if (ch) {
+	debug("Got it\n");
+	return ch;		/* All went OK, returning */
+    }
+    return NULL;
+}
+
+
+int
+manage_request()
+{
+    ntlmhdr *fast_header;
+    char buf[BUFFER_SIZE];
+    char helper_command[3];
+    char *c, *decoded, *cred;
+    int plen;
+    int oversized = 0;
+    char * ErrorMessage;
+
+try_again:
+    if (fgets(buf, BUFFER_SIZE, stdin) == NULL) 
+        return 0;
+
+    c = memchr(buf, '\n', BUFFER_SIZE);	/* safer against overrun than strchr */
+    if (c) {
+	if (oversized) {
+	    helperfail("illegal request received");
+	    fprintf(stderr, "Illegal request received: '%s'\n", buf);
+	    return 1;
+	}
+	*c = '\0';
+    } else {
+	fprintf(stderr, "No newline in '%s'\n", buf);
+	oversized = 1;
+	goto try_again;
+    }
+    if ((strlen(buf) > 3) && NTLM_packet_debug_enabled) {
+        decoded = base64_decode(buf + 3);
+        strncpy(helper_command, buf, 2);
+        debug("Got '%s' from Squid with data:\n", helper_command);
+        hex_dump(decoded, ((strlen(buf) - 3) * 3) / 4);
+    } else
+        debug("Got '%s' from Squid\n", buf);
+    if (memcmp(buf, "YR", 2) == 0) {	/* refresh-request */
+	/* figure out what we got */
+        if (strlen(buf) > 3)
+            decoded = base64_decode(buf + 3);
+        else
+            decoded = base64_decode(ntlm_make_negotiate());
+	/* Note: we don't need to manage memory at this point, since
+	 *  base64_decode returns a pointer to static storage.
+	 */
+	if (!decoded) {		/* decoding failure, return error */
+	    SEND("NA Packet format error, couldn't base64-decode");
+	    return 1;
+	}
+	/* fast-track-decode request type. */
+	fast_header = (struct _ntlmhdr *) decoded;
+
+	/* sanity-check: it IS a NTLMSSP packet, isn't it? */
+	if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
+	    SEND("NA Broken authentication packet");
+	    return 1;
+	}
+	switch (fast_header->type) {
+	case NTLM_NEGOTIATE:
+	    /* Obtain challenge against SSPI */
+            if (strlen(buf) > 3)
+                plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
+            else
+                plen = NEGOTIATE_LENGTH;
+            if ((c = (char *) obtain_challenge((ntlm_negotiate *) decoded, plen)) != NULL )
+            {
+                if (NTLM_packet_debug_enabled) {
+                    printf("TT %s\n",c);
+                    decoded = base64_decode(c);
+	            debug("sending 'TT' to squid with data:\n");
+                    hex_dump(decoded, (strlen(c) * 3) / 4);
+                    if (NTLM_LocalCall)
+                        debug("NTLM Local Call detected\n");
+                } else {
+               	    SEND2("TT %s", c);
+                }
+                have_challenge = 1;
+            } else
+                helperfail("can't obtain challenge");
+	    return 1;
+	    /* notreached */
+	case NTLM_CHALLENGE:
+	    SEND
+		("NA Got a challenge. We refuse to have our authority disputed");
+	    return 1;
+	    /* notreached */
+	case NTLM_AUTHENTICATE:
+	    SEND("NA Got authentication request instead of negotiate request");
+	    return 1;
+	    /* notreached */
+	default:
+	    helperfail("unknown refresh-request packet type");
+	    return 1;
+	}
+	return 1;
+    }
+    if (memcmp(buf, "KK ", 3) == 0) {	/* authenticate-request */
+        if (!have_challenge) {
+	    helperfail("invalid challenge");
+	    return 1;
+        }
+	/* figure out what we got */
+	decoded = base64_decode(buf + 3);
+	/* Note: we don't need to manage memory at this point, since
+	 *  base64_decode returns a pointer to static storage.
+	 */
+
+	if (!decoded) {		/* decoding failure, return error */
+	    SEND("NA Packet format error, couldn't base64-decode");
+	    return 1;
+	}
+	/* fast-track-decode request type. */
+	fast_header = (struct _ntlmhdr *) decoded;
+
+	/* sanity-check: it IS a NTLMSSP packet, isn't it? */
+	if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
+	    SEND("NA Broken authentication packet");
+	    return 1;
+	}
+	switch (fast_header->type) {
+	case NTLM_NEGOTIATE:
+	    SEND("NA Invalid negotiation request received");
+	    return 1;
+	    /* notreached */
+	case NTLM_CHALLENGE:
+	    SEND
+		("NA Got a challenge. We refuse to have our authority disputed");
+	    return 1;
+	    /* notreached */
+	case NTLM_AUTHENTICATE:
+	    /* check against SSPI */
+	    plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
+	    cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
+            have_challenge = 0;
+	    if (cred == NULL) {
+#ifdef FAIL_DEBUG
+                fail_debug_enabled =1;
+#endif
+		switch (ntlm_errno) {
+		case NTLM_BAD_NTGROUP:
+		    SEND("NA Incorrect Group Membership");
+		    return 1;
+		case NTLM_BAD_REQUEST:
+		    SEND("NA Incorrect Request Format");
+		    return 1;
+		case NTLM_SSPI_ERROR:
+                    FormatMessage( 
+                    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+                    FORMAT_MESSAGE_FROM_SYSTEM | 
+                    FORMAT_MESSAGE_IGNORE_INSERTS,
+                    NULL,
+                    GetLastError(),
+                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                    (LPTSTR) &ErrorMessage,
+                    0,
+                    NULL);
+                    if (ErrorMessage[strlen(ErrorMessage) - 1] == '\n')
+                        ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
+                    if (ErrorMessage[strlen(ErrorMessage) - 1] == '\r')
+                        ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
+		    SEND2("NA %s", ErrorMessage);
+                    LocalFree(ErrorMessage);
+		    return 1;
+		default:
+		    SEND("NA Unknown Error");
+		    return 1;
+		}
+	    }
+	    lc(cred);		/* let's lowercase them for our convenience */
+	    SEND2("AF %s", cred);
+	    return 1;
+	default:
+	    helperfail("unknown authentication packet type");
+	    return 1;
+	}
+	return 1;
+    } else {	/* not an auth-request */
+	helperfail("illegal request received");
+	fprintf(stderr, "Illegal request received: '%s'\n", buf);
+	return 1;
+    }
+    helperfail("detected protocol error");
+    return 1;
+/********* END ********/
+}
+
+int
+main(int argc, char *argv[])
+{
+    my_program_name = argv[0];
+
+    process_options(argc, argv);
+
+    debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name);
+    
+    if (LoadSecurityDll(SSP_NTLM) == NULL) {
+	fprintf(stderr, "FATAL, can't initialize SSPI, exiting.\n");
+	exit(1);
+    }
+    debug("SSPI initialized OK\n");
+
+    atexit(UnloadSecurityDll);
+
+    /* initialize FDescs */
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+
+    while (manage_request()) {
+	/* everything is done within manage_request */
+    }
+    exit(0);
+}
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/helpers/ntlm_auth/mswin_sspi/readme.txt	Wed Feb 14 13:35:26 2007
@@ -0,0 +1,70 @@
+mswin_ntlm_auth.exe
+
+Native Windows NTLM/NTLMv2 authenticator for Squid with
+automatic support for NTLM NEGOTIATE packets.
+
+=====
+Usage
+=====
+
+mswin_ntlm_auth [-d] [-v] [-A|D LocalUserGroup] [-h]
+
+-d enables debugging.
+-v enables verbose NTLM packet debugging.
+-A specify a Windows Local Group name allowed to authenticate.
+-D specify a Windows Local Group name not allowed to authenticate.
+-h print program usage
+
+This is released under the GNU General Public License
+
+==============
+Allowing Users
+==============
+
+Users that are allowed to access the web proxy must have the Windows NT
+User Rights "logon from the network".
+Optionally the authenticator can verify the NT LOCAL group membership of 
+the user against the User Group specified in the Authenticator's command
+line. 
+This can be accomplished creating a local user group on the NT machine,
+grant the privilege, and adding users to it, it works only with MACHINE
+Local Groups, not Domain Local Groups.
+Better group checking is available with External Acl, see mswin_check_group
+documentation.
+
+The use of NTLM NEGOTIATE packet allow full NTLM/NTLMv2 support, but
+Squid too must be configured to use NTLM NEGOTIATE, see squid.conf.
+
+Squid.conf typical minimal required changes:
+
+auth_param ntlm program c:/squid/libexec/mswin_ntlm_auth.exe
+auth_param ntlm children 5
+auth_param ntlm max_challenge_reuses 0
+auth_param ntlm max_challenge_lifetime 2 minutes
+auth_param ntlm use_ntlm_negotiate on
+
+acl password proxy_auth REQUIRED
+
+http_access allow password
+http_access deny all
+
+When using "use_ntlm_negotiate on" 
+max_challenge_reuses and max_challenge_lifetime parameters must be specified
+but they are are ignored.
+
+Refer to Squid documentation for more details.
+
+Currently Internet Explorer has some problems with ftp:// URLs when handling
+internal Squid FTP icons. The following squid.conf ACL works around this:
+
+acl internal_icons urlpath_regex -i /squid-internal-static/icons/
+
+http_access allow our_networks internal_icons <== BEFORE authentication ACL !!!
+
+
+===============
+Contact details
+===============
+
+To contact the maintainer of this package, e-mail on squidnt@acmeconsulting.it.
+The latest version may be found on http://www.acmeconsulting.it/SquidNT.htm.
