From 1ce586101b799134685dd0080c1c44cda06ddc83 Mon Sep 17 00:00:00 2001 From: Francesco Chemolli <5175948+kinkie@users.noreply.github.com> Date: Thu, 6 Mar 2025 00:24:22 +0000 Subject: [PATCH] Remove basic_smb_lm_auth helper (#2009) This helper implementation is based on an old snapshot and adaptation of Samba code. Samba project offers a more secure and better maintained tool. --- configure.ac | 2 - doc/release-notes/release-7.sgml.in | 17 +- src/auth/basic/Makefile.am | 1 - src/auth/basic/SMB_LM/Makefile.am | 27 - src/auth/basic/SMB_LM/README.html | 151 ----- src/auth/basic/SMB_LM/msntauth-v2.0.lsm | 13 - src/auth/basic/SMB_LM/msntauth.cc | 167 ------ src/auth/basic/SMB_LM/msntauth.h | 16 - src/auth/basic/SMB_LM/required.m4 | 14 - src/auth/basic/SMB_LM/valid.cc | 55 -- src/auth/basic/SMB_LM/valid.h | 21 - src/auth/basic/helpers.m4 | 1 - src/auth/ntlm/Makefile.am | 1 - src/auth/ntlm/SMB_LM/Makefile.am | 23 - src/auth/ntlm/SMB_LM/ntlm_smb_lm_auth.cc | 702 ----------------------- src/auth/ntlm/SMB_LM/required.m4 | 17 - src/auth/ntlm/helpers.m4 | 1 - 17 files changed, 16 insertions(+), 1213 deletions(-) delete mode 100644 src/auth/basic/SMB_LM/Makefile.am delete mode 100644 src/auth/basic/SMB_LM/README.html delete mode 100644 src/auth/basic/SMB_LM/msntauth-v2.0.lsm delete mode 100644 src/auth/basic/SMB_LM/msntauth.cc delete mode 100644 src/auth/basic/SMB_LM/msntauth.h delete mode 100755 src/auth/basic/SMB_LM/required.m4 delete mode 100644 src/auth/basic/SMB_LM/valid.cc delete mode 100644 src/auth/basic/SMB_LM/valid.h delete mode 100644 src/auth/ntlm/SMB_LM/Makefile.am delete mode 100644 src/auth/ntlm/SMB_LM/ntlm_smb_lm_auth.cc delete mode 100755 src/auth/ntlm/SMB_LM/required.m4 diff --git a/configure.ac b/configure.ac index 6d8fcd1639..09d3468f2e 100644 --- a/configure.ac +++ b/configure.ac @@ -2548,7 +2548,6 @@ AC_CONFIG_FILES([ src/auth/basic/RADIUS/Makefile src/auth/basic/SASL/Makefile src/auth/basic/SMB/Makefile - src/auth/basic/SMB_LM/Makefile src/auth/basic/SSPI/Makefile src/auth/digest/Makefile src/auth/digest/eDirectory/Makefile @@ -2560,7 +2559,6 @@ AC_CONFIG_FILES([ src/auth/negotiate/wrapper/Makefile src/auth/ntlm/Makefile src/auth/ntlm/fake/Makefile - src/auth/ntlm/SMB_LM/Makefile src/auth/ntlm/SSPI/Makefile src/base/Makefile src/clients/Makefile diff --git a/doc/release-notes/release-7.sgml.in b/doc/release-notes/release-7.sgml.in index 906511edd9..0aac602b89 100644 --- a/doc/release-notes/release-7.sgml.in +++ b/doc/release-notes/release-7.sgml.in @@ -34,6 +34,7 @@ The Squid-@SQUID_RELEASE@ change history can be

-

No build options have changed behaviour in this version. + + --enable-auth-basic= +

Removed SMB_LM helper, in favour of the ntlm_auth + alternative offered by the Samba project. + + --enable-auth-ntlm= +

Removed SMB_LM helper, in favour of the ntlm_auth + alternative offered by the Samba project.

diff --git a/src/auth/basic/Makefile.am b/src/auth/basic/Makefile.am index f146de3bca..18a6b4a347 100644 --- a/src/auth/basic/Makefile.am +++ b/src/auth/basic/Makefile.am @@ -19,7 +19,6 @@ DIST_SUBDIRS = \ RADIUS \ SASL \ SMB \ - SMB_LM \ SSPI SUBDIRS = $(BASIC_AUTH_HELPERS) diff --git a/src/auth/basic/SMB_LM/Makefile.am b/src/auth/basic/SMB_LM/Makefile.am deleted file mode 100644 index 3f2989ed9f..0000000000 --- a/src/auth/basic/SMB_LM/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -## Copyright (C) 1996-2025 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -include $(top_srcdir)/src/Common.am - -libexec_PROGRAMS= basic_smb_lm_auth - -basic_smb_lm_auth_SOURCES = \ - msntauth.cc \ - msntauth.h \ - valid.cc \ - valid.h -basic_smb_lm_auth_LDADD= \ - $(top_builddir)/lib/smblib/libsmblib.la \ - $(top_builddir)/lib/rfcnb/librfcnb.la \ - $(top_builddir)/lib/libmiscencoding.la \ - $(COMPAT_LIB) \ - $(XTRA_LIBS) - -EXTRA_DIST= \ - msntauth-v2.0.lsm \ - README.html \ - required.m4 diff --git a/src/auth/basic/SMB_LM/README.html b/src/auth/basic/SMB_LM/README.html deleted file mode 100644 index 85c6835ed4..0000000000 --- a/src/auth/basic/SMB_LM/README.html +++ /dev/null @@ -1,151 +0,0 @@ - - -MSNTAUTH readme - - - - - -

-MSNT Auth v3.0.0
-Squid web proxy NT authentication module
-Modified by the Squid HTTP Proxy team
-Original release by Antonino Iannella, Stellar-X Pty Ltd
-

- -

Contents

- - - -

Introduction

- -

-This is an authentication module for the Squid proxy server -to use an NT domain server. - -

-It originates from the Samba and SMB packages by Andrew Tridgell -and Richard Sharpe. It is sourced from the Pike -authentication module by William Welliver (hwellive@intersil.com), -and the SMB 1.0.1 libraries. -Releases up to version 2.0.3 were created by Antonino Iannella -(antonino@rager.com.au, http://stellarx.tripod.com). -The module is now distributed with Squid, and is maintained by the -Squid proxy team as an Open Source effort. -Msntauth is released under the GNU General Public License. - -

-basic_msnt_auth follows the standard Squid basic authentication helper protocol. -See https://wiki.squid-cache.org/Features/AddonHelpers#basic-scheme for details. -Problems are logged to syslog. - -

-Msntauth works in environments with NT domain controllers on -Windows (TM) NT 4, 2000, and Samba. It only uses the ancient Lanman protocol, -the authenticating systems must be configured to accept it. - -

Installation

- -

-Msntauth will be compiled when you compile Squid, using -their autoconf system. -Refer to Squid documentation for details. -If the build is suitable, you can skip this section. - -

Configuration

- -

-As of version 3.0.0, a configuration file is no longer needed. -The specification of the domains and domain controllers to use is -passed as a list of arguments on the command line. - -The syntax is: -

-basic_msnt_auth domain1/domaincontroller1 [domain2/domaincontroller2 ...]
-
-An arbitrary number of domain controllers can be specified, for any number of daomains. -Domain controllers will be attempted in the same order they are configured, until -any of them successfully authenticates the user passed by squid. If all domain -controllers fail to authenticate the user, then access is denied. -Domain controllers can be specified by their NetBios name. - -

-WARNING! this means that a wrong password will be attempted a number of times. -Watch out for domain lock-out policies! - -

Squid.conf changes

- -

-Refer to Squid documentation for the required changes to squid.conf. -You will need to set the following lines to enable authentication for -your access list - - -

-  acl yourACL proxy_auth REQUIRED
-  http_access allow password
-  http_access allow yourACL
-  http_access deny all
-
- -

-You will also need to review the following directives. The number of -msntauth children spawned is set with authenticate_children. -The number of children needed is site-dependent, so some -experimentation may be required to find the best number. -There should be no visible delay in performance with Squid once -msntauth is in use. - -Please see http://www.squid-cache.org/Doc/config/auth_param/ or your squid.conf.default -file to check how to configure squid to make use of this helper. - -

Testing

- -

-I strongly urge that Msntauth is tested prior to being used in a -production environment. It may behave differently on different platforms. -To test it, run it from the command line, and enter username and password -pairs separated by a space. - -

-It should behave in the following way - -

- - Press ENTER to get an OK or ERR message.
- - Make sure pressing CTRL-D behaves the same as a carriage return.
- - Make sure pressing CTRL-C aborts the program.
- - Test that entering no details does not result in an OK or ERR message.
- - Test that entering an invalid username and password results in
-   an ERR message. Note that if NT guest user access is allowed on
-   the PDC, an OK message may be returned instead of ERR.
- - Test that entering an valid username and password results in an OK message.
-   Try usernames which are and aren't in the denied/allowed user files,
-   if they're in use.
- - Test that entering a guest username and password returns the correct response.
-
- -

-If the above didn't work as expected, you may need to modify the main() -function in msntauth.c. Inform the Squid maintainers of any problems. - -

-Usernames and passwords are expected to be URL-encoded (see RFC 1738 for details) - -

Support details

- -

-Refer to the Squid website at http://www.squid-cache.org. -You can submit problems or fixes using the Squid project's Bugzilla database. - - - diff --git a/src/auth/basic/SMB_LM/msntauth-v2.0.lsm b/src/auth/basic/SMB_LM/msntauth-v2.0.lsm deleted file mode 100644 index f50d16f161..0000000000 --- a/src/auth/basic/SMB_LM/msntauth-v2.0.lsm +++ /dev/null @@ -1,13 +0,0 @@ -Begin3 -Title: msntauth -Version: 2.0 -Entered-date: 01SEP01 -Description: Squid web proxy NT domain authentication module -Keywords: Squid WWW proxy SMB NT domain authentication module source -Author: antonino@rager.com.au (Antonino Iannella) -Maintained-by: antonino@rager.com.au (Antonino Iannella) -Primary-site: sunsite.unc.edu /pub/Linux/system/network/misc - msntauth-v2.0.tgz -Original-site: http://members.tripod.com/stellarx -Copying-policy: GPL -End diff --git a/src/auth/basic/SMB_LM/msntauth.cc b/src/auth/basic/SMB_LM/msntauth.cc deleted file mode 100644 index c0698e0a8b..0000000000 --- a/src/auth/basic/SMB_LM/msntauth.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* - * MSNT - Microsoft Windows NT domain squid authenticator module - * Version 2.0 by Stellar-X Pty Ltd, Antonino Iannella - * Sun Sep 2 14:39:53 CST 2001 - * - * Modified to act as a Squid authenticator module. - * Removed all Pike stuff. - * Returns OK for a successful authentication, or ERR upon error. - * - * Uses code from - - * Andrew Tridgell 1997 - * Richard Sharpe 1996 - * Bill Welliver 1999 - * Duane Wessels 2000 (wessels@squid-cache.org) - * - * Released under GNU Public License - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include "squid.h" -#include "rfc1738.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include - -#include "auth/basic/SMB_LM/msntauth.h" -#include "auth/basic/SMB_LM/valid.h" - -static char msntauth_version[] = "Msntauth v3.0.0 (C) 2 Sep 2001 Stellar-X Antonino Iannella.\nModified by the Squid HTTP Proxy team 2002-2014"; - -struct domaincontroller { - std::string domain; - std::string server; -}; -typedef std::vector domaincontrollers_t; -domaincontrollers_t domaincontrollers; - -static bool -validate_user(char *username, char *password) -{ - for (domaincontrollers_t::iterator dc = domaincontrollers.begin(); dc != domaincontrollers.end(); ++dc) { - //std::cerr << "testing against " << dc->server << std::endl; - const int rv = Valid_User(username, password, dc->server.c_str(), nullptr, dc->domain.c_str()); - //std::cerr << "check result: " << rv << std::endl; - if (rv == NTV_NO_ERROR) - return true; - } - return false; -} - -static char instructions[] = "Usage instructions: basic_nsnt_auth / [/ ...]"; -static void -display_usage_instructions() -{ - using std::endl; - std::cerr << msntauth_version << endl << instructions << endl << endl; -} - -// arguments: domain/server_name [domain/server_name ...] -int -main(int argc, char **argv) -{ - char username[256]; - char password[256]; - char wstr[256]; - int err = 0; - - openlog("basic_smb_lm_auth", LOG_PID, LOG_USER); - setbuf(stdout, nullptr); - - for (int j = 1; j < argc; ++j) { - std::string arg = argv[j]; - size_t pos=arg.find('/'); - if (arg.find('/',pos+1) != std::string::npos) { - std::cerr << "Error: can't understand domain controller specification '" - << arg << "'. Ignoring" << std::endl; - } - domaincontroller dc; - dc.domain = arg.substr(0,pos); - dc.server = arg.substr(pos+1); - if (dc.domain.length() == 0 || dc.server.length() == 0) { - std::cerr << "Error: invalid domain specification in '" << arg << - "'. Ignoring." << std::endl; - exit(EXIT_FAILURE); - } - domaincontrollers.push_back(dc); - } - if (domaincontrollers.empty()) { - display_usage_instructions(); - std::cerr << "Error: no domain controllers specified" << std::endl; - exit(EXIT_FAILURE); - } - - while (1) { - int n; - /* Read whole line from standard input. Terminate on break. */ - memset(wstr, '\0', sizeof(wstr)); - if (fgets(wstr, 255, stdin) == NULL) - break; - /* ignore this line if we didn't get the end-of-line marker */ - if (NULL == strchr(wstr, '\n')) { - err = 1; - continue; - } - if (err) { - syslog(LOG_WARNING, "oversized message"); - puts("ERR"); - err = 0; - continue; - } - - /* - * extract username and password. - */ - username[0] = '\0'; - password[0] = '\0'; - n = sscanf(wstr, "%s %[^\n]", username, password); - if (2 != n) { - puts("ERR"); - continue; - } - /* Check for invalid or blank entries */ - if ((username[0] == '\0') || (password[0] == '\0')) { - puts("ERR"); - continue; - } - - rfc1738_unescape(username); - rfc1738_unescape(password); - - if (validate_user(username, password)) { - puts("OK"); - } else { - syslog(LOG_INFO, "'%s' login failed", username); - puts("ERR"); - } - err = 0; - } - - return EXIT_SUCCESS; -} - diff --git a/src/auth/basic/SMB_LM/msntauth.h b/src/auth/basic/SMB_LM/msntauth.h deleted file mode 100644 index 44275f2ddc..0000000000 --- a/src/auth/basic/SMB_LM/msntauth.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_AUTH_BASIC_SMB_LM_MSNTAUTH_H -#define SQUID_SRC_AUTH_BASIC_SMB_LM_MSNTAUTH_H - -extern int QueryServers(char *, char *); -extern void Check_forallowchange(void); - -#endif /* SQUID_SRC_AUTH_BASIC_SMB_LM_MSNTAUTH_H */ - diff --git a/src/auth/basic/SMB_LM/required.m4 b/src/auth/basic/SMB_LM/required.m4 deleted file mode 100755 index b364f9f6e1..0000000000 --- a/src/auth/basic/SMB_LM/required.m4 +++ /dev/null @@ -1,14 +0,0 @@ -## Copyright (C) 1996-2025 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -# DONT build this helper on Windows -# DONT build this helper by default -AS_IF([test "x$auto_helpers" != "xyes"],[ - BUILD_HELPER="SMB_LM" - AC_CHECK_HEADERS([w32api/windows.h windows.h],[BUILD_HELPER=""]) - AS_IF([test "x$BUILD_HELPER" = "xSMB_LM"],[require_smblib="yes"]) -]) diff --git a/src/auth/basic/SMB_LM/valid.cc b/src/auth/basic/SMB_LM/valid.cc deleted file mode 100644 index 564f8c9a4e..0000000000 --- a/src/auth/basic/SMB_LM/valid.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#include "squid.h" -#include "auth/basic/SMB_LM/valid.h" -#include "smblib/smblib.h" - -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_SYSLOG_H -#include -#endif - -// BACKUP is unused -int -Valid_User(char *USERNAME, char *PASSWORD, const char *SERVER, char *, const char *DOMAIN) -{ - const char *supportedDialects[] = {"PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "LANMAN1.0", - "LM1.2X002", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL - }; - SMB_Handle_Type con; - - SMB_Init(); - con = SMB_Connect_Server(nullptr, SERVER, DOMAIN); - if (con == NULL) { - return (NTV_SERVER_ERROR); - } - if (SMB_Negotiate(con, supportedDialects) < 0) { /* An error */ - SMB_Discon(con, 0); - return (NTV_PROTOCOL_ERROR); - } - if (SMB_Logon_Server(con, USERNAME, PASSWORD, nullptr, 0) < 0) { - SMB_Discon(con, 0); - return (NTV_LOGON_ERROR); - } - SMB_Discon(con, 0); - return (NTV_NO_ERROR); -} - diff --git a/src/auth/basic/SMB_LM/valid.h b/src/auth/basic/SMB_LM/valid.h deleted file mode 100644 index 0aa88c2f20..0000000000 --- a/src/auth/basic/SMB_LM/valid.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_AUTH_BASIC_SMB_LM_VALID_H -#define SQUID_SRC_AUTH_BASIC_SMB_LM_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, const char *SERVER, char *BACKUP, const char *DOMAIN); - -#endif /* SQUID_SRC_AUTH_BASIC_SMB_LM_VALID_H */ - diff --git a/src/auth/basic/helpers.m4 b/src/auth/basic/helpers.m4 index 0a81f038bb..d80700d53b 100644 --- a/src/auth/basic/helpers.m4 +++ b/src/auth/basic/helpers.m4 @@ -18,7 +18,6 @@ AS_IF([test "x$enable_auth" != "xno"],[ SQUID_CHECK_HELPER([RADIUS],[auth/basic]) SQUID_CHECK_HELPER([SASL],[auth/basic]) SQUID_CHECK_HELPER([SMB],[auth/basic]) - SQUID_CHECK_HELPER([SMB_LM],[auth/basic]) SQUID_CHECK_HELPER([SSPI],[auth/basic]) SQUID_CHECK_HELPER([fake],[auth/basic]) SQUID_CHECK_HELPER([getpwnam],[auth/basic]) diff --git a/src/auth/ntlm/Makefile.am b/src/auth/ntlm/Makefile.am index a4190460af..3546542b09 100644 --- a/src/auth/ntlm/Makefile.am +++ b/src/auth/ntlm/Makefile.am @@ -9,7 +9,6 @@ include $(top_srcdir)/src/Common.am DIST_SUBDIRS = \ fake \ - SMB_LM \ SSPI SUBDIRS= $(NTLM_AUTH_HELPERS) EXTRA_DIST= helpers.m4 diff --git a/src/auth/ntlm/SMB_LM/Makefile.am b/src/auth/ntlm/SMB_LM/Makefile.am deleted file mode 100644 index a6a26395b0..0000000000 --- a/src/auth/ntlm/SMB_LM/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -## Copyright (C) 1996-2025 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -include $(top_srcdir)/src/Common.am - -libexec_PROGRAMS = ntlm_smb_lm_auth - -ntlm_smb_lm_auth_SOURCES = ntlm_smb_lm_auth.cc -ntlm_smb_lm_auth_LDADD = \ - $(top_builddir)/lib/smblib/libsmblib.la \ - $(top_builddir)/lib/rfcnb/librfcnb.la \ - $(top_builddir)/lib/ntlmauth/libntlmauth.la \ - $(top_builddir)/lib/libmiscencoding.la \ - $(COMPAT_LIB) \ - $(LIBNETTLE_LIBS) \ - $(CRYPTLIB) \ - $(XTRA_LIBS) - -EXTRA_DIST = required.m4 diff --git a/src/auth/ntlm/SMB_LM/ntlm_smb_lm_auth.cc b/src/auth/ntlm/SMB_LM/ntlm_smb_lm_auth.cc deleted file mode 100644 index f39b221c2d..0000000000 --- a/src/auth/ntlm/SMB_LM/ntlm_smb_lm_auth.cc +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* - * (C) 2000 Francesco Chemolli - * Distributed freely under the terms of the GNU General Public License, - * version 2 or later. 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 "squid.h" -#include "base64.h" -#include "compat/debug.h" -#include "helper/protocol_defines.h" -#include "ntlmauth/ntlmauth.h" -#include "ntlmauth/support_bits.cci" -#include "rfcnb/rfcnb.h" -#include "smblib/smblib.h" - -#include -#include -#include -#include -#include -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_GETOPT_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif - -/************* CONFIGURATION ***************/ - -#define DEAD_DC_RETRY_INTERVAL 30 - -/************* END CONFIGURATION ***************/ - -/* A couple of harmless helper macros */ -#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n"); -#ifdef __GNUC__ -#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); -#define SEND3(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); -#else -/* no gcc, no debugging. varargs macros are a gcc extension */ -#define SEND2 printf -#define SEND3 printf -#endif - -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 */ -static void usage(void); -static void process_options(int argc, char *argv[]); -static const char * obtain_challenge(void); -static void manage_request(void); -static const char *make_challenge(char *domain, char *controller); -static char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length); -static void dc_disconnect(void); - -#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 = nullptr; -static NtlmError 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[NTLM_BLOB_BUFFER_SIZE]; -#endif -char load_balance = 0, protocol_pedantic = 0; -dc *controllers = nullptr; -int numcontrollers = 0; -dc *current_dc; -char smb_error_buffer[1000]; - -/* Disconnects from the DC. A reconnection will be done upon the next request - */ -static void -dc_disconnect() -{ - if (handle != NULL) - SMB_Discon(handle, 0); - handle = nullptr; -} - -/* 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(nullptr, 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 = nullptr; - return 2; - } - if (handle->Security == 0) { /* share-level security, unusable */ - debug("SMB Server uses share-level security .. we need user security.\n"); - SMB_Discon(handle, 0); - handle = nullptr; - 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 const char * -make_challenge(char *domain, char *domain_controller) -{ - /* trying to circumvent some strange problem with pointers in SMBLib */ - /* Ugly as hell, but the lib is going to be dropped... */ - strncpy(my_domain, domain, sizeof(my_domain)-1); - my_domain[sizeof(my_domain)-1] = '\0'; - strncpy(my_domain_controller, domain_controller, sizeof(my_domain_controller)-1); - my_domain_controller[sizeof(my_domain_controller)-1] = '\0'; - - if (init_challenge(my_domain, my_domain_controller) > 0) { - return nullptr; - } - - ntlm_challenge chal; - uint32_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); - - size_t len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen); - // for lack of a good NTLM token size limit, allow up to what the helper input can be - // validations later will expect to be limited to that size. - static char b64buf[HELPER_INPUT_BUFFER-10]; /* 10 for other line fields, delimiters and terminator */ - if (base64_encode_len(len) < sizeof(b64buf)-1) { - debug("base64 encoding of the token challenge will exceed %zu bytes", sizeof(b64buf)); - return nullptr; - } - - struct base64_encode_ctx ctx; - base64_encode_init(&ctx); - size_t blen = base64_encode_update(&ctx, b64buf, len, reinterpret_cast(&chal)); - blen += base64_encode_final(&ctx, b64buf+blen); - b64buf[blen] = '\0'; - return b64buf; -} - -/* 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 - */ -static char * -ntlm_check_auth(ntlm_authenticate * auth, int auth_length) -{ - 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 = NtlmError::NotConnected; - return nullptr; - } - - /* 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 = NtlmError::LoginEror; - return nullptr; - } - if (tmp.l > MAX_DOMAIN_LEN) { - debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN); - ntlm_errno = NtlmError::LoginEror; - return nullptr; - } - memcpy(domain, tmp.str, tmp.l); - user = domain + tmp.l; - *user = '\0'; - ++user; - - /* 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 = NtlmError::LoginEror; - return nullptr; - } - if (tmp.l > MAX_USERNAME_LEN) { - debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN); - ntlm_errno = NtlmError::LoginEror; - return nullptr; - } - memcpy(user, tmp.str, tmp.l); - *(user + tmp.l) = '\0'; - - // grab the *response blobs. these are fixed length 24 bytes of binary - const ntlmhdr *packet = &(auth->hdr); - { - const strhdr * str = &auth->lmresponse; - - int16_t len = le16toh(str->len); - int32_t offset = le32toh(str->offset); - - if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) { - debug("LM response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset); - ntlm_errno = NtlmError::LoginEror; - return nullptr; - } - tmp.str = (char *)packet + offset; - tmp.l = len; - } - if (tmp.l > MAX_PASSWD_LEN) { - debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN); - ntlm_errno = NtlmError::LoginEror; - return nullptr; - } - - /* Authenticating against the NT response doesn't seem to work... in SMB LM helper. */ - memcpy(pass, tmp.str, tmp.l); - pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0'; - - 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=NtlmError::LoginEror; - return nullptr; - } - - /* still fetch the NT response and check validity against empty password */ - { - const strhdr * str = &auth->ntresponse; - int16_t len = le16toh(str->len); - // NT response field may be absent. that is okay. - if (len != 0) { - int32_t offset = le32toh(str->offset); - - if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) { - debug("NT response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset); - ntlm_errno = NtlmError::LoginEror; - return nullptr; - } - tmp.str = (char *)packet + offset; - tmp.l = len; - - 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 = NtlmError::LoginEror; - return nullptr; - } - } - } - - debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass); - - const auto rv = SMB_Logon_Server(handle, user, pass, domain, 1); - debug("Login attempt had result %d\n", rv); - - switch (rv) { - case SMBlibE_Success: - ntlm_errno = NtlmError::None; - break; - case SMBlibE_BAD: - ntlm_errno = NtlmError::BlobError; - return nullptr; - case SMBlibE_ProtLow: - case SMBlibE_NoSpace: - case SMBlibE_BadParam: - case SMBlibE_NegNoProt: - case SMBlibE_LowerLayer: - case SMBlibE_SendFailed: - case SMBlibE_RecvFailed: - case SMBlibE_ProtUnknown: - case SMBlibE_NoSuchMsg: - ntlm_errno = NtlmError::ProtocolError; - return nullptr; - case SMBlibE_NotImpl: - case SMBlibE_CallFailed: - case SMBlibE_Remote: - ntlm_errno = NtlmError::ServerError; - return nullptr; - case SMBlibE_GuestOnly: - ntlm_errno = NtlmError::LoginEror; - return nullptr; - default: - ntlm_errno = NtlmError::ServerError; - return nullptr; - } - - *(user - 1) = '\\'; /* hack. Performing, but ugly. */ - - debug("credentials: %s\n", credentials); - return credentials; -} - -static char got_timeout = 0; -/** signal handler to be invoked when the authentication operation - * times out */ -extern "C" void -timeout_during_auth(int) -{ - dc_disconnect(); -} - -/* - * options: - * -b try load-balancing the domain-controllers - * -f fail-over to another DC if DC connection fails. - * DEPRECATED and VERBOSELY IGNORED. This is on by default now. - * -l last-ditch-mode - * domain\controller ... - */ -char *my_program_name = nullptr; - -static void -usage() -{ - fprintf(stderr, - "%s usage:\n%s [-b] [-f] [-d] [-l] domain\\controller [domain\\controller ...]\n" - "-b enables load-balancing among controllers\n" - "-f enables failover among controllers (DEPRECATED and always active)\n" - "-d enables debugging statements if DEBUG was defined at build-time.\n\n" - "You MUST specify at least one Domain Controller.\n" - "You can use either \\ or / as separator between the domain name \n" - "and the controller name\n", - my_program_name, my_program_name); -} - -/* int debug_enabled=0; defined in libcompat */ - -static void -process_options(int argc, char *argv[]) -{ - int opt, j, had_error = 0; - dc *new_dc = nullptr, *last_dc = nullptr; - while (-1 != (opt = getopt(argc, argv, "bfld"))) { - switch (opt) { - case 'b': - load_balance = 1; - break; - case 'f': - fprintf(stderr, - "WARNING. The -f flag is DEPRECATED and always active.\n"); - break; - case 'd': - debug_enabled=1; - break; - default: - fprintf(stderr, "unknown option: -%c. Exiting\n", opt); - usage(); - had_error = 1; - } - } - if (had_error) - exit(EXIT_FAILURE); - /* Okay, now begin filling controllers up */ - /* we can avoid memcpy-ing, and just reuse argv[] */ - for (j = optind; j < argc; ++j) { - 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 = static_cast(xmalloc(strlen(argv[j]) + 1)); - strcpy(d, argv[j]); - debug("Adding domain-controller %s\n", d); - if (NULL == (c = strchr(d, '\\')) && NULL == (c = strchr(d, '/'))) { - fprintf(stderr, "Couldn't grok domain-controller %s\n", d); - free(d); - continue; - } - /* more than one delimiter is not allowed */ - if (NULL != strchr(c + 1, '\\') || NULL != strchr(c + 1, '/')) { - fprintf(stderr, "Broken domain-controller %s\n", d); - free(d); - continue; - } - *c= '\0'; - ++c; - new_dc = static_cast(xmalloc(sizeof(dc))); - if (!new_dc) { - fprintf(stderr, "Malloc error while parsing DC options\n"); - free(d); - continue; - } - /* capitalize */ - uc(c); - uc(d); - ++numcontrollers; - new_dc->domain = d; - new_dc->controller = c; - new_dc->dead = 0; - if (controllers == NULL) { /* first controller */ - controllers = new_dc; - last_dc = new_dc; - } else { - last_dc->next = new_dc; /* can't be null */ - last_dc = new_dc; - } - } - if (numcontrollers == 0) { - fprintf(stderr, "You must specify at least one domain-controller!\n"); - usage(); - exit(EXIT_FAILURE); - } - last_dc->next = controllers; /* close the queue, now it's circular */ -} - -/** - * tries connecting to the domain controllers in the "controllers" ring, - * with failover if the adequate option is specified. - */ -static const char * -obtain_challenge() -{ - int j = 0; - const char *ch = nullptr; - for (j = 0; j < numcontrollers; ++j) { - debug("obtain_challenge: selecting %s\\%s (attempt #%d)\n", - current_dc->domain, current_dc->controller, j + 1); - if (current_dc->dead != 0) { - if (time(NULL) - current_dc->dead >= DEAD_DC_RETRY_INTERVAL) { - /* mark helper as retry-worthy if it's so. */ - debug("Reviving DC\n"); - current_dc->dead = 0; - } else { /* skip it */ - debug("Skipping it\n"); - continue; - } - } - /* else branch. Here we KNOW that the DC is fine */ - debug("attempting challenge retrieval\n"); - ch = make_challenge(current_dc->domain, current_dc->controller); - debug("make_challenge retuned %p\n", ch); - if (ch) { - debug("Got it\n"); - return ch; /* All went OK, returning */ - } - /* Huston, we've got a problem. Take this DC out of the loop */ - debug("Marking DC as DEAD\n"); - current_dc->dead = time(NULL); - /* Try with the next */ - debug("moving on to next controller\n"); - current_dc = current_dc->next; - } - /* all DCs failed. */ - return nullptr; -} - -static void -manage_request() -{ - ntlmhdr *fast_header; - char buf[NTLM_BLOB_BUFFER_SIZE]; - char decoded[NTLM_BLOB_BUFFER_SIZE]; - char *ch2, *cred = nullptr; - - if (fgets(buf, NTLM_BLOB_BUFFER_SIZE, stdin) == NULL) { - fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno, - strerror(errno)); - exit(EXIT_FAILURE); /* BIIG buffer */ - } - debug("managing request\n"); - ch2 = (char*)memchr(buf, '\n', NTLM_BLOB_BUFFER_SIZE); /* safer against overrun than strchr */ - if (ch2) { - *ch2 = '\0'; /* terminate the string at newline. */ - } - debug("ntlm authenticator. Got '%s' from Squid\n", buf); - - if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */ - /* figure out what we got */ - struct base64_decode_ctx ctx; - base64_decode_init(&ctx); - size_t dstLen = 0; - int decodedLen = 0; - if (!base64_decode_update(&ctx, &dstLen, reinterpret_cast(decoded), strlen(buf)-3, buf+3) || - !base64_decode_final(&ctx)) { - SEND("NA Packet format error, couldn't base64-decode"); - return; - } - decodedLen = dstLen; - - if ((size_t)decodedLen < sizeof(ntlmhdr)) { /* decoding failure, return error */ - SEND("NA Packet format error, truncated packet header."); - return; - } - /* fast-track-decode request type. */ - fast_header = (ntlmhdr *) decoded; - - /* sanity-check: it IS a NTLMSSP packet, isn't it? */ - if (ntlm_validate_packet(fast_header, NTLM_ANY) < 0) { - SEND("NA Broken authentication packet"); - return; - } - switch (le32toh(fast_header->type)) { - case NTLM_NEGOTIATE: - SEND("NA Invalid negotiation request received"); - return; - /* notreached */ - case NTLM_CHALLENGE: - SEND("NA Got a challenge. We refuse to have our authority disputed"); - return; - /* notreached */ - case NTLM_AUTHENTICATE: - /* check against the DC */ - signal(SIGALRM, timeout_during_auth); - alarm(30); - cred = ntlm_check_auth((ntlm_authenticate *) decoded, decodedLen); - alarm(0); - signal(SIGALRM, SIG_DFL); - if (got_timeout != 0) { - fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid()); - SEND("BH Timeout during authentication"); - got_timeout = 0; - return; - } - if (cred == NULL) { - int smblib_err, smb_errorclass, smb_errorcode, nb_error; - if (ntlm_errno == NtlmError::LoginEror) { /* hackish */ - SEND("NA Logon Failure"); - return; - } - /* there was an error. We have two errno's to look at. - * libntlmssp's erno is insufficient, we'll have to look at - * the actual SMB library error codes, to actually figure - * out what's happening. The thing has braindamaged interfacess..*/ - smblib_err = SMB_Get_Last_Error(); - smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err()); - smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err()); - nb_error = RFCNB_Get_Last_Error(); - debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n", - smblib_err, smb_errorclass, smb_errorcode, nb_error); - /* Should I use smblib_err? Actually it seems I can do as well - * without it.. */ - if (nb_error != 0) { /* netbios-level error */ - SEND("BH NetBios error!"); - fprintf(stderr, "NetBios error code %d (%s)\n", nb_error, - RFCNB_Error_Strings[abs(nb_error)]); - return; - } - switch (smb_errorclass) { - case SMBC_SUCCESS: - debug("Huh? Got a SMB success code but could check auth.."); - SEND("NA Authentication failed"); - return; - case SMBC_ERRDOS: - /*this is the most important one for errors */ - debug("DOS error\n"); - switch (smb_errorcode) { - /* two categories matter to us: those which could be - * server errors, and those which are auth errors */ - case SMBD_noaccess: /* 5 */ - SEND("NA Access denied"); - return; - case SMBD_badformat: - SEND("NA bad format in authentication packet"); - return; - case SMBD_badaccess: - SEND("NA Bad access request"); - return; - case SMBD_baddata: - SEND("NA Bad Data"); - return; - default: - SEND("BH DOS Error"); - return; - } - case SMBC_ERRSRV: /* server errors */ - debug("Server error"); - switch (smb_errorcode) { - /* mostly same as above */ - case SMBV_badpw: - SEND("NA Bad password"); - return; - case SMBV_access: - SEND("NA Server access error"); - return; - default: - SEND("BH Server Error"); - return; - } - case SMBC_ERRHRD: /* hardware errors don't really matter */ - SEND("BH Domain Controller Hardware error"); - return; - case SMBC_ERRCMD: - SEND("BH Domain Controller Command Error"); - return; - } - SEND("BH unknown internal error."); - return; - } - - lc(cred); /* let's lowercase them for our convenience */ - SEND2("AF %s", cred); - return; - default: - SEND("BH unknown authentication packet type"); - return; - } - /* notreached */ - return; - } - if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */ - dc_disconnect(); - const char *ch = obtain_challenge(); - /* Robert says we can afford to wait forever. I'll trust him on this - * one */ - while (ch == NULL) { - sleep(30); - ch = obtain_challenge(); - } - SEND2("TT %s", ch); - return; - } - SEND("BH Helper detected protocol error"); - return; - /********* END ********/ - -} - -int -main(int argc, char *argv[]) -{ - debug("%s " VERSION " " SQUID_BUILD_INFO " starting up...\n", argv[0]); - - my_program_name = argv[0]; - process_options(argc, argv); - - debug("options processed OK\n"); - - /* initialize FDescs */ - setbuf(stdout, nullptr); - setbuf(stderr, nullptr); - - /* select the first domain controller we're going to use */ - current_dc = controllers; - if (load_balance != 0 && numcontrollers > 1) { - int n; - pid_t pid = getpid(); - n = pid % numcontrollers; - debug("load balancing. Selected controller #%d\n", n); - while (n > 0) { - current_dc = current_dc->next; - --n; - } - } - while (1) { - manage_request(); - } - /* notreached */ - return EXIT_SUCCESS; -} - diff --git a/src/auth/ntlm/SMB_LM/required.m4 b/src/auth/ntlm/SMB_LM/required.m4 deleted file mode 100755 index ea57ce6867..0000000000 --- a/src/auth/ntlm/SMB_LM/required.m4 +++ /dev/null @@ -1,17 +0,0 @@ -## Copyright (C) 1996-2025 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -# -# DONT build this helper on Windows -# DONT build this helper by default -# -# XXX: do we really need the mingw check? -AS_IF([test "$squid_host_os" != "mingw" -a "x$auto_helpers" != "xyes"],[ - BUILD_HELPER="SMB_LM" - AC_CHECK_HEADERS([w32api/windows.h windows.h],[BUILD_HELPER=""]) - AS_IF([test "x$BUILD_HELPER" = "xSMB_LM"],[require_smblib="yes"]) -]) diff --git a/src/auth/ntlm/helpers.m4 b/src/auth/ntlm/helpers.m4 index 1ef124dba5..aba81c43ac 100644 --- a/src/auth/ntlm/helpers.m4 +++ b/src/auth/ntlm/helpers.m4 @@ -9,7 +9,6 @@ AS_IF([test "x$enable_auth" != "xno"],[ SQUID_HELPER_FEATURE_CHECK([auth_ntlm],[$enable_auth],[auth/ntlm],[ # NP: we only need this list because m4_include() does not accept variables SQUID_CHECK_HELPER([fake],[auth/ntlm]) - SQUID_CHECK_HELPER([SMB_LM],[auth/ntlm]) SQUID_CHECK_HELPER([SSPI],[auth/ntlm]) ]) NTLM_AUTH_HELPERS=$squid_cv_BUILD_HELPERS -- 2.47.2