--------------------- PatchSet 509 Date: 2000/08/08 13:16:56 Author: kinkie Branch: ntlm Tag: (none) Log: Added some prototypes so the compiler will stop complaining. Removed some leftover code. Commented some low-level debugging out. More sanity checks when retrieving values out of the payload. Completed the initialization of the ntlmssp struct. Avoided some memory leaks in the ntlmssp struct dealloaction. Added NTLMSSP flags management. Re-added some negotiated protocols on the SMB side. Removed MOD_NTLM stuff, it's bungled anyways. Members: ntlm_auth_modules/NTLMSSP/libntlmssp.c:1.1.2.3->1.1.2.4 Index: squid/ntlm_auth_modules/NTLMSSP/libntlmssp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/ntlm_auth_modules/NTLMSSP/Attic/libntlmssp.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- squid/ntlm_auth_modules/NTLMSSP/libntlmssp.c 6 Aug 2000 01:17:36 -0000 1.1.2.3 +++ squid/ntlm_auth_modules/NTLMSSP/libntlmssp.c 8 Aug 2000 13:16:56 -0000 1.1.2.4 @@ -18,10 +18,6 @@ #include "util.h" /* from Squid */ #include "valid.h" -#ifndef OLD -#include "smblib-priv.h" /* from samba */ -#endif - #if HAVE_STRING_H #include #endif @@ -31,6 +27,17 @@ static ntlmssp *model; +#include "smblib-priv.h" /* for SMB_Handle_Type */ + +/* a few forward-declarations. Hackish, but I don't care right now */ +SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, + char *server, char *NTdomain); +int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle); +int SMB_Negotiate(void *Con_Handle, char *Prots[]); +int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, + char *PassWord, int precrypted); + + #define lstring_zero(s) s.str=NULL; s.l=-1; /* instantiates an empty ntlmssp, with fields initalized to 0/NULL @@ -39,7 +46,7 @@ */ ntlmssp * create_ntlmssp () { ntlmssp *rv; - debug("create_ntlmssp: entering\n"); +/* debug("create_ntlmssp: entering\n"); */ if (!model) { debug("create_ntlmssp: building model\n"); model=malloc(sizeof(ntlmssp)); @@ -53,8 +60,11 @@ lstring_zero(model->workstation); lstring_zero(model->user); lstring_zero(model->sessionkey); + lstring_zero(model->challenge); + lstring_zero(model->target); lstring_zero(model->lm); lstring_zero(model->nt); + } rv=malloc(sizeof(ntlmssp)); if (!rv) { @@ -65,15 +75,65 @@ return rv; } +#ifdef debug +void debug_dump_ntlmssp(ntlmssp *n) { + fprintf(stderr,"Request type %d\n",n->type); + fprintf(stderr,"\tflags: %s%s%s%s%s%s%s%s%s%s%s%s%s\n", + (n->flags&NEGOTIATE_UNICODE?"Unicode ":""), + (n->flags&NEGOTIATE_ASCII?"ASCII ":""), + (n->flags&NEGOTIATE_REQUEST_TARGET?"ReqTgt ":""), + (n->flags&NEGOTIATE_REQUEST_SIGN?"ReqSign ":""), + (n->flags&NEGOTIATE_REQUEST_SEAL?"ReqSeal ":""), + (n->flags&NEGOTIATE_DATAGRAM_STYLE?"Dgram ":""), + (n->flags&NEGOTIATE_USE_LM?"UseLM ":""), + (n->flags&NEGOTIATE_USE_NETWARE?"UseNW ":""), + (n->flags&NEGOTIATE_USE_NTLM?"UseNTLM ":""), + (n->flags&NEGOTIATE_DOMAIN_SUPPLIED?"HaveDomain ":""), + (n->flags&NEGOTIATE_WORKSTATION_SUPPLIED?"HaveWKS ":""), + (n->flags&NEGOTIATE_THIS_IS_LOCAL_CALL?"LocalCall ":""), + (n->flags&NEGOTIATE_ALWAYS_SIGN?"AlwaysSign ":"") + ); + fprintf(stderr,"\textra flags: Target is %s%s%s, Sesskey %s%s%s\n", + (n->flags&CHALLENGE_TARGET_IS_DOMAIN?"domain ":""), + (n->flags&CHALLENGE_TARGET_IS_SERVER?"server ":""), + (n->flags&CHALLENGE_TARGET_IS_SHARE?"share ":""), + (n->flags&REQUEST_INIT_RESPONSE?"init ":""), + (n->flags&REQUEST_ACCEPT_RESPONSE?"accept ":""), + (n->flags&REQUEST_NON_NT_SESSION_KEY?"non_nt ":"") + ); + if (n->domain.l>=0) + fprintf(stderr,"\tdomain: '%s'\n",n->domain.str); /* what about unicode? */ + if (n->workstation.l>=0) + fprintf(stderr,"\tworkstation:'%s'\n",n->workstation.str); + if (n->user.l>=0) + fprintf(stderr,"\tuser: '%s'\n",n->user.str); + if (n->sessionkey.l>=0) + fprintf(stderr,"\tsessionkey: '%s'\n",n->sessionkey.str); + if (n->challenge.l >= 0) + fprintf(stderr,"\tchallenge: '%s'\n",n->challenge.str); + if (n->target.l >= 0) + fprintf(stderr,"\ttarget: '%s'\n",n->target.str); + if (n->lm.l>=0) + fprintf(stderr,"\tntlm-auth: '%s'\n",n->lm.str); + if (n->nt.l>=0) + fprintf(stderr,"\tntnt-auth: '%s'\n",n->nt.str); +} +#else +#define debug_dump_ntlmssp(X) /**/ +#endif + +#define drop_lstring(X) if(X.l >= 0) free(X.str); /* Frees the ntlmssp and all it references. */ void drop_ntlmssp(ntlmssp *nt) { - debug("dropping ntlmssp\n"); - if (nt->domain.str) free(nt->domain.str); - if (nt->workstation.str) free(nt->workstation.str); - if (nt->user.str) free(nt->user.str); - if (nt->sessionkey.str) free(nt->sessionkey.str); - if (nt->lm.str) free(nt->lm.str); - if (nt->nt.str) free(nt->nt.str); +/* debug("dropping ntlmssp\n"); */ + drop_lstring(nt->domain); + drop_lstring(nt->workstation); + drop_lstring(nt->user); + drop_lstring(nt->sessionkey); + drop_lstring(nt->challenge); + drop_lstring(nt->target); + drop_lstring(nt->lm); + drop_lstring(nt->nt); free(nt); } @@ -87,9 +147,9 @@ l = SSWAP(str->len); o = WSWAP(str->offset); - debug("fetch_string(l=%d,o=%d)\n",l,o); +/* debug("fetch_string(l=%d,o=%d)\n",l,o); */ - if (l < 0 || l > MAX_FIELD_LENGTH || o+l > length) { + if (l < 0 || l > MAX_FIELD_LENGTH || o+l > length || o==0) { debug("ntlmssp: insane data (l: %d, o: %d)\n", l,o); rv.l=-1; rv.str=NULL; @@ -99,11 +159,11 @@ rv.l=l; rv.str=malloc(l+1); memcpy(rv.str,packet+o,l); -/* FIXME: what if the response has \0 in it ? */ + /* FIXME: what if the response has \0 in it ? */ - rv.str[l]='\0'; /* add a dummy just in case, it shouldn't */ -/* be needed anyways. */ - debug("fetch_string got '%s'\n",rv.str); + rv.str[l]='\0'; + /* add a dummy just in case, it shouldn't be needed anyways. */ +/* debug("fetch_string got '%s'\n",rv.str); */ return rv; } @@ -144,20 +204,17 @@ rv->domain=fetch_string(decoded,length,&n->domain); rv->workstation=fetch_string(decoded,length,&n->workstation); rv->flags=n->flags; - debug("decode_ntlmssp_auth: negotiation request\n\tdomain: '%s'\n" - "\tworkstation: '%s'\n\tflags: %d\n",rv->domain.str, - rv->workstation.str, rv->flags); + debug_dump_ntlmssp(rv); break; case NTLM_CHALLENGE: c=(struct ntlm_challenge *) decoded; -// rv->target=fetch_string(decoded,length,&c->target); + rv->target=fetch_string(decoded,length,&c->target); rv->flags=c->flags; rv->challenge.str=malloc(9); /* 8+1 */ rv->challenge.l=8; memcpy(rv->challenge.str,&c->challenge,8); rv->challenge.str[8]='\0'; - debug("decode_ntlmssp_auth: challenge header\n\ttarget: '%s'\n" - "\tchallenge: '%s'\n\tflags: %d\n",rv->target.str,rv->challenge.str,rv->flags); + debug_dump_ntlmssp(rv); break; case NTLM_AUTHENTICATE: a=(struct ntlm_authenticate *) decoded; @@ -168,12 +225,7 @@ rv->workstation=fetch_string(decoded,length,&a->workstation); rv->sessionkey=fetch_string(decoded,length,&a->sessionkey); rv->flags=a->flags; - debug("decode_ntlmssp_auth: authentication request\n" - "\tlmresponse: '%s'\n\tntresponse: '%s'\n\tdomain: '%s'\n" - "\tuser: '%s'\n\tworkstation: '%s'\n\tsession key: '%s'\n" - "\tflags: %d\n", - rv->lm.str, rv->nt.str, rv->domain.str, rv->user.str, - rv->workstation.str, rv->sessionkey.str,rv->flags); + debug_dump_ntlmssp(rv); break; default: drop_ntlmssp(rv); @@ -201,26 +253,19 @@ static char challenge[8]; -#ifdef OLD -static void *handle=NULL; - -/* connects if necessary. Returns the handle (or NULL if - the connection failed) */ -static void* init_challenge() { - if (handle!=NULL) - return handle; - handle=NTLM_Connect("supervisor","tlc1","GCSINT",challenge); - return (handle!=NULL); -} -#else /* OLD */ SMB_Handle_Type handle=NULL; /* returns 0 on success, > 0 on failure */ static int init_challenge() { char *SMB_Prots[] = { + "PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", "LANMAN1.0", "LM1.2X002", "Samba", + "NT LM 0.12", + "NT LANMAN 1.0", NULL}; if (handle==NULL) /* we are not connected */ handle=SMB_Connect_Server(NULL,DOMAIN_CONTROLLER,NTLM_DOMAIN); @@ -245,8 +290,6 @@ return 0; } -#endif /* OLD */ - /* FIX a lot of stuff, like checks for memory etc. */ char* make_challenge(ntlmssp * negotiate) { struct ntlm_challenge ch; @@ -257,30 +300,20 @@ memset(&ch, 0, sizeof(struct ntlm_challenge)); memcpy(ch.hdr.signature, "NTLMSSP", 8); ch.hdr.type = WSWAP(NTLM_CHALLENGE); -#ifdef USE_MOD_NTLM_STUFF - ch.flags = WSWAP(0x8201); - ch.len=WSWAP(sizeof(struct ntlm_challenge)); -// ch.target.len=strlen(NTLM_DOMAIN); /*magic number time */ -// ch.target.maxlen=ch.target.len; -// add_to_payload(ch.pad,&pl,&ch.target,NTLM_DOMAIN,strlen(NTLM_DOMAIN),48); - -#else /* use previous squid conventions. */ add_to_payload(ch.pad,&pl,&ch.target,NTLM_DOMAIN,strlen(NTLM_DOMAIN), NTLM_CHALLENGE_HEADER_OFFSET); - ch.flags=WSWAP(0x18206); - ch.unknown[6] = SSWAP(0x003a); -#endif -//#ifdef USE_STATIC_CHALLENGE -// memcpy(ch.challenge,NTLM_STATIC_CHALLENGE,8); -//#else + ch.flags=WSWAP( + REQUEST_NON_NT_SESSION_KEY | + CHALLENGE_TARGET_IS_DOMAIN | + NEGOTIATE_ALWAYS_SIGN | + NEGOTIATE_USE_NTLM | NEGOTIATE_USE_LM | + NEGOTIATE_ASCII | + 0 + ); + ch.context_low=0; /* check this out */ + ch.context_high=0; memcpy(ch.challenge,challenge,8); -//#endif - debug("preflags :%d\n",ch.flags); - if(ch.flags & FLAGS_UNICODE){ - debug("Unicode challenge\n"); - ch.flags=(ch.flags & (~FLAGS_UNICODE)) | FLAGS_ASCII; /*clear UNICODE, set ASCII*/ - } - debug("flags :%d\n",ch.flags); + debug("flags :%x\n",ch.flags); encoded=base64_encode_bin((char *)&ch,48+pl); /* we should copy the string to release the static * in base64_encode_bin). */ @@ -288,20 +321,16 @@ } /* FIXME: we're assuming that we are connected and haven't been dropped off */ +/* Returns 1 if OK, 0 if failure */ int ntlm_check_auth(ntlmssp *got) { int rv; - if (handle==NULL) /*if null we aren't connected*/ - if (init_challenge() > 0) - return NULL; + if (handle==NULL) /*if null we aren't connected*/ + if (init_challenge() > 0) + return 0; debug("ntlm_check_auth entered\n"); -#ifdef OLD - rv=NTLM_Auth(handle,got->user.str, - (got->nt.l==24?got->nt.str:got->lm.str),1); -#else debug("ntlm_check_auth: using %s challenge\n",(got->nt.l==24?"nt":"lm")); rv=SMB_Logon_Server(handle,got->user.str, (got->nt.l==24?got->nt.str:got->lm.str),1); -#endif debug("\tresult is %d\n",rv); return (rv==NTV_NO_ERROR); }