--------------------- PatchSet 7117 Date: 2005/10/22 17:45:23 Author: serassio Branch: negotiate-nt-2_5 Tag: (none) Log: Added native Windows Negotiate Helper Members: helpers/Makefile.am:1.2.8.2->1.2.8.2.2.1 helpers/basic_auth/win32_locallogon/NT_auth.c:1.1.4.7->1.1.4.7.2.1 helpers/negotiate_auth/.cvsignore:1.1->1.1.2.1 helpers/negotiate_auth/Makefile.am:1.1->1.1.2.1 helpers/negotiate_auth/Win32/.cvsignore:1.1->1.1.2.1 helpers/negotiate_auth/Win32/Makefile.am:1.1->1.1.2.1 helpers/negotiate_auth/Win32/libnegotiatessp.c:1.1->1.1.2.1 helpers/negotiate_auth/Win32/negotiate.h:1.1->1.1.2.1 helpers/negotiate_auth/Win32/negotiate_auth.c:1.1->1.1.2.1 helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c:1.1.4.11->1.1.4.11.2.1 helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h:1.1.4.9->1.1.4.9.2.1 helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c:1.1.4.20->1.1.4.20.2.1 include/sspwin32.h:1.1.4.4->1.1.4.4.2.1 lib/sspwin32.c:1.1.4.7->1.1.4.7.2.1 Index: squid/helpers/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid/helpers/Makefile.am,v retrieving revision 1.2.8.2 retrieving revision 1.2.8.2.2.1 diff -u -r1.2.8.2 -r1.2.8.2.2.1 --- squid/helpers/Makefile.am 13 Jul 2002 06:27:44 -0000 1.2.8.2 +++ squid/helpers/Makefile.am 22 Oct 2005 17:45:23 -0000 1.2.8.2.2.1 @@ -1 +1 @@ -SUBDIRS = basic_auth ntlm_auth digest_auth external_acl +SUBDIRS = basic_auth ntlm_auth digest_auth negotiate_auth external_acl Index: squid/helpers/basic_auth/win32_locallogon/NT_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/helpers/basic_auth/win32_locallogon/Attic/NT_auth.c,v retrieving revision 1.1.4.7 retrieving revision 1.1.4.7.2.1 diff -u -r1.1.4.7 -r1.1.4.7.2.1 --- squid/helpers/basic_auth/win32_locallogon/NT_auth.c 14 Sep 2005 12:12:21 -0000 1.1.4.7 +++ squid/helpers/basic_auth/win32_locallogon/NT_auth.c 22 Oct 2005 17:45:23 -0000 1.1.4.7.2.1 @@ -120,7 +120,7 @@ debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name); - if (LoadSecurityDll(SSP_BASIC) == NULL) { + if (LoadSecurityDll(SSP_BASIC, NTLM_PACKAGE_NAME) == NULL) { fprintf(stderr, "FATAL, can't initialize SSPI, exiting.\n"); exit(1); } --- /dev/null Wed Feb 14 01:13:16 2007 +++ squid/helpers/negotiate_auth/.cvsignore Wed Feb 14 01:13:32 2007 @@ -0,0 +1,2 @@ +.cvsignore +Makefile.in --- /dev/null Wed Feb 14 01:13:16 2007 +++ squid/helpers/negotiate_auth/Makefile.am Wed Feb 14 01:13:32 2007 @@ -0,0 +1,7 @@ +# Makefile for storage modules in the Squid Object Cache server +# +# $Id: Makefile.am,v 1.1.2.1 2005/10/22 17:45:23 serassio Exp $ +# + +DIST_SUBDIRS = Win32 +SUBDIRS = @NEGOTIATE_AUTH_HELPERS@ --- /dev/null Wed Feb 14 01:13:16 2007 +++ squid/helpers/negotiate_auth/Win32/.cvsignore Wed Feb 14 01:13:32 2007 @@ -0,0 +1,2 @@ +.cvsignore +Makefile.in --- /dev/null Wed Feb 14 01:13:16 2007 +++ squid/helpers/negotiate_auth/Win32/Makefile.am Wed Feb 14 01:13:32 2007 @@ -0,0 +1,20 @@ +# +# Makefile for the Squid Object Cache server +# +# $Id: Makefile.am,v 1.1.2.1 2005/10/22 17:45:23 serassio Exp $ +# + +libexec_PROGRAMS = win32_negotiate_auth + +win32_negotiate_auth_SOURCES = libnegotiatessp.c negotiate_auth.c negotiate.h + +if ENABLE_MINGW32SPECIFIC +INCLUDES = -I. -I$(top_srcdir)/port/win32/include -I$(top_srcdir)/include -I$(top_srcdir)/src +else +INCLUDES = -I. -I$(top_srcdir)/include -I$(top_srcdir)/src +endif + +LDADD = -L$(top_builddir)/lib -lntlmauth -lsspwin32 -lnetapi32 \ + -ladvapi32 -lmiscutil $(CRYPTLIB) $(XTRA_LIBS) + +EXTRA_DIST = readme.txt --- /dev/null Wed Feb 14 01:13:16 2007 +++ squid/helpers/negotiate_auth/Win32/libnegotiatessp.c Wed Feb 14 01:13:32 2007 @@ -0,0 +1,80 @@ +/* + * (C) 2002 Guido Serassio + * 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 "negotiate.h" +#if HAVE_CTYPE_H +#include +#endif + +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 01:13:16 2007 +++ squid/helpers/negotiate_auth/Win32/negotiate.h Wed Feb 14 01:13:32 2007 @@ -0,0 +1,116 @@ +/* + * (C) 2002 Guido Serassio + * 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 +#include +#include +#include "ntlmauth.h" +#undef debug + +/************* CONFIGURATION ***************/ +/* + * define this if you want debugging + */ +#ifndef DEBUG +#define DEBUG +#endif + +#define FAIL_DEBUG 0 + +/************* END CONFIGURATION ***************/ + +#include + +extern int debug_enabled; +#if FAIL_DEBUG +extern int fail_debug_enabled; +#endif + +/* Debugging stuff */ + +#ifdef __GNUC__ /* this is really a gcc-ism */ +#ifdef DEBUG +#include +#include +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 FAIL_DEBUG + if (debug_enabled || fail_debug_enabled) { +#else + if (debug_enabled) { +#endif + va_list args; + + va_start(args,format); + fprintf(stderr, "negotiate-auth[%d]: ",getpid()); + vfprintf(stderr, format, args); + va_end(args); +#if 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); +#define SEND3(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); +#define SEND3(X,Y,Z) debug("sending '" X "' to squid\n",Y,Z); printf(X "\n",Y,Z); +#endif + +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 char *negotiate_check_auth(SSP_blobP 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 01:13:16 2007 +++ squid/helpers/negotiate_auth/Win32/negotiate_auth.c Wed Feb 14 01:13:32 2007 @@ -0,0 +1,316 @@ +/* + * win32_ntlm_auth: helper for NTLM Authentication for Squid Cache + * + * (C)2005 Guido Serassio - Acme Consulting S.r.l. + * + * Authors: + * Guido Serassio + * Acme Consulting S.r.l., Italy + * + * 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.0 + * 29-10-2005 Guido Serassio + * First release. + * + * + */ + +#include "util.h" +#if HAVE_GETOPT_H +#include +#endif +#include "negotiate.h" +#if HAVE_CTYPE_H +#include +#endif + +#define BUFFER_SIZE 10240 + +int debug_enabled = 0; +int Negotiate_packet_debug_enabled = 0; + +static int have_serverblob; + +/* 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) +{ +#if FAIL_DEBUG + fail_debug_enabled =1; +#endif + SEND2("BH %s", reason); +} + +/* + options: + -d enable debugging. + -v enable verbose NTLM packet debugging. + */ +char *my_program_name = NULL; + +void +usage() +{ + fprintf(stderr, + "Usage: %s [-d] [-v] [-h]\n" + " -d enable debugging.\n" + " -v enable verbose NTLM packet debugging.\n" + " -h this message\n\n", + my_program_name); +} + + +void +process_options(int argc, char *argv[]) +{ + int opt, had_error = 0; + + opterr =0; + while (-1 != (opt = getopt(argc, argv, "hdv"))) { + switch (opt) { + case 'd': + debug_enabled = 1; + break; + case 'v': + debug_enabled = 1; + Negotiate_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); +} + +int +manage_request() +{ + char buf[BUFFER_SIZE]; + char helper_command[3]; + char *c, *decoded; + int plen, status; + int oversized = 0; + char * ErrorMessage; + static char cred[SSP_MAX_CRED_LEN+1]; + BOOL Done = FALSE; + +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) && Negotiate_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 ", 3) == 0) { /* refresh-request */ + /* 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; + } + /* Obtain server blob against SSPI */ + plen = (strlen(buf) - 3) * 3 / 4; /* we only need it here. Optimization */ + c = (char *) SSP_MakeNegotiateBlob(decoded, plen, &Done, &status, cred); + + if (status == SSP_OK) { + if (Done) { + lc(cred); /* let's lowercase them for our convenience */ + have_serverblob = 0; + Done = FALSE; + if (Negotiate_packet_debug_enabled) { + printf("AF %s %s\n",c,cred); + decoded = base64_decode(c); + debug("sending 'AF' %s to squid with data:\n", cred); + hex_dump(decoded, (strlen(c) * 3) / 4); + } else + SEND3("AF %s %s", c, cred); + } else { + if (Negotiate_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); + } else { + SEND2("TT %s", c); + } + have_serverblob = 1; + } + } else + helperfail("can't obtain server blob"); + return 1; + } + + if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */ + if (!have_serverblob) { + helperfail("invalid server blob"); + 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; + } + + /* check against SSPI */ + plen = (strlen(buf) - 3) * 3 / 4; /* we only need it here. Optimization */ + c = (char *) SSP_ValidateNegotiateCredentials(decoded, plen, &Done, &status, cred); + + if (status == SSP_ERROR) { +#if FAIL_DEBUG + fail_debug_enabled = 1; +#endif + 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; + } + + if (Done) { + lc(cred); /* let's lowercase them for our convenience */ + have_serverblob = 0; + Done = FALSE; + if (Negotiate_packet_debug_enabled) { + printf("AF %s %s\n",c,cred); + decoded = base64_decode(c); + debug("sending 'AF' %s to squid with data:\n", cred); + hex_dump(decoded, (strlen(c) * 3) / 4); + } else { + SEND3("AF %s %s", c, cred); + } + return 1; + } else { + if (Negotiate_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); + } else + SEND2("TT %s", c); + 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, NEGOTIATE_PACKAGE_NAME) == 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); +} Index: squid/helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/helpers/ntlm_auth/NTLMSSP-WIN32/Attic/libntlmssp.c,v retrieving revision 1.1.4.11 retrieving revision 1.1.4.11.2.1 diff -u -r1.1.4.11 -r1.1.4.11.2.1 --- squid/helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c 16 Sep 2005 07:57:13 -0000 1.1.4.11 +++ squid/helpers/ntlm_auth/NTLMSSP-WIN32/libntlmssp.c 22 Oct 2005 17:45:23 -0000 1.1.4.11.2.1 @@ -271,7 +271,7 @@ } else debug("checking local user\n"); - rv = SSP_ValidateCredentials(auth, auth_length, credentials); + rv = SSP_ValidateNTLMCredentials(auth, auth_length, credentials); debug("Login attempt had result %d\n", rv); Index: squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h =================================================================== RCS file: /cvsroot/squid-sf//squid/helpers/ntlm_auth/NTLMSSP-WIN32/Attic/ntlm.h,v retrieving revision 1.1.4.9 retrieving revision 1.1.4.9.2.1 diff -u -r1.1.4.9 -r1.1.4.9.2.1 --- squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h 16 Sep 2005 07:57:13 -0000 1.1.4.9 +++ squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm.h 22 Oct 2005 17:45:23 -0000 1.1.4.9.2.1 @@ -40,7 +40,7 @@ #include extern int debug_enabled; -#ifdef FAIL_DEBUG +#if FAIL_DEBUG extern int fail_debug_enabled; #endif @@ -65,14 +65,18 @@ { #ifdef DEBUG #ifdef _SQUID_MSWIN_ +#if FAIL_DEBUG if (debug_enabled || fail_debug_enabled) { +#else + if (debug_enabled) { +#endif va_list args; va_start(args,format); fprintf(stderr, "ntlm-auth[%d]: ",getpid()); vfprintf(stderr, format, args); va_end(args); -#ifdef FAIL_DEBUG +#if FAIL_DEBUG fail_debug_enabled = 0; #endif } Index: squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/helpers/ntlm_auth/NTLMSSP-WIN32/Attic/ntlm_auth.c,v retrieving revision 1.1.4.20 retrieving revision 1.1.4.20.2.1 diff -u -r1.1.4.20 -r1.1.4.20.2.1 --- squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c 16 Sep 2005 07:57:13 -0000 1.1.4.20 +++ squid/helpers/ntlm_auth/NTLMSSP-WIN32/ntlm_auth.c 22 Oct 2005 17:45:23 -0000 1.1.4.20.2.1 @@ -76,7 +76,7 @@ char * NTDisAllowedGroup; int UseDisallowedGroup = 0; int UseAllowedGroup = 0; -#ifdef FAIL_DEBUG +#if FAIL_DEBUG int fail_debug_enabled = 0; #endif @@ -105,7 +105,7 @@ void helperfail(const char *reason) { -#ifdef FAIL_DEBUG +#if FAIL_DEBUG fail_debug_enabled =1; #endif SEND2("BH %s", reason); @@ -342,7 +342,7 @@ cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen); have_challenge = 0; if (cred == NULL) { -#ifdef FAIL_DEBUG +#if FAIL_DEBUG fail_debug_enabled =1; #endif switch (ntlm_errno) { @@ -402,7 +402,7 @@ debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name); - if (LoadSecurityDll(SSP_NTLM) == NULL) { + if (LoadSecurityDll(SSP_NTLM, NTLM_PACKAGE_NAME) == NULL) { fprintf(stderr, "FATAL, can't initialize SSPI, exiting.\n"); exit(1); } Index: squid/include/sspwin32.h =================================================================== RCS file: /cvsroot/squid-sf//squid/include/sspwin32.h,v retrieving revision 1.1.4.4 retrieving revision 1.1.4.4.2.1 diff -u -r1.1.4.4 -r1.1.4.4.2.1 --- squid/include/sspwin32.h 30 Nov 2003 11:44:38 -0000 1.1.4.4 +++ squid/include/sspwin32.h 22 Oct 2005 17:47:59 -0000 1.1.4.4.2.1 @@ -19,6 +19,7 @@ #define _LIBSSPWIN32_H_ #define SECURITY_WIN32 #define NTLM_PACKAGE_NAME "NTLM" +#define NEGOTIATE_PACKAGE_NAME "Negotiate" #ifdef _SQUID_CYGWIN_ #include @@ -30,17 +31,28 @@ #include #include +typedef char * SSP_blobP; + #define WINNT_SECURITY_DLL "security.dll" #define WIN2K_SECURITY_DLL "secur32.dll" #define SSP_BASIC 1 #define SSP_NTLM 2 -HMODULE LoadSecurityDll(int); +#define SSP_MAX_CRED_LEN 848 + +#define SSP_DEBUG 1 + +#define SSP_OK 1 +#define SSP_ERROR 2 + +HMODULE LoadSecurityDll(int, char *); void UnloadSecurityDll(void); BOOL WINAPI SSP_LogonUser(PTSTR, PTSTR, PTSTR); -BOOL WINAPI SSP_ValidateCredentials(PVOID, int, char *); +BOOL WINAPI SSP_ValidateNTLMCredentials(PVOID, int, char *); +const char * WINAPI SSP_ValidateNegotiateCredentials(PVOID, int, PBOOL, int *, char *); const char * WINAPI SSP_MakeChallenge(PVOID, int); +const char * WINAPI SSP_MakeNegotiateBlob(PVOID, int, PBOOL, int *, char *); extern BOOL Use_Unicode; extern BOOL NTLM_LocalCall; Index: squid/lib/sspwin32.c =================================================================== RCS file: /cvsroot/squid-sf//squid/lib/sspwin32.c,v retrieving revision 1.1.4.7 retrieving revision 1.1.4.7.2.1 diff -u -r1.1.4.7 -r1.1.4.7.2.1 --- squid/lib/sspwin32.c 30 Nov 2003 11:44:38 -0000 1.1.4.7 +++ squid/lib/sspwin32.c 22 Oct 2005 17:47:44 -0000 1.1.4.7.2.1 @@ -31,6 +31,7 @@ static HMODULE hModule; static int NTLM_mode = SSP_BASIC; +static char * SSP_Package_InUse; SECURITY_STATUS SecurityStatus = SEC_E_OK; static DWORD cbMaxToken = 0; @@ -67,6 +68,7 @@ if (hModule) FreeLibrary(hModule); + xfree(SSP_Package_InUse); xfree(pClientBuf); xfree(pServerBuf); @@ -84,7 +86,7 @@ } -HMODULE LoadSecurityDll(int mode) +HMODULE LoadSecurityDll(int mode, char * SSP_Package) { TCHAR lpszDLL[MAX_PATH]; OSVERSIONINFO VerInfo; @@ -199,13 +201,14 @@ } /* Get max token size */ - _QuerySecurityPackageInfo(_T("NTLM"), &pSPI); + _QuerySecurityPackageInfo(_T(SSP_Package), &pSPI); cbMaxToken = pSPI->cbMaxToken; _FreeContextBuffer(pSPI); /* Allocate buffers for client and server messages */ pClientBuf = xcalloc(cbMaxToken, sizeof(char)); pServerBuf = xcalloc(cbMaxToken, sizeof(char)); + SSP_Package_InUse = xstrdup(SSP_Package); return hModule; } @@ -232,7 +235,7 @@ ULONG fContextAttr; if (!pAS->fInitialized) { - SecurityStatus = _AcquireCredentialsHandle(NULL, _T(NTLM_PACKAGE_NAME), + SecurityStatus = _AcquireCredentialsHandle(NULL, _T(SSP_Package_InUse), SECPKG_CRED_OUTBOUND, NULL, (NTLM_mode == SSP_NTLM) ? NULL : pAuthIdentity, NULL, NULL, &pAS->hcred, &tsExpiry); if (SecurityStatus < 0) @@ -303,11 +306,18 @@ SecPkgContext_Names namebuffer; if (!pAS->fInitialized) { - SecurityStatus = _AcquireCredentialsHandle(NULL, _T("NTLM"), + SecurityStatus = _AcquireCredentialsHandle(NULL, _T(SSP_Package_InUse), SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &pAS->hcred, &pAS->hcredLifeTime); - if (SecurityStatus < 0) +#if SSP_DEBUG + fprintf(stderr, "AcquireCredentialsHandle returned: %x\n", SecurityStatus); +#endif + if (SecurityStatus < 0) { +#if SSP_DEBUG + fprintf(stderr, "AcquireCredentialsHandle failed: %x\n", SecurityStatus); +#endif return FALSE; + } pAS->fHaveCredHandle = TRUE; } @@ -330,28 +340,50 @@ pAS->fInitialized ? &pAS->hctxt : NULL, &sbdIn, (NTLM_mode == SSP_NTLM) ? ASC_REQ_DELEGATE : 0, SECURITY_NATIVE_DREP, &pAS->hctxt, &sbdOut, &fContextAttr, &pAS->hctxtLifeTime); - if (SecurityStatus < 0) +#if SSP_DEBUG + fprintf(stderr, "AcceptSecurityContext returned: %x\n", SecurityStatus); +#endif + if (SecurityStatus < 0) { +#if SSP_DEBUG + fprintf(stderr, "AcceptSecurityContext failed: %x\n", SecurityStatus); +#endif return FALSE; + } pAS->fHaveCtxtHandle = TRUE; /* If necessary, complete token */ if (SecurityStatus == SEC_I_COMPLETE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE) { SecurityStatus = _CompleteAuthToken(&pAS->hctxt, &sbdOut); - if (SecurityStatus < 0) +#if SSP_DEBUG + fprintf(stderr, "CompleteAuthToken returned: %x\n", SecurityStatus); +#endif + if (SecurityStatus < 0) { +#if SSP_DEBUG + fprintf(stderr, "CompleteAuthToken failed: %x\n", SecurityStatus); +#endif return FALSE; + } } - if (credentials != NULL) { - SecurityStatus = _QueryContextAttributes(&pAS->hctxt, SECPKG_ATTR_NAMES, &namebuffer); - if (SecurityStatus < 0) + if ((credentials != NULL) && + !(SecurityStatus == SEC_I_CONTINUE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE)) { + SecurityStatus = _QueryContextAttributes(&pAS->hctxt, SECPKG_ATTR_NAMES, &namebuffer); +#if SSP_DEBUG + fprintf(stderr, "QueryContextAttributes returned: %x\n", SecurityStatus); +#endif + if (SecurityStatus < 0) { +#if SSP_DEBUG + fprintf(stderr, "QueryContextAttributes failed: %x\n", SecurityStatus); +#endif return FALSE; - strcpy(credentials, namebuffer.sUserName); + } + strncpy(credentials, namebuffer.sUserName, SSP_MAX_CRED_LEN); } *pcbOut = sbOut.cbBuffer; if (!pAS->fInitialized) pAS->fInitialized = TRUE; - *pfDone = !(SecurityStatus = SEC_I_CONTINUE_NEEDED + *pfDone = !(SecurityStatus == SEC_I_CONTINUE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE); return TRUE; } @@ -474,7 +506,7 @@ } -BOOL WINAPI SSP_ValidateCredentials(PVOID PAutenticateBuf, int AutenticateLen, char * credentials) +BOOL WINAPI SSP_ValidateNTLMCredentials(PVOID PAutenticateBuf, int AutenticateLen, char * credentials) { BOOL fDone = FALSE; BOOL fResult = FALSE; @@ -498,3 +530,65 @@ return fResult; } + + +const char * WINAPI SSP_MakeNegotiateBlob(PVOID PNegotiateBuf, int NegotiateLen, PBOOL fDone, int * Status, char * credentials) +{ + DWORD cbOut = 0; + DWORD cbIn = 0; + const char * encoded = NULL; + + if (NTLM_asServer.fHaveCtxtHandle) + _DeleteSecurityContext(&NTLM_asServer.hctxt); + if (NTLM_asServer.fHaveCredHandle) + _FreeCredentialsHandle(&NTLM_asServer.hcred); + + memcpy(pClientBuf, PNegotiateBuf, NegotiateLen); + ZeroMemory(pServerBuf, cbMaxToken); + ZeroMemory(&NTLM_asServer, sizeof(NTLM_asServer)); + do { + if (!hModule) + break; + + /* Prepare server message (challenge) */ + cbIn = NegotiateLen; + cbOut = cbMaxToken; + if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut, + fDone, credentials)) { + *Status = SSP_ERROR; + break; + } + *Status = SSP_OK; + } while(0); + if (pServerBuf != NULL && cbOut > 0) + encoded = base64_encode_bin((char *) pServerBuf, cbOut); + return encoded; +} + + +const char * WINAPI SSP_ValidateNegotiateCredentials(PVOID PAutenticateBuf, int AutenticateLen, PBOOL fDone, int * Status, char * credentials) +{ + DWORD cbOut = 0; + DWORD cbIn = 0; + const char * encoded = NULL; + + memcpy(pClientBuf, PAutenticateBuf, AutenticateLen); + ZeroMemory(pServerBuf, cbMaxToken); + do { + if (!hModule) + break; + + /* Prepare server message (authentication) */ + cbIn = AutenticateLen; + cbOut = cbMaxToken; + if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut, + fDone, credentials)) { + *Status = SSP_ERROR; + break; + } + *Status = SSP_OK; + } while(0); + if (pServerBuf != NULL && cbOut > 0) + encoded = base64_encode_bin((char *) pServerBuf, cbOut); + return encoded; +}