This patch is generated from the ntlm_smbpasswd branch of HEAD in squid Mon Jan 26 12:56:48 2004 GMT See http://devel.squid-cache.org/ Index: squid/configure.in diff -u squid/configure.in:1.48 squid/configure.in:1.47.2.2 --- squid/configure.in:1.48 Sat Mar 30 08:55:04 2002 +++ squid/configure.in Mon Apr 1 03:18:00 2002 @@ -2170,6 +2170,7 @@ src/auth/ntlm/helpers/no_check/Makefile \ src/auth/ntlm/helpers/NTLMSSP/Makefile \ src/auth/ntlm/helpers/NTLMSSP/smbval/Makefile \ + src/auth/ntlm/helpers/smbpasswd/Makefile \ contrib/Makefile \ snmplib/Makefile \ icons/Makefile \ Index: squid/src/auth/ntlm/auth_ntlm.c diff -u squid/src/auth/ntlm/auth_ntlm.c:1.19 squid/src/auth/ntlm/auth_ntlm.c:1.19.2.1 --- squid/src/auth/ntlm/auth_ntlm.c:1.19 Mon Feb 18 15:43:12 2002 +++ squid/src/auth/ntlm/auth_ntlm.c Tue Feb 26 03:37:41 2002 @@ -737,7 +737,7 @@ helperStatefulSubmit(ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, NULL); } else { /* Server with invalid challenge */ - snprintf(buf, 8192, "YR\n"); + snprintf(buf, 8192, "YR %s\n", sent_string); helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authserver); } } else { Index: squid/src/auth/ntlm/helpers/smbpasswd/Makefile.am diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/Makefile.am:1.1.2.1 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/Makefile.am Sat Feb 23 19:29:20 2002 @@ -0,0 +1,13 @@ +# +# Makefile for the Squid Object Cache server +# +# $Id: squid-ntlm_smbpasswd-HEAD,v 1.1 2004/08/17 20:55:13 hno Exp $ +# +# Uncomment and customize the following to suit your needs: +# + +libexec_PROGRAMS = ntlm_smbpasswd +ntlm_smbpasswd_SOURCES = ntlm_smbpasswd.c ntlm.c ntlm.h smbdes.c smbdes.h +INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/ +LDADD = -L$(top_builddir)/lib -lmiscutil $(CRYPTLIB) $(XTRA_LIBS) Index: squid/src/auth/ntlm/helpers/smbpasswd/README diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/README:1.1.2.2 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/README Sat Dec 7 10:21:33 2002 @@ -0,0 +1,7 @@ +README for ntlm_smbpasswd + +ntlm_smbpasswd is a NTLM helper to Squid, allowing you to perform +NTLM authentication to Samba like smbpasswd files. + +ntlm_smbpasswd is (C)2002 Henrik Nordstrom . It includes +components copyrighted by others. See respective source file for details. Index: squid/src/auth/ntlm/helpers/smbpasswd/ntlm.c diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/ntlm.c:1.1.2.5 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/ntlm.c Mon Apr 1 03:16:53 2002 @@ -0,0 +1,389 @@ +/* + * AUTHOR: Henrik Nordstrom + * + * Loosely based on fakeauth by Robert Collins + * + * NTLM authentication originally by ad@interlude.eu.org - 07/1999 + */ + +#include "config.h" +#include "squid_types.h" + +#include "ntlm.h" +#include "smbdes.h" +#include "util.h" + +#if HAVE_STDIO_H +#include +#endif +#if HAVE_STDLIB_H +#include +#endif +#if HAVE_STRING_H +#include +#endif + + +#define ERR "ERR\n" +#define OK "OK\n" + +static char *authenticate_ntlm_domain = "LIFELESSWKS"; + +/* + * Generates a challenge request. The randomness of the 8 byte + * challenge strings can be guarenteed to be poor at best. + * XXX FIX ME + */ +void +ntlmMakeChallenge(ntlm_challenge *chal) +{ + static unsigned hash; + int r; + char *d; + int i; + + memset(chal, 0, sizeof(*chal)); + memcpy(chal->hdr.signature, "NTLMSSP", 8); + chal->flags = WSWAP(0x00018206); + chal->hdr.type = WSWAP(NTLMSSP_CHALLENGE); + //chal->unknown[6] = SSWAP(0x003a); + + d = (char *) chal + 48; + i = 0; + + /* XXX WHAT ABOUT THIS?? */ + if (authenticate_ntlm_domain != NULL) + while (authenticate_ntlm_domain[i++]); + + chal->target.offset = WSWAP(48); + chal->target.maxlen = SSWAP(i); + chal->target.len = chal->target.maxlen; + + r = (int) rand(); + r = (hash ^ r) + r; + + for (i = 0; i < 8; i++) { + chal->challenge[i] = r; + r = (r >> 2) ^ r; + } + + hash = r; +} + +void ntlmNegotiateChallenge(const ntlm_negotiate *nego, ntlm_challenge *chal) +{ + int32_t flags = WSWAP(nego->flags); + ntlmMakeChallenge(chal); + flags &= ( + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_LM | + NTLMSSP_NEGOTIATE_NTLM | +#if 0 /* Documentation yet incomplete */ + NTLMSSP_NEGOTIATE_NTLM2 | +#endif + NTLMSSP_NEGOTIATE_ALWAYS_SIGN + ); + flags |= NTLMSSP_CHALLENGE_TARGET_IS_DOMAIN; + chal->flags = WSWAP(flags); +} + +#if 0 +/* + * Returns the length of a string + */ +static int +ntlmStringLength(strhdr *str) +{ + return SSWAP(str->len); +} +#endif + +/* + * Check the validity of a string. Return <0 on error. + */ +static int +ntlmCheckString(const ntlmhdr * hdr, const strhdr *str, size_t size) +{ + int offset = WSWAP(str->offset); + int len = SSWAP(str->len); + int maxlen = SSWAP(str->maxlen); + + if (len == 0) + return 0; + + if (offset < sizeof(ntlmhdr)) { + fprintf(stderr, "ntlmCheckString: too low offset\n"); + return -1; + } + if (offset > size || offset + len > size) { + /* both are required above to protect from integrer wrap */ + fprintf(stderr, "ntlmCheckString: too high offset\n"); + return -1; + } + if (len > maxlen) { + fprintf(stderr, "ntlmCheckString: too long\n"); + return -1; + } + if (offset + maxlen > size) { + fprintf(stderr, "ntlmCheckString: too big\n"); + return -1; + } + return 0; +} + +/* + * Check the validity of a fixed length string. Return <0 on error. + */ +static int +ntlmCheckStringLength(const ntlmhdr *hdr, const strhdr *str, size_t size, int len) +{ + if (SSWAP(str->len) && len != SSWAP(str->len)) { + fprintf(stderr, "ntlmCheckStringLength: invalid length %d (expected %d)\n", SSWAP(str->len), len); + return -1; + } + return ntlmCheckString(hdr, str, size); +} + +/* + * Check the vailidity of a request. Return <0 on error. + */ +int +ntlmCheckPacket(const ntlmhdr * hdr, int type, size_t size) +{ + /* + * Must be the correct security package and request type. The + * 8 bytes compared includes the ASCII 'NUL'. + */ + if (memcmp(hdr->signature, "NTLMSSP", 8) != 0) { + fprintf(stderr, "ntlmCheckHeader: bad header signature\n"); + return -1; + } + if (type != NTLMSSP_ANY && WSWAP(hdr->type) != type) { + fprintf(stderr, "ntlmCheckHeader: unexpected type %d (expected %d)\n", WSWAP(hdr->type), type); + return -1; + } + switch(WSWAP(hdr->type)) { + case NTLMSSP_NEGOTIATE: { + ntlm_negotiate * p = (ntlm_negotiate *) hdr; + uint32_t flags = WSWAP(p->flags); + if (flags & NTLMSSP_OEM_DOMAIN_SUPPLIED && ntlmCheckString(hdr, &p->domain, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed negotiate packet (domain)\n"); + return -1; + } + if (flags & NTLMSSP_OEM_WORKSTATION_SUPPLIED && ntlmCheckString(hdr, &p->workstation, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed negotiate packet (workstation)\n"); + return -1; + } + } break; + case NTLMSSP_CHALLENGE: { + ntlm_challenge *p = (ntlm_challenge *) hdr; + if (ntlmCheckString(hdr, &p->target, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed challenge packet (target)\n"); + return -1; + } + } break; + case NTLMSSP_AUTHENTICATE: { + ntlm_authenticate *p = (ntlm_authenticate *) hdr; + if (ntlmCheckStringLength(hdr, &p->lmresponse, size, 24) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (lmresponse)\n"); + return -1; + } + if (ntlmCheckStringLength(hdr, &p->ntresponse, size, 24) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (ntresponse)\n"); + return -1; + } + if (ntlmCheckString(hdr, &p->domain, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (domain)\n"); + return -1; + } + if (ntlmCheckString(hdr, &p->user, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (user)\n"); + return -1; + } + if (ntlmCheckString(hdr, &p->workstation, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (workstation)\n"); + return -1; + } +#if 0 + if (ntlmCheckString(hdr, &p->sessionkey, size) < 0) { + fprintf(stderr, "ntlmCheckHeader: malformed authenticate packet (sessionkey)\n"); + return -1; + } +#endif + } break; + } + return 0; +} + +/* + * Extract a string from an NTLM request and return as ASCII. + */ +unsigned char * +ntlmGetString(const ntlmhdr * hdr, const strhdr * str, uint32_t flags) +{ + static unsigned char buf[512]; + unsigned char *d; + int l, o; + + l = SSWAP(str->len); + o = WSWAP(str->offset); + + if (flags & NTLMSSP_NEGOTIATE_UNICODE) { + /* UNICODE string */ + u_short *s = (u_short *) ((char *) hdr + o); + d = buf; + l = l >> 1; /* 16 bit characters */ + + if (l > sizeof(buf) - 1) { + fprintf(stderr, "ntlmGetString: too large: %d\n", l); + return NULL; + } + while (l--) { + u_short c = SSWAP(*s++); + if (c > 254 || c == '\0' || c < 32) { + fprintf(stderr, "ntlmGetString: bad uni char: %04x\n", c); + return NULL; + } + *d++ = c; + } + *d = 0; + } else { + /* ASCII string */ + unsigned char *s = (unsigned char *) hdr + o; + d = buf; + + if (l > sizeof(buf) - 1) { + fprintf(stderr, "ntlmGetString: too large: %d\n", l); + return NULL; + } + for (; l; l--) { + unsigned char c = *s++; + if (c == '\0' || c < 32) { + fprintf(stderr, "ntlmGetString: bad ascii: %02x\n", c); + return (NULL); + } + *d++ = c; + } + + *d = 0; + } + + return (buf); +} + +/* + * Extract a binary string from an NTLM request + */ +static unsigned char * +ntlmGetBinary(const ntlmhdr * hdr, const strhdr * str, size_t *lenp) +{ + static unsigned char buf[512]; + unsigned char *d, *s; + int l, o; + + l = SSWAP(str->len); + o = WSWAP(str->offset); + + s = (unsigned char *) hdr + o; + d = buf; + + if (l > sizeof(buf)) { + fprintf(stderr, "ntlmGetBinary: too large: %d\n", l); + return NULL; + } + if (lenp) + *lenp = l; + while (l--) { + *d++ = *s++; + } + + return (buf); +} + +/* + * Return the full username including domain + */ +int +ntlmGetFullUserName(const ntlm_authenticate *auth, char *buf, size_t size) +{ + unsigned char *p; + int s; + uint32_t flags = WSWAP(auth->flags); /* XXX The flags field do not always exists */ + + if ((p = ntlmGetString(&auth->hdr, &auth->domain, flags)) == NULL) + p = authenticate_ntlm_domain; + if (!p) + return -1; + s = strlen(p); + if (s > size) + return -1; + strcpy(buf, p); + size -= s; + buf += s; + + if (!size) + return -1; + *buf++ = '\\'; /* Using \ is more consistent with MS-proxy */ + size--; + + p = ntlmGetString(&auth->hdr, &auth->user, flags); + if (!p) + return -1; + s = strlen(p); + if (s > size) + return -1; + while (*p) + *buf++ = *p++; + + *buf++ = '\0'; + size -= s; + + return 0; +} + +void +ntlmEncrypt(const unsigned char *pwhash, const unsigned char *key, unsigned char *out) +{ + unsigned char tmp[21]; + memset(tmp, 0, sizeof(tmp)); + memcpy(tmp, pwhash, 16); + E_P24(tmp, key, out); +} + +/* + * Verify that the password supplied by the user matches + */ +int ntlmCheckAuth(const ntlm_authenticate *auth, const ntlm_challenge *challenge, const unsigned char *lmhash, const unsigned char *nthash) +{ + if (nthash) { + unsigned char *ntresp = ntlmGetBinary(&auth->hdr, &auth->ntresponse, NULL); + if (ntresp) { + uint32_t flags = WSWAP(auth->flags); + if (flags & NTLMSSP_NEGOTIATE_NTLM2) { + unsigned char local_response[24]; + /* XXX This is not correct. Documentation is incomplete, + * but there is some magic with the lmhash here.. + */ + ntlmEncrypt(nthash, challenge->challenge, local_response); + if (memcmp(ntresp, local_response, 24) == 0) + return 0; + } else { + unsigned char local_response[24]; + ntlmEncrypt(nthash, challenge->challenge, local_response); + if (memcmp(ntresp, local_response, 24) == 0) + return 0; + } + } + } + if (lmhash) { + unsigned char *lmresp = ntlmGetBinary(&auth->hdr, &auth->lmresponse, NULL); + if (lmresp) { + unsigned char local_response[24]; + ntlmEncrypt(lmhash, challenge->challenge, local_response); + if (memcmp(lmresp, local_response, 24) == 0) + return 0; + } + } + return -1; +} + Index: squid/src/auth/ntlm/helpers/smbpasswd/ntlm.h diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/ntlm.h:1.1.2.4 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/ntlm.h Sat Dec 7 10:21:33 2002 @@ -0,0 +1,139 @@ +/* + * $Id: squid-ntlm_smbpasswd-HEAD,v 1.1 2004/08/17 20:55:13 hno Exp $ + * + * AUTHOR: Andrew Doran + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * 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. + * + */ + +#ifndef _NTLM_H_ +#define _NTLM_H_ + +#include + +/* All of this cruft is little endian */ +#ifdef WORDS_BIGENDIAN +#define SSWAP(x) (bswap16((x))) +#define WSWAP(x) (bswap32((x))) +#else +#define SSWAP(x) (x) +#define WSWAP(x) (x) +#endif + +/* NTLM request types that we know about */ +#define NTLMSSP_NEGOTIATE 1 +#define NTLMSSP_CHALLENGE 2 +#define NTLMSSP_AUTHENTICATE 3 +#define NTLMSSP_ANY 0 + +/* flags */ +#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 /* Text are in unicode */ +#define NTLMSSP_NEGOTIATE_OEM 0x00000002 /* Text are in OEM (???) */ +#define NTLMSSP_REQUEST_TARGET 0x00000004 /* Ask server to return its target/realm */ +#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* Request signature capability */ +#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* Request seal capability */ +#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040 +#define NTLMSSP_NEGOTIATE_LM 0x00000080 /* Client/Server supports LM key for sign/seal */ +#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 /* Client/Server supports Netware authentication (???) */ +#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 /* Client/Server supports NTLM */ +#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000 +#define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000 +#define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000 +#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 +#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 /* Client/Server supports NTLMv2 */ +#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 /* ??? */ +#define NTLMSSP_NEGOTIATE_128 0x20000000 /* ??? */ +#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 /* ??? */ + +/* challenge TargetName is a XXX */ +#define NTLMSSP_CHALLENGE_TARGET_IS_DOMAIN 0x00010000 /* TargetName is a domain name */ +#define NTLMSSP_CHALLENGE_TARGET_IS_SERVER 0x00020000 /* TargetName is a server name */ +#define NTLMSSP_CHALLENGE_TARGET_IS_SHARE 0x00040000 /* TargetName is a share name */ + +/* these NTLMSSP_are marked as "extra" fields */ +#define NTLMSSP_REQUEST_INIT_RESPONSE 0x00100000 /* request NT session key */ +#define NTLMSSP_REQUEST_ACCEPT_RESPONSE 0x00200000 /* request session key, LUID? */ +#define NTLMSSP_REQUEST_NON_NT_SESSION_KEY 0x00400000 /* request non-NT session key (LM?) */ + +/* This is an header common to all signatures, it's used to discriminate + * among the different signature types. */ +typedef struct { + char signature[8]; /* "NTLMSSP" */ + int32_t type; /* One of the NTLM_* types above. */ +} ntlmhdr; + +/* String header. String data resides at the end of the request */ +typedef struct _strhdr { + int16_t len; /* Length in bytes */ + int16_t maxlen; /* Allocated space in bytes */ + int32_t offset; /* Offset from start of request */ +} strhdr; + +/* Negotiation request sent by client */ +typedef struct { + ntlmhdr hdr; /* NTLM header */ + int32_t flags; /* Request flags */ + /* the rest is optional fields */ + strhdr domain; /* Domain we wish to authenticate in */ + strhdr workstation; /* Client workstation name */ + char pad[256]; /* String data */ +} ntlm_negotiate; + +/* Challenge request sent by server. */ +typedef struct { + ntlmhdr hdr; /* NTLM header */ + strhdr target; /* Authentication target (domain/server/share ...) */ + int32_t flags; /* Request flags */ + u_char challenge[8]; /* Challenge string */ + uint32_t ServerContextHandle[2]; /* Some sort of context data */ + strhdr unknown2; /* Some sort of context string data */ + char pad[256]; /* String data */ +} ntlm_challenge; + +/* Authentication request sent by client in response to challenge */ +typedef struct { + ntlmhdr hdr; /* NTLM header */ + strhdr lmresponse; /* LANMAN challenge response */ + strhdr ntresponse; /* NT challenge response */ + strhdr domain; /* Domain to authenticate against */ + strhdr user; /* Username */ + strhdr workstation; /* Workstation name */ + strhdr sessionkey; /* Session key for server's use */ + int32_t flags; /* Request flags */ + char pad[256 * 6]; /* String data */ +} ntlm_authenticate; + +unsigned char *ntlmGetString(const ntlmhdr * hdr, const strhdr * str, u_int32_t flags); +void ntlmMakeChallenge(ntlm_challenge *chal); +int ntlmCheckPacket(const ntlmhdr * hdr, int type, size_t len); +int ntlmGetFullUserName(const ntlm_authenticate *auth, char *buf, size_t size); +int ntlmCheckAuth(const ntlm_authenticate *auth, const ntlm_challenge *challenge, const unsigned char *lmhash, const unsigned char *nthash); +void ntlmNegotiateChallenge(const ntlm_negotiate *nego, ntlm_challenge *chal); +void ntlm2MakeResponse(const char *nthash, const char *user, const char *challenge, char *response); + +#endif /* _NTLM_H_ */ Index: squid/src/auth/ntlm/helpers/smbpasswd/ntlm_smbpasswd.c diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/ntlm_smbpasswd.c:1.1.2.6 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/ntlm_smbpasswd.c Mon Apr 1 03:16:53 2002 @@ -0,0 +1,133 @@ +/* + * AUTHOR: Henrik Nordstrom + * + * Loosely based on fakeauth by Robert Collins + */ + +#include "config.h" +#include "squid_types.h" + +#include "ntlm.h" +#include "util.h" +#include + +#if HAVE_STDIO_H +#include +#endif +#if HAVE_STDLIB_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_STRING_H +#include +#endif + +#define DEBUG(args...) fprintf(stderr, ## args) +#define WARN(args...) fprintf(stderr, ## args) + +#ifndef DEBUG +#define DEBUG(args...) +#endif + + +#ifdef DEBUG +#include +void send_result(const char *fmt, ...) +{ + char buf[8192]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + fprintf(stderr, buf); + printf(buf); +} +#else +#define send_result printf +#endif + +#define ERR "ERR\n" +#define OK "OK\n" + +/* test1234 */ +char lmhash[] = { 0x62, 0x4A, 0xAC, 0x41, 0x37, 0x95, 0xCD, 0xC1, 0xFF, 0x17, 0x36, 0x5F, 0xAF, 0x1F, 0xFE, 0x89 }; +//char nthash[] = { 0x3B, 0x1B, 0x47, 0xE4, 0x2E, 0x04, 0x63, 0x27, 0x6E, 0x3D, 0xED, 0x6C, 0xEF, 0x34, 0x9F, 0x93 }; + +/* topsecret */ +//char lmhash[] = { 0x3E, 0x67, 0x37, 0xD0, 0xC0, 0xDC, 0x52, 0x3B, 0x9A, 0x0F, 0x5D, 0x12, 0xD8, 0xF6, 0x12, 0xD0 }; +char nthash[] = { 0x7C, 0x45, 0x18, 0x51, 0xEA, 0x87, 0xB6, 0x3E, 0xC7, 0x69, 0x21, 0x26, 0x41, 0x6D, 0x01, 0xEB }; + +/* 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++; + } +} + +int +main(int argc, char **argv) +{ + char buf[8192]; + char user[256], *p; + ntlm_challenge chal; + int len; + char *data = NULL; + + setbuf(stdout, NULL); + while (fgets(buf, 8192, stdin) != NULL) { + if ((p = strchr(buf, '\n')) != NULL) + *p = '\0'; /* strip \n */ +#ifdef DEBUG + { + char *p2 = base64_decode("AAA"); + memset(p2, '!', 4096); + } +#endif + DEBUG("%s\n", buf); + if (strncasecmp(buf, "YR ", 3) == 0) { + ntlm_negotiate *nego = (ntlm_negotiate *) base64_decode(buf + 3); + len = strlen(buf + 3) * 3 / 4; /* approximation, in lack of base64_decode_bin */ + if (ntlmCheckPacket(&nego->hdr, NTLMSSP_NEGOTIATE, len) != 0) { + send_result("BH invalid NTLMSSP packet\n"); + continue; + } + ntlmNegotiateChallenge(nego, &chal); + len = (int)&((ntlm_challenge *)NULL)->pad + + SSWAP(chal.target.maxlen); + data = (char *) base64_encode_bin((char *) &chal, len); + send_result("TT %s\n", data); + } else if (strncasecmp(buf, "YR", 2) == 0) { + ntlmMakeChallenge(&chal); + len = (int)&((ntlm_challenge *)NULL)->pad + + SSWAP(chal.target.maxlen); + data = (char *) base64_encode_bin((char *) &chal, len); + send_result("TT %s\n", data); + } else if (strncasecmp(buf, "KK ", 3) == 0) { + ntlm_authenticate *auth = (ntlm_authenticate *) base64_decode(buf + 3); + len = strlen(buf + 3) * 3 / 4; /* approximation, in lack of base64_decode_bin */ + if (ntlmCheckPacket(&auth->hdr, NTLMSSP_AUTHENTICATE, len) != 0) { + send_result("BH invalid NTLMSSP packet\n"); + continue; + } + if (ntlmGetFullUserName(auth, user, 256) == 0) { + lc(user); + if (ntlmCheckAuth(auth, &chal, lmhash, nthash) == 0) { + send_result("AF %s\n", user); + } else { + send_result("NA invalid credentials\n"); + } + } else { + send_result("NA invalid username\n"); + } + } else { + WARN("ntlm_smbpass: Unknown input: %s\n", buf); + send_result("BH unknown packet format!\n"); + } + } + exit(0); +} Index: squid/src/auth/ntlm/helpers/smbpasswd/smbdes.c diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/smbdes.c:1.1.2.3 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/smbdes.c Mon Feb 25 05:46:32 2002 @@ -0,0 +1,311 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + + a partial implementation of DES designed for use in the + SMB authentication protocol + + Copyright (C) Andrew Tridgell 1998-2000 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) +*/ + + +#define uchar unsigned char + +static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4}; + +static uchar perm2[48] = {14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32}; + +static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7}; + +static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1}; + +static uchar perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25}; + + +static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25}; + + +static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + +static uchar sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; + +static void permute(char *out, char *in, uchar *p, int n) +{ + int i; + for (i=0;i>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } +} + + +static void smbhash(uchar *out, const uchar *in, const uchar *key, int forw) +{ + int i; + char outb[64]; + char inb[64]; + char keyb[64]; + uchar key2[8]; + + str_to_key(key, key2); + + for (i=0;i<64;i++) { + inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + outb[i] = 0; + } + + dohash(outb, inb, keyb, forw); + + for (i=0;i<8;i++) { + out[i] = 0; + } + + for (i=0;i<64;i++) { + if (outb[i]) + out[i/8] |= (1<<(7-(i%8))); + } +} + +void E_P24(const uchar *p21, const uchar *c8, uchar *p24) +{ + smbhash(p24, c8, p21, 1); + smbhash(p24+8, c8, p21+7, 1); + smbhash(p24+16, c8, p21+14, 1); +} Index: squid/src/auth/ntlm/helpers/smbpasswd/smbdes.h diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/smbdes.h:1.1.2.3 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/smbdes.h Mon Feb 25 05:46:32 2002 @@ -0,0 +1 @@ +void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24); Index: squid/src/auth/ntlm/helpers/smbpasswd/std-defines.h diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/std-defines.h:1.1.2.1 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/std-defines.h Sat Feb 23 19:29:20 2002 @@ -0,0 +1,49 @@ +#ifndef __STD_DEFINES__ +#define __STD_DEFINES__ + +/* RFCNB Standard includes ... */ +/* + * + * SMBlib Standard Includes + * + * Copyright (C) 1996, Richard Sharpe + * + * One day we will conditionalize these on OS types ... */ + +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "squid_types.h" +#define BOOL int16_t +#define int16 int16_t +#define uint16 u_int16_t +#define int32 int32_t +#define uint32 u_int32_t + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +#endif /* __STD_DEFINES__ */ Index: squid/src/auth/ntlm/helpers/smbpasswd/std-includes.h diff -u /dev/null squid/src/auth/ntlm/helpers/smbpasswd/std-includes.h:1.1.2.1 --- /dev/null Mon Jan 26 04:56:12 2004 +++ squid/src/auth/ntlm/helpers/smbpasswd/std-includes.h Sat Feb 23 19:29:20 2002 @@ -0,0 +1,47 @@ +/* RFCNB Standard includes ... */ +/* + * + * RFCNB Standard Includes + * + * Copyright (C) 1996, Richard Sharpe + * + * One day we will conditionalize these on OS types ... */ + +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* the types are provided by squid's configure preocess */ +#include "squid_types.h" +#define BOOL int16_t +#define int16 int16_t + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/* Pick up define for INADDR_NONE */ + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif squid-ntlm_smbpasswd-HEAD.new squid-ntlm_smbpasswd-HEAD differ: char 73, line 2