--------------------- PatchSet 3354 Date: 2001/11/21 21:54:31 Author: kinkie Branch: ntlm Tag: (none) Log: First added. This is a winbindd-based NTLM authenticator. It requires a working winbindd (from samba) setup. Members: src/auth/ntlm/helpers/winbind/Makefile.am:1.1->1.1.2.1 src/auth/ntlm/helpers/winbind/wb_ntlm_auth.c:1.1->1.1.2.1 src/auth/ntlm/helpers/winbind/wbntlm.h:1.1->1.1.2.1 --- /dev/null Wed Feb 14 00:55:47 2007 +++ squid/src/auth/ntlm/helpers/winbind/Makefile.am Wed Feb 14 00:56:33 2007 @@ -0,0 +1,11 @@ +# +# Makefile for the Squid Object Cache server +# +# $Id: Makefile.am,v 1.1.2.1 2001/11/21 21:54:31 kinkie Exp $ +# + +libexec_PROGRAMS = wb_ntlmauth +winbindd_ntlmauth_SOURCES = wb_ntlm_auth.c +INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/src +DEFS = -DMYFILE=$@ --- /dev/null Wed Feb 14 00:55:47 2007 +++ squid/src/auth/ntlm/helpers/winbind/wb_ntlm_auth.c Wed Feb 14 00:56:33 2007 @@ -0,0 +1,195 @@ +/* + * (C) 2000 Francesco Chemolli + * 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. + * + */ + + +#include "wbntlm.h" +#include "util.h" +/* stdio.h is included in wbntlm.h */ +#include +#include +#include +#include /* for gettimeofday */ +#include /* BUG: is this portable? */ + + + +static tristate have_urandom = DONTKNOW; +FILE *urandom_file=NULL; + +void init_random() { + if (have_urandom == DONTKNOW) { + int result=0; + struct stat st; + result=stat(ENTROPY_SOURCE,&st); + if (result != 0 || ! (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { + debug("Entropy source " ENTROPY_SOURCE " is unavailable\n"); + have_urandom=NO; + } + if ((urandom_file = fopen(ENTROPY_SOURCE,"r")) == NULL) { + unsigned int seed; + struct timeval t; + unsigned long garbage; /* intentionally not initialized */ + warn("Can't open entropy source " ENTROPY_SOURCE "\n"); + have_urandom=NO; + gettimeofday(&t,NULL); + seed=getpid()*t.tv_sec*t.tv_usec-garbage; + squid_srandom(seed); + } else { + have_urandom=YES; + } + } +} + +static unsigned char challenge[CHALLENGE_LEN+1]; +static char *build_challenge(void) { + size_t gotchars; + unsigned char rd,j; + switch (have_urandom) { + case YES: + if ((gotchars=fread(&challenge,CHALLENGE_LEN,1,urandom_file))==0) { + /* couldn't get a challenge. Fall back to random() and friends. + notice that even a single changed byte is good enough for us */ + have_urandom=NO; + return build_challenge(); + } + return challenge; + case NO: + for (j=0;jdomain); + if (tmp.str == NULL || tmp.l == 0) { /* no domain supplied */ + SEND("NA No domain supplied"); + return; + } + memcpy(domuser, tmp.str, tmp.l); + domuser[l]='\\'; + offset=l+1; + + /* username */ + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->user); + if (tmp.str == NULL || tmp.l == 0) { + SEND("NA No username in request"); + return; + } + memcpy(domuser+offset,tmp.str,tmp.l); + domuser[offset+tmp.l]='\0'; + + /* now the LM hash */ + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->lmresponse); + if (tmp.str == NULL || tmp.l == 0) { + SEND("NA No lm hash"); + return NULL; + } + memcpy(lmhash,tmp.str,tmp.l); + lmhash[tmp.l]='\0'; + + tmp = ntlm_fetch_string((char *) auth, auth_length, &auth->ntresponse); + if (tmp.str == NULL || tmp.l == 0) + have_nt_hash=0; + else { + have_nt_hash=1; + memcpy(nthash,tmp.str,tmp.l); + nthash[tmp.l]='\0'; + } + /* I'm here. */ + +} + +void manage_request(void) { + char buf[BUFFER_SIZE+1]; + char *c, *decoded; + + if (fgets(buf, BUFFER_SIZE, stdin) == NULL) { + warn("fgets() failed! dying..... errno=%d (%s)\n", errno, + strerror(errno)); + exit(1); /* BIIG buffer */ + } + c=memchr(buf,'\n',BUFFER_SIZE); + if (c) + *c='\0'; + else + warn("No newline in '%s'. Dying.\n",buf); + + debug("Got '%s' from squid.\n",buf); + if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */ + SEND2("TT %s",ntlm_make_challenge(DOMAIN,NULL,build_challenge(), + CHALLENGE_LEN)); + return; + } + if (memcmp(buf,"KK ",3) != 0 ) { /* not an auth-request */ + SEND("BH squid-client protocol error"); + warn("Illegal request received\n"); + } + /* At this point I'm sure it's a KK */ + decoded=base64_decode(buf+3); + if (!decoded) { /* decoding failure, return error */ + SEND("NA Packet format error, couldn't base64-decode"); + return; + } + 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; + } + /* Understand what we got */ + switch (fast_header->type) { + case NTLM_NEGOTIATE: + SEND("NA Invalid negotiation request received"); + return; + case NTLM_CHALLENGE: + SEND("NA Got a challenge. We refuse to have our authority disputed"); + return; + case NTLM_AUTHENTICATE: + do_authenticate((ntlm_authenticate *) decoded, (strlen(buf)-3)*3/4); + return; + default: + SEND("BH unknown authentication packet type"); + return; + } + /* Ok. We're authenticating. */ + + +} + +int main (int argc, char ** argv) { + debug("ntlm winbindd auth helper build " __DATE__ ", " __TIME__ + " starting up...\n"); + /* initialize FDescs */ + setbuf(stdout, NULL); + setbuf(stderr, NULL); + init_random(); + while(1) { + manage_request(); + } + return 0; +} --- /dev/null Wed Feb 14 00:55:47 2007 +++ squid/src/auth/ntlm/helpers/winbind/wbntlm.h Wed Feb 14 00:56:33 2007 @@ -0,0 +1,94 @@ +/* + * (C) 2000 Francesco Chemolli , + * inspired by previous work by 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 _WBNTLM_H_ +#define _WBNTLM_H_ + +#include "config.h" +#include "ntlmauth.h" +#include +#include +#include + + +/*************** CONFIGURATION ***************/ +#ifndef DEBUG +#define DEBUG +#endif + +/* the attempted entropy source. If it doesn't exist, random() is uesed */ +#define ENTROPY_SOURCE "/dev/urandom" + +#define DOMAIN "GCSINT" /* TODO: fix ntlm_make_challenge */ + +/************* END CONFIGURATION *************/ + +#include + +/* Debugging stuff */ + +#ifndef MYFILE +#define MYFILE __FILE__ +#endif + +#ifdef __GNUC__ /* this is really a gcc-ism */ +static char *__foo; +#define warn(X...) fprintf(stderr,"ntlm-auth[%d](%s:%d): ", getpid(), \ + ((__foo=strrchr(MYFILE,'/'))==NULL?MYFILE:__foo+1),\ + __LINE__);\ + fprintf(stderr,X) +#ifdef DEBUG +#include +#include +extern char debug_enabled; +#define debug(X...) if(debug_enabled) warn(X) +#else /* DEBUG */ +#define debug(X...) /* */ +#endif /* DEBUG */ +#else /* __GNUC__ */ +static void +debug(char *format,...) +{ +} +static void +warn(char *format,...) +{ +} +#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 printf +#endif + +typedef enum { + YES, + NO, + DONTKNOW +} tristate; + +#define CHALLENGE_LEN 8 +#define BUFFER_SIZE 1010 + +#endif /* _WBNTLM_H_ */