- Major rewrite of proxy authentication to support other schemes
than basic. First in the line is NTLM support but others can
easily be added (digest is on the way). See Programmers Guide.
- (Robert Collins & Chemolli Francesco)
+ (Robert Collins & Francesco Chemolli)
- Reworked how request bodies are passed down to the protocols.
Now all client side processing is inside client_side.c, and
the pass and pump modules is no longer used.
dnl
dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
dnl
-dnl $Id: configure.in,v 1.221 2001/02/25 21:49:08 hno Exp $
+dnl $Id: configure.in,v 1.222 2001/03/10 00:55:35 hno Exp $
dnl
dnl
dnl
AC_INIT(src/main.c)
AC_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.221 $)dnl
+AC_REVISION($Revision: 1.222 $)dnl
AC_PREFIX_DEFAULT(/usr/local/squid)
AC_CONFIG_AUX_DIR(cfgaux)
fi
AC_SUBST(DIGEST_AUTH_HELPERS)
+dnl Enable "NTLM fail open"
+AC_ARG_ENABLE(ntlm-fail-open,
+[ --enable-ntlm-fail-open Enable NTLM fail open, where a helper that fails one of the
+ Authentication steps can allow squid to still authenticate
+ the user.],
+[ if test "$enableval" = "yes" ; then
+ AC_DEFINE(NTLM_FAIL_OPEN)
+ fi
+])
+
dnl Disable "unlinkd" code
AC_ARG_ENABLE(unlinkd,
[ --disable-unlinkd Do not use unlinkd],
#define debug(X...) /* */
#endif /* DEBUG */
#else /* __GNUC__ */
-#define debug(char *format, ...) {} /* Too lazy to write va_args stuff */
+static void
+debug(char *format,...)
+{
+}
+
#endif
/* A couple of harmless helper macros */
#define SEND(X) debug("sending '%s' to squid\n",X); printf(X); printf("\n");
+#ifdef __GNUC__
#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X,Y);\
printf("\n");
+#else
+/* no gcc, no debugging. varargs macros are a gcc extension */
+#define SEND2 printf
+#endif
extern int ntlm_errno;
#define NTLM_NO_ERROR 0
#include "ntlmauth.h"
#include "ntlm.h"
#include "util.h"
+#include "smbval/smblib-common.h"
+#include "smbval/rfcnb-error.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();
extern int SMB_Get_Last_SMB_Err();
+extern int RFCNB_Get_Last_Error();
+#include <errno.h>
#define BUFFER_SIZE 10240
if (last_ditch_enabled) {
creds = fetch_credentials(failedauth, authlen);
if (creds) {
+ lc(creds);
SEND2("LD %s", creds);
} else {
SEND("NA last-ditch on, but no credentials");
usage()
{
fprintf(stderr,
- "%s usage:\n"
- "%s [-b] [-f] domain\\controller [domain\\controller ...]\n"
- "-b, if specified, enables load-balancing among controllers\n"
- "-f, if specified, enables failover among controllers\n"
- "-l, if specified, changes behavior on domain controller failyures to"
- "\tlast-ditch\n\n" "You MUST specify at least one Domain Controller.\n"
- "You can use either \\ or / as separator between the domain name \n"
- "\tand the controller name\n",
+ "%s usage:\n%s [-b] [-f] domain\\controller [domain\\controller ...]\n-b, if specified, enables load-balancing among controllers\n-f, if specified, enables failover among controllers\n-l, if specified, changes behavior on domain controller failyures to\tlast-ditch\n\nYou MUST specify at least one Domain Controller.\nYou can use either \\ or / as separator between the domain name \n\tand the controller name\n",
my_program_name, my_program_name);
}
debug("obtain_challenge: getting new challenge\n");
for (j = 0; j < numcontrollers; j++) {
if (current_dc->status == DC_OK) {
- debug("getting challenge from %s\%s\n", current_dc->domain, current_dc->controller);
+ debug("getting challenge from %s\\%s (attempt no. %d)\n",
+ current_dc->domain, current_dc->controller, j + 1);
ch = make_challenge(current_dc->domain, current_dc->controller);
- if (ch)
+ 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->status = DC_DEAD;
need_dc_resurrection = 1;
+ } else {
+ debug("controller %s\\%s not OK, skipping\n", current_dc->domain,
+ current_dc->controller);
}
if (failover_enabled == 0) /* No failover. Just return */
return NULL;
/* Try with the next */
+ debug("moving on to next controller\n");
current_dc = current_dc->next;
}
/* DC (all DCs if failover is enabled) failed. */
char *ch2, *decoded, *cred;
int plen;
- if (fgets(buf, BUFFER_SIZE, stdin) == NULL)
- exit(0); /* BIIG buffer */
+ if (fgets(buf, BUFFER_SIZE, stdin) == NULL) {
+ fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
+ strerror(errno));
+ abort();
+ exit(1); /* BIIG buffer */
+ }
+ debug("managing request\n");
ch2 = memchr(buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */
if (ch2) {
*ch2 = '\0'; /* terminate the string at newline. */
return;
/* notreached */
case NTLM_CHALLENGE:
- SEND("NA Got a challenge. We refuse to have our authority disputed");
+ SEND
+ ("NA Got a challenge. We refuse to have our authority disputed");
return;
/* notreached */
case NTLM_AUTHENTICATE:
plen = strlen(buf) * 3 / 4; /* we only need it here. Optimization */
cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
if (cred == NULL) {
- int errorclass, errorcode;
-#ifdef DEBUG
- SMB_Get_Error_Msg(SMB_Get_Last_SMB_Err(),
- error_messages_buffer, BUFFER_SIZE);
- debug("Authentication failure. SMB error: %d: %s\n. Class=%d, "
- "Code=%d\n",
- SMB_Get_Last_SMB_Err(), error_messages_buffer,
- SMB_Get_Last_SMB_Err() & 0xff, SMB_Get_Last_SMB_Err() >> 16);
-#endif
- /* This is kind of a special case, which happens when the
- * client sends credentials in a domain which is not trusted
- * by the domain we're using when authenticating. Unfortunately,
- * it can't currently be accommodated in the current framework so
- * I'll leave it hanging here, waiting for the general framework
- * to be expanded to better accommodate the generale case. */
- errorclass = SMB_Get_Last_SMB_Err() & 0xff;
- errorcode = SMB_Get_Last_SMB_Err() >> 16;
- if (errorclass == 1 && errorcode == 5) {
- SEND("NA Wrong password or untrusted domain");
+ int smblib_err, smb_errorclass, smb_errorcode, nb_error;
+ /* 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 acually 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_or_ld("NetBios error!",
+ (ntlm_authenticate *) decoded, plen);
+ fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
+ RFCNB_Error_Strings[abs(nb_error)]);
return;
}
- switch (ntlm_errno) {
- case NTLM_LOGON_ERROR:
- SEND("NA authentication failure");
- /* I must have been drugged when I wrote the following two lines */
- /* dc_disconnect();
- * current_dc = current_dc->next; */
- return;
- case NTLM_SERVER_ERROR:
- send_bh_or_ld("BH Domain Controller Error", (ntlm_authenticate *) decoded, plen);
- /* SEND("BH Domain Controller Error"); */
- /* we don't really need to disconnect NOW.
- * Besides, we asked squid to force a reconnect. This way, if we
- * have authentications in flight, we might even succeed.
+ switch (smb_errorclass) {
+ case SMBC_SUCCESS:
+ debug("Huh? Got a SMB success code but could check auth..");
+ SEND("NA Authentication failed");
+ /*
+ * send_bh_or_ld("SMB success, but no creds. Internal error?",
+ * (ntlm_authenticate *) decoded, plen);
*/
- /* dc_disconnect(); */
-
- SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000);
- debug("Last error was: %s, RFC errno=%d\n", smb_error_buffer,
- RFCNB_Get_Last_Errno());
- if (failover_enabled)
- current_dc = current_dc->next;
- return;
- case NTLM_PROTOCOL_ERROR:
- send_bh_or_ld("BH Domain Controller communication error", (ntlm_authenticate *) decoded, plen);
- /* SEND("BH Domain Controller communication error"); */
- /* dc_disconnect(); */
- if (failover_enabled)
- current_dc = current_dc->next;
- return;
- case NTLM_NOT_CONNECTED:
- send_bh_or_ld("BH Domain Controller (or network) died on us", (ntlm_authenticate *) decoded, plen);
- /* SEND("BH Domain Controller (or network) died on us"); */
- /* dc_disconnect(); */
- if (failover_enabled)
- current_dc = current_dc->next;
return;
- case NTLM_BAD_PROTOCOL:
- send_bh_or_ld("BH Domain controller failure", (ntlm_authenticate *) decoded, plen);
- /* SEND("BH Domain controller failure"); */
- /* dc_disconnect(); *//* maybe we're overreacting? */
- SMB_Get_Error_Msg(SMB_Get_Last_Error(), smb_error_buffer, 1000);
- debug("Last error was: %s. RFCNB errno=%d\n", smb_error_buffer,
- RFCNB_Get_Last_Errno());
- if (failover_enabled)
- current_dc = current_dc->next;
+ 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_or_ld("DOS Error",
+ (ntlm_authenticate *) decoded, plen);
+ 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_or_ld("Server Error",
+ (ntlm_authenticate *) decoded, plen);
+ return;
+ }
+ case SMBC_ERRHRD: /* hardware errors don't really matter */
+ send_bh_or_ld("Domain Controller Hardware error",
+ (ntlm_authenticate *) decoded, plen);
return;
- default:
- send_bh_or_ld("BH Unhandled error while talking to Domain Controller", (ntlm_authenticate *) decoded, plen);
- /* SEND("BH Unhandled error while talking to Domain Controller"); */
- /* dc_disconnect(); *//* maybe we're overreacting? */
- if (failover_enabled)
- current_dc = current_dc->next;
+ case SMBC_ERRCMD:
+ send_bh_or_ld("Domain Controller Command Error",
+ (ntlm_authenticate *) decoded, plen);
return;
}
}
{
debug("ntlm_auth build " __DATE__ ", " __TIME__ " starting up...\n");
+#ifdef DEBUG
+ debug("changing dir to /tmp\n");
+ chdir("/tmp");
+#endif
my_program_name = argv[0];
process_options(argc, argv);
}
}
while (1) {
- debug("managing request\n");
manage_request();
}
return 0;
* It assumes that a int is at least 32 bits long
*/
#include <string.h>
-
-typedef unsigned int uint32;
+#include "std-defines.h" /* for the types */
static uint32 A, B, C, D;
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "std-includes.h"
+
void RFCNB_CvtPad_Name(char *name1, char *name2);
/* global data structures */
-static char *RFCNB_Error_Strings[] =
+char *RFCNB_Error_Strings[] =
{
"RFCNBE_OK: Routine completed successfully.",
#include <string.h>
#include <ctype.h>
-//#include <arpa/inet.h>
#include <dirent.h>
#include <string.h>
-//#include <sys/vfs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "std-defines.h"
#include "smblib-common.h"
-#include <sys/types.h>
#include <unistd.h>
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-
#include "byteorder.h" /* Hmmm ... hot good */
#define max(a,b) (a < b ? b : a)
+
/* UNIX SMBlib NetBIOS implementation
*
* Version 1.0
#include <signal.h>
-#define DEBUG
+/* #define DEBUG */
SMB_State_Types SMBlib_State;
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define BOOL int
-typedef short int16;
+#include "squid_types.h"
+#define BOOL int16_t
+#define int16 int16_t
+#define uint16 u_int16_t
+#define int32 int32_t
+#define uint32 u_int32_t
#include <netdb.h>
#include <sys/types.h>
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define BOOL int
-typedef short int16;
+/* the types are provided by squid's configure preocess */
+#include "squid_types.h"
+#define BOOL int16_t
+#define int16 int16_t
#include <netdb.h>
#include <sys/types.h>
*/
#include "config.h"
+#include "squid_types.h"
+#include "ntlmauth.h"
#include "ntlm.h"
#include "util.h"
* Check the vailidity of a request header. Return -1 on error.
*/
int
-ntlmCheckHeader(struct ntlmhdr *hdr, int type)
+ntlmCheckHeader(ntlmhdr * hdr, int type)
{
/*
* Must be the correct security package and request type. The
printf("TT %s\n", data);
} else if (strncasecmp(buf, "KK ", 3) == 0) {
cleartext = (char *) uudecode(buf + 3);
- if (!ntlmCheckHeader((struct ntlmhdr *) cleartext, NTLM_AUTHENTICATE)) {
+ if (!ntlmCheckHeader((ntlmhdr *) cleartext, NTLM_AUTHENTICATE)) {
if (!ntlmDecodeAuth((struct ntlm_authenticate *) cleartext, user, 256)) {
lc(user);
printf("AF %s\n", user);
/*
- * $Id: ntlm.h,v 1.2 2001/01/12 00:37:31 wessels Exp $
+ * $Id: ntlm.h,v 1.3 2001/03/10 00:55:39 hno Exp $
*
* AUTHOR: Andy Doran <ad@netbsd.org>
*
#define NTLM_AUTHENTICATE 3
#define NTLM_ANY 0
-/* Header proceeding each request */
-typedef struct ntlmhdr {
- char signature[8]; /* NTLMSSP */
- int32_t type; /* One of NTLM_* from above */
-} ntlmhdr;
-
-/* String header. String data resides at the end of the request */
-typedef struct strhdr {
- int16_t len; /* Length in bytes */
- int16_t maxlen; /* Allocated space in bytes */
- int32_t offset; /* Offset from start of request */
-} strhdr;
-
/* Negotiation request sent by client */
struct ntlm_negotiate {
ntlmhdr hdr; /* NTLM header */
char *ntlmGetString(ntlmhdr * hdr, strhdr * str, int flags);
void ntlmMakeChallenge(struct ntlm_challenge *chal);
-int ntlmCheckHeader(struct ntlmhdr *hdr, int type);
+int ntlmCheckHeader(ntlmhdr * hdr, int type);
int ntlmCheckNegotiation(struct ntlm_negotiate *neg);
int ntlmAuthenticate(struct ntlm_authenticate *neg);
/*
- * $Id: ntlmauth.h,v 1.3 2001/02/25 21:49:09 hno Exp $
+ * $Id: ntlmauth.h,v 1.4 2001/03/10 00:55:36 hno Exp $
*
* * * * * * * * Legal stuff * * * * * * *
*
* among the different signature types. */
typedef struct _ntlmhdr {
char signature[8]; /* "NTLMSSP" */
- int32_t type; /* LSWAP(0x1) */
+ int32_t type; /* One of the NTLM_* types above. */
} ntlmhdr;
/* Negotiation request sent by client */
/*
- * $Id: HttpStatusLine.cc,v 1.23 2001/02/23 20:59:50 hno Exp $
+ * $Id: HttpStatusLine.cc,v 1.24 2001/03/10 00:55:36 hno Exp $
*
* DEBUG: section 57 HTTP Status-line
* AUTHOR: Alex Rousskov
}
if (!(start = strchr(start, ' ')))
return 0;
- sline->status = (http_status)atoi(++start);
+ sline->status = (http_status) atoi(++start);
/* we ignore 'reason-phrase' */
return 1; /* success */
}
/*
- * $Id: acl.cc,v 1.250 2001/03/03 10:39:30 hno Exp $
+ * $Id: acl.cc,v 1.251 2001/03/10 00:55:36 hno Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
default:
debug(28, 0) ("%s line %d: %s\n",
cfg_filename, config_lineno, config_input_line);
- debug(28, 0) ("aclParseTimeSpec: Bad Day '%c'\n",
- *t);
+ debug(28, 0) ("aclParseTimeSpec: Bad Day '%c'\n", *t);
break;
}
}
Top = splay_splay(user, Top, (SPLAYCMP *) strcmp);
/* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */
debug(28, 7) ("aclMatchUser: returning %d,Top is %p, Top->data is %s\n",
- !splayLastResult,
- Top, (Top ? Top->data : "Unavailable"));
+ !splayLastResult, Top, (Top ? Top->data : "Unavailable"));
data->names = Top;
return !splayLastResult;
}
while (link) {
auth_match = link->data;
if (auth_match->acl_data == data) {
- debug(28, 4) ("aclCacheMatchAcl: cache hit on acl '%d'\n",
- data);
+ debug(28, 4) ("aclCacheMatchAcl: cache hit on acl '%d'\n", data);
return auth_match->matchrv;
}
link = link->next;
*/
static int
aclMatchProxyAuth(void *data, http_hdr_type headertype,
- auth_user_request_t * auth_user_request, aclCheck_t * checklist, squid_acl acltype)
+ auth_user_request_t * auth_user_request, aclCheck_t * checklist,
+ squid_acl acltype)
{
/* checklist is used to register user name when identified, nothing else */
const char *proxy_auth;
*/
return 0;
}
- if (((proxy_auth == NULL) && (checklist->conn->auth_type == AUTH_UNKNOWN)) || (checklist->conn->auth_type == AUTH_BROKEN)) {
+ /*
+ * a note on proxy_auth logix here:
+ * proxy_auth==NULL -> unauthenticated request || already authenticated connection
+ * so we test for an authenticated connection when we recieve no authentication
+ * header.
+ */
+ if (((proxy_auth == NULL) && (!authenticateUserAuthenticated(auth_user_request)))
+ || (checklist->conn->auth_type == AUTH_BROKEN)) {
/* no header or authentication failed/got corrupted - restart */
checklist->conn->auth_type = AUTH_UNKNOWN;
debug(28, 4) ("aclMatchProxyAuth: broken auth or no proxy_auth header. Requesting auth header.\n");
* not had bungled connection oriented authentication happen on it. */
debug(28, 9) ("aclMatchProxyAuth: header %s.\n", proxy_auth);
if (auth_user_request == NULL) {
- debug(28, 9) ("aclMatchProxyAuth: This is a new request on FD:%d\n", checklist->conn->fd);
- if ((!checklist->request->auth_user_request) && (checklist->conn->auth_type == AUTH_UNKNOWN)) {
+ debug(28, 9) ("aclMatchProxyAuth: This is a new request on FD:%d\n",
+ checklist->conn->fd);
+ if ((!checklist->request->auth_user_request)
+ && (checklist->conn->auth_type == AUTH_UNKNOWN)) {
/* beginning of a new request check */
debug(28, 4) ("aclMatchProxyAuth: no connection authentication type\n");
- if (!authenticateValidateUser(auth_user_request = authenticateGetAuthUser(proxy_auth))) {
+ if (!authenticateValidateUser(auth_user_request =
+ authenticateGetAuthUser(proxy_auth))) {
/* the decode might have left a username for logging, or a message to
* the user */
if (authenticateUserRequestUsername(auth_user_request)) {
authenticateAuthUserRequestLock(auth_user_request);
} else {
/* failed connection based authentication */
- debug(28, 4) ("aclMatchProxyAuth: Aauth user request %d conn-auth user request %d conn type %d authentication failed.\n", auth_user_request, checklist->conn->auth_user_request, checklist->conn->auth_type);
+ debug(28, 4) ("aclMatchProxyAuth: Auth user request %d conn-auth user request %d conn type %d authentication failed.\n",
+ auth_user_request, checklist->conn->auth_user_request,
+ checklist->conn->auth_type);
return -2;
}
}
checklist->auth_user_request = NULL;
if (!authenticateUserAuthenticated(auth_user_request)) {
/* User not logged in. Log them in */
- authenticateAuthUserRequestSetIp(auth_user_request, checklist->src_addr);
- authenticateAuthenticateUser(auth_user_request, checklist->request, checklist->conn, headertype);
+ authenticateAuthUserRequestSetIp(auth_user_request,
+ checklist->src_addr);
+ authenticateAuthenticateUser(auth_user_request, checklist->request,
+ checklist->conn, headertype);
switch (authenticateDirection(auth_user_request)) {
case 1:
/* this ACL check is finished. Unlock. */
/* this ACL check completed */
authenticateAuthUserRequestUnlock(auth_user_request);
/* check to see if we have matched the user-acl before */
- return aclCacheMatchAcl(&auth_user_request->auth_user->proxy_match_cache,
- acltype, data, authenticateUserRequestUsername(auth_user_request));
+ return aclCacheMatchAcl(&auth_user_request->auth_user->
+ proxy_match_cache, acltype, data,
+ authenticateUserRequestUsername(auth_user_request));
}
/* this acl check completed */
authenticateAuthUserRequestUnlock(auth_user_request);
case ACL_REP_MIME_TYPE:
if (!checklist->reply)
return 0;
- header = httpHeaderGetStr(&checklist->reply->header,
- HDR_CONTENT_TYPE);
+ header = httpHeaderGetStr(&checklist->reply->header, HDR_CONTENT_TYPE);
if (NULL == header)
header = "";
return aclMatchRegex(ae->data, header);
if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) {
checklist->state[ACL_DST_IP] = ACL_LOOKUP_PENDING;
ipcache_nbgethostbyname(checklist->request->host,
- aclLookupDstIPDone,
- checklist);
+ aclLookupDstIPDone, checklist);
return;
} else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) {
checklist->state[ACL_DST_ASN] = ACL_LOOKUP_PENDING;
ipcache_nbgethostbyname(checklist->request->host,
- aclLookupDstIPforASNDone,
- checklist);
+ aclLookupDstIPforASNDone, checklist);
return;
} else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) {
checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING;
fqdncache_nbgethostbyaddr(checklist->src_addr,
- aclLookupSrcFQDNDone,
- checklist);
+ aclLookupSrcFQDNDone, checklist);
return;
} else if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) {
ia = ipcacheCheckNumeric(checklist->request->host);
checklist->dst_addr = ia->in_addrs[0];
checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING;
fqdncache_nbgethostbyaddr(checklist->dst_addr,
- aclLookupDstFQDNDone,
- checklist);
+ aclLookupDstFQDNDone, checklist);
return;
} else if (checklist->state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) {
debug(28, 3)
}
aclCheck_t *
-aclChecklistCreate(const acl_access * A,
- request_t * request,
- const char *ident)
+aclChecklistCreate(const acl_access * A, request_t * request, const char *ident)
{
int i;
aclCheck_t *checklist;
t->weekbits & ACL_THURSDAY ? 'H' : '-',
t->weekbits & ACL_FRIDAY ? 'F' : '-',
t->weekbits & ACL_SATURDAY ? 'A' : '-',
- t->start / 60,
- t->start % 60,
- t->stop / 60,
- t->stop % 60);
+ t->start / 60, t->start % 60, t->stop / 60, t->stop % 60);
wordlistAdd(&W, buf);
t = t->next;
}
arpReq.arp_ha.sa_data[2] & 0xff,
arpReq.arp_ha.sa_data[3] & 0xff,
arpReq.arp_ha.sa_data[4] & 0xff,
- arpReq.arp_ha.sa_data[5] & 0xff,
- ifr->ifr_name);
+ arpReq.arp_ha.sa_data[5] & 0xff, ifr->ifr_name);
/* Do lookup */
*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
/* Return if match, otherwise continue to other interfaces */
arpReq.arp_ha.sa_data[1] == 0 &&
arpReq.arp_ha.sa_data[2] == 0 &&
arpReq.arp_ha.sa_data[3] == 0 &&
- arpReq.arp_ha.sa_data[4] == 0 &&
- arpReq.arp_ha.sa_data[5] == 0)
+ arpReq.arp_ha.sa_data[4] == 0 && arpReq.arp_ha.sa_data[5] == 0)
return 0;
debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n",
arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff,
/* the digest_request structure is what follows the http_request around */
struct _digest_request_h {
- char *nonceb64; // = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
-
- char *cnonce; // = "0a4f113b";
-
- char *realm; // = "testrealm@host.com";
-
- char *pszPass; // = "Circle Of Life";
-
- char *algorithm; // = "md5";
-
- char nc[9]; // = "00000001";
-
- char *pszMethod; // = "GET";
-
- char *qop; // = "auth";
-
- char *uri; // = "/dir/index.html";
-
+ char *nonceb64; /* "dcd98b7102dd2f0e8b11d0f600bfb0c093" */
+ char *cnonce; /* "0a4f113b" */
+ char *realm; /* = "testrealm@host.com" */
+ char *pszPass; /* = "Circle Of Life" */
+ char *algorithm; /* = "md5" */
+ char nc[9]; /* = "00000001" */
+ char *pszMethod; /* = "GET" */
+ char *qop; /* = "auth" */
+ char *uri; /* = "/dir/index.html" */
char *response;
struct {
unsigned int authinfo_sent:1;
/*
- * $Id: auth_ntlm.cc,v 1.7 2001/03/03 10:39:36 hno Exp $
+ * $Id: auth_ntlm.cc,v 1.8 2001/03/10 00:55:37 hno Exp $
*
* DEBUG: section 29 NTLM Authenticator
* AUTHOR: Robert Collins
/* TODO: In here send the initial YR to preinitialise the challenge cache */
/* Think about this... currently we ask when the challenge is needed. Better? */
if (!ntlminit) {
- cachemgrRegister("ntlmauthenticator",
- "User NTLM Authenticator Stats",
- authenticateNTLMStats, 0, 1);
+ cachemgrRegister("ntlmauthenticator", "User NTLM Authenticator Stats", authenticateNTLMStats, 0, 1);
ntlminit++;
}
CBDATA_INIT_TYPE(authenticateStateData);
int
authNTLMConfigured()
{
- if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) &&
- (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1)
- && (ntlmConfig->challengelifetime > -1)) {
+ if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) && (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1) && (ntlmConfig->challengelifetime > -1)) {
debug(29, 9) ("authNTLMConfigured: returning configured\n");
return 1;
}
ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ);
ntlm_request->authhelper = NULL;
auth_user->flags.credentials_ok = 1; /* login ok */
+#ifdef NTLM_FAIL_OPEN
+ } else if (strncasecmp(reply, "LD ", 3) == 0) {
+ /* This is a variant of BH, which rather than deny access
+ * allows the user through. The helper is starved and then refreshed
+ * via YR, all pending authentications are likely to fail also.
+ * It is meant for those helpers which occasionally fail for
+ * no reason at all (casus belli, NTLMSSP helper on NT domain,
+ * failing about 1 auth out of 1k.
+ * The code is a merge from the BH case with snippets of the AF
+ * case */
+ /* AF code: mark user as authenticated */
+ reply += 3;
+ assert(r->auth_user_request != NULL);
+ assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM);
+ auth_user_request = r->auth_user_request;
+ assert(auth_user_request->scheme_data != NULL);
+ ntlm_request = auth_user_request->scheme_data;
+ auth_user = auth_user_request->auth_user;
+ ntlm_user = auth_user_request->auth_user->scheme_data;
+ assert(ntlm_user != NULL);
+ result = S_HELPER_RELEASE;
+ /* we only expect OK when finishing the handshake */
+ assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE);
+ ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ);
+ helperstate = helperStatefulServerGetData(ntlm_request->authhelper);
+ ntlm_request->authhelper = NULL;
+ auth_user->flags.credentials_ok = 1; /* login ok */
+ /* BH code: mark helper as broken */
+ /* Not a valid helper response to a YR request. Assert so the helper
+ * programmer will fix their bugs! */
+ assert(ntlm_request->auth_state != AUTHENTICATE_STATE_NEGOTIATE);
+ /* mark it for starving */
+ helperstate->starve = 1;
+#endif
} else if (strncasecmp(reply, "NA ", 3) == 0) {
/* TODO: only work with auth_user here if it exists */
assert(r->auth_user_request != NULL);
int
authenticateNTLMValidChallenge(ntlm_helper_state_t * helperstate)
{
+ debug(29, 9) ("authenticateNTLMValidChallenge: Challenge is %s\n", helperstate->challenge ? "Valid" : "Invalid");
if (helperstate->challenge == NULL)
return 0;
return 1;
/* don't check for invalid challenges just for expiry choices */
/* this is needed because we have to starve the helper until all old
* requests have been satisfied */
- if (helperstate->challengeuses > ntlmConfig->challengeuses)
+ if (!helperstate->renewed) {
+ /* first use, no challenge has been set. Without this check, it will
+ * loop forever */
+ debug(29, 5) ("authenticateNTLMChangeChallenge: first use\n");
+ return 0;
+ }
+ if (helperstate->challengeuses > ntlmConfig->challengeuses) {
+ debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig->challengeuses);
return 1;
- if (helperstate->renewed + ntlmConfig->challengelifetime >= squid_curtime)
+ }
+ if (helperstate->renewed + ntlmConfig->challengelifetime < squid_curtime) {
+ debug(29, 4) ("authenticateNTLMChangeChallenge: Challenge exceeded max lifetime by %d seconds\n", squid_curtime - (helperstate->renewed + ntlmConfig->challengelifetime));
return 1;
+ }
+ debug(29, 9) ("Challenge is to be reused\n");
return 0;
}
*/
server = helperStatefulDefer(ntlmauthenticators);
helperstate = server ? helperStatefulServerGetData(server) : NULL;
- while ((server != NULL) &&
- authenticateNTLMChangeChallenge(helperstate)) {
+ while ((server != NULL) && authenticateNTLMChangeChallenge(helperstate)) {
/* flag this helper for challenge changing */
helperstate->starve = 1;
/* and release the deferred request */
/* increment the challenge uses */
helperstate->challengeuses++;
/* assign the challenge */
- ntlm_request->authchallenge =
- xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5);
+ ntlm_request->authchallenge = xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5);
handler(data, NULL);
}
{
auth_user_hash_pointer *proxy_auth_hash;
ntlm_user_t *ntlm_user;
- proxy_auth_hash =
- memAllocate(MEM_AUTH_USER_HASH);
+ proxy_auth_hash = memAllocate(MEM_AUTH_USER_HASH);
proxy_auth_hash->key = xstrdup(key);
proxy_auth_hash->auth_user = auth_user;
ntlm_user = auth_user->scheme_data;
- dlinkAddTail(proxy_auth_hash, &proxy_auth_hash->link,
- &ntlm_user->proxy_auth_list);
+ dlinkAddTail(proxy_auth_hash, &proxy_auth_hash->link, &ntlm_user->proxy_auth_list);
hash_join(proxy_auth_cache, (hash_link *) proxy_auth_hash);
}
switch (ntlm_request->auth_state) {
case AUTHENTICATE_STATE_NONE:
/* we've recieved a negotiate request. pass to a helper */
- debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n",
- proxy_auth);
+ debug(29, 9) ("authenticateNTLMAuthenticateUser: auth state ntlm none. %s\n", proxy_auth);
if (auth_user->flags.credentials_ok == 2) {
/* the authentication fialed badly... */
return;
assert(auth_user->auth_type == AUTH_NTLM);
/* get the existing entries details */
ntlm_user = auth_user->scheme_data;
- debug(29, 9) ("Username to be used is %s\n",
- ntlm_user->username);
+ debug(29, 9) ("Username to be used is %s\n", ntlm_user->username);
auth_user->flags.credentials_ok = 1; /* authenticated ok */
/* on ntlm auth we do not unlock the auth_user until the
* connection is dropped. Thank MS for this quirk */
ntlm_request->authchallenge);
/* see if this is an existing user with a different proxy_auth
* string */
- if ((usernamehash = hash_lookup(proxy_auth_username_cache,
- ntlm_user->username))) {
- while ((usernamehash->auth_user->auth_type !=
- auth_user->auth_type) && (usernamehash->next) &&
- !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user))
+ if ((usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username))) {
+ while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user))
usernamehash = usernamehash->next;
if (usernamehash->auth_user->auth_type == auth_user->auth_type) {
/*
/*
- * $Id: authenticate.cc,v 1.21 2001/02/07 18:56:51 hno Exp $
+ * $Id: authenticate.cc,v 1.22 2001/03/10 00:55:36 hno Exp $
*
* DEBUG: section 29 Authenticator
* AUTHOR: Duane Wessels
temp_auth->auth_type = AUTH_UNKNOWN;
temp_auth->references = 0;
temp_auth->auth_module = authenticateAuthSchemeId(scheme) + 1;
+ temp_auth->usernamehash = NULL;
return temp_auth;
}
int
authenticateUserAuthenticated(auth_user_request_t * auth_user_request)
{
- assert(authenticateValidateUser(auth_user_request));
+ if (!authenticateValidateUser(auth_user_request))
+ return 0;
if (auth_user_request->auth_user->auth_module > 0)
return authscheme_list[auth_user_request->auth_user->auth_module - 1].authenticated(auth_user_request);
else