From: Amos Jeffries Date: Wed, 30 Jun 2010 12:32:50 +0000 (+1200) Subject: NTLM helpers cleanup pt 3: migrate libsmbval into libntlmauth X-Git-Tag: SQUID_3_2_0_1~104 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1dcf61eb8b17dc47e6ba3ed0921caa25fc1c232b;p=thirdparty%2Fsquid.git NTLM helpers cleanup pt 3: migrate libsmbval into libntlmauth Library changes: * ntlmauth.* files moved to libntlmauth/ * helpers/ntlm_auth/smb_lm/smbval moved to libntlmauth/ * No behaviour changes. Since I can't test the deeper logics. Just enough to make the code built with portable types available in Squid * API shuffled slightly to use less .h and to remove all external uses of private *-priv.h definitions. Library now provides three NTLM backend API: libntlmauth/ntlmauth.h - NTLM packet handling libntlmauth/smb.h - SMB LM credential validation libntlmauth/rfcnb.h - RFCNB (NetBIOS) domain server communications Helper Changes: * NTLM helpers tweaked slightly to build with the adjusted libntlmauth API and ntlm_smb_lm_auth helper to build as C++ * automake logics updated to obey --disable-auth and --disable-auth-ntlm NOTE: There will be extra code safety and testing benefits gained by converting libntlmauth to C++ as well. But that requries someone who can test the code behaviour during the upgrade. For now this wil do. --- diff --git a/Makefile.am b/Makefile.am index 344cc3c975..ddec8d2feb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,11 +2,14 @@ # AUTOMAKE_OPTIONS = dist-bzip2 subdir-objects 1.5 foreign -DIST_SUBDIRS = compat lib libltdl snmplib scripts src icons errors contrib doc helpers test-suite tools +DIST_SUBDIRS = compat lib libltdl libntlmauth snmplib scripts src icons errors contrib doc helpers test-suite tools SUBDIRS = compat lib $(makesnmplib) if USE_LOADABLE_MODULES SUBDIRS += libltdl endif +if ENABLE_AUTH_NTLM +SUBDIRS += libntlmauth +endif SUBDIRS += scripts src icons errors doc helpers test-suite tools DISTCLEANFILES = include/stamp-h include/stamp-h[0-9]* diff --git a/configure.in b/configure.in index 14daa51aad..1e6745bd4e 100644 --- a/configure.in +++ b/configure.in @@ -3773,6 +3773,7 @@ AC_CONFIG_FILES([\ Makefile \ compat/Makefile \ lib/Makefile \ + libntlmauth/Makefile \ scripts/Makefile \ src/Makefile \ src/base/Makefile \ @@ -3819,7 +3820,6 @@ AC_CONFIG_FILES([\ helpers/ntlm_auth/Makefile \ helpers/ntlm_auth/fake/Makefile \ helpers/ntlm_auth/smb_lm/Makefile \ - helpers/ntlm_auth/smb_lm/smbval/Makefile \ helpers/ntlm_auth/SSPI/Makefile \ helpers/negotiate_auth/Makefile \ helpers/negotiate_auth/kerberos/Makefile \ diff --git a/doc/release-notes/release-3.2.sgml b/doc/release-notes/release-3.2.sgml index 764e19c424..4c2f92f26b 100644 --- a/doc/release-notes/release-3.2.sgml +++ b/doc/release-notes/release-3.2.sgml @@ -124,8 +124,9 @@ Most user-facing changes are reflected in squid.conf (see below). NTLM Authentication protocol helpers

fakeauth_auth - ntlm_fake_auth - Perform NTLMSSP to recover the username but don't verify the password. + mswin_ntlm_auth - ntlm_sspi_auth - Perform NTLMSSP authentication using Windows native Security Support Provider Interface API. ntlm_auth - ntlm_smb_lm_auth - Perform SMB LanManager domain-less authentication over NTLM protocol. - no_check.pl - Deprecated. - Use the faster and less decryptable ntlm_fake_auth instead. + no_check.pl - Deprecated. - Use the faster and less easily decrypted ntlm_fake_auth instead. URL re-write helpers diff --git a/helpers/Makefile.am b/helpers/Makefile.am index 95a5a9d70d..3b4339e370 100644 --- a/helpers/Makefile.am +++ b/helpers/Makefile.am @@ -1,4 +1,6 @@ -SUBDIRS = \ +EXTRA_DIST = defines.h + +DIST_SUBDIRS = \ basic_auth \ digest_auth \ external_acl \ @@ -7,4 +9,14 @@ SUBDIRS = \ ntlm_auth \ url_rewrite -EXTRA_DIST = defines.h +SUBDIRS = \ + basic_auth \ + digest_auth \ + external_acl \ + log_daemon \ + negotiate_auth \ + url_rewrite + +if ENABLE_AUTH_NTLM +SUBDIRS += ntlm_auth +endif diff --git a/helpers/negotiate_auth/mswin_sspi/Makefile.am b/helpers/negotiate_auth/mswin_sspi/Makefile.am index 0599adaddf..0f310518f4 100644 --- a/helpers/negotiate_auth/mswin_sspi/Makefile.am +++ b/helpers/negotiate_auth/mswin_sspi/Makefile.am @@ -14,6 +14,10 @@ libexec_PROGRAMS = mswin_negotiate_auth mswin_negotiate_auth_SOURCES = libnegotiatessp.c negotiate_auth.c negotiate.h -LDADD = -L$(top_builddir)/lib -lsspwin32 -ladvapi32 -lmiscutil $(XTRA_LIBS) +LDADD = \ + -L$(top_builddir)/lib -lsspwin32 \ + $(COMPAT_LIB) \ + -ladvapi32 \ + $(XTRA_LIBS) EXTRA_DIST = readme.txt config.test diff --git a/helpers/ntlm_auth/fake/Makefile.am b/helpers/ntlm_auth/fake/Makefile.am index fc45bb36db..3f95da400a 100644 --- a/helpers/ntlm_auth/fake/Makefile.am +++ b/helpers/ntlm_auth/fake/Makefile.am @@ -4,7 +4,7 @@ libexec_PROGRAMS = ntlm_fake_auth ntlm_fake_auth_SOURCES = ntlm_fake_auth.cc ntlm_fake_auth_LDADD = \ - -L$(top_builddir)/lib -lntlmauth \ + -L$(top_builddir)/libntlmauth -lntlmauth \ $(COMPAT_LIB) \ $(CRYPTLIB) \ $(XTRA_LIBS) diff --git a/helpers/ntlm_auth/fake/ntlm_fake_auth.cc b/helpers/ntlm_auth/fake/ntlm_fake_auth.cc index 42f6f9de17..000eb675bc 100644 --- a/helpers/ntlm_auth/fake/ntlm_fake_auth.cc +++ b/helpers/ntlm_auth/fake/ntlm_fake_auth.cc @@ -54,7 +54,8 @@ #define IGNORANCE_IS_BLISS #include "config.h" -#include "ntlmauth.h" +#include "libntlmauth/ntlmauth.h" +#include "libntlmauth/support_bits.cci" #include "util.h" #if HAVE_CTYPE_H @@ -73,9 +74,6 @@ #include #endif - -#define safe_free(x) if (x) { free(x); x = NULL; } - /* A couple of harmless helper macros */ #define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n"); #ifdef __GNUC__ @@ -96,76 +94,6 @@ const char *authenticate_ntlm_domain = "WORKGROUP"; int strip_domain_enabled = 0; int NTLM_packet_debug_enabled = 0; -static void -hex_dump(unsigned char *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 (!data) - return; - - 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", - (int) (p - data)); - } - c = *p; - if (xisalnum(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); - } - } -} - - -/* makes a null-terminated string lower-case. Changes CONTENTS! */ -static void -lc(char *string) -{ - char *p = string, c; - while ((c = *p)) { - *p = xtolower(c); - p++; - } -} - /* * options: * -d enable debugging. @@ -266,7 +194,7 @@ main(int argc, char *argv[]) ntlm_negotiate *nego = (ntlm_negotiate *)packet; ntlm_make_challenge(&chal, authenticate_ntlm_domain, NULL, nonce, NTLM_NONCE_LEN, nego->flags); } else { - ntlm_make_challenge(&chal, authenticate_ntlm_domain, NULL, nonce, NTLM_NONCE_LEN, NEGOTIATE_ASCII); + ntlm_make_challenge(&chal, authenticate_ntlm_domain, NULL, nonce, NTLM_NONCE_LEN, NTLM_NEGOTIATE_ASCII); } // TODO: find out what this context means, and why only the fake auth helper contains it. chal.context_high = htole32(0x003a<<16); @@ -282,8 +210,8 @@ main(int argc, char *argv[]) } else if (strncasecmp(buf, "KK ", 3) == 0) { if (!packet) { SEND("BH received KK with no data! user="); - } else if (!ntlm_validate_packet(packet, NTLM_AUTHENTICATE)) { - if (ntlm_unpack_auth((ntlm_authenticate *)packet, user, domain, (buflen-3)) == 0) { + } else if (ntlm_validate_packet(packet, NTLM_AUTHENTICATE) == NTLM_ERR_NONE) { + if (ntlm_unpack_auth((ntlm_authenticate *)packet, user, domain, (buflen-3)) == NTLM_ERR_NONE) { lc(user); lc(domain); if (strip_domain_enabled) { diff --git a/helpers/ntlm_auth/smb_lm/Makefile.am b/helpers/ntlm_auth/smb_lm/Makefile.am index 1d4c2ce20a..3ea3be14b7 100644 --- a/helpers/ntlm_auth/smb_lm/Makefile.am +++ b/helpers/ntlm_auth/smb_lm/Makefile.am @@ -1,18 +1,10 @@ include $(top_srcdir)/src/Common.am -SUBDIRS = smbval - libexec_PROGRAMS = ntlm_smb_lm_auth -ntlm_smb_lm_auth_SOURCES = libntlmssp.c ntlm_smb_lm_auth.c ntlm_smb_lm_auth.h - -## we need our local files too (but avoid -I. at all costs) -INCLUDES += \ - -I$(srcdir) \ - -I$(srcdir)/smbval +ntlm_smb_lm_auth_SOURCES = ntlm_smb_lm_auth.cc ntlm_smb_lm_auth_LDADD = \ - -L$(top_builddir)/lib -lntlmauth \ - smbval/libsmbvalid.a \ + -L$(top_builddir)/libntlmauth -lntlmauth \ $(COMPAT_LIB) \ $(CRYPTLIB) \ $(XTRA_LIBS) diff --git a/helpers/ntlm_auth/smb_lm/libntlmssp.c b/helpers/ntlm_auth/smb_lm/libntlmssp.c deleted file mode 100644 index 1f4f892710..0000000000 --- a/helpers/ntlm_auth/smb_lm/libntlmssp.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * (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 "config.h" - -typedef unsigned char uchar; - -#include "ntlm_smb_lm_auth.h" -#include "util.h" /* from Squid */ -#include "compat/stdvarargs.h" -#include "valid.h" -#include "smbencrypt.h" - -#if HAVE_STRING_H -#include -#endif /* HAVE_STRING_H */ -#if HAVE_UNISTD_H -#include -#endif - -/* these are part of rfcnb-priv.h and smblib-priv.h */ -extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); -extern int SMB_Get_Last_Error(); -extern int RFCNB_Get_Last_Errno(); - -#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); - -/* this one is reallllly haackiish. We really should be using anything from smblib-priv.h - */ -static char const *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL - }; - -#if 0 -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, char *Domain, int precrypted); -#endif - -#if DEBUG -#define debug_dump_ntlmssp_flags dump_ntlmssp_flags -#else /* DEBUG */ -#define debug_dump_ntlmssp_flags(X) /* empty */ -#endif /* DEBUG */ - -#define ENCODED_PASS_LEN 24 -static unsigned char challenge[NTLM_NONCE_LEN]; -static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN], -ntencoded_empty_pass[ENCODED_PASS_LEN]; -SMB_Handle_Type handle = NULL; - -/* Disconnects from the DC. A reconnection will be done upon the next request - */ -void -dc_disconnect() -{ - if (handle != NULL) - SMB_Discon(handle, 0); - handle = NULL; -} - -int -connectedp() -{ - return (handle != NULL); -} - - -/* Tries to connect to a DC. Returns 0 on failure, 1 on OK */ -int -is_dc_ok(char *domain, char *domain_controller) -{ - SMB_Handle_Type h = SMB_Connect_Server(NULL, domain_controller, domain); - if (h == NULL) - return 0; - SMB_Discon(h, 0); - return 1; -} - - -static char errstr[1001]; -/* returns 0 on success, > 0 on failure */ -static int -init_challenge(char *domain, char *domain_controller) -{ - int smberr; - - if (handle != NULL) { - return 0; - } - debug("Connecting to server %s domain %s\n", domain_controller, domain); - handle = SMB_Connect_Server(NULL, domain_controller, domain); - smberr = SMB_Get_Last_Error(); - SMB_Get_Error_Msg(smberr, errstr, 1000); - - - if (handle == NULL) { /* couldn't connect */ - debug("Couldn't connect to SMB Server. Error:%s\n", errstr); - return 1; - } - if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */ - debug("Error negotiating protocol with SMB Server\n"); - SMB_Discon(handle, 0); - handle = NULL; - return 2; - } - if (handle->Security == 0) { /* share-level security, unuseable */ - debug("SMB Server uses share-level security .. we need user security.\n"); - SMB_Discon(handle, 0); - handle = NULL; - return 3; - } - memcpy(challenge, handle->Encrypt_Key, NTLM_NONCE_LEN); - SMBencrypt((unsigned char *)"",challenge,lmencoded_empty_pass); - SMBNTencrypt((unsigned char *)"",challenge,ntencoded_empty_pass); - return 0; -} - -static char my_domain[100], my_domain_controller[100]; -const char * -make_challenge(char *domain, char *domain_controller) -{ - /* trying to circumvent some strange problem wih pointers in SMBLib */ - /* Ugly as hell, but the lib is going to be dropped... */ - strcpy(my_domain,domain); - strcpy(my_domain_controller,domain_controller); - if (init_challenge(my_domain, my_domain_controller) > 0) { - return NULL; - } - ntlm_challenge chal; - u_int32_t flags = REQUEST_NON_NT_SESSION_KEY | - CHALLENGE_TARGET_IS_DOMAIN | - NEGOTIATE_ALWAYS_SIGN | - NEGOTIATE_USE_NTLM | - NEGOTIATE_USE_LM | - NEGOTIATE_ASCII; - ntlm_make_challenge(&chal, my_domain, my_domain_controller, (char *)challenge, NTLM_NONCE_LEN, flags); - int len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen); - return base64_encode_bin((char *)&chal, len); -} - -int ntlm_errno; -#define MAX_USERNAME_LEN 255 -#define MAX_DOMAIN_LEN 255 -#define MAX_PASSWD_LEN 31 -static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]; /* we can afford to waste */ - - -/* Fetches the user's credentials from the challenge. - * Returns NULL if domain or user is not defined - * No identity control is performed. - * WARNING! The result is static storage, shared with ntlm_check_auth - */ -char * -fetch_credentials(ntlm_authenticate * auth, int auth_length) -{ - char *p = credentials; - lstring tmp; - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->domain, auth->flags); - *p = '\0'; - if (tmp.str == NULL) - return NULL; - memcpy(p, tmp.str, tmp.l); - p += tmp.l; - *p++ = '\\'; - *p = '\0'; - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags); - if (tmp.str == NULL) - return NULL; - memcpy(p, tmp.str, tmp.l); - *(p + tmp.l) = '\0'; - return credentials; -} - -/* 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 pass[MAX_PASSWD_LEN+1]; - char *domain = credentials; - char *user; - lstring tmp; - - if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */ - debug("Weird, we've been disconnected\n"); - ntlm_errno = NTLM_NOT_CONNECTED; - return NULL; - } - - /* debug("fetching domain\n"); */ - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->domain, auth->flags); - if (tmp.str == NULL || tmp.l == 0) { - debug("No domain supplied. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - if (tmp.l > MAX_DOMAIN_LEN) { - debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - memcpy(domain, tmp.str, tmp.l); - user = domain + tmp.l; - *user++ = '\0'; - - /* debug("fetching user name\n"); */ - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags); - if (tmp.str == NULL || tmp.l == 0) { - debug("No username supplied. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - if (tmp.l > MAX_USERNAME_LEN) { - debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - memcpy(user, tmp.str, tmp.l); - *(user + tmp.l) = '\0'; - - - /* Authenticating against the NT response doesn't seem to work... */ - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->lmresponse, auth->flags); - if (tmp.str == NULL || tmp.l == 0) { - fprintf(stderr, "No auth at all. Returning no-auth\n"); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - if (tmp.l > MAX_PASSWD_LEN) { - debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN); - ntlm_errno = NTLM_LOGON_ERROR; - return NULL; - } - - memcpy(pass, tmp.str, tmp.l); - pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0'; - -#if 1 - debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s'" - "(length: %d)\n", - user,lmencoded_empty_pass,tmp.str,tmp.l); - if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) { - fprintf(stderr,"Empty LM password supplied for user %s\\%s. " - "No-auth\n",domain,user); - ntlm_errno=NTLM_LOGON_ERROR; - return NULL; - } - - tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->ntresponse, auth->flags); - if (tmp.str != NULL && tmp.l != 0) { - debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s'" - "(length: %d)\n", - user,ntencoded_empty_pass,tmp.str,tmp.l); - if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) { - fprintf(stderr,"Empty NT password supplied for user %s\\%s. " - "No-auth\n",domain,user); - ntlm_errno=NTLM_LOGON_ERROR; - return NULL; - } - } -#endif - - /* TODO: check against empty password!!!!! */ - - - debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass); - - rv = SMB_Logon_Server(handle, user, pass, domain, 1); - debug("Login attempt had result %d\n", rv); - - if (rv != NTV_NO_ERROR) { /* failed */ - ntlm_errno = rv; - return NULL; - } - *(user - 1) = '\\'; /* hack. Performing, but ugly. */ - - debug("credentials: %s\n", credentials); - return credentials; -} diff --git a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.c b/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc similarity index 60% rename from helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.c rename to helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc index 89379611c9..45be55f613 100644 --- a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.c +++ b/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc @@ -15,26 +15,24 @@ */ #define SQUID_NO_ALLOC_PROTECT 1 #include "config.h" +#include "libntlmauth/ntlmauth.h" +#include "libntlmauth/smb.h" +#include "libntlmauth/rfcnb.h" +#include "libntlmauth/support_bits.cci" +#include "util.h" /* from Squid */ -#include "ntlmauth.h" -#include "ntlm_smb_lm_auth.h" -#include "util.h" -#include "smbval/smblib-common.h" -#include "smbval/rfcnb-error.h" - +#if HAVE_STRING_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SIGNAL_H #include - -/* these are part of rfcnb-priv.h and smblib-priv.h */ -extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); -extern int SMB_Get_Last_Error(void); -extern int SMB_Get_Last_SMB_Err(void); -extern int RFCNB_Get_Last_Error(void); - - +#endif +#if HAVE_ERRNO_H #include - -#define BUFFER_SIZE 10240 - +#endif #if HAVE_STDLIB_H #include #endif @@ -53,6 +51,41 @@ extern int RFCNB_Get_Last_Error(void); #if HAVE_ASSERT_H #include #endif +#if HAVE_TIME_H +#include +#endif + + +/************* CONFIGURATION ***************/ + +#define DEAD_DC_RETRY_INTERVAL 30 + +/************* END CONFIGURATION ***************/ + +/* 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 printf +#define SEND3 printf +#endif + +const char *make_challenge(char *domain, char *controller); +char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length); +void dc_disconnect(void); +int connectedp(void); +int is_dc_ok(char *domain, char *domain_controller); + +typedef struct _dc dc; +struct _dc { + char *domain; + char *controller; + time_t dead; /* 0 if it's alive, otherwise time of death */ + dc *next; +}; /* local functions */ void send_bh_or_ld(char const *bhmessage, ntlm_authenticate * failedauth, int authlen); @@ -61,64 +94,277 @@ void process_options(int argc, char *argv[]); const char * obtain_challenge(void); void manage_request(void); +/* these are part of rfcnb-priv.h and smblib-priv.h */ +extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); +extern int SMB_Get_Last_Error(); +extern int RFCNB_Get_Last_Errno(); +extern int RFCNB_Get_Last_Error(void); +extern int SMB_Get_Last_SMB_Err(void); + +/* 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); + +/* this one is reallllly haackiish. We really should be using anything from smblib-priv.h + */ +static char const *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", + "DOS LANMAN1.0", + "LANMAN1.0", + "DOS LM1.2X002", + "LM1.2X002", + "DOS LANMAN2.1", + "LANMAN2.1", + "Samba", + "NT LM 0.12", + "NT LANMAN 1.0", + NULL + }; + +#define ENCODED_PASS_LEN 24 +#define MAX_USERNAME_LEN 255 +#define MAX_DOMAIN_LEN 255 +#define MAX_PASSWD_LEN 31 + +static unsigned char challenge[NTLM_NONCE_LEN]; +static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN], +ntencoded_empty_pass[ENCODED_PASS_LEN]; +SMB_Handle_Type handle = NULL; +int ntlm_errno; +static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]; /* we can afford to waste */ +static char my_domain[100], my_domain_controller[100]; +static char errstr[1001]; #if DEBUG -char error_messages_buffer[BUFFER_SIZE]; +char error_messages_buffer[NTLM_BLOB_BUFFER_SIZE]; #endif - char load_balance = 0, protocol_pedantic = 0; #if NTLM_FAIL_OPEN char last_ditch_enabled = 0; #endif - dc *controllers = NULL; int numcontrollers = 0; dc *current_dc; - char smb_error_buffer[1000]; -/* signal handler to be invoked when the authentication operation - * times out */ -static char got_timeout = 0; -static void -timeout_during_auth(int signum) + +/* Disconnects from the DC. A reconnection will be done upon the next request + */ +void +dc_disconnect() { - dc_disconnect(); + if (handle != NULL) + SMB_Discon(handle, 0); + handle = NULL; } -/* makes a null-terminated string upper-case. Changes CONTENTS! */ -static void -uc(char *string) +int +connectedp() +{ + return (handle != NULL); +} + +/* Tries to connect to a DC. Returns 0 on failure, 1 on OK */ +int +is_dc_ok(char *domain, char *domain_controller) { - char *p = string, c; - while ((c = *p)) { - *p = xtoupper(c); - p++; + SMB_Handle_Type h = SMB_Connect_Server(NULL, domain_controller, domain); + if (h == NULL) + return 0; + SMB_Discon(h, 0); + return 1; +} + +/* returns 0 on success, > 0 on failure */ +static int +init_challenge(char *domain, char *domain_controller) +{ + int smberr; + + if (handle != NULL) { + return 0; } + debug("Connecting to server %s domain %s\n", domain_controller, domain); + handle = SMB_Connect_Server(NULL, domain_controller, domain); + smberr = SMB_Get_Last_Error(); + SMB_Get_Error_Msg(smberr, errstr, 1000); + + + if (handle == NULL) { /* couldn't connect */ + debug("Couldn't connect to SMB Server. Error:%s\n", errstr); + return 1; + } + if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */ + debug("Error negotiating protocol with SMB Server\n"); + SMB_Discon(handle, 0); + handle = NULL; + return 2; + } + if (handle->Security == 0) { /* share-level security, unuseable */ + debug("SMB Server uses share-level security .. we need user security.\n"); + SMB_Discon(handle, 0); + handle = NULL; + return 3; + } + memcpy(challenge, handle->Encrypt_Key, NTLM_NONCE_LEN); + SMBencrypt((unsigned char *)"",challenge,lmencoded_empty_pass); + SMBNTencrypt((unsigned char *)"",challenge,ntencoded_empty_pass); + return 0; } -/* makes a null-terminated string lower-case. Changes CONTENTS! */ -static void -lc(char *string) +const char * +make_challenge(char *domain, char *domain_controller) +{ + /* trying to circumvent some strange problem wih pointers in SMBLib */ + /* Ugly as hell, but the lib is going to be dropped... */ + strcpy(my_domain,domain); + strcpy(my_domain_controller,domain_controller); + if (init_challenge(my_domain, my_domain_controller) > 0) { + return NULL; + } + ntlm_challenge chal; + u_int32_t flags = NTLM_REQUEST_NON_NT_SESSION_KEY | + NTLM_CHALLENGE_TARGET_IS_DOMAIN | + NTLM_NEGOTIATE_ALWAYS_SIGN | + NTLM_NEGOTIATE_USE_NTLM | + NTLM_NEGOTIATE_USE_LM | + NTLM_NEGOTIATE_ASCII; + ntlm_make_challenge(&chal, my_domain, my_domain_controller, (char *)challenge, NTLM_NONCE_LEN, flags); + int len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen); + return base64_encode_bin((char *)&chal, len); +} + +/* 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) { - char *p = string, c; - while ((c = *p)) { - *p = xtolower(c); - p++; + int rv; + char pass[MAX_PASSWD_LEN+1]; + char *domain = credentials; + char *user; + lstring tmp; + + if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */ + debug("Weird, we've been disconnected\n"); + ntlm_errno = NTLM_ERR_NOT_CONNECTED; + return NULL; + } + + /* debug("fetching domain\n"); */ + tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->domain, auth->flags); + if (tmp.str == NULL || tmp.l == 0) { + debug("No domain supplied. Returning no-auth\n"); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + if (tmp.l > MAX_DOMAIN_LEN) { + debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + memcpy(domain, tmp.str, tmp.l); + user = domain + tmp.l; + *user++ = '\0'; + + /* debug("fetching user name\n"); */ + tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags); + if (tmp.str == NULL || tmp.l == 0) { + debug("No username supplied. Returning no-auth\n"); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + if (tmp.l > MAX_USERNAME_LEN) { + debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; } + memcpy(user, tmp.str, tmp.l); + *(user + tmp.l) = '\0'; + + + /* Authenticating against the NT response doesn't seem to work... */ + tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->lmresponse, auth->flags); + if (tmp.str == NULL || tmp.l == 0) { + fprintf(stderr, "No auth at all. Returning no-auth\n"); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + if (tmp.l > MAX_PASSWD_LEN) { + debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + + memcpy(pass, tmp.str, tmp.l); + pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0'; + +#if 1 + debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n", + user,lmencoded_empty_pass,tmp.str,tmp.l); + if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) { + fprintf(stderr,"Empty LM password supplied for user %s\\%s. " + "No-auth\n",domain,user); + ntlm_errno=NTLM_ERR_LOGON; + return NULL; + } + + tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->ntresponse, auth->flags); + if (tmp.str != NULL && tmp.l != 0) { + debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n", + user,ntencoded_empty_pass,tmp.str,tmp.l); + if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) { + fprintf(stderr,"ERROR: Empty NT password supplied for user %s\\%s. No-auth\n", domain, user); + ntlm_errno = NTLM_ERR_LOGON; + return NULL; + } + } +#endif + + /* TODO: check against empty password!!!!! */ + + + debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass); + + rv = SMB_Logon_Server(handle, user, pass, domain, 1); + debug("Login attempt had result %d\n", rv); + + if (rv != NTLM_ERR_NONE) { /* failed */ + ntlm_errno = rv; + return NULL; + } + *(user - 1) = '\\'; /* hack. Performing, but ugly. */ + + debug("credentials: %s\n", credentials); + return credentials; } +/* signal handler to be invoked when the authentication operation + * times out */ +static char got_timeout = 0; +static void +timeout_during_auth(int signum) +{ + dc_disconnect(); +} void send_bh_or_ld(char const *bhmessage, ntlm_authenticate * failedauth, int authlen) { #if NTLM_FAIL_OPEN - char *creds = NULL; + char user[NTLM_MAX_FIELD_LENGTH]; + char domain[NTLM_MAX_FIELD_LENGTH]; if (last_ditch_enabled) { - creds = fetch_credentials(failedauth, authlen); - if (creds) { - lc(creds); - SEND2("LD %s", creds); + user[0] = '\0'; + domain[0] = '\0'; + if (ntlm_unpack_auth(failedauth, user, domain, authlen) == 0) { + lc(domain); + lc(user); + SEND3("LD %s%s%s", domain, (domain[0]!='\0'?"//":""), user); } else { SEND("NA last-ditch on, but no credentials"); } @@ -193,7 +439,7 @@ process_options(int argc, char *argv[]) char *d, *c; /* d will not be freed in case of non-error. Since we don't reconfigure, * it's going to live as long as the process anyways */ - d = malloc(strlen(argv[j]) + 1); + d = (char*)malloc(strlen(argv[j]) + 1); strcpy(d, argv[j]); debug("Adding domain-controller %s\n", d); if (NULL == (c = strchr(d, '\\')) && NULL == (c = strchr(d, '/'))) { @@ -283,18 +529,18 @@ void manage_request() { ntlmhdr *fast_header; - char buf[BUFFER_SIZE]; + char buf[NTLM_BLOB_BUFFER_SIZE]; const char *ch; char *ch2, *decoded, *cred = NULL; int plen; - if (fgets(buf, BUFFER_SIZE, stdin) == NULL) { + if (fgets(buf, NTLM_BLOB_BUFFER_SIZE, stdin) == NULL) { fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno, strerror(errno)); exit(1); /* BIIG buffer */ } debug("managing request\n"); - ch2 = memchr(buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */ + ch2 = (char*)memchr(buf, '\n', NTLM_BLOB_BUFFER_SIZE); /* safer against overrun than strchr */ if (ch2) { *ch2 = '\0'; /* terminate the string at newline. */ ch = ch2; @@ -313,10 +559,10 @@ manage_request() return; } /* fast-track-decode request type. */ - fast_header = (struct _ntlmhdr *) decoded; + fast_header = (ntlmhdr *) decoded; /* sanity-check: it IS a NTLMSSP packet, isn't it? */ - if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) { + if (ntlm_validate_packet(fast_header, NTLM_ANY) < 0) { SEND("NA Broken authentication packet"); return; } @@ -345,7 +591,7 @@ manage_request() } if (cred == NULL) { int smblib_err, smb_errorclass, smb_errorcode, nb_error; - if (ntlm_errno == NTLM_LOGON_ERROR) { /* hackish */ + if (ntlm_errno == NTLM_ERR_LOGON) { /* hackish */ SEND("NA Logon Failure"); return; } diff --git a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.h b/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.h deleted file mode 100644 index 3d96aaf456..0000000000 --- a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (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 _NTLM_H_ -#define _NTLM_H_ - -#include "config.h" -#include "ntlmauth.h" - -/* for time_t */ -#if HAVE_TIME_H -#include -#endif - -/************* CONFIGURATION ***************/ -/* - * define this if you want debugging - */ -#ifndef DEBUG -#define DEBUG 1 -#endif - -#define DEAD_DC_RETRY_INTERVAL 30 - -/************* END CONFIGURATION ***************/ - - -/* 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 - -extern int ntlm_errno; -#define NTLM_NO_ERROR 0 -#define NTLM_SERVER_ERROR 1 -#define NTLM_PROTOCOL_ERROR 2 -#define NTLM_LOGON_ERROR 3 -#define NTLM_UNTRUSTED_DOMAIN 4 -#define NTLM_BAD_PROTOCOL -1 -#define NTLM_NOT_CONNECTED 10 - - -const char *make_challenge(char *domain, char *controller); -extern char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length); -extern char *fetch_credentials(ntlm_authenticate * auth, int auth_length); -void dc_disconnect(void); -int connectedp(void); -int is_dc_ok(char *domain, char *domain_controller); - -typedef struct _dc dc; -struct _dc { - char *domain; - char *controller; - time_t dead; /* 0 if it's alive, otherwise time of death */ - dc *next; -}; - - -#endif /* _NTLM_H_ */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/Makefile.am b/helpers/ntlm_auth/smb_lm/smbval/Makefile.am deleted file mode 100644 index d1144cc126..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# makefile for smblib - -include $(top_srcdir)/src/Common.am - -## we need our local files too (but avoid -I. at all costs) -INCLUDES += -I$(srcdir) - - -noinst_LIBRARIES = libsmbvalid.a - -libsmbvalid_a_SOURCES = valid.c session.c rfcnb-util.c rfcnb-io.c \ - smblib-util.c smblib.c smbencrypt.c smbdes.c md4.c byteorder.h \ - rfcnb-error.h rfcnb-util.h smbencrypt.h smblib.h valid.h \ - md4.h rfcnb-io.h rfcnb.h smblib-common.h std-defines.h \ - rfcnb-common.h rfcnb-priv.h smbdes.h smblib-priv.h std-includes.h - -##OBJS = smblib.o smblib-util.o file.o smb-errors.o exper.o smblib-api.o smbencrypt.o smbdes.o md4.o diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-common.h b/helpers/ntlm_auth/smb_lm/smbval/rfcnb-common.h deleted file mode 100644 index 653fb698aa..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-common.h +++ /dev/null @@ -1,39 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Common Structures etc Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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. - */ - -#ifndef _SMB_LM_SMBVAL_RFCNB_COMMON_H -#define _SMB_LM_SMBVAL_RFCNB_COMMON_H - -/* A data structure we need */ - -typedef struct RFCNB_Pkt { - - char *data; /* The data in this portion */ - int len; - struct RFCNB_Pkt *next; - -} RFCNB_Pkt; - -#endif /* _SMB_LM_SMBVAL_RFCNB_COMMON_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-error.h b/helpers/ntlm_auth/smb_lm/smbval/rfcnb-error.h deleted file mode 100644 index 0cb89995c6..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-error.h +++ /dev/null @@ -1,74 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Error Response Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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. - */ - -/* Error responses */ - -#define RFCNBE_Bad -1 /* Bad response */ -#define RFCNBE_OK 0 - -/* these should follow the spec ... is there one ? */ - -#define RFCNBE_NoSpace 1 /* Could not allocate space for a struct */ -#define RFCNBE_BadName 2 /* Could not translate a name */ -#define RFCNBE_BadRead 3 /* Read sys call failed */ -#define RFCNBE_BadWrite 4 /* Write Sys call failed */ -#define RFCNBE_ProtErr 5 /* Protocol Error */ -#define RFCNBE_ConGone 6 /* Connection dropped */ -#define RFCNBE_BadHandle 7 /* Handle passed was bad */ -#define RFCNBE_BadSocket 8 /* Problems creating socket */ -#define RFCNBE_ConnectFailed 9 /* Connect failed */ -#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN */ -#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN */ -#define RFCNBE_CallRejCNNP 12 /* Call rejected, called name not present */ -#define RFCNBE_CallRejInfRes 13 /* Call rejetced, name ok, no resources */ -#define RFCNBE_CallRejUnSpec 14 /* Call rejected, unspecified error */ -#define RFCNBE_BadParam 15 /* Bad parameters passed ... */ -#define RFCNBE_Timeout 16 /* IO Timed out */ - -/* Text strings for the error responses */ -extern char const *RFCNB_Error_Strings[]; -/* - * static char *RFCNB_Error_Strings[] = { - * - * "RFCNBE_OK: Routine completed successfully.", - * "RFCNBE_NoSpace: No space available for a malloc call.", - * "RFCNBE_BadName: NetBIOS name could not be translated to IP address.", - * "RFCNBE_BadRead: Read system call returned an error. Check errno.", - * "RFCNBE_BadWrite: Write system call returned an error. Check errno.", - * "RFCNBE_ProtErr: A protocol error has occurred.", - * "RFCNBE_ConGone: Connection dropped during a read or write system call.", - * "RFCNBE_BadHandle: Bad connection handle passed.", - * "RFCNBE_BadSocket: Problems creating socket.", - * "RFCNBE_ConnectFailed: Connection failed. See errno.", - * "RFCNBE_CallRejNLOCN: Call rejected. Not listening on called name.", - * "RFCNBE_CallRejNLFCN: Call rejected. Not listening for called name.", - * "RFCNBE_CallRejCNNP: Call rejected. Called name not present.", - * "RFCNBE_CallRejInfRes: Call rejected. Name present, but insufficient resources.", - * "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.", - * "RFCNBE_BadParam: Bad parameters passed to a routine.", - * "RFCNBE_Timeout: IO Operation timed out ..." - * - * }; - */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.h b/helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.h deleted file mode 100644 index 06aa5f5f46..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.h +++ /dev/null @@ -1,35 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB IO Routines Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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. - */ - -#ifndef _SMB_LM_SMBVAL_RFCNB_IO_H -#define _SMB_LM_SMBVAL_RFCNB_IO_H - -extern int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); - -extern int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); - -extern void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt); - -#endif /* _SMB_LM_SMBVAL_RFCNB_IO_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.h b/helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.h deleted file mode 100644 index 34ab9aa85f..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.h +++ /dev/null @@ -1,52 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Utility Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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 "std-includes.h" - - -void RFCNB_CvtPad_Name(char *name1, char *name2); - -void RFCNB_AName_To_NBName(char *AName, char *NBName); - -void RFCNB_NBName_To_AName(char *NBName, char *AName); - -void RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len); - -struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); - -void RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len); - -int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP); - -int RFCNB_Close(int socket); - -int RFCNB_IP_Connect(struct in_addr Dest_IP, int port); - -int RFCNB_Session_Req(struct RFCNB_Con *con, - char *Called_Name, - char *Calling_Name, - BOOL * redirect, - struct in_addr *Dest_IP, - int *port); diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb.h b/helpers/ntlm_auth/smb_lm/smbval/rfcnb.h deleted file mode 100644 index eff6d7a268..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb.h +++ /dev/null @@ -1,60 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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. - */ - -#ifndef SMB_LM_SMBVAL_RFCNB_H -#define SMB_LM_SMBVAL_RFCNB_H - -/* Error responses */ - -#include "rfcnb-error.h" -#include "rfcnb-common.h" -#include "smblib-priv.h" -#include "rfcnb-priv.h" - -/* Defines we need */ - -#define RFCNB_Default_Port 139 - -/* Definition of routines we define */ - -extern void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, int port); - -extern int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *Data, int Length); - -extern int RFCNB_Recv(void *Con_Handle, struct RFCNB_Pkt *Data, int Length); - -extern int RFCNB_Hangup(struct RFCNB_Con *con_Handle); - -extern void *RFCNB_Listen(void); - -extern void RFCNB_Get_Error(char *buffer, int buf_len); - -extern struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); - -extern void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt); - -extern int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn); - -#endif /* SMB_LM_SMBVAL_RFCNB_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/smbencrypt.h b/helpers/ntlm_auth/smb_lm/smbval/smbencrypt.h deleted file mode 100644 index cee12f7e66..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/smbencrypt.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SMB_LM_SMBVAL_SMBENCRYPT_H -#define __SMB_LM_SMBVAL_SMBENCRYPT_H - - -extern void SMBencrypt(uchar * passwd, uchar * c8, uchar * p24); -extern void SMBNTencrypt(uchar * passwd, uchar * c8, uchar * p24); - -#endif /* __SMB_LM_SMBVAL_SMBENCRYPT_H */ - diff --git a/helpers/ntlm_auth/smb_lm/smbval/smblib.h b/helpers/ntlm_auth/smb_lm/smbval/smblib.h deleted file mode 100644 index e299aa466f..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/smblib.h +++ /dev/null @@ -1,98 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ - -/* - * 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 "std-defines.h" -#include "smblib-common.h" - -/* Just define all the entry points */ - -/* Create a handle to allow us to set/override some parameters ... */ - -void *SMB_Create_Con_Handle(); - -/* Connect to a server, but do not do a tree con etc ... */ - -void *SMB_Connect_Server(void *Con, char *server, char *NTdomain); - -/* Connect to a server and give us back a handle. If Con == NULL, create */ -/* The handle and populate it with defaults */ - -void *SMB_Connect(void *Con, void **tree, - char *name, char *User, char *Password); - -/* Negotiate a protocol */ - -int SMB_Negotiate(void *Con_Handle, char *Prots[]); - -/* Connect to a tree ... */ - -void *SMB_TreeConnect(void *con_handle, void *tree_handle, - char *path, char *password, char *dev); - -/* Disconnect a tree ... */ - -int SMB_TreeDisconect(void *tree_handle); - -/* Open a file */ - -void *SMB_Open(void *tree_handle, - void *file_handle, - char *file_name, - unsigned short mode, - unsigned short search); - -/* Close a file */ - -int SMB_Close(void *file_handle); - -/* Disconnect from server. Has flag to specify whether or not we keep the */ -/* handle. */ - -int SMB_Discon(void *Con, BOOL KeepHandle); - -void *SMB_Create(void *Tree_Handle, - void *File_Handle, - char *file_name, - short search); - -int SMB_Delete(void *tree, char *file_name, short search); - -int SMB_Create_Dir(void *tree, char *dir_name); - -int SMB_Delete_Dir(void *tree, char *dir_name); - -int SMB_Check_Dir(void *tree, char *dir_name); - -int SMB_Get_Last_Error(); - -int SMB_Get_Last_SMB_Err(); - -int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); - -void *SMB_Logon_And_TCon(void *con, void *tree, char *user, char *pass, - char *service, char *st); - - -#define SMBLIB_DEFAULT_DOMAIN "anydom" diff --git a/helpers/ntlm_auth/smb_lm/smbval/std-defines.h b/helpers/ntlm_auth/smb_lm/smbval/std-defines.h deleted file mode 100644 index fcbffda544..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/std-defines.h +++ /dev/null @@ -1,49 +0,0 @@ -#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 "config.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__ */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/std-includes.h b/helpers/ntlm_auth/smb_lm/smbval/std-includes.h deleted file mode 100644 index 9155659561..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/std-includes.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 "util.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 diff --git a/helpers/ntlm_auth/smb_lm/smbval/valid.h b/helpers/ntlm_auth/smb_lm/smbval/valid.h deleted file mode 100644 index 4c2f6d2128..0000000000 --- a/helpers/ntlm_auth/smb_lm/smbval/valid.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _VALID_H_ -#define _VALID_H_ -/* SMB User verification function */ - -#define NTV_NO_ERROR 0 -#define NTV_SERVER_ERROR 1 -#define NTV_PROTOCOL_ERROR 2 -#define NTV_LOGON_ERROR 3 - -int Valid_User(char *USERNAME, char *PASSWORD, char *SERVER, char *BACKUP, char *DOMAIN); -void *NTLM_Connect(char *SERVER, char *BACKUP, char *DOMAIN, char *nonce); -int NTLM_Auth(void *handle, char *USERNAME, char *PASSWORD, int flag); -void NTLM_Disconnect(void *handle); - -#endif diff --git a/lib/Makefile.am b/lib/Makefile.am index dc2119b519..f474316568 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -34,7 +34,6 @@ EXTRA_LIBRARIES = \ libsspwin32.a noinst_LIBRARIES = \ libmiscutil.a \ - libntlmauth.a \ $(LIBSSPWIN32) # @@ -77,10 +76,6 @@ libmiscutil_a_SOURCES = \ libmiscutil_a_LIBADD = $(LIBOBJS) # $(top_srcdir)/include/version.h should be a dependency -libntlmauth_a_SOURCES = \ - ntlmauth.c -libntlmauth_a_LIBADD = \ - $(LIBOBJS) libsspwin32_a_SOURCES = \ base64.c \ sspwin32.c diff --git a/lib/sspwin32.c b/lib/sspwin32.c index ffe36e2c61..0cb0a37675 100644 --- a/lib/sspwin32.c +++ b/lib/sspwin32.c @@ -35,7 +35,7 @@ #include "util.h" -#include "ntlmauth.h" +#include "libntlmauth/ntlmauth.h" #include "sspwin32.h" typedef struct _AUTH_SEQ { diff --git a/libntlmauth/Makefile.am b/libntlmauth/Makefile.am new file mode 100644 index 0000000000..6773731fbd --- /dev/null +++ b/libntlmauth/Makefile.am @@ -0,0 +1,26 @@ +include $(top_srcdir)/src/Common.am +include $(top_srcdir)/src/TestHeaders.am + +noinst_LIBRARIES = libntlmauth.a + +libntlmauth_a_SOURCES = \ + ntlmauth.cc \ + ntlmauth.h \ + rfcnb.h \ + rfcnb-io.c \ + rfcnb-priv.h \ + rfcnb-session.c \ + rfcnb-util.c \ + smb-byteorder.h \ + smb-des.c \ + smb-des.h \ + smb-encrypt.c \ + smb.h \ + smblib.c \ + smblib-priv.h \ + smblib-util.c \ + smblmauth.c \ + smblmauth.h \ + smb-md4.c \ + smb-md4.h \ + support_bits.cci diff --git a/lib/ntlmauth.c b/libntlmauth/ntlmauth.cc similarity index 72% rename from lib/ntlmauth.c rename to libntlmauth/ntlmauth.cc index 9688083b37..553e1c25e4 100644 --- a/lib/ntlmauth.c +++ b/libntlmauth/ntlmauth.cc @@ -34,7 +34,7 @@ #include #endif -#include "ntlmauth.h" +#include "libntlmauth/ntlmauth.h" #include "util.h" /* for base64-related stuff */ /* ************************************************************************* */ @@ -46,25 +46,25 @@ void ntlm_dump_ntlmssp_flags(u_int32_t flags) { fprintf(stderr, "flags: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - (flags & NEGOTIATE_UNICODE ? "Unicode " : ""), - (flags & NEGOTIATE_ASCII ? "ASCII " : ""), - (flags & NEGOTIATE_REQUEST_TARGET ? "ReqTgt " : ""), - (flags & NEGOTIATE_REQUEST_SIGN ? "ReqSign " : ""), - (flags & NEGOTIATE_REQUEST_SEAL ? "ReqSeal " : ""), - (flags & NEGOTIATE_DATAGRAM_STYLE ? "Dgram " : ""), - (flags & NEGOTIATE_USE_LM ? "UseLM " : ""), - (flags & NEGOTIATE_USE_NETWARE ? "UseNW " : ""), - (flags & NEGOTIATE_USE_NTLM ? "UseNTLM " : ""), - (flags & NEGOTIATE_DOMAIN_SUPPLIED ? "HaveDomain " : ""), - (flags & NEGOTIATE_WORKSTATION_SUPPLIED ? "HaveWKS " : ""), - (flags & NEGOTIATE_THIS_IS_LOCAL_CALL ? "LocalCall " : ""), - (flags & NEGOTIATE_ALWAYS_SIGN ? "AlwaysSign " : ""), - (flags & CHALLENGE_TARGET_IS_DOMAIN ? "Tgt_is_domain" : ""), - (flags & CHALLENGE_TARGET_IS_SERVER ? "Tgt_is_server " : ""), - (flags & CHALLENGE_TARGET_IS_SHARE ? "Tgt_is_share " : ""), - (flags & REQUEST_INIT_RESPONSE ? "Req_init_response " : ""), - (flags & REQUEST_ACCEPT_RESPONSE ? "Req_accept_response " : ""), - (flags & REQUEST_NON_NT_SESSION_KEY ? "Req_nonnt_sesskey " : "") + (flags & NTLM_NEGOTIATE_UNICODE ? "Unicode " : ""), + (flags & NTLM_NEGOTIATE_ASCII ? "ASCII " : ""), + (flags & NTLM_NEGOTIATE_REQUEST_TARGET ? "ReqTgt " : ""), + (flags & NTLM_NEGOTIATE_REQUEST_SIGN ? "ReqSign " : ""), + (flags & NTLM_NEGOTIATE_REQUEST_SEAL ? "ReqSeal " : ""), + (flags & NTLM_NEGOTIATE_DATAGRAM_STYLE ? "Dgram " : ""), + (flags & NTLM_NEGOTIATE_USE_LM ? "UseLM " : ""), + (flags & NTLM_NEGOTIATE_USE_NETWARE ? "UseNW " : ""), + (flags & NTLM_NEGOTIATE_USE_NTLM ? "UseNTLM " : ""), + (flags & NTLM_NEGOTIATE_DOMAIN_SUPPLIED ? "HaveDomain " : ""), + (flags & NTLM_NEGOTIATE_WORKSTATION_SUPPLIED ? "HaveWKS " : ""), + (flags & NTLM_NEGOTIATE_THIS_IS_LOCAL_CALL ? "LocalCall " : ""), + (flags & NTLM_NEGOTIATE_ALWAYS_SIGN ? "AlwaysSign " : ""), + (flags & NTLM_CHALLENGE_TARGET_IS_DOMAIN ? "Tgt_is_domain" : ""), + (flags & NTLM_CHALLENGE_TARGET_IS_SERVER ? "Tgt_is_server " : ""), + (flags & NTLM_CHALLENGE_TARGET_IS_SHARE ? "Tgt_is_share " : ""), + (flags & NTLM_REQUEST_INIT_RESPONSE ? "Req_init_response " : ""), + (flags & NTLM_REQUEST_ACCEPT_RESPONSE ? "Req_accept_response " : ""), + (flags & NTLM_REQUEST_NON_NT_SESSION_KEY ? "Req_nonnt_sesskey " : "") ); } @@ -73,7 +73,11 @@ ntlm_dump_ntlmssp_flags(u_int32_t flags) /* ************************************************************************* */ /** - * Check the validity of a decoded NTLM packet. Return -1 on error. + * Check the validity of a decoded NTLM packet. + * + * \retval NTLM_ERR_NONE Packet is okay + * \retval NTLM_ERR_BLOB Packet is not even an NTLMSSP packet at all. + * \retval NTLM_ERR_PROTOCOL Packet is not the expected type. */ int ntlm_validate_packet(const ntlmhdr * hdr, const int type) @@ -84,17 +88,17 @@ ntlm_validate_packet(const ntlmhdr * hdr, const int type) */ if (memcmp(hdr->signature, "NTLMSSP", 8) != 0) { fprintf(stderr, "ntlmCheckHeader: bad header signature\n"); - return (-1); + return NTLM_ERR_BLOB; } if (type == NTLM_ANY) - return 0; + return NTLM_ERR_NONE; if (le32toh(hdr->type) != type) { /* don't report this error - it's ok as we do a if() around this function */ // fprintf(stderr, "ntlmCheckHeader: type is %d, wanted %d\n", le32toh(hdr->type), type); - return (-1); + return NTLM_ERR_PROTOCOL; } - return (0); + return NTLM_ERR_NONE; } #define lstring_zero(s) s.str=NULL; s.l=-1; @@ -106,7 +110,7 @@ ntlm_validate_packet(const ntlmhdr * hdr, const int type) * be used in any way that requires a tailing \0. (can check whether the * value is there though, in that case lstring.length == -1). * - * String may be either ASCII or UNICODE depending on whether flags contains NEGOTIATE_ASCII + * String may be either ASCII or UNICODE depending on whether flags contains NTLM_NEGOTIATE_ASCII */ lstring ntlm_fetch_string(const ntlmhdr *packet, const int32_t packet_size, const strhdr * str, const u_int32_t flags) @@ -129,7 +133,7 @@ ntlm_fetch_string(const ntlmhdr *packet, const int32_t packet_size, const strhdr return rv; } rv.str = (char *)packet + o; - if ((flags & NEGOTIATE_ASCII) == 0) { + if ((flags & NTLM_NEGOTIATE_ASCII) == 0) { /* UNICODE string */ s = (u_short *) ((char *) packet + o); rv.str = d = buf; @@ -187,7 +191,7 @@ ntlm_add_to_payload(const ntlmhdr *packet_hdr, /* Negotiate Packet functions */ /* ************************************************************************* */ -// ?? +// ? /* ************************************************************************* */ @@ -213,39 +217,6 @@ ntlm_make_nonce(char *nonce) hash = r; } -#if DEAD_API -/** - * Prepares a base64-encode challenge packet to be sent to the client - * \note domain should be upper_case - * \note the storage type for the returned value depends on - * base64_encode_bin. Currently this means static storage. - */ -void -ntlm_make_challenge(const char *domain, const char *dc_UNUSED, - const char *cn, const int cnl) -{ - /* This function API has changes somewhat, and not all user helpers */ - ntlm_challenge chal; - - /* ORIGINAL flags was HARD-CODED set to these: - TODO: find all old callers (without flags field) and have them send these in manually now... - */ - u_int32_t flags = REQUEST_NON_NT_SESSION_KEY | - CHALLENGE_TARGET_IS_DOMAIN | - NEGOTIATE_ALWAYS_SIGN | - NEGOTIATE_USE_NTLM | - NEGOTIATE_USE_LM | - NEGOTIATE_ASCII; - - ntlm_make_challenge(&chal, domain, dc_UNUSED, cn, cnl, flags); - - /* ORIGINAL handling of ntlm_challenge object was to encode it like this: - TODO: find all old callers and have them do teh decode themselves now. - */ - return base64_encode_bin((char *)&chal, NTLM_CHALLENGE_HEADER_OFFSET + pl); -} -#endif - /** * Prepares a challenge packet to be sent to the client * \note domain should be upper_case @@ -279,9 +250,10 @@ ntlm_make_challenge(ntlm_challenge *ch, * this function will only insert data if the packet contains any. Otherwise * the buffers will be left untouched. * - * \retval -1 packet type is not an authentication packet. - * \retval 0 username present and maybe also domain. - * \retval 1 no username. + * \retval NTLM_ERR_NONE username present, maybe also domain. + * \retval NTLM_ERR_PROTOCOL packet type is not an authentication packet. + * \retval NTLM_ERR_LOGON no username. + * \retval NTLM_ERR_BLOB domain field is apparently larger than the packet. */ int ntlm_unpack_auth(const ntlm_authenticate *auth, char *user, char *domain, const int32_t size) @@ -290,7 +262,7 @@ ntlm_unpack_auth(const ntlm_authenticate *auth, char *user, char *domain, const if (ntlm_validate_packet(&auth->hdr, NTLM_AUTHENTICATE)) { fprintf(stderr, "ntlmDecodeAuth: header check fails\n"); - return -1; + return NTLM_ERR_PROTOCOL; } debug("ntlmDecodeAuth: size of %d\n", size); debug("ntlmDecodeAuth: flg %08x\n", auth->flags); @@ -303,7 +275,7 @@ ntlm_unpack_auth(const ntlm_authenticate *auth, char *user, char *domain, const debug("ntlm_unpack_auth: Domain '%s'.\n", domain); } if (rv.l >= size) - return 1; + return NTLM_ERR_BLOB; rv = ntlm_fetch_string(&auth->hdr, size, &auth->user, auth->flags); if (rv.l > 0) { @@ -311,7 +283,7 @@ ntlm_unpack_auth(const ntlm_authenticate *auth, char *user, char *domain, const user[rv.l] = '\0'; debug("ntlm_unpack_auth: Username '%s'.\n", user); } else - return 1; + return NTLM_ERR_LOGON; - return 0; + return NTLM_ERR_NONE; } diff --git a/include/ntlmauth.h b/libntlmauth/ntlmauth.h similarity index 80% rename from include/ntlmauth.h rename to libntlmauth/ntlmauth.h index 371ae9c2e3..93c62d7d35 100644 --- a/include/ntlmauth.h +++ b/libntlmauth/ntlmauth.h @@ -67,14 +67,32 @@ extern "C" { * Right. */ #define NTLM_MAX_FIELD_LENGTH 300 /* max length of an NTLMSSP field */ + /* max length of the BLOB data. (and helper input/output buffer) */ +#define NTLM_BLOB_BUFFER_SIZE 10240 /* Here start the NTLMSSP definitions */ /* these are marked as "extra" fields */ -#define REQUEST_INIT_RESPONSE 0x100000 -#define REQUEST_ACCEPT_RESPONSE 0x200000 -#define REQUEST_NON_NT_SESSION_KEY 0x400000 - +#define NTLM_REQUEST_INIT_RESPONSE 0x100000 +#define NTLM_REQUEST_ACCEPT_RESPONSE 0x200000 +#define NTLM_REQUEST_NON_NT_SESSION_KEY 0x400000 + + /* NTLM error codes */ +#define NTLM_ERR_INTERNAL -3 +#define NTLM_ERR_BLOB -2 +#define NTLM_ERR_BAD_PROTOCOL -1 +#define NTLM_ERR_NONE 0 /* aka. SMBLM_ERR_NONE */ + /* codes used by smb_lm helper */ +#define NTLM_ERR_SERVER 1 /* aka. SMBLM_ERR_SERVER */ +#define NTLM_ERR_PROTOCOL 2 /* aka. SMBLM_ERR_PROTOCOL */ +#define NTLM_ERR_LOGON 3 /* aka. SMBLM_ERR_LOGON */ +#define NTLM_ERR_UNTRUSTED_DOMAIN 4 +#define NTLM_ERR_NOT_CONNECTED 10 + /* codes used by mswin_ntlmsspi helper */ +#define NTLM_SSPI_ERROR 1 +#define NTLM_BAD_NTGROUP 2 +#define NTLM_BAD_REQUEST 3 + /* TODO: reduce the above codes down to one set non-overlapping. */ /** String header. String data resides at the end of the request */ typedef struct _strhdr { @@ -134,27 +152,27 @@ extern "C" { /* ************************************************************************* */ /* negotiate request flags */ -#define NEGOTIATE_UNICODE 0x0001 -#define NEGOTIATE_ASCII 0x0002 -#define NEGOTIATE_REQUEST_TARGET 0x0004 -#define NEGOTIATE_REQUEST_SIGN 0x0010 -#define NEGOTIATE_REQUEST_SEAL 0x0020 -#define NEGOTIATE_DATAGRAM_STYLE 0x0040 -#define NEGOTIATE_USE_LM 0x0080 -#define NEGOTIATE_USE_NETWARE 0x0100 -#define NEGOTIATE_USE_NTLM 0x0200 -#define NEGOTIATE_DOMAIN_SUPPLIED 0x1000 -#define NEGOTIATE_WORKSTATION_SUPPLIED 0x2000 -#define NEGOTIATE_THIS_IS_LOCAL_CALL 0x4000 -#define NEGOTIATE_ALWAYS_SIGN 0x8000 +#define NTLM_NEGOTIATE_UNICODE 0x0001 +#define NTLM_NEGOTIATE_ASCII 0x0002 +#define NTLM_NEGOTIATE_REQUEST_TARGET 0x0004 +#define NTLM_NEGOTIATE_REQUEST_SIGN 0x0010 +#define NTLM_NEGOTIATE_REQUEST_SEAL 0x0020 +#define NTLM_NEGOTIATE_DATAGRAM_STYLE 0x0040 +#define NTLM_NEGOTIATE_USE_LM 0x0080 +#define NTLM_NEGOTIATE_USE_NETWARE 0x0100 +#define NTLM_NEGOTIATE_USE_NTLM 0x0200 +#define NTLM_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 +#define NTLM_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000 +#define NTLM_NEGOTIATE_THIS_IS_LOCAL_CALL 0x4000 +#define NTLM_NEGOTIATE_ALWAYS_SIGN 0x8000 /** Negotiation request sent by client */ typedef struct _ntlm_negotiate { ntlmhdr hdr; /**< "NTLMSSP" , LSWAP(0x1) */ - u_int32_t flags; /**< Request flags */ + u_int32_t flags; /**< Request flags */ strhdr domain; /**< Domain we wish to authenticate in */ - strhdr workstation; /**< Client workstation name */ - char payload[256]; /**< String data */ + strhdr workstation; /**< Client workstation name */ + char payload[256]; /**< String data */ } ntlm_negotiate; @@ -165,9 +183,9 @@ extern "C" { #define NTLM_NONCE_LEN 8 /* challenge request flags */ -#define CHALLENGE_TARGET_IS_DOMAIN 0x10000 -#define CHALLENGE_TARGET_IS_SERVER 0x20000 -#define CHALLENGE_TARGET_IS_SHARE 0x40000 +#define NTLM_CHALLENGE_TARGET_IS_DOMAIN 0x10000 +#define NTLM_CHALLENGE_TARGET_IS_SERVER 0x20000 +#define NTLM_CHALLENGE_TARGET_IS_SHARE 0x40000 /** Challenge request sent by server. */ typedef struct _ntlm_challenge { diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.c b/libntlmauth/rfcnb-io.c similarity index 98% rename from helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.c rename to libntlmauth/rfcnb-io.c index d9700067e8..b449b29ba3 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-io.c +++ b/libntlmauth/rfcnb-io.c @@ -22,12 +22,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* #include */ #include "config.h" -#include "std-includes.h" -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" +#include "libntlmauth/rfcnb-priv.h" + #include #include #include @@ -228,7 +225,7 @@ RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) char hdr[RFCNB_Pkt_Hdr_Len]; /* Local space for the header */ struct RFCNB_Pkt *pkt_frag; int more, this_time, offset, frag_len, this_len; - BOOL seen_keep_alive = TRUE; + int seen_keep_alive = 1; /* Read that header straight into the buffer */ @@ -285,7 +282,7 @@ RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) #endif } else { - seen_keep_alive = FALSE; + seen_keep_alive = 0; } } diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-priv.h b/libntlmauth/rfcnb-priv.h similarity index 75% rename from helpers/ntlm_auth/smb_lm/smbval/rfcnb-priv.h rename to libntlmauth/rfcnb-priv.h index fdd7dbfaab..24dbfb94b6 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-priv.h +++ b/libntlmauth/rfcnb-priv.h @@ -26,13 +26,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Defines we need */ +/* The Public API stuff */ +#include "libntlmauth/rfcnb.h" -#define GLOBAL extern +/* The internals */ +#include "libntlmauth/smb-byteorder.h" -#include "rfcnb-error.h" -#include "rfcnb-common.h" -#include "byteorder.h" +#if HAVE_NETINET_IN_H +#include +#endif #ifdef RFCNB_PORT #define RFCNB_Default_Port RFCNB_PORT @@ -53,27 +55,6 @@ /* Structures */ -typedef struct redirect_addr *redirect_ptr; - -struct redirect_addr { - - struct in_addr ip_addr; - int port; - redirect_ptr next; - -}; - -typedef struct RFCNB_Con { - - int fd; /* File descripter for TCP/IP connection */ - int rfc_errno; /* last error */ - int timeout; /* How many milli-secs before IO times out */ - int redirects; /* How many times we were redirected */ - struct redirect_addr *redirect_list; /* First is first address */ - struct redirect_addr *last_addr; - -} RFCNB_Con; - typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with */ /* char[0] as the type, char[1] the */ /* flags, and char[2..3] the length */ @@ -151,4 +132,38 @@ extern int RFCNB_errno; extern int RFCNB_saved_errno; /* Save this from point of error */ #endif +/* I/O functions */ +extern int RFCNB_Put_Pkt(RFCNB_Con *con, RFCNB_Pkt *pkt, int len); + +extern int RFCNB_Get_Pkt(RFCNB_Con *con, RFCNB_Pkt *pkt, int len); + +extern void RFCNB_Free_Pkt(RFCNB_Pkt *pkt); + +/* Util functions */ + +void RFCNB_CvtPad_Name(char *name1, char *name2); + +void RFCNB_AName_To_NBName(char *AName, char *NBName); + +void RFCNB_NBName_To_AName(char *NBName, char *AName); + +void RFCNB_Print_Hex(FILE * fd, RFCNB_Pkt *pkt, int Offset, int Len); + +RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); + +void RFCNB_Print_Pkt(FILE * fd, char *dirn, RFCNB_Pkt *pkt, int len); + +int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP); + +int RFCNB_Close(int socket); + +int RFCNB_IP_Connect(struct in_addr Dest_IP, int port); + +int RFCNB_Session_Req(RFCNB_Con *con, + char *Called_Name, + char *Calling_Name, + int * redirect, + struct in_addr *Dest_IP, + int *port); + #endif /* __RFCNB_H__ */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/session.c b/libntlmauth/rfcnb-session.c similarity index 96% rename from helpers/ntlm_auth/smb_lm/smbval/session.c rename to libntlmauth/rfcnb-session.c index d854aaad59..ba352c8b6b 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/session.c +++ b/libntlmauth/rfcnb-session.c @@ -24,24 +24,17 @@ */ #define SQUID_NO_ALLOC_PROTECT 1 #include "config.h" +#include "libntlmauth/rfcnb-priv.h" +#include #include int RFCNB_errno = 0; int RFCNB_saved_errno = 0; -#define RFCNB_ERRNO - -#include "std-includes.h" -#include -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" -#include "rfcnb.h" +//#define RFCNB_ERRNO /* local functions */ - -int RFCNB_Get_Last_Error(void); int RFCNB_Get_Last_Errno(void); void RFCNB_Get_Error_Msg(int code, char *msg_buf, int len); void RFCNB_Register_Print_Routine(void (*fn) ()); @@ -88,7 +81,7 @@ RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, struct RFCNB_Con *con; struct in_addr Dest_IP; int Client; - BOOL redirect; + int redirect; struct redirect_addr *redir_addr; char *Service_Address; @@ -127,11 +120,11 @@ RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, } /* Now connect to the remote end */ - redirect = TRUE; /* Fudge this one so we go once through */ + redirect = 1; /* Fudge this one so we go once through */ while (redirect) { /* Connect and get session info etc */ - redirect = FALSE; /* Assume all OK */ + redirect = 0; /* Assume all OK */ /* Build the redirect info. First one is first addr called */ /* And tack it onto the list of addresses we called */ @@ -323,7 +316,7 @@ RFCNB_Hangup(struct RFCNB_Con *con_Handle) /* Set TCP_NODELAY on the socket */ int -RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn) +RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, int yn) { return (setsockopt(con_Handle->fd, IPPROTO_TCP, TCP_NODELAY, diff --git a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.c b/libntlmauth/rfcnb-util.c similarity index 98% rename from helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.c rename to libntlmauth/rfcnb-util.c index 20165dc52d..7eeb4a816d 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.c +++ b/libntlmauth/rfcnb-util.c @@ -24,14 +24,10 @@ */ #define SQUID_NO_ALLOC_PROTECT 1 #include "config.h" +#include "libntlmauth/rfcnb-priv.h" -#include - -#include "std-includes.h" -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" #include +#include extern void (*Prot_Print_Routine) (); /* Pointer to protocol print routine */ @@ -408,7 +404,7 @@ int RFCNB_Session_Req(struct RFCNB_Con *con, char *Called_Name, char *Calling_Name, - BOOL * redirect, + int * redirect, struct in_addr *Dest_IP, int *port) { @@ -507,7 +503,7 @@ RFCNB_Session_Req(struct RFCNB_Con *con, case RFCNB_SESSION_RETARGET: /* Go elsewhere */ - *redirect = TRUE; /* Copy port and ip addr */ + *redirect = 1; /* Copy port and ip addr */ memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr)); *port = SVAL(resp, RFCNB_Pkt_Port_Offset); diff --git a/libntlmauth/rfcnb.h b/libntlmauth/rfcnb.h new file mode 100644 index 0000000000..c5d9936561 --- /dev/null +++ b/libntlmauth/rfcnb.h @@ -0,0 +1,149 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + * + * Version 1.0 + * RFCNB Defines + * + * Copyright (C) Richard Sharpe 1996 + * + */ + +/* + * 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. + */ + +#ifndef _LIBNTLMAUTH_RFCNB_H +#define _LIBNTLMAUTH_RFCNB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if HAVE_NETINET_IN_H +#include +#endif + +/* API Defines we need */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error responses */ +/* these should follow the spec ... is there one ? */ + +#define RFCNBE_Bad -1 /* Bad response */ +#define RFCNBE_OK 0 /* Routine completed successfully. */ +#define RFCNBE_NoSpace 1 /* Could not allocate space for a struct */ +#define RFCNBE_BadName 2 /* Could not translate a name */ +#define RFCNBE_BadRead 3 /* Read sys call failed */ +#define RFCNBE_BadWrite 4 /* Write Sys call failed */ +#define RFCNBE_ProtErr 5 /* Protocol Error */ +#define RFCNBE_ConGone 6 /* Connection dropped */ +#define RFCNBE_BadHandle 7 /* Handle passed was bad */ +#define RFCNBE_BadSocket 8 /* Problems creating socket */ +#define RFCNBE_ConnectFailed 9 /* Connect failed */ +#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN */ +#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN */ +#define RFCNBE_CallRejCNNP 12 /* Call rejected, called name not present */ +#define RFCNBE_CallRejInfRes 13 /* Call rejetced, name ok, no resources */ +#define RFCNBE_CallRejUnSpec 14 /* Call rejected, unspecified error */ +#define RFCNBE_BadParam 15 /* Bad parameters passed ... */ +#define RFCNBE_Timeout 16 /* IO Timed out */ + +/* Text strings for the error responses */ +extern char const *RFCNB_Error_Strings[]; +/* + * static char *RFCNB_Error_Strings[] = { + * + * "RFCNBE_OK: Routine completed successfully.", + * "RFCNBE_NoSpace: No space available for a malloc call.", + * "RFCNBE_BadName: NetBIOS name could not be translated to IP address.", + * "RFCNBE_BadRead: Read system call returned an error. Check errno.", + * "RFCNBE_BadWrite: Write system call returned an error. Check errno.", + * "RFCNBE_ProtErr: A protocol error has occurred.", + * "RFCNBE_ConGone: Connection dropped during a read or write system call.", + * "RFCNBE_BadHandle: Bad connection handle passed.", + * "RFCNBE_BadSocket: Problems creating socket.", + * "RFCNBE_ConnectFailed: Connection failed. See errno.", + * "RFCNBE_CallRejNLOCN: Call rejected. Not listening on called name.", + * "RFCNBE_CallRejNLFCN: Call rejected. Not listening for called name.", + * "RFCNBE_CallRejCNNP: Call rejected. Called name not present.", + * "RFCNBE_CallRejInfRes: Call rejected. Name present, but insufficient resources.", + * "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.", + * "RFCNBE_BadParam: Bad parameters passed to a routine.", + * "RFCNBE_Timeout: IO Operation timed out ..." + * + * }; + */ + +#define RFCNB_Default_Port 139 + +/* API Structures */ + +typedef struct redirect_addr * redirect_ptr; + +struct redirect_addr { + struct in_addr ip_addr; + int port; + redirect_ptr next; +}; + +typedef struct RFCNB_Con { + int fd; /* File descripter for TCP/IP connection */ + int rfc_errno; /* last error */ + int timeout; /* How many milli-secs before IO times out */ + int redirects; /* How many times we were redirected */ + struct redirect_addr *redirect_list; /* First is first address */ + struct redirect_addr *last_addr; +} RFCNB_Con; + +typedef struct RFCNB_Pkt { + char *data; /* The data in this portion */ + int len; + struct RFCNB_Pkt *next; +} RFCNB_Pkt; + +/* API Definition of routines we define */ + +void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, int port); + +int RFCNB_Send(RFCNB_Con *Con_Handle, RFCNB_Pkt *Data, int Length); + +int RFCNB_Recv(void *Con_Handle, RFCNB_Pkt *Data, int Length); + +int RFCNB_Hangup(RFCNB_Con *con_Handle); + +void *RFCNB_Listen(void); + +void RFCNB_Get_Error(char *buffer, int buf_len); + +int RFCNB_Get_Last_Error(void); + +RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); + +void RFCNB_Free_Pkt(RFCNB_Pkt *pkt); + +int RFCNB_Set_Sock_NoDelay(RFCNB_Con *con_Handle, int yn); + +#ifdef __cplusplus +}; +#endif + +#endif /* _LIBNTLMAUTH_RFCNB_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/byteorder.h b/libntlmauth/smb-byteorder.h similarity index 96% rename from helpers/ntlm_auth/smb_lm/smbval/byteorder.h rename to libntlmauth/smb-byteorder.h index 138bcfe9d9..e1f52a669d 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/byteorder.h +++ b/libntlmauth/smb-byteorder.h @@ -18,6 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _LIBNTLMAUTH_SMB_BYTEORER_H +#define _LIBNTLMAUTH_SMB_BYTEORER_H /* * This file implements macros for machine independent short and @@ -78,3 +80,5 @@ #define RIVAL(buf,pos) IREV(IVAL(buf,pos)) #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) + +#endif /* LIBNTLMAUTH_SMB_BYTEORER_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/smbdes.c b/libntlmauth/smb-des.c similarity index 99% rename from helpers/ntlm_auth/smb_lm/smbval/smbdes.c rename to libntlmauth/smb-des.c index 8e1931219f..5c4f068ead 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smbdes.c +++ b/libntlmauth/smb-des.c @@ -44,8 +44,8 @@ * should confirm it for yourself (and maybe let me know if you come * up with a different answer to the one above) */ - -#include "smbdes.h" +#include "config.h" +#include "libntlmauth/smb-des.h" /* local functions */ void cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key); diff --git a/helpers/ntlm_auth/smb_lm/smbval/smbdes.h b/libntlmauth/smb-des.h similarity index 100% rename from helpers/ntlm_auth/smb_lm/smbval/smbdes.h rename to libntlmauth/smb-des.h diff --git a/helpers/ntlm_auth/smb_lm/smbval/smbencrypt.c b/libntlmauth/smb-encrypt.c similarity index 84% rename from helpers/ntlm_auth/smb_lm/smbval/smbencrypt.c rename to libntlmauth/smb-encrypt.c index 3bbf4a2f7a..6c2024305d 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smbencrypt.c +++ b/libntlmauth/smb-encrypt.c @@ -19,8 +19,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "config.h" +#include "libntlmauth/smb-byteorder.h" +#include "libntlmauth/smb-des.h" +#include "libntlmauth/smb-md4.h" +#include "libntlmauth/smblib-priv.h" -#include "std-includes.h" #include #include #include @@ -28,20 +32,12 @@ #include #include -#include "smblib-priv.h" -#include "md4.h" -#include "smbdes.h" - -#define uchar unsigned char extern int DEBUGLEVEL; -#include "byteorder.h" -#include "smbencrypt.h" - /* local functions */ char *StrnCpy(char *dest, char *src, int n); void strupper(char *s); -void E_md4hash(uchar * passwd, uchar * p16); +void E_md4hash(unsigned char * passwd, unsigned char * p16); void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16); /* @@ -49,9 +45,9 @@ void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16); * It takes a password, a 8 byte "crypt key" and puts 24 bytes of * encrypted password into p24 */ void -SMBencrypt(uchar * passwd, uchar * c8, uchar * p24) +SMBencrypt(unsigned char * passwd, unsigned char * c8, unsigned char * p24) { - uchar p14[15], p21[21]; + unsigned char p14[15], p21[21]; memset(p21, '\0', 21); memset(p14, '\0', 14); @@ -64,7 +60,7 @@ SMBencrypt(uchar * passwd, uchar * c8, uchar * p24) /* Routines for Windows NT MD4 Hash functions. */ static int -_my_wcslen(int16 * str) +_my_wcslen(int16_t * str) { int len = 0; while (*str++ != 0) @@ -80,10 +76,10 @@ _my_wcslen(int16 * str) */ static int -_my_mbstowcs(int16 * dst, uchar * src, int len) +_my_mbstowcs(int16_t * dst, unsigned char * src, int len) { int i; - int16 val; + int16_t val; for (i = 0; i < len; i++) { val = *src; @@ -100,10 +96,10 @@ _my_mbstowcs(int16 * dst, uchar * src, int len) * Creates the MD4 Hash of the users password in NT UNICODE. */ void -E_md4hash(uchar * passwd, uchar * p16) +E_md4hash(unsigned char * passwd, unsigned char * p16) { int len; - int16 wpwd[129]; + int16_t wpwd[129]; /* Password cannot be longer than 128 characters */ len = strlen((char *) passwd); @@ -113,16 +109,16 @@ E_md4hash(uchar * passwd, uchar * p16) _my_mbstowcs(wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(int16); + len = _my_wcslen(wpwd) * sizeof(int16_t); mdfour(p16, (unsigned char *) wpwd, len); } /* Does the NT MD4 hash then des encryption. */ void -SMBNTencrypt(uchar * passwd, uchar * c8, uchar * p24) +SMBNTencrypt(unsigned char * passwd, unsigned char * c8, unsigned char * p24) { - uchar p21[21]; + unsigned char p21[21]; memset(p21, '\0', 21); @@ -139,7 +135,7 @@ nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash((uchar *) passwd, (uchar *) nt_p16); + E_md4hash((unsigned char *) passwd, (unsigned char *) nt_p16); /* Mangle the passwords into Lanman format */ passwd[14] = '\0'; @@ -148,7 +144,7 @@ nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *) p16); + E_P16((unsigned char *) passwd, (unsigned char *) p16); /* clear out local copy of user's password (just being paranoid). */ memset(passwd, 0, sizeof(passwd)); diff --git a/helpers/ntlm_auth/smb_lm/smbval/md4.c b/libntlmauth/smb-md4.c similarity index 88% rename from helpers/ntlm_auth/smb_lm/smbval/md4.c rename to libntlmauth/smb-md4.c index 8bcf494c6d..9c06b809aa 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/md4.c +++ b/libntlmauth/smb-md4.c @@ -24,48 +24,50 @@ * * It assumes that a int is at least 32 bits long */ +#include "config.h" +#include "libntlmauth/smblib-priv.h" +#include "libntlmauth/smb-md4.h" + #include -#include "std-defines.h" /* for the types */ -#include "md4.h" -static uint32 A, B, C, D; +static uint32_t A, B, C, D; -static uint32 -F(uint32 X, uint32 Y, uint32 Z) +static uint32_t +F(uint32_t X, uint32_t Y, uint32_t Z) { return (X & Y) | ((~X) & Z); } -static uint32 -G(uint32 X, uint32 Y, uint32 Z) +static uint32_t +G(uint32_t X, uint32_t Y, uint32_t Z) { return (X & Y) | (X & Z) | (Y & Z); } -static uint32 -H(uint32 X, uint32 Y, uint32 Z) +static uint32_t +H(uint32_t X, uint32_t Y, uint32_t Z) { return X ^ Y ^ Z; } -static uint32 -lshift(uint32 x, int s) +static uint32_t +lshift(uint32_t x, int s) { x &= 0xFFFFFFFF; return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); } #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) +#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32_t)0x5A827999,s) +#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32_t)0x6ED9EBA1,s) /* this applies md4 to 64 byte chunks */ static void -mdfour64(uint32 * M) +mdfour64(uint32_t * M) { int j; - uint32 AA, BB, CC, DD; - uint32 X[16]; + uint32_t AA, BB, CC, DD; + uint32_t X[16]; for (j = 0; j < 16; j++) X[j] = M[j]; @@ -141,7 +143,7 @@ mdfour64(uint32 * M) } static void -copy64(uint32 * M, unsigned char *in) +copy64(uint32_t * M, unsigned char *in) { int i; @@ -151,7 +153,7 @@ copy64(uint32 * M, unsigned char *in) } static void -copy4(unsigned char *out, uint32 x) +copy4(unsigned char *out, uint32_t x) { out[0] = x & 0xFF; out[1] = (x >> 8) & 0xFF; @@ -164,8 +166,8 @@ void mdfour(unsigned char *out, unsigned char *in, int n) { unsigned char buf[128]; - uint32 M[16]; - uint32 b = n * 8; + uint32_t M[16]; + uint32_t b = n * 8; int i; A = 0x67452301; diff --git a/helpers/ntlm_auth/smb_lm/smbval/md4.h b/libntlmauth/smb-md4.h similarity index 100% rename from helpers/ntlm_auth/smb_lm/smbval/md4.h rename to libntlmauth/smb-md4.h diff --git a/helpers/ntlm_auth/smb_lm/smbval/smblib-common.h b/libntlmauth/smb.h similarity index 52% rename from helpers/ntlm_auth/smb_lm/smbval/smblib-common.h rename to libntlmauth/smb.h index 678305d426..2e4ffdf569 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smblib-common.h +++ b/libntlmauth/smb.h @@ -1,10 +1,7 @@ -#ifndef __SMBLIB_COMMON_H__ -#define __SMBLIB_COMMON_H__ - /* UNIX SMBlib NetBIOS implementation * * Version 1.0 - * SMBlib Common Defines + * SMBlib Defines * * Copyright (C) Richard Sharpe 1996 * @@ -25,6 +22,26 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _SMBVAL_SMBLIB_H +#define _SMBVAL_SMBLIB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef PRIVATE_API +#define SMBLIB_DEFAULT_DOMAIN "anydom" +#endif /* PRIVATE_API */ + +#ifdef __cplusplus +extern "C" { +#endif /* To get the error class we want the first 8 bits */ /* Because we just grab 4bytes from the SMB header, we have to re-order */ @@ -186,4 +203,156 @@ typedef struct { /* A structure for a Dirent */ } SMB_CP_dirent; -#endif /* __SMBLIB_COMMON_H__ */ +/* Handle Structures */ + +typedef struct SMB_Tree_Structure * SMB_Tree_Handle; +typedef struct SMB_Connect_Def * SMB_Handle_Type; + +struct SMB_Tree_Structure { + SMB_Tree_Handle next, prev; + SMB_Handle_Type con; + char path[129]; + char device_type[20]; + int mbs; /* Local MBS */ + int tid; +}; + +struct SMB_Connect_Def { + SMB_Handle_Type Next_Con, Prev_Con; /* Next and previous conn */ + int protocol; /* What is the protocol */ + int prot_IDX; /* And what is the index */ + void *Trans_Connect; /* The connection */ + + /* All these strings should be malloc'd */ + + char service[80], username[80], password[80], desthost[80], sock_options[80]; + char address[80], myname[80]; + + SMB_Tree_Handle first_tree, last_tree; /* List of trees on this server */ + + int gid; /* Group ID, do we need it? */ + int mid; /* Multiplex ID? We might need one per con */ + int pid; /* Process ID */ + + int uid; /* Authenticated user id. */ + + /* It is pretty clear that we need to bust some of */ + /* these out into a per TCon record, as there may */ + /* be multiple TCon's per server, etc ... later */ + + int port; /* port to use in case not default, this is a TCPism! */ + + int max_xmit; /* Max xmit permitted by server */ + int Security; /* 0 = share, 1 = user */ + int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */ + int16_t encrypt_passwords; /* TRUE/FALSE. FALSE = don't */ + int MaxMPX, MaxVC, MaxRaw; + unsigned int SessionKey, Capabilities; + int SvrTZ; /* Server Time Zone */ + int Encrypt_Key_Len; + char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40]; + char Svr_OS[80], Svr_LMType[80], Svr_PDom[80]; +}; + +/* Initialize the SMBlib package */ +int SMB_Init(void); + +/* Create a handle to allow us to set/override some parameters ... */ +SMB_Handle_Type SMB_Create_Con_Handle(); + +/* Connect to a server, but do not do a tree con etc ... */ +SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, + char *server, + char *NTdomain); + +/* Connect to a server and give us back a handle. If Con == NULL, create */ +/* The handle and populate it with defaults */ +SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, + SMB_Tree_Handle * tree, + char *service, + char *username, + char *password); + +int SMB_Logon_Server(SMB_Handle_Type Con_Handle, + char *UserName, + char *PassWord, + char *UserDomain, + int precrypted); + +/* Negotiate a protocol */ +int SMB_Negotiate(SMB_Handle_Type con, char const *Prots[]); + +/* Connect to a tree ... */ +SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con, + SMB_Tree_Handle tree, + char *path, + char *password, + char const *device); + + +/* Disconnect a tree ... */ +int SMB_TreeDisconect(void *tree_handle); + +/* Open a file */ +void *SMB_Open(void *tree_handle, + void *file_handle, + char *file_name, + unsigned short mode, + unsigned short search); + +/* Close a file */ +int SMB_Close(void *file_handle); + +/* Disconnect from server. Has flag to specify whether or not we keep the */ +/* handle. */ +int SMB_Discon(SMB_Handle_Type Con, + int KeepHandle); + +void *SMB_Create(void *Tree_Handle, + void *File_Handle, + char *file_name, + short search); + +int SMB_Delete(void *tree, + char *file_name, + short search); + +int SMB_Create_Dir(void *tree, + char *dir_name); + +int SMB_Delete_Dir(void *tree, + char *dir_name); + +int SMB_Check_Dir(void *tree, + char *dir_name); + +int SMB_Get_Last_Error(); + +int SMB_Get_Last_SMB_Err(); + +int SMB_Get_Error_Msg(int msg, + char *msgbuf, + int len); + +void *SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, + void *tree, + char *user, + char *pass, + char *service, + char *st); + +/* Encryption Functions */ + +void SMBencrypt(unsigned char * passwd, + unsigned char * c8, + unsigned char * p24); + +void SMBNTencrypt(unsigned char * passwd, + unsigned char * c8, + unsigned char * p24); + +#ifdef __cplusplus +} +#endif + +#endif /* _SMBVAL_SMBLIB_H */ diff --git a/helpers/ntlm_auth/smb_lm/smbval/smblib-priv.h b/libntlmauth/smblib-priv.h similarity index 90% rename from helpers/ntlm_auth/smb_lm/smbval/smblib-priv.h rename to libntlmauth/smblib-priv.h index f54f9a6566..b83864ce17 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smblib-priv.h +++ b/libntlmauth/smblib-priv.h @@ -26,11 +26,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "std-defines.h" -#include "smblib-common.h" +/* The public API bits */ +#define PRIVATE_API +#include "libntlmauth/smb.h" + +//#include "std-defines.h" #include -#include "byteorder.h" /* Hmmm ... hot good */ +//#include "byteorder.h" /* Hmmm ... not good */ #ifndef max #define max(a,b) ((a) < (b) ? (b) : (a)) @@ -131,11 +134,14 @@ #define SMB_FLG2_EXT_ATR 0x02 /* We know about Extended Attributes */ #define SMB_FLG2_LNG_NAM 0x04 /* Long names ? */ +/* Not good */ +#if 0 typedef unsigned short WORD; typedef unsigned short UWORD; typedef unsigned int ULONG; typedef unsigned char BYTE; typedef unsigned char UCHAR; +#endif /* Some macros to allow access to actual packet data so that we */ /* can change the underlying representation of packets. */ @@ -159,7 +165,7 @@ typedef unsigned char UCHAR; /* We define these as offsets into a char SMB[] array for the */ /* sake of portability */ -/* NOTE!. Some of the lenght defines, SMB__len do not include */ +/* NOTE!. Some of the length defines, SMB__len do not include */ /* the data that follows in the SMB packet, so the code will have to */ /* take that into account. */ @@ -548,50 +554,8 @@ typedef struct SMB_Status { } status; } SMB_Status; -typedef struct SMB_Tree_Structure *SMB_Tree_Handle; - -typedef struct SMB_Connect_Def *SMB_Handle_Type; - -struct SMB_Connect_Def { - - SMB_Handle_Type Next_Con, Prev_Con; /* Next and previous conn */ - int protocol; /* What is the protocol */ - int prot_IDX; /* And what is the index */ - void *Trans_Connect; /* The connection */ - - /* All these strings should be malloc'd */ - - char service[80], username[80], password[80], desthost[80], sock_options[80]; - char address[80], myname[80]; - - SMB_Tree_Handle first_tree, last_tree; /* List of trees on this server */ - - int gid; /* Group ID, do we need it? */ - int mid; /* Multiplex ID? We might need one per con */ - int pid; /* Process ID */ - - int uid; /* Authenticated user id. */ - - /* It is pretty clear that we need to bust some of */ - /* these out into a per TCon record, as there may */ - /* be multiple TCon's per server, etc ... later */ - - int port; /* port to use in case not default, this is a TCPism! */ - - int max_xmit; /* Max xmit permitted by server */ - int Security; /* 0 = share, 1 = user */ - int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */ - BOOL encrypt_passwords; /* FALSE = don't */ - int MaxMPX, MaxVC, MaxRaw; - unsigned int SessionKey, Capabilities; - int SvrTZ; /* Server Time Zone */ - int Encrypt_Key_Len; - char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40]; - char Svr_OS[80], Svr_LMType[80], Svr_PDom[80]; - -}; - -#ifndef SMBLIB_DEFAULT_DOMAIN +#if 0 +// #ifndef SMBLIB_DEFAULT_DOMAIN #define SMBLIB_DEFAULT_DOMAIN "STAFF" #endif #define SMBLIB_DEFAULT_OSNAME "UNIX of some type" @@ -601,52 +565,25 @@ struct SMB_Connect_Def { #define SMB_Sec_Mode_Share 0 #define SMB_Sec_Mode_User 1 -/* A Tree_Structure */ - -struct SMB_Tree_Structure { - - SMB_Tree_Handle next, prev; - SMB_Handle_Type con; - char path[129]; - char device_type[20]; - int mbs; /* Local MBS */ - int tid; - -}; - typedef struct SMB_File_Def SMB_File; struct SMB_File_Def { - SMB_Tree_Handle tree; char filename[256]; /* We should malloc this ... */ - UWORD fid; + unsigned short /*UWORD*/ fid; unsigned int lastmod; unsigned int size; /* Could blow up if 64bit files supported */ - UWORD access; + unsigned short /*UWORD*/ access; off_t fileloc; - }; /* global Variables for the library */ - extern SMB_State_Types SMBlib_State; - -#ifndef SMBLIB_ERRNO extern int SMBlib_errno; extern int SMBlib_SMB_Error; /* last Error */ -#endif - -extern SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con, SMB_Tree_Handle tree, - char *path, char *password, char const *dev); -extern int SMB_Init(void); extern void SMB_Get_My_Name(char *name, int len); -extern int SMB_Negotiate(SMB_Handle_Type Con_Handle, char const *Prots[]); -extern int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle); - -extern int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, - char *PassWord, char *UserDomain, int precrypted); +extern int SMB_Discon(SMB_Handle_Type Con_Handle, int KeepHandle); extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); diff --git a/helpers/ntlm_auth/smb_lm/smbval/smblib-util.c b/libntlmauth/smblib-util.c similarity index 98% rename from helpers/ntlm_auth/smb_lm/smbval/smblib-util.c rename to libntlmauth/smblib-util.c index c6bc5043a0..ef7822d525 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smblib-util.c +++ b/libntlmauth/smblib-util.c @@ -24,21 +24,21 @@ */ #define SQUID_NO_ALLOC_PROTECT 1 #include "config.h" +#include "libntlmauth/rfcnb.h" +#include "libntlmauth/smblib-priv.h" +#include "libntlmauth/smb-byteorder.h" -#include "smblib-priv.h" #include -#include "rfcnb.h" - /* local functions */ char * SMB_DOSTimToStr(int DOS_time); -char * SMB_AtrToStr(int attribs, BOOL verbose); +char * SMB_AtrToStr(int attribs, int verbose); int SMB_Get_Tree_MBS(SMB_Tree_Handle tree); int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle); int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle); int SMB_Get_Protocol(SMB_Handle_Type Con_Handle); int SMB_Figure_Protocol(char const *dialects[], int prot_index); -int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard); +int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard); // int SMB_Get_Last_Error(void); int SMB_Get_Last_SMB_Err(void); @@ -78,7 +78,7 @@ static char const *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", /* Print out an SMB pkt in all its gory detail ... */ #if 0 // DEAD CODE void -SMB_Print_Pkt(FILE fd, RFCNB_Pkt * pkt, BOOL command, int Offset, int Len) +SMB_Print_Pkt(FILE fd, RFCNB_Pkt * pkt, int command, int Offset, int Len) { /* Well, just how do we do this ... print it I suppose */ @@ -126,7 +126,7 @@ SMB_DOSTimToStr(int DOS_time) * true, we print out long form of strings ... */ char * -SMB_AtrToStr(int attribs, BOOL verbose) +SMB_AtrToStr(int attribs, int verbose) { static char SMB_Attrib_Temp[128]; @@ -608,7 +608,7 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, } int -SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard) +SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) { struct RFCNB_Pkt *pkt; int pkt_len; @@ -689,7 +689,7 @@ SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard) /* What about the tree handle ? */ - if (discard == TRUE) { /* Unlink it and free it ... */ + if (discard) { /* Unlink it and free it ... */ if (Tree_Handle->next == NULL) Tree_Handle->con->first_tree = Tree_Handle->prev; diff --git a/helpers/ntlm_auth/smb_lm/smbval/smblib.c b/libntlmauth/smblib.c similarity index 95% rename from helpers/ntlm_auth/smb_lm/smbval/smblib.c rename to libntlmauth/smblib.c index ae1dfe59de..d196a5fbb6 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/smblib.c +++ b/libntlmauth/smblib.c @@ -26,65 +26,47 @@ #define SQUID_NO_ALLOC_PROTECT 1 #include "config.h" +#include "libntlmauth/rfcnb.h" +#include "libntlmauth/smblib-priv.h" +#include "libntlmauth/smb-byteorder.h" +//#include "smbencrypt.h" + #include +#include #include int SMBlib_errno; int SMBlib_SMB_Error; -#define SMBLIB_ERRNO -#define uchar unsigned char -#include "smblib-priv.h" - -#include "rfcnb.h" -#include "smbencrypt.h" - -#include +SMB_State_Types SMBlib_State; /* local functions */ int SMB_Term(void); SMB_Handle_Type SMB_Create_Con_Handle(void); -int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn); -SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, char *server, char *NTdomain); -SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, SMB_Tree_Handle * tree, char *service, char *username, char *password); - +int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, int yn); -/* #define DEBUG */ - -SMB_State_Types SMBlib_State; -/* Initialize the SMBlib package */ +/** Initialize the SMBlib package */ int SMB_Init() { - SMBlib_State = SMB_State_Started; - signal(SIGPIPE, SIG_IGN); /* Ignore these ... */ /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */ #ifdef SMBLIB_INSTRUMENT - SMBlib_Instrument_Init(); - #endif - return 0; - } int SMB_Term() { - #ifdef SMBLIB_INSTRUMENT - SMBlib_Instrument_Term(); /* Clean up and print results */ - #endif - return 0; - } /** @@ -99,7 +81,7 @@ SMB_Create_Con_Handle() } int -SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn) +SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, int yn) { if (RFCNB_Set_Sock_NoDelay(Con_Handle->Trans_Connect, yn) < 0) { fprintf(stderr, "Setting no-delay on TCP socket failed ...\n"); @@ -118,20 +100,16 @@ SMB_Connect_Server(SMB_Handle_Type Con_Handle, int i; /* Get a connection structure if one does not exist */ - con = Con_Handle; if (Con_Handle == NULL) { - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; return NULL; } } - /* Init some things ... */ + /* Init some things ... */ strcpy(con->service, ""); strcpy(con->username, ""); strcpy(con->password, ""); @@ -155,11 +133,9 @@ SMB_Connect_Server(SMB_Handle_Type Con_Handle, } } - con->port = 0; /* No port selected */ /* Get some things we need for the SMB Header */ - con->pid = getpid(); con->mid = con->pid; /* This will do for now ... */ con->uid = 0; /* Until we have done a logon, no uid ... */ @@ -189,9 +165,7 @@ SMB_Connect_Server(SMB_Handle_Type Con_Handle, con->port); /* Did we get one? */ - if (con->Trans_Connect == NULL) { - if (Con_Handle == NULL) { Con_Handle = NULL; free(con); @@ -201,7 +175,6 @@ SMB_Connect_Server(SMB_Handle_Type Con_Handle, } return (con); - } /* SMB_Connect: Connect to the indicated server */ @@ -226,19 +199,16 @@ SMB_Connect(SMB_Handle_Type Con_Handle, int i; /* Get a connection structure if one does not exist */ - con = Con_Handle; if (Con_Handle == NULL) { - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - SMBlib_errno = SMBlibE_NoSpace; return NULL; } } - /* Init some things ... */ + /* Init some things ... */ strcpy(con->service, service); strcpy(con->username, username); strcpy(con->password, password); @@ -254,14 +224,12 @@ SMB_Connect(SMB_Handle_Type Con_Handle, con->port = 0; /* No port selected */ /* Get some things we need for the SMB Header */ - con->pid = getpid(); con->mid = con->pid; /* This will do for now ... */ con->uid = 0; /* Until we have done a logon, no uid */ con->gid = getgid(); /* Now figure out the host portion of the service */ - strcpy(temp, service); host = (char *) strtok(temp, "/\\"); /* Separate host name portion */ strcpy(con->desthost, host); @@ -292,14 +260,12 @@ SMB_Connect(SMB_Handle_Type Con_Handle, /* Did we get one? */ if (con->Trans_Connect == NULL) { - if (Con_Handle == NULL) { free(con); Con_Handle = NULL; } SMBlib_errno = -SMBlibE_CallFailed; return NULL; - } /* Now, negotiate the protocol */ @@ -315,12 +281,10 @@ SMB_Connect(SMB_Handle_Type Con_Handle, return NULL; } return (con); - } /* Logon to the server. That is, do a session setup if we can. We do not do */ /* Unicode yet! */ - int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, char *UserDomain, int precrypted) @@ -332,12 +296,9 @@ SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, /* First we need a packet etc ... but we need to know what protocol has */ /* been negotiated to figure out if we can do it and what SMB format to */ /* use ... */ - if (Con_Handle->protocol < SMB_P_LanMan1) { - SMBlib_errno = SMBlibE_ProtLow; return (SMBlibE_BAD); - } if (precrypted) { pass_len = 24; @@ -346,13 +307,12 @@ SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, strcpy(pword, PassWord); if (Con_Handle->encrypt_passwords) { pass_len = 24; - SMBencrypt((uchar *) PassWord, (uchar *) Con_Handle->Encrypt_Key, (uchar *) pword); + SMBencrypt((unsigned char *) PassWord, (unsigned char *) Con_Handle->Encrypt_Key, (unsigned char *) pword); } else pass_len = strlen(pword); } /* Now build the correct structure */ - if (Con_Handle->protocol < SMB_P_NT1) { param_len = strlen(UserName) + 1 + pass_len + 1 + @@ -486,77 +446,60 @@ SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, } /* Now send it and get a response */ - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - #ifdef DEBUG fprintf(stderr, "Error sending SessSetupX request\n"); #endif - RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_SendFailed; return (SMBlibE_BAD); - } - /* Now get the response ... */ + /* Now get the response ... */ if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - #ifdef DEBUG fprintf(stderr, "Error receiving response to SessSetupAndX\n"); #endif - RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_RecvFailed; return (SMBlibE_BAD); - } - /* Check out the response type ... */ + /* Check out the response type ... */ if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ - #ifdef DEBUG fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); #endif - SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_Remote; return (SMBlibE_BAD); - } + /** @@@ mdz: check for guest login { **/ if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1) { /* do we allow guest login? NO! */ return (SMBlibE_BAD); - } /** @@@ mdz: } **/ - #ifdef DEBUG fprintf(stderr, "SessSetupAndX response. Action = %i\n", SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); #endif /* Now pick up the UID for future reference ... */ - Con_Handle->uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); RFCNB_Free_Pkt(pkt); - return (0); - } - /* Disconnect from the server, and disconnect all tree connects */ - int -SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle) +SMB_Discon(SMB_Handle_Type Con_Handle, int KeepHandle) { - /* We just disconnect the connection for now ... */ if (Con_Handle != NULL) RFCNB_Hangup(Con_Handle->Trans_Connect); @@ -565,5 +508,4 @@ SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle) free(Con_Handle); return (0); - } diff --git a/helpers/ntlm_auth/smb_lm/smbval/valid.c b/libntlmauth/smblmauth.c similarity index 74% rename from helpers/ntlm_auth/smb_lm/smbval/valid.c rename to libntlmauth/smblmauth.c index 4130dda766..01c855b2ce 100644 --- a/helpers/ntlm_auth/smb_lm/smbval/valid.c +++ b/libntlmauth/smblmauth.c @@ -1,4 +1,7 @@ #include "config.h" +#include "libntlmauth/ntlmauth.h" +#include "libntlmauth/smblmauth.h" +#include "libntlmauth/smb.h" #if HAVE_SYS_TYPES_H #include @@ -13,13 +16,11 @@ #include #endif -#include "smblib-priv.h" -#include "valid.h" - -SMB_Handle_Type SMB_Connect_Server(void *, char *, char *); - +/** Do a full authentication sequence against the given server with user/pass/domain. + * Password is pre-encrypted. + */ int -Valid_User(char *username, char *password, char *server, char *backup, char *domain) +smblm_authenticate_atomic(char *username, char *password, char *server, char *backup, char *domain) { int pass_is_precrypted_p = 0; char const *supportedDialects[] = { @@ -40,28 +41,29 @@ Valid_User(char *username, char *password, char *server, char *backup, char *dom if (con == NULL) { /* Error ... */ con = SMB_Connect_Server(NULL, backup, domain); if (con == NULL) { - return (NTV_SERVER_ERROR); + return SMBLM_ERR_SERVER; } } if (SMB_Negotiate(con, supportedDialects) < 0) { /* An error */ SMB_Discon(con, 0); - return (NTV_PROTOCOL_ERROR); + return SMBLM_ERR_PROTOCOL; } /* Test for a server in share level mode do not authenticate against it */ if (con->Security == 0) { SMB_Discon(con, 0); - return (NTV_PROTOCOL_ERROR); + return SMBLM_ERR_PROTOCOL; } if (SMB_Logon_Server(con, username, password, domain, pass_is_precrypted_p) < 0) { SMB_Discon(con, 0); - return (NTV_LOGON_ERROR); + return SMBLM_ERR_LOGON; } SMB_Discon(con, 0); - return (NTV_NO_ERROR); + return SMBLM_ERR_NONE; } +/** Fetches a SMB LanMan challenge nonce from the given server. */ void * -NTLM_Connect(char *server, char *backup, char *domain, char *nonce) +smblm_get_nonce(char *server, char *backup, char *domain, char *nonce) { char const *SMB_Prots[] = { /* "PC NETWORK PROGRAM 1.0", */ @@ -84,34 +86,30 @@ NTLM_Connect(char *server, char *backup, char *domain, char *nonce) return (NULL); } } + if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */ SMB_Discon(con, 0); return (NULL); } + /* Test for a server in share level mode do not authenticate against it */ if (con->Security == 0) { SMB_Discon(con, 0); return (NULL); } - memcpy(nonce, con->Encrypt_Key, 8); + memcpy(nonce, con->Encrypt_Key, 8); return (con); } +/** Authenticate with given username/password */ int -NTLM_Auth(void *handle, char *username, char *password, int flag) +smblm_authenticate(void *handle, char *username, char *password, int flag) { SMB_Handle_Type con = handle; if (SMB_Logon_Server(con, username, password, NULL, flag) < 0) { - return (NTV_LOGON_ERROR); + return SMBLM_ERR_LOGON; } - return (NTV_NO_ERROR); -} - -void -NTLM_Disconnect(void *handle) -{ - SMB_Handle_Type con = handle; - SMB_Discon(con, 0); + return SMBLM_ERR_NONE; } diff --git a/libntlmauth/smblmauth.h b/libntlmauth/smblmauth.h new file mode 100644 index 0000000000..07d237ed42 --- /dev/null +++ b/libntlmauth/smblmauth.h @@ -0,0 +1,39 @@ +#ifndef _LIBNTLMAUTH_SMBLMAUTH_H +#define _LIBNTLMAUTH_SMBLMAUTH_H + +/* TODO: copyright. who owns this? there was none in the original code!! */ +/* Maybe Richard Sharpe or maybe not. */ + + /* SMB LM Error Codes */ +#define SMBLM_ERR_NONE 0 +#define SMBLM_ERR_SERVER 1 +#define SMBLM_ERR_PROTOCOL 2 +#define SMBLM_ERR_LOGON 3 + +/** + * Connect to a SMB LanMan server and authenticate the provided credentials. + * + * TODO: const-correctness on the parameters. + */ +extern int smblm_authenticate_atomic(char *username, + char *password, + char *server, + char *backup, + char *domain); + +/** Fetches a SMB LanMan challenge nonce from the given server. */ +void * smblm_get_nonce(char *server, + char *backup, + char *domain, + char *nonce); + +/** Authenticate with given username/password */ +int smblm_authenticate(void *handle, + char *username, + char *password, + int flag); + +/** Disconnect a handle from use */ +#define smblm_disconnect(x) SMB_Discon(X, 0) + +#endif /* _LIBNTLMAUTH_SMBLMAUTH_H */ diff --git a/libntlmauth/support_bits.cci b/libntlmauth/support_bits.cci new file mode 100644 index 0000000000..b87cd7646c --- /dev/null +++ b/libntlmauth/support_bits.cci @@ -0,0 +1,93 @@ +#ifndef _SQUID_LIBNTLMAUTH_SUPPORT_BITS_CCI +#define _SQUID_LIBNTLMAUTH_SUPPORT_BITS_CCI + +#if HAVE_STRING_H +#include +#endif + +/* + * Defines several functions which are used and mutually shared by the NTLM helpers + * These do not (yet) have a defined stable home to go to. + * For now include this file into helper main .cc where needed. + */ + +/* makes a null-terminated string upper-case. Changes CONTENTS! */ +static void +uc(char *string) +{ + char *p = string, c; + while ((c = *p)) { + *p = xtoupper(c); + p++; + } +} + +/* makes a null-terminated string lower-case. Changes CONTENTS! */ +static void +lc(char *string) +{ + char *p = string, c; + while ((c = *p)) { + *p = xtolower(c); + p++; + } +} + +static void +hex_dump(unsigned char *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 (!data) + return; + + 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", (int) (p - data)); + } + c = *p; + if (xisalnum(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); + } + } +} + +#endif /* _SQUID_LIBNTLMAUTH_SUPPORT_BITS_CCI */