dnl Configuration input file for Squid
dnl
-dnl $Id: configure.in,v 1.460 2007/06/24 22:34:15 hno Exp $
+dnl $Id: configure.in,v 1.461 2007/06/25 11:02:34 hno Exp $
dnl
dnl
dnl
AC_CONFIG_AUX_DIR(cfgaux)
AC_CONFIG_SRCDIR([src/main.cc])
AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.460 $)dnl
+AC_REVISION($Revision: 1.461 $)dnl
AC_PREFIX_DEFAULT(/usr/local/squid)
AM_MAINTAINER_MODE
helpers/basic_auth/SASL/Makefile \
helpers/basic_auth/POP3/Makefile \
helpers/basic_auth/DB/Makefile \
+ helpers/basic_auth/squid_radius_auth/Makefile \
helpers/digest_auth/Makefile \
helpers/digest_auth/password/Makefile \
helpers/digest_auth/ldap/Makefile \
# Makefile for storage modules in the Squid Object Cache server
#
-# $Id: Makefile.am,v 1.8 2007/06/02 23:49:23 hno Exp $
+# $Id: Makefile.am,v 1.9 2007/06/25 11:02:35 hno Exp $
#
-DIST_SUBDIRS = getpwnam LDAP MSNT multi-domain-NTLM NCSA PAM SMB YP SASL mswin_sspi POP3 DB
+DIST_SUBDIRS = getpwnam LDAP MSNT multi-domain-NTLM NCSA PAM SMB YP SASL mswin_sspi POP3 DB squid_radius_auth
SUBDIRS = @BASIC_AUTH_HELPERS@
--- /dev/null
+This program is based on code from Livingston Enterprises, Inc. and parts are
+
+ COPYRIGHT NOTICE SQUID_RAD_AUTH
+
+Copyright (C) 1992-1995 Livingston Enterprises, Inc and Cistron Internet Services
+B.V. who both have given permission to modify and distribute those parts. The new
+parts of the code is Copyright (C) 1998 R.M. van Selm <selm@cistron.nl> with
+modifications Copyright (C) 2004 Henrik Nordstrom <hno@squid-cache.org>
+
+Permission to use, copy, modify, and distribute this software for any purpose
+and without fee is hereby granted, provided that this copyright and permission
+notice appear on all copies and supporting documentation, the name of
+Livingston Enterprises, Inc. not be used in advertising or publicity pertaining
+to distribution of the program without specific prior permission, and notice be
+given in supporting documentation that copying and distribution is by
+permission of Livingston Enterprises, Inc. and Cistron Internet Services B.V.
+
+Neither Livingston Enterprises, Inc. nor Cistron Internet Services B.V. nor I
+(R.M. van Selm) make representations about the suitability of this software for
+any purpose. It isprovided "as is" without express or implied warranty.
+
+Marc van Selm <selm@cistron.nl>
+
+
+ COPYRIGHT NOTICE SQUID_RAD_AUTH Documentation
+
+Copyright (C) 2004 Henrik Nordstrom
+
+Permission to use, copy, modify, and distribute this software for any purpose
+and without fee is hereby granted, provided that this copyright and permission
+notice appear on all copies and supporting documentation, the name of Henrik
+Nordstrom. not be used in advertising or publicity pertaining to distribution
+of the program without specific prior permission.
+
+The author makes no representations about the suitability of this documentation
+for any purpose. It isprovided "as is" without express or implied warranty.
+
+Henrik Nordstrom <hno@squid-cache.org>
+
+ COPYRIGHT NOTICE CISTRON RADIUS
+
+/* This program is based on code from Livingston Enterprises, Inc. and parts are
+ * Copyright (C) 1992-1995 Livingston Enterprises, Inc who has given permission
+ * to modify and distribute those parts. The new code is Copyright (C) 1996-1997
+ * Cistron Internet Services B.V.
+ *
+ * Permission to use, copy, modify, and distribute this software for any purpose
+ * and without fee is hereby granted, provided that this copyright and permission
+ * notice appear on all copies and supporting documentation, the name of
+ * Livingston Enterprises, Inc. not be used in advertising or publicity pertaining
+ * to distribution of the program without specific prior permission, and notice be
+ * given in supporting documentation that copying and distribution is by
+ * permission of Livingston Enterprises, Inc. and Cistron Internet Services B.V.
+
+ * Neither Livingston Enterprises, Inc. nor Cistron Internet Services B.V. make
+ * representations about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+*/
+
+ COPYRIGHT NOTICE LIVINGSTON RADIUS 1.16
+
+/*
+ *
+ * RADIUS
+ * Remote Authentication Dial In User Service
+ *
+ *
+ * Livingston Enterprises, Inc.
+ * 6920 Koll Center Parkway
+ * Pleasanton, CA 94566
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that this
+ * copyright and permission notice appear on all copies and supporting
+ * documentation, the name of Livingston Enterprises, Inc. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * program without specific prior permission, and notice be given
+ * in supporting documentation that copying and distribution is by
+ * permission of Livingston Enterprises, Inc.
+ *
+ * Livingston Enterprises, Inc. makes no representations about
+ * the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+
+
+ COPYRIGHT NOTICE RSA Data Security MD5 (md5.c)
+
+MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+
--- /dev/null
+1.09: - RADIUS protocol fixes by Henrik Nordstrom <hno@squid-cache.org>
+ - Corrected how retransmits & timeouts is handled
+ - The shared secret now verified properly
+ - Request/response processing paired properly
+ - New -t command line option to tune the RADIUS timeout
+1.08: - RADIUS port/service option by Joost de Heer <sanguis@xs4all.nl>
+ - Added service/port tags to the configuration file allowing
+ manual override of the RADIUS port number via the config
+ file in addition to the already existing -p command line
+ option doing the same.
+ - The default port used if the radius service could not be found
+ in /etc/services changed from the obsolete 1645 to the official
+ port 1812
+1.07: - Squid-2.5 update by Henrik Nordstrom <hno@squid-cache.org>
+ The Basic auth helper communication has changed slightly in
+ Squid-2.5 to use URL-encoded strings. This to allow use of "odd"
+ characters such as space without problems.
+ - Major cleanup to remove dead code and unneeded references to
+ RADIUS dictionary files.
+ - Added commandline opttions. No more hardcoded paths.
+ - Added manpage documentation to document the configuration of this
+ helper
+1.06: - Included byte-order patch from Klaus Weidner <kw@w-m-p.com>
+ The assignment of 'auth->length' erroneously used 'htonl' instead
+ of 'htons' to assign a 16-bit value. The symptom was that the radius
+ server ignored the requests, because they had zero length according
+ to the data header.
+ - Initial warnings confused Squid. Most (all) of them now warn to stderr
+ so you should see them in the cache.log
+ - A fix by Moslem Saleh: A select timeout causes the redirector to skip
+ the reply. Moslem detected/fixed this issue on a BSD 4.1 (on Intel)
+ system.
+1.05a: - Minor fixes and warnings. Should fix some compiler issues (compiler
+ fixes are untested except on Debian Linux 1.3 & GCC-2.95-2)
+1.04: - Rolled in patches from Mike McCauley and Andrea Dell'Amico:
+ These patches fix a few bugs and make the kit more platform
+ independent.
+ also fixes:
+ Unwanted characters in the reply. This confuses Squid.
+ This is caused by unexpected replies from the RADIUS server
+ and should have been ignored by
+ the authenticator;
+ It enables long passwords (up to 254 characters);
+ It allows passwords with embedded spaces.
+ Mike McCauley mikem@open.com.au
+ Added Makefile.solaris for Solaris 2.5.1
+1.03: - Fixes for Solaris(2.5)
+ (UINT4 *)ptr = htonln(nas_ipaddr) causes a coredumps in Solaris.
+ This works better:
+ nip=htonl(nas_ipaddr);
+ memcpy(prt, nip, 4)
+ - Also portno is changed in this fashion.
+
+1.02: - Pre release (various fixes)
+1.01: - various bug fixes
--- /dev/null
+#
+# Makefile RADIUS authentifications for squid
+#
+#
+
+PREFIX = /usr/local/squid
+BINDIR = $(PREFIX)/libexec/
+MANDIR = $(PREFIX)/man/man8
+MANEXT = .8
+CONFDIR = $(PREFIX)/etc
+
+INCLUDES = radius.h md5.h
+
+ALL: squid_radius_auth
+
+
+attrprint.o: attrprint.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c attrprint.c
+
+dict.o: dict.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c dict.c
+
+util.o: util.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c util.c
+
+squid_radius_auth: squid_rad_auth.o md5.o util.o
+ $(CC) $(LDFLAGS) -o squid_radius_auth squid_rad_auth.o md5.o util.o $(LIBS)
+
+squid_radius_auth.o: squid_rad_auth.c $(INCLUDES)
+ $(CC) $(CFLAGS) -c squid_rad_auth.c
+
+md5.o: md5.c md5.h
+ $(CC) $(CFLAGS) -c md5.c
+
+clean:
+ rm -f *.o squid_radius_auth
+
+install: squid_radius_auth
+ mkdir -p $(DESTDIR)$(BINDIR)
+ install -m 755 -s squid_radius_auth $(DESTDIR)$(BINDIR)/squid_radius_auth
+ mkdir -p $(DESTDIR)$(MANDIR)
+ install -m 755 squid_radius_auth.8 $(DESTDIR)$(MANDIR)/squid_radius_auth$(MANEXT)
+ mkdir -p $(DESTDIR)$(CONFDIR)
+ install -m 644 etc/squid_radius_auth.conf $(DESTDIR)$(CONFDIR)/squid_radius_auth.conf.default
+ if ! test -f $(DESTDIR)$(CONFDIR)/squid_radius_auth.conf; then \
+ cp -p $(DESTDIR)$(CONFDIR)/squid_radius_auth.conf.default $(DESTDIR)$(CONFDIR)/squid_radius_auth.conf; \
+ fi
+
+
--- /dev/null
+#
+# Makefile for the Squid LDAP authentication helper
+#
+# $Id: Makefile.am,v 1.1 2007/06/25 11:02:35 hno Exp $
+#
+# Uncomment and customize the following to suit your needs:
+#
+
+libexec_PROGRAMS = squid_radius_auth
+man_MANS = squid_radius_auth.8
+EXTRA_DIST = squid_radius_auth.8
+squid_radius_auth_SOURCES = \
+ squid_rad_auth.c \
+ md5.c md5.h \
+ radius.h \
+ util.c util.h
+
+LDADD = $(XTRA_LIBS)
--- /dev/null
+#
+# Makefile RADIUS authentifications for squid & Linux (2.0.x, lib5 or libc6)
+#
+#
+
+CC = gcc
+CFLAGS = -O2 -Wall -g
+LDFLAGS = -g
+LIBS =
+
+include Make.inc
--- /dev/null
+#
+# Makefile RADIUS authentifications for squid & Solaris 2.5.1
+#
+#
+
+CC = gcc
+CFLAGS = -O2 -Wall -g
+LDFLAGS = -g
+LIBS = -lsocket -lnsl
+
+include Make.inc
--- /dev/null
+Squid_radius_auth V1.09
+
+This kit is loosely based on radtest from the Cistron-radiusd which
+again is based on Livingston sources. See COPYRIGHT for details.
+
+This authenticator is specifically made for Squid-2.5 and later.
+
+Installation:
+
+Copy the correct makefile to Makefile
+ Makefile.default = Most OS:es.
+ Makefile.solaris = SunOS5 (Solaris)
+
+cp Makefile.default Makefile
+make clean
+make install
+
+or if you want the helper installed elsewhere than /usr/local/squid
+(the default installation path of Squid-2.5) use something like:
+
+make CONFDIR=/etc PREFIX=/usr BINDIR='${PREFIX}/libexec/squid' install
+
+Complete list of make options for tweakin the installation paths:
+
+ PREFIX Top level installation directory (/usr/local/squid)
+ BINDIR Where the binary is installed (PREFIX/libexec)
+ CONFDIR Where the configuration file is installed (PREFIX/etc)
+ MANDIR Where the manpage is installed (PREFIX/man/man8)
+ MANEXT Manpage extension (.8)
+ DESTDIR Root prefix for packaging
+
+
+Configuration:
+
+The RADIUS authenticator is configured using a small configuration file.
+
+The configuration file should look like this:
+# squid_rad_auth configuration file
+# MvS: 28-10-1998
+server suncone.cistron.nl
+secret testje
+
+An example can be found in etc/squid_rad_auth.conf
+
+
+/etc/services:
+
+Modify /etc/services and add:
+radius 1812/udp
+
+Adding this is not mandatory because it used the default port 1812 anyway.
+
+Note: Some old RADIUS servers uses the unofficial port 1645, and you may
+need to override the service port used either by editing /etc/services
+or by specifying the port using the -p command line option or the port
+tag in squid_rad_auth.conf
+
+
+Test it:
+
+Start squid_rad_auth and type a username and a username. The authenticator
+returns OK if the radiusd accepted your password. In any other case you'll
+get ERR.
+
+
+Squid:
+
+Add the authenticator to squid.conf. See the instructions from squid for
+help.
+
+Marc van Selm <selm@cistron.nl>
+Henrik Nordstrom <hno@squid-cache.org>
--- /dev/null
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context; /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
--- /dev/null
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+ The following makes PROTOTYPES default to 0 if it has not already
+ been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+# if __STDC__
+# define PROTOTYPES 1
+# else
+# define PROTOTYPES 0
+# endif
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+#if defined(__alpha) && (defined(__osf__) || defined(__linux__))
+typedef unsigned int UINT4;
+#else
+typedef unsigned long int UINT4;
+#endif
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+ ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+void md5_calc PROTO_LIST ((unsigned char *output, unsigned char *input, unsigned int inlen));
+
--- /dev/null
+/*
+ *
+ * RADIUS
+ * Remote Authentication Dial In User Service
+ *
+ *
+ * Livingston Enterprises, Inc.
+ * 6920 Koll Center Parkway
+ * Pleasanton, CA 94566
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that this
+ * copyright and permission notice appear on all copies and supporting
+ * documentation, the name of Livingston Enterprises, Inc. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * program without specific prior permission, and notice be given
+ * in supporting documentation that copying and distribution is by
+ * permission of Livingston Enterprises, Inc.
+ *
+ * Livingston Enterprises, Inc. makes no representations about
+ * the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ */
+
+/*
+ * @(#)radius.h 2.0 03-Aug-1996
+ */
+
+#define AUTH_VECTOR_LEN 16
+#define AUTH_PASS_LEN 16
+#define AUTH_STRING_LEN 128 /* maximum of 254 */
+
+
+typedef struct pw_auth_hdr {
+ u_char code;
+ u_char id;
+ u_short length;
+ u_char vector[AUTH_VECTOR_LEN];
+ u_char data[2];
+} AUTH_HDR;
+
+#define AUTH_HDR_LEN 20
+#define CHAP_VALUE_LENGTH 16
+
+#define PW_AUTH_UDP_PORT 1812
+#define PW_ACCT_UDP_PORT 1813
+
+#define VENDORPEC_USR 429
+
+#define PW_TYPE_STRING 0
+#define PW_TYPE_INTEGER 1
+#define PW_TYPE_IPADDR 2
+#define PW_TYPE_DATE 3
+
+
+#define PW_AUTHENTICATION_REQUEST 1
+#define PW_AUTHENTICATION_ACK 2
+#define PW_AUTHENTICATION_REJECT 3
+#define PW_ACCOUNTING_REQUEST 4
+#define PW_ACCOUNTING_RESPONSE 5
+#define PW_ACCOUNTING_STATUS 6
+#define PW_PASSWORD_REQUEST 7
+#define PW_PASSWORD_ACK 8
+#define PW_PASSWORD_REJECT 9
+#define PW_ACCOUNTING_MESSAGE 10
+#define PW_ACCESS_CHALLENGE 11
+
+#define PW_USER_NAME 1
+#define PW_PASSWORD 2
+#define PW_CHAP_PASSWORD 3
+#define PW_NAS_IP_ADDRESS 4
+#define PW_NAS_PORT_ID 5
+#define PW_SERVICE_TYPE 6
+#define PW_FRAMED_PROTOCOL 7
+#define PW_FRAMED_IP_ADDRESS 8
+#define PW_FRAMED_IP_NETMASK 9
+#define PW_FRAMED_ROUTING 10
+#define PW_FILTER_ID 11
+#define PW_FRAMED_MTU 12
+#define PW_FRAMED_COMPRESSION 13
+#define PW_LOGIN_IP_HOST 14
+#define PW_LOGIN_SERVICE 15
+#define PW_LOGIN_TCP_PORT 16
+#define PW_OLD_PASSWORD 17
+#define PW_REPLY_MESSAGE 18
+#define PW_CALLBACK_NUMBER 19
+#define PW_CALLBACK_ID 20
+#define PW_EXPIRATION 21
+#define PW_FRAMED_ROUTE 22
+#define PW_FRAMED_IPXNET 23
+#define PW_STATE 24
+#define PW_CLASS 25
+#define PW_VENDOR_SPECIFIC 26
+#define PW_SESSION_TIMEOUT 27
+#define PW_IDLE_TIMEOUT 28
+#define PW_CALLED_STATION_ID 30
+#define PW_CALLING_STATION_ID 31
+#define PW_NAS_ID 32
+#define PW_PROXY_STATE 33
+
+#define PW_ACCT_STATUS_TYPE 40
+#define PW_ACCT_DELAY_TIME 41
+#define PW_ACCT_INPUT_OCTETS 42
+#define PW_ACCT_OUTPUT_OCTETS 43
+#define PW_ACCT_SESSION_ID 44
+#define PW_ACCT_AUTHENTIC 45
+#define PW_ACCT_SESSION_TIME 46
+#define PW_ACCT_INPUT_PACKETS 47
+#define PW_ACCT_OUTPUT_PACKETS 48
+
+#define PW_CHAP_CHALLENGE 60
+#define PW_NAS_PORT_TYPE 61
+#define PW_PORT_LIMIT 62
+#define PW_CONNECT_INFO 77
+
+#define PW_HUNTGROUP_NAME 221
+#define PW_AUTHTYPE 1000
+#define PW_PREFIX 1003
+#define PW_SUFFIX 1004
+#define PW_GROUP 1005
+#define PW_CRYPT_PASSWORD 1006
+#define PW_CONNECT_RATE 1007
+#define PW_USER_CATEGORY 1029
+#define PW_GROUP_NAME 1030
+#define PW_SIMULTANEOUS_USE 1034
+#define PW_STRIP_USERNAME 1035
+#define PW_FALL_THROUGH 1036
+#define PW_ADD_PORT_TO_IP_ADDRESS 1037
+#define PW_EXEC_PROGRAM 1038
+#define PW_EXEC_PROGRAM_WAIT 1039
+#define PW_HINT 1040
+#define PAM_AUTH_ATTR 1041
+#define PW_LOGIN_TIME 1042
+
+/*
+ * INTEGER TRANSLATIONS
+ */
+
+/* USER TYPES */
+
+#define PW_LOGIN_USER 1
+#define PW_FRAMED_USER 2
+#define PW_DIALBACK_LOGIN_USER 3
+#define PW_DIALBACK_FRAMED_USER 4
+
+/* FRAMED PROTOCOLS */
+
+#define PW_PPP 1
+#define PW_SLIP 2
+
+/* FRAMED ROUTING VALUES */
+
+#define PW_NONE 0
+#define PW_BROADCAST 1
+#define PW_LISTEN 2
+#define PW_BROADCAST_LISTEN 3
+
+/* FRAMED COMPRESSION TYPES */
+
+#define PW_VAN_JACOBSEN_TCP_IP 1
+
+/* LOGIN SERVICES */
+
+#define PW_TELNET 0
+#define PW_RLOGIN 1
+#define PW_TCP_CLEAR 2
+#define PW_PORTMASTER 3
+
+/* AUTHENTICATION LEVEL */
+
+#define PW_AUTHTYPE_LOCAL 0
+#define PW_AUTHTYPE_SYSTEM 1
+#define PW_AUTHTYPE_SECURID 2
+#define PW_AUTHTYPE_CRYPT 3
+#define PW_AUTHTYPE_REJECT 4
+#define PW_AUTHTYPE_PAM 253
+#define PW_AUTHTYPE_ACCEPT 254
+
+/* PORT TYPES */
+#define PW_NAS_PORT_ASYNC 0
+#define PW_NAS_PORT_SYNC 1
+#define PW_NAS_PORT_ISDN 2
+#define PW_NAS_PORT_ISDN_V120 3
+#define PW_NAS_PORT_ISDN_V110 4
+
+/* STATUS TYPES */
+
+#define PW_STATUS_START 1
+#define PW_STATUS_STOP 2
+#define PW_STATUS_ALIVE 3
+#define PW_STATUS_ACCOUNTING_ON 7
+#define PW_STATUS_ACCOUNTING_OFF 8
+
--- /dev/null
+/*
+ * RADIUS
+ * Remote Authentication Dial In User Service
+ *
+ *
+ * Livingston Enterprises, Inc.
+ * 6920 Koll Center Parkway
+ * Pleasanton, CA 94566
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that this
+ * copyright and permission notice appear on all copies and supporting
+ * documentation, the name of Livingston Enterprises, Inc. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * program without specific prior permission, and notice be given
+ * in supporting documentation that copying and distribution is by
+ * permission of Livingston Enterprises, Inc.
+ *
+ * Livingston Enterprises, Inc. makes no representations about
+ * the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * The new parts of the code is Copyright (C) 1998 R.M. van Selm <selm@cistron.nl>
+ * with modifications
+ * Copyright (C) 2004 Henrik Nordstrom <hno@squid-cache.org>
+ * Copyright (C) 2006 Henrik Nordstrom <hno@squid-cache.org>
+ */
+
+/* Squid_rad_auth is a RADIUS authenticator for Squid-2.5 and later.
+ * The authenticator reads a line with a user and password combination.
+ * If access is granted OK is returned. Else ERR.
+ *
+ * Squid_rad_auth-1.0 is based on modules from the Cistron-radiusd-1.5.4.
+ *
+ * Currently you should only start 1 authentificator at a time because the
+ * the ID's of the different programs can start to conflict. I'm not sure it
+ * would help anyway. I think the RADIUS server is close by and I don't think
+ * it will handle requests in parallel anyway (correct me if I'm wrong here)
+ *
+ * Marc van Selm <selm@cistron.nl>
+ * with contributions from
+ * Henrik Nordstrom <hno@squid-cache.org>
+ * and many others
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#include "md5.h"
+#include "radius.h"
+#include "util.h"
+
+#define MAXPWNAM 254
+#define MAXPASS 254
+#define MAXLINE 254
+
+
+static int i_send_buffer[2048];
+static int i_recv_buffer[2048];
+static char *send_buffer = (char *) i_send_buffer;
+static char *recv_buffer = (char *) i_recv_buffer;
+static int sockfd;
+static int request_id;
+static char vector[AUTH_VECTOR_LEN];
+static char secretkey[MAXPASS + 1] = "";
+static char server[MAXLINE] = "";
+static char identifier[MAXLINE] = "";
+static char svc_name[MAXLINE] = "radius";
+static int nasport = 111;
+static int nasporttype = 0;
+static UINT4 nas_ipaddr;
+static UINT4 auth_ipaddr;
+static int retries = 30;
+
+char *progname = "squid_rad_auth";
+int debug_flag = 0;
+
+/*
+ * Diff two timeval, b - a
+ */
+static int
+timeval_diff(const struct timeval *a, const struct timeval *b)
+{
+ return (b->tv_sec - a->tv_sec) * 1000000 + (b->tv_usec - a->tv_usec);
+}
+
+/*
+ * Time since a timeval
+ */
+static int
+time_since(const struct timeval *when)
+{
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ return timeval_diff(when, &now);
+}
+
+/*
+ * Receive and verify the result.
+ */
+static int
+result_recv(UINT4 host, u_short udp_port, char *buffer, int length)
+{
+ AUTH_HDR *auth;
+ int totallen;
+ unsigned char reply_digest[AUTH_VECTOR_LEN];
+ unsigned char calc_digest[AUTH_VECTOR_LEN];
+ int secretlen;
+ /* VALUE_PAIR *req; */
+
+ auth = (AUTH_HDR *) buffer;
+ totallen = ntohs(auth->length);
+
+ if (totallen != length) {
+ fprintf(stderr,
+ "Squid_rad_auth: Received invalid reply length from server (want %d/ got %d)\n",
+ totallen, length);
+ return -1;
+ }
+
+ if (auth->id != request_id) {
+ /* Duplicate response of an earlier query, ignore */
+ return -1;
+ }
+
+ /* Verify the reply digest */
+ memcpy(reply_digest, auth->vector, AUTH_VECTOR_LEN);
+ memcpy(auth->vector, vector, AUTH_VECTOR_LEN);
+ secretlen = strlen(secretkey);
+ memcpy(buffer + length, secretkey, secretlen);
+ md5_calc(calc_digest, (unsigned char *) auth, length + secretlen);
+
+ if (memcmp(reply_digest, calc_digest, AUTH_VECTOR_LEN) != 0) {
+ fprintf(stderr, "Warning: Received invalid reply digest from server\n");
+ return -1;
+ }
+
+ if (auth->code != PW_AUTHENTICATION_ACK)
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ * Generate a random vector.
+ */
+static void
+random_vector(char *vector)
+{
+ int randno;
+ int i;
+
+ srand((time(0) ^ rand()) + rand());
+ for (i = 0; i < AUTH_VECTOR_LEN;) {
+ randno = rand();
+ memcpy(vector, &randno, sizeof(int));
+ vector += sizeof(int);
+ i += sizeof(int);
+ }
+}
+
+/* read the config file
+ * The format should be something like:
+ * # squid_rad_auth configuration file
+ * # MvS: 28-10-1998
+ * server suncone.cistron.nl
+ * secret testje
+ */
+static int
+rad_auth_config(const char *cfname)
+{
+ FILE *cf;
+ char line[MAXLINE];
+ int srv = 0, crt = 0;
+
+ if ((cf = fopen(cfname, "r")) == NULL) {
+ perror(cfname);
+ return -1;
+ }
+ while (fgets(line, MAXLINE, cf) != NULL) {
+ if (!memcmp(line, "server", 6))
+ srv = sscanf(line, "server %s", server);
+ if (!memcmp(line, "secret", 6))
+ crt = sscanf(line, "secret %s", secretkey);
+ if (!memcmp(line, "identifier", 10))
+ sscanf(line, "identifier %s", identifier);
+ if (!memcmp(line, "service", 7))
+ sscanf(line, "service %s", svc_name);
+ if (!memcmp(line, "port", 4))
+ sscanf(line, "port %s", svc_name);
+ }
+ if (srv && crt)
+ return 0;
+ return -1;
+}
+
+static void
+urldecode(char *dst, const char *src, int size)
+{
+ char tmp[3];
+ tmp[2] = '\0';
+ while (*src && size > 1) {
+ if (*src == '%' && src[1] != '\0' && src[2] != '\0') {
+ src++;
+ tmp[0] = *src++;
+ tmp[1] = *src++;
+ *dst++ = strtol(tmp, NULL, 16);
+ } else {
+ *dst++ = *src++;
+ }
+ size--;
+ }
+ *dst++ = '\0';
+}
+
+static int
+authenticate(int sockfd, const char *username, const char *passwd)
+{
+ AUTH_HDR *auth;
+ u_short total_length;
+ u_char *ptr;
+ int length;
+ char passbuf[MAXPASS];
+ u_char md5buf[256];
+ int secretlen;
+ u_char cbc[AUTH_VECTOR_LEN];
+ int i, j;
+ UINT4 ui;
+ struct sockaddr_in saremote;
+ fd_set readfds;
+ socklen_t salen;
+ int retry = retries;
+
+ /*
+ * Build an authentication request
+ */
+ auth = (AUTH_HDR *) send_buffer;
+ auth->code = PW_AUTHENTICATION_REQUEST;
+ auth->id = ++request_id;
+ random_vector(vector);
+ memcpy(auth->vector, vector, AUTH_VECTOR_LEN);
+ total_length = AUTH_HDR_LEN;
+ ptr = auth->data;
+
+ /*
+ * User Name
+ */
+ *ptr++ = PW_USER_NAME;
+ length = strlen(username);
+ if (length > MAXPWNAM) {
+ length = MAXPWNAM;
+ }
+ *ptr++ = length + 2;
+ memcpy(ptr, username, length);
+ ptr += length;
+ total_length += length + 2;
+
+ /*
+ * Password
+ */
+ length = strlen(passwd);
+ if (length > MAXPASS) {
+ length = MAXPASS;
+ }
+ memset(passbuf, 0, MAXPASS);
+ memcpy(passbuf, passwd, length);
+
+ /*
+ * Length is rounded up to multiple of 16,
+ * and the password is encoded in blocks of 16
+ * with cipher block chaining
+ */
+ length = ((length / AUTH_VECTOR_LEN) + 1) * AUTH_VECTOR_LEN;
+
+ *ptr++ = PW_PASSWORD;
+ *ptr++ = length + 2;
+
+ secretlen = strlen(secretkey);
+ /* Set up the Cipher block chain */
+ memcpy(cbc, auth->vector, AUTH_VECTOR_LEN);
+ for (j = 0; j < length; j += AUTH_VECTOR_LEN) {
+ /* Calculate the MD5 Digest */
+ strcpy((char *)md5buf, secretkey);
+ memcpy(md5buf + secretlen, cbc, AUTH_VECTOR_LEN);
+ md5_calc(cbc, md5buf, secretlen + AUTH_VECTOR_LEN);
+
+ /* Xor the password into the MD5 digest */
+ for (i = 0; i < AUTH_VECTOR_LEN; i++) {
+ *ptr++ = (cbc[i] ^= passbuf[j + i]);
+ }
+ }
+ total_length += length + 2;
+
+ *ptr++ = PW_NAS_PORT_ID;
+ *ptr++ = 6;
+
+ ui = htonl(nasport);
+ memcpy(ptr, &ui, 4);
+ ptr += 4;
+ total_length += 6;
+
+ *ptr++ = PW_NAS_PORT_TYPE;
+ *ptr++ = 6;
+
+ ui = htonl(nasporttype);
+ memcpy(ptr, &ui, 4);
+ ptr += 4;
+ total_length += 6;
+
+ if (*identifier) {
+ int len = strlen(identifier);
+ *ptr++ = PW_NAS_ID;
+ *ptr++ = len + 2;
+ memcpy(ptr, identifier, len);
+ ptr += len;
+ } else {
+ *ptr++ = PW_NAS_IP_ADDRESS;
+ *ptr++ = 6;
+
+ ui = htonl(nas_ipaddr);
+ memcpy(ptr, &ui, 4);
+ ptr += 4;
+ total_length += 6;
+ }
+
+ /* Klaus Weidner <kw@w-m-p.com> changed this
+ * from htonl to htons. It might have caused
+ * you trouble or not. That depends on the byte
+ * order of your system.
+ * The symptom was that the radius server
+ * ignored the requests, because they had zero
+ * length according to the data header.
+ */
+ auth->length = htons(total_length);
+
+ while(retry--) {
+ int time_spent;
+ struct timeval sent;
+ /*
+ * Send the request we've built.
+ */
+ gettimeofday(&sent, NULL);
+ send(sockfd, (char *) auth, total_length, 0);
+ while ((time_spent = time_since(&sent)) < 1000000) {
+ struct timeval tv;
+ int rc, len;
+ if (!time_spent) {
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000000 - time_spent;
+ }
+ FD_ZERO(&readfds);
+ FD_SET(sockfd, &readfds);
+ if (select(sockfd + 1, &readfds, NULL, NULL, &tv) == 0) /* Select timeout */
+ break;
+ salen = sizeof(saremote);
+ len = recvfrom(sockfd, recv_buffer, sizeof(i_recv_buffer),
+ 0, (struct sockaddr *) &saremote, &salen);
+
+ if (len < 0)
+ continue;
+
+ rc = result_recv(saremote.sin_addr.s_addr, saremote.sin_port, recv_buffer, len);
+ if (rc == 0)
+ return 1;
+ if (rc == 1)
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "%s: No response from RADIUS server\n", progname);
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sockaddr_in salocal;
+ struct sockaddr_in saremote;
+ struct servent *svp;
+ u_short svc_port;
+ char username[MAXPWNAM];
+ char passwd[MAXPASS];
+ char *ptr;
+ char authstring[MAXLINE];
+ const char *cfname = NULL;
+ int err = 0;
+ socklen_t salen;
+ int c;
+
+ while ((c = getopt(argc, argv, "h:p:f:w:i:t:")) != -1) {
+ switch(c) {
+ case 'f':
+ cfname = optarg;
+ break;
+ case 'h':
+ strcpy(server, optarg);
+ break;
+ case 'p':
+ strcpy(svc_name, optarg);
+ break;
+ case 'w':
+ strcpy(secretkey, optarg);
+ break;
+ case 'i':
+ strcpy(identifier, optarg);
+ break;
+ case 't':
+ retries = atoi(optarg);
+ break;
+ }
+ }
+ /* make standard output line buffered */
+ if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
+ return 1;
+
+ if (cfname) {
+ if (rad_auth_config(cfname) < 0) {
+ fprintf(stderr, "%s: can't open configuration file '%s'.\n", argv[0], cfname);
+ exit(1);
+ }
+ }
+
+ if (!*server) {
+ fprintf(stderr, "%s: Server not specified\n", argv[0]);
+ exit(1);
+ }
+
+ if (!*secretkey) {
+ fprintf(stderr, "%s: Shared secret not specified\n", argv[0]);
+ exit(1);
+ }
+
+ /*
+ * Open a connection to the server.
+ */
+ svp = getservbyname(svc_name, "udp");
+ if (svp != NULL)
+ svc_port = ntohs((u_short) svp->s_port);
+ else
+ svc_port = atoi(svc_name);
+ if (svc_port == 0)
+ svc_port = PW_AUTH_UDP_PORT;
+
+ /* Get the IP address of the authentication server */
+ if ((auth_ipaddr = get_ipaddr(server)) == 0) {
+ fprintf(stderr, "Couldn't find host %s\n", server);
+ exit(1);
+ }
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0) {
+ perror("socket");
+ exit(1);
+ }
+ memset(&saremote, 0, sizeof(saremote));
+ saremote.sin_family = AF_INET;
+ saremote.sin_addr.s_addr = htonl(auth_ipaddr);
+ saremote.sin_port = htons(svc_port);
+
+ if (connect(sockfd, (struct sockaddr *) &saremote, sizeof(saremote)) < 0) {
+ perror("connect");
+ exit(1);
+ }
+ salen = sizeof(salocal);
+ if (getsockname(sockfd, (struct sockaddr *) &salocal, &salen) < 0) {
+ perror("getsockname");
+ exit(1);
+ }
+#ifdef O_NONBLOCK
+ fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
+#endif
+ nas_ipaddr = ntohl(salocal.sin_addr.s_addr);
+ while (fgets(authstring, MAXLINE, stdin) != NULL) {
+ char *end;
+ /* protect me form to long lines */
+ if ((end = strchr(authstring, '\n')) == NULL) {
+ err = 1;
+ continue;
+ }
+ if (err) {
+ printf("ERR\n");
+ err = 0;
+ continue;
+ }
+ if (strlen(authstring) > MAXLINE) {
+ printf("ERR\n");
+ continue;
+ }
+ /* Strip off the trailing newline */
+ *end = '\0';
+
+ /* Parse out the username and password */
+ ptr = authstring;
+ while (isspace(*ptr))
+ ptr++;
+ if ((end = strchr(ptr, ' ')) == NULL) {
+ printf("ERR\n"); /* No password */
+ continue;
+ }
+ *end = '\0';
+ urldecode(username, ptr, MAXPWNAM);
+ ptr = end + 1;
+ while (isspace(*ptr))
+ ptr++;
+ urldecode(passwd, ptr, MAXPASS);
+
+ if (authenticate(sockfd, username, passwd))
+ printf("OK\n");
+ else
+ printf("ERR\n");
+ }
+ close(sockfd);
+ exit(1);
+}
--- /dev/null
+.TH squid_radius_auth 8 "7 August 2004" "Squid RADIUS Auth"
+.
+.SH NAME
+squid_radius_auth - Squid RADIUS authentication helper
+.
+.SH SYNOPSIS
+.B squid_radius_auth
+-f configfile
+.br
+.B squid_radius_auth
+-h "server" [-p port] [-i identifier] -w secret
+.
+.SH DESCRIPTION
+This helper allows Squid to connect to a RADIUS server to
+validate the user name and password of Basic HTTP authentication.
+.
+.TP
+.BI "-f " "configfile "
+Specifies the path to a configuration file. See the CONFIGURATION section
+for details.
+.
+.TP
+.BI "-h " server
+Alternative method of specifying the server to connect to
+.
+.TP
+.BI "-p " port
+Specify another server port where the RADIUS server listens for requests
+if different from the default RADIUS port. Normally not specified.
+.
+.TP
+.BI "-i " identifier
+Unique identifier identifying this Squid proxy to the RADIUS server.
+If not specified the IP address is used as to identify the proxy.
+.TP
+.BI "-w " secret
+Alternative method of specifying the shared secret. Using the
+configuration file is generally more secure and recommended.
+.
+.TP
+.BI "-t " timeout
+RADIUS request timeout. Default 10 seconds.
+.
+.SH CONFIGURATION
+The configuration specifies how the helper connects to RADIUS.
+The file contains a list of directives (one per line). Lines
+beginning with a # is ignored.
+.
+.TP
+.BI "server " radiusserver
+specifies the name or address of the RADIUS server to connect to.
+.
+.TP
+.BI "secret " somesecretstring
+specifies the shared RADIUS secret.
+.
+.TP
+.BI "identifier " nameofserver
+specifies what the proxy should identify itsels as to the RADIUS server.
+This directive is optional.
+.
+.TP
+.BI "port " portnumber
+Specifies the port number or service name where the helper should connect.
+.SH AUTHOR
+This manual page was written by
+.I Henrik Nordstrom <hno@squid-cache.org>
+.P
+squid_radius_auth is written by
+.I Marc van Selm <selm@cistron.nl>
+with contributions from
+.I Henrik Nordstrom <hno@squid-cache.org>
+and many others
+.
+.SH QUESTIONS
+Any questions on usage can be sent to
+.IR "Squid Users <squid-users@squid-cache.org>" ,
+or to your favorite RADIUS list/friend if the question is more related to
+RADIUS than Squid.
+.
+.SH REPORTING BUGS
+Report bugs or bug-fixes to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+or ideas for new improvements to
+.I Squid Developers <squid-dev@squid-cache.org>
+.
+.SH "SEE ALSO"
+.BR RFC2058 " - Remote Authentication Dial In User Service (RADIUS)"
--- /dev/null
+/*
+ *
+ * RADIUS
+ * Remote Authentication Dial In User Service
+ *
+ *
+ * Livingston Enterprises, Inc.
+ * 6920 Koll Center Parkway
+ * Pleasanton, CA 94566
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ * Copyright 1997 Cistron Internet Services B.V.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that this
+ * copyright and permission notice appear on all copies and supporting
+ * documentation, the name of Livingston Enterprises, Inc. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * program without specific prior permission, and notice be given
+ * in supporting documentation that copying and distribution is by
+ * permission of Livingston Enterprises, Inc.
+ *
+ * Livingston Enterprises, Inc. makes no representations about
+ * the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ */
+
+/*
+ * util.c Miscellanous generic functions.
+ *
+ */
+
+char util_sccsid[] =
+"@(#)util.c 1.5 Copyright 1992 Livingston Enterprises Inc\n"
+" 2.1 Copyright 1997 Cistron Internet Services B.V.";
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <time.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include "md5.h"
+#include "util.h"
+
+/*
+ * Check for valid IP address in standard dot notation.
+ */
+static int good_ipaddr(char *addr)
+{
+ int dot_count;
+ int digit_count;
+
+ dot_count = 0;
+ digit_count = 0;
+ while(*addr != '\0' && *addr != ' ') {
+ if(*addr == '.') {
+ dot_count++;
+ digit_count = 0;
+ }
+ else if(!isdigit(*addr)) {
+ dot_count = 5;
+ }
+ else {
+ digit_count++;
+ if(digit_count > 3) {
+ dot_count = 5;
+ }
+ }
+ addr++;
+ }
+ if(dot_count != 3) {
+ return(-1);
+ }
+ else {
+ return(0);
+ }
+}
+
+/*
+ * Return an IP address in host long notation from
+ * one supplied in standard dot notation.
+ */
+static UINT4 ipstr2long(char *ip_str)
+{
+ char buf[6];
+ char *ptr;
+ int i;
+ int count;
+ UINT4 ipaddr;
+ int cur_byte;
+
+ ipaddr = (UINT4)0;
+ for(i = 0;i < 4;i++) {
+ ptr = buf;
+ count = 0;
+ *ptr = '\0';
+ while(*ip_str != '.' && *ip_str != '\0' && count < 4) {
+ if(!isdigit(*ip_str)) {
+ return((UINT4)0);
+ }
+ *ptr++ = *ip_str++;
+ count++;
+ }
+ if(count >= 4 || count == 0) {
+ return((UINT4)0);
+ }
+ *ptr = '\0';
+ cur_byte = atoi(buf);
+ if(cur_byte < 0 || cur_byte > 255) {
+ return((UINT4)0);
+ }
+ ip_str++;
+ ipaddr = ipaddr << 8 | (UINT4)cur_byte;
+ }
+ return(ipaddr);
+}
+
+/*
+ * Return an IP address in host long notation from a host
+ * name or address in dot notation.
+ */
+UINT4 get_ipaddr(char *host)
+{
+ struct hostent *hp;
+
+ if(good_ipaddr(host) == 0) {
+ return(ipstr2long(host));
+ }
+ else if((hp = gethostbyname(host)) == (struct hostent *)NULL) {
+ return((UINT4)0);
+ }
+ return(ntohl(*(UINT4 *)hp->h_addr));
+}
+
+
+void md5_calc(unsigned char *output, unsigned char *input, unsigned int inlen)
+{
+ MD5_CTX context;
+
+ MD5Init(&context);
+ MD5Update(&context, input, inlen);
+ MD5Final(output, &context);
+}
+
--- /dev/null
+/* util.c */
+UINT4 get_ipaddr (char *);