#
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]*
Makefile \
compat/Makefile \
lib/Makefile \
+ libntlmauth/Makefile \
scripts/Makefile \
src/Makefile \
src/base/Makefile \
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 \
<sect2>NTLM Authentication protocol helpers
<p><itemize>
<item>fakeauth_auth - ntlm_fake_auth - Perform NTLMSSP to recover the username but don't verify the password.
+ <item>mswin_ntlm_auth - ntlm_sspi_auth - Perform NTLMSSP authentication using Windows native Security Support Provider Interface API.
<item>ntlm_auth - ntlm_smb_lm_auth - Perform SMB LanManager domain-less authentication over NTLM protocol.
- <item>no_check.pl - Deprecated. - Use the faster and less decryptable ntlm_fake_auth instead.
+ <item>no_check.pl - Deprecated. - Use the faster and less easily decrypted ntlm_fake_auth instead.
</itemize>
<sect2>URL re-write helpers
-SUBDIRS = \
+EXTRA_DIST = defines.h
+
+DIST_SUBDIRS = \
basic_auth \
digest_auth \
external_acl \
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
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
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)
#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
#include <getopt.h>
#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__
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.
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);
} 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) {
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)
+++ /dev/null
-/*
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
- * 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 <string.h>
-#endif /* HAVE_STRING_H */
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#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;
-}
*/
#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 <string.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SIGNAL_H
#include <signal.h>
-
-/* 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 <errno.h>
-
-#define BUFFER_SIZE 10240
-
+#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_ASSERT_H
#include <assert.h>
#endif
+#if HAVE_TIME_H
+#include <time.h>
+#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);
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");
}
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, '/'))) {
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;
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;
}
}
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;
}
+++ /dev/null
-/*
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>,
- * inspired by previous work by Andrew Doran <ad@interlude.eu.org>
- *
- * 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 <time.h>
-#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_ */
+++ /dev/null
-# 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
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 ..."
- *
- * };
- */
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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);
+++ /dev/null
-/* 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 */
+++ /dev/null
-#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 */
-
+++ /dev/null
-/* 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"
+++ /dev/null
-#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 <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-
-#define TRUE 1
-#define FALSE 0
-
-#endif /* __STD_DEFINES__ */
+++ /dev/null
-/* 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 <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#define TRUE 1
-#define FALSE 0
-
-/* Pick up define for INADDR_NONE */
-
-#ifndef INADDR_NONE
-#define INADDR_NONE -1
-#endif
+++ /dev/null
-#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
libsspwin32.a
noinst_LIBRARIES = \
libmiscutil.a \
- libntlmauth.a \
$(LIBSSPWIN32)
#
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
#include "util.h"
-#include "ntlmauth.h"
+#include "libntlmauth/ntlmauth.h"
#include "sspwin32.h"
typedef struct _AUTH_SEQ {
--- /dev/null
+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
#include <strings.h>
#endif
-#include "ntlmauth.h"
+#include "libntlmauth/ntlmauth.h"
#include "util.h" /* for base64-related stuff */
/* ************************************************************************* */
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 " : "")
);
}
/* ************************************************************************* */
/**
- * 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)
*/
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;
* 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)
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;
/* Negotiate Packet functions */
/* ************************************************************************* */
-// ??
+// ?
/* ************************************************************************* */
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
* 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)
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);
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) {
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;
}
* 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 {
/* ************************************************************************* */
/* 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;
#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 {
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* #include <features.h> */
#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 <sys/uio.h>
#include <sys/signal.h>
#include <string.h>
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 */
#endif
} else {
- seen_keep_alive = FALSE;
+ seen_keep_alive = 0;
}
}
* 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 <netinet/in.h>
+#endif
#ifdef RFCNB_PORT
#define RFCNB_Default_Port RFCNB_PORT
/* 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 */
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__ */
*/
#define SQUID_NO_ALLOC_PROTECT 1
#include "config.h"
+#include "libntlmauth/rfcnb-priv.h"
+#include <netinet/tcp.h>
#include <string.h>
int RFCNB_errno = 0;
int RFCNB_saved_errno = 0;
-#define RFCNB_ERRNO
-
-#include "std-includes.h"
-#include <netinet/tcp.h>
-#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) ());
struct RFCNB_Con *con;
struct in_addr Dest_IP;
int Client;
- BOOL redirect;
+ int redirect;
struct redirect_addr *redir_addr;
char *Service_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 */
/* 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,
*/
#define SQUID_NO_ALLOC_PROTECT 1
#include "config.h"
+#include "libntlmauth/rfcnb-priv.h"
-#include <string.h>
-
-#include "std-includes.h"
-#include "rfcnb-priv.h"
-#include "rfcnb-util.h"
-#include "rfcnb-io.h"
#include <arpa/inet.h>
+#include <string.h>
extern void (*Prot_Print_Routine) (); /* Pointer to protocol print routine */
RFCNB_Session_Req(struct RFCNB_Con *con,
char *Called_Name,
char *Calling_Name,
- BOOL * redirect,
+ int * redirect,
struct in_addr *Dest_IP,
int *port)
{
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);
--- /dev/null
+/* 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 <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#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 */
* 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
#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 */
* 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);
* 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 <string.h>
#include <ctype.h>
#include <dirent.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#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);
/*
* 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);
/* Routines for Windows NT MD4 Hash functions. */
static int
-_my_wcslen(int16 * str)
+_my_wcslen(int16_t * str)
{
int len = 0;
while (*str++ != 0)
*/
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;
* 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);
_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);
/* 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';
/* 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));
*
* 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 <string.h>
-#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];
}
static void
-copy64(uint32 * M, unsigned char *in)
+copy64(uint32_t * M, unsigned char *in)
{
int i;
}
static void
-copy4(unsigned char *out, uint32 x)
+copy4(unsigned char *out, uint32_t x)
{
out[0] = x & 0xFF;
out[1] = (x >> 8) & 0xFF;
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;
-#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
*
* 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 <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+
+#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 */
} 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 */
* 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 <unistd.h>
-#include "byteorder.h" /* Hmmm ... hot good */
+//#include "byteorder.h" /* Hmmm ... not good */
#ifndef max
#define max(a,b) ((a) < (b) ? (b) : (a))
#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. */
/* We define these as offsets into a char SMB[] array for the */
/* sake of portability */
-/* NOTE!. Some of the lenght defines, SMB_<protreq>_len do not include */
+/* NOTE!. Some of the length defines, SMB_<protreq>_len do not include */
/* the data that follows in the SMB packet, so the code will have to */
/* take that into account. */
} 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"
#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);
*/
#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 <string.h>
-#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);
/* 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 */
* 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];
}
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;
/* 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;
#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 <ctype.h>
+#include <signal.h>
#include <string.h>
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 <signal.h>
+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;
-
}
/**
}
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");
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, "");
}
}
-
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->port);
/* Did we get one? */
-
if (con->Trans_Connect == NULL) {
-
if (Con_Handle == NULL) {
Con_Handle = NULL;
free(con);
}
return (con);
-
}
/* SMB_Connect: Connect to the indicated server */
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);
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);
/* 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 */
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)
/* 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;
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 +
}
/* 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);
free(Con_Handle);
return (0);
-
}
#include "config.h"
+#include "libntlmauth/ntlmauth.h"
+#include "libntlmauth/smblmauth.h"
+#include "libntlmauth/smb.h"
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#include <string.h>
#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[] = {
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", */
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;
}
--- /dev/null
+#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 */
--- /dev/null
+#ifndef _SQUID_LIBNTLMAUTH_SUPPORT_BITS_CCI
+#define _SQUID_LIBNTLMAUTH_SUPPORT_BITS_CCI
+
+#if HAVE_STRING_H
+#include <string.h>
+#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 */