diff -Nur squid-3/tools/1 squid-3-krb5/tools/1
--- squid-3/tools/1	1970-01-01 01:00:00.000000000 +0100
+++ squid-3-krb5/tools/1	2010-08-15 11:56:58.000000000 +0100
@@ -0,0 +1,94 @@
+#
+#  Makefile for the Squid Object Cache server
+#
+#  Uncomment and customize the following to suit your needs:
+#
+
+include $(top_srcdir)/src/Common.am
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+## we need our local files too (but avoid -I. at all costs)
+INCLUDES += -I$(srcdir)
+
+SUBDIRS = 
+EXTRA_DIST = 
+man_MANS = 
+DISTCLEANFILES = 
+
+LDADD = \
+	$(top_builddir)/src/time.o \
+	$(top_builddir)/src/ip/libip.la \
+	$(COMPAT_LIB) \
+	$(XTRA_LIBS) \
+	$(KRB5LIBS)
+# On Windows may need:
+# secur32.lib ws2_32.lib advapi32.lib
+#
+
+include $(top_srcdir)/doc/manuals/Substitute.am
+
+test_tools.cc: $(top_srcdir)/test-suite/test_tools.cc
+	cp $(top_srcdir)/test-suite/test_tools.cc .
+
+# stock tools for unit tests - library independent versions of dlink_list
+# etc.
+# globals.cc is needed by test_tools.cc.
+# Neither of these should be disted from here.
+TESTSOURCES= test_tools.cc
+CLEANFILES += test_tools.cc
+
+## ##### helper-mux #####
+
+libexec_SCRIPTS = helper-mux.pl
+EXTRA_DIST += helper-mux.pl helper-mux.README
+
+## Test Scripts
+EXTRA_DIST += helper-ok-dying.pl helper-ok.pl
+
+## ##### squidclient  #####
+
+bin_PROGRAMS = squidclient
+
+squidclient_SOURCES = squidclient.cc \
+	test_tools.cc
+
+EXTRA_DIST += squidclient.1
+man_MANS += squidclient.1
+
+
+
+## ##### cachemgr.cgi  #####
+
+DEFAULT_CACHEMGR_CONFIG = $(sysconfdir)/cachemgr.conf
+
+libexec_PROGRAMS = cachemgr$(CGIEXT)
+
+cachemgr__CGIEXT__SOURCES = cachemgr.cc \
+	test_tools.cc
+
+cachemgr__CGIEXT__CXXFLAGS = -DDEFAULT_CACHEMGR_CONFIG=\"$(DEFAULT_CACHEMGR_CONFIG)\" $(AM_CXXFLAGS)
+
+EXTRA_DIST += cachemgr.conf cachemgr.cgi.8 cachemgr.cgi.8.in
+CLEANFILES += cachemgr.cgi.8
+man_MANS += cachemgr.cgi.8
+
+cachemgr.cgi.8: $(srcdir)/cachemgr.cgi.8.in Makefile
+	$(SUBSTITUTE) < $(srcdir)/cachemgr.cgi.8.in > $@
+
+
+
+## Shared
+
+install-data-local:
+	$(INSTALL_DATA) $(srcdir)/cachemgr.conf $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG).default
+	@if test -f $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG) ; then \
+	        echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG)" ; \
+	else \
+	        echo "$(INSTALL_DATA) $(srcdir)/cachemgr.conf $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG)"; \
+	        $(INSTALL_DATA) $(srcdir)/cachemgr.conf $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG); \
+	fi
+
+uninstall-local:
+	@$(SHELL) $(top_srcdir)/scripts/remove-cfg.sh "$(RM)" $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG)
+	$(RM) -f $(DESTDIR)$(DEFAULT_CACHEMGR_CONFIG).default
diff -Nur squid-3/tools/Makefile.am squid-3-krb5/tools/Makefile.am
--- squid-3/tools/Makefile.am	2010-08-13 01:12:56.000000000 +0100
+++ squid-3-krb5/tools/Makefile.am	2010-08-15 11:57:01.000000000 +0100
@@ -20,7 +20,11 @@
 	$(top_builddir)/src/time.o \
 	$(top_builddir)/src/ip/libip.la \
 	$(COMPAT_LIB) \
-	$(XTRA_LIBS)
+	$(XTRA_LIBS) \
+	$(KRB5LIBS)
+# On Windows may need:
+# secur32.lib ws2_32.lib advapi32.lib
+#
 
 include $(top_srcdir)/doc/manuals/Substitute.am
 
diff -Nur squid-3/tools/Makefile.in squid-3-krb5/tools/Makefile.in
--- squid-3/tools/Makefile.in	2010-08-13 01:14:18.000000000 +0100
+++ squid-3-krb5/tools/Makefile.in	2010-08-15 11:54:26.000000000 +0100
@@ -74,7 +74,7 @@
 am__DEPENDENCIES_2 =
 cachemgr__CGIEXT__DEPENDENCIES = $(top_builddir)/src/time.o \
 	$(top_builddir)/src/ip/libip.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_2)
+	$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2)
 cachemgr__CGIEXT__LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -84,7 +84,7 @@
 squidclient_LDADD = $(LDADD)
 squidclient_DEPENDENCIES = $(top_builddir)/src/time.o \
 	$(top_builddir)/src/ip/libip.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_2)
+	$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2)
 libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(libexec_SCRIPTS)
 DEFAULT_INCLUDES = 
@@ -341,7 +341,8 @@
 	$(top_builddir)/src/time.o \
 	$(top_builddir)/src/ip/libip.la \
 	$(COMPAT_LIB) \
-	$(XTRA_LIBS)
+	$(XTRA_LIBS) \
+	$(KRB5LIBS)
 
 SUBSTITUTE = sed "\
 	s%@DEFAULT_ERROR_DIR@%$(DEFAULT_ERROR_DIR)%g;\
diff -Nur squid-3/tools/squidclient.cc squid-3-krb5/tools/squidclient.cc
--- squid-3/tools/squidclient.cc	2010-08-13 01:12:56.000000000 +0100
+++ squid-3-krb5/tools/squidclient.cc	2010-08-15 12:25:02.000000000 +0100
@@ -79,6 +79,51 @@
 #include <getopt.h>
 #endif
 
+#if HAVE_GSSAPI
+#ifdef HAVE_HEIMDAL_KERBEROS
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#else
+#error "GSSAPI header required"
+#endif
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#else
+#ifdef HAVE_SEAM_KERBEROS
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#else
+#error "GSSAPI header required"
+#endif
+#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#else /*MIT */
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#else
+#error "GSSAPI header required"
+#endif
+#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif
+#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif
+#endif
+#endif
+
+#ifndef gss_mech_spnego
+static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
+gss_OID gss_mech_spnego = &_gss_mech_spnego;
+#endif
+#endif
 
 #ifndef BUFSIZ
 #define BUFSIZ		8192
@@ -104,6 +149,13 @@
 static void set_our_signal(void);
 static ssize_t myread(int fd, void *buf, size_t len);
 static ssize_t mywrite(int fd, void *buf, size_t len);
+
+
+#if HAVE_GSSAPI
+static int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function);
+static char *GSSAPI_token(const char *server);
+#endif
+
 static int put_fd;
 static char *put_file = NULL;
 
@@ -149,10 +201,14 @@
             "    -u user      Proxy authentication username\n"
             "    -U user      WWW authentication username\n"
             "    -v           Verbose. Print outgoing message to stderr.\n"
-            "    -V version   HTTP Version. Use '-' for HTTP/0.9 omitted case\n",
+            "    -V version   HTTP Version. Use '-' for HTTP/0.9 omitted case\n"
             "    -w password  Proxy authentication password\n"
             "    -W password  WWW authentication password\n"
-            VERSION, progname, CACHE_HTTP_PORT);
+#if HAVE_GSSAPI
+            "    -n           Proxy Negotiate(Kerberos) authentication\n"
+            "    -N           WWW Negotiate(Kerberos) authentication\n"
+#endif
+            ,VERSION, progname, CACHE_HTTP_PORT);
     exit(1);
 }
 
@@ -166,6 +222,7 @@
     int keep_alive = 0;
     int opt_noaccept = 0;
     int opt_verbose = 0;
+    int www_neg, proxy_neg;
     const char *hostname, *localhost;
     Ip::Address iaddr;
     char url[BUFSIZ], msg[MESSAGELEN], buf[BUFSIZ];
@@ -196,6 +253,8 @@
     ping = 0;
     pcount = 0;
     ping_int = 1 * 1000;
+    www_neg = 0;
+    proxy_neg = 0;
 
     if (argc < 2) {
         usage(argv[0]);		/* need URL */
@@ -205,8 +264,11 @@
 
         if (url[0] == '-')
             usage(argv[0]);
-
+#if HAVE_GSSAPI
+        while ((c = getopt(argc, argv, "ah:j:V:l:P:i:km:p:rsvt:g:p:I:H:T:u:U:w:W:nN?")) != -1)
+#else
         while ((c = getopt(argc, argv, "ah:j:V:l:P:i:km:p:rsvt:g:p:I:H:T:u:U:w:W:?")) != -1)
+#endif
             switch (c) {
 
             case 'a':
@@ -307,6 +369,15 @@
                 www_password = optarg;
                 break;
 
+#if HAVE_GSSAPI
+            case 'n':
+                proxy_neg = 1;
+                break;
+
+            case 'N':
+                www_neg = 1;
+                break;
+#endif
             case 'v':
                 /* undocumented: may increase verb-level by giving more -v's */
                 opt_verbose++;
@@ -348,7 +419,6 @@
 
         fstat(put_fd, &sb);
     }
-
     if (!host) {
         char *newhost = strstr(url, "://");
         if (newhost) {
@@ -364,7 +434,6 @@
             host = newhost;
         }
     }
-
     if (version[0] == '-' || !version[0] || version[0] == '0') {
         /* HTTP/0.9, no headers, no version */
         snprintf(msg, BUFSIZ, "%s %s\r\n", method, url);
@@ -373,9 +442,8 @@
 
         if (host) {
             snprintf(buf, BUFSIZ, "Host: %s\r\n", host);
-            strcat(msg,buf);
+            strcat(msg, buf);
         }
-
         if (reload) {
             snprintf(buf, BUFSIZ, "Pragma: no-cache\r\n");
             strcat(msg, buf);
@@ -426,6 +494,24 @@
             snprintf(buf, BUFSIZ, "Authorization: Basic %s\r\n", base64_encode(buf));
             strcat(msg, buf);
         }
+#if HAVE_GSSAPI
+        if (www_neg || proxy_neg) {
+            if (www_neg) {
+                if (host) {
+                    snprintf(buf, BUFSIZ, "Authorization: Negotiate %s\r\n", GSSAPI_token(host));
+                    strcat(msg, buf);
+                } else
+                    fprintf(stderr, "ERROR: server host missing\n");
+            }
+            if (proxy_neg) {
+                if (hostname) {
+                    snprintf(buf, BUFSIZ, "Proxy-Authorization: Negotiate %s\r\n", GSSAPI_token(hostname));
+                    strcat(msg, buf);
+                } else
+                    fprintf(stderr, "ERROR: porxy server host missing\n");
+            }
+        }
+#endif
 
         /* HTTP/1.0 may need keep-alive */
         if (strcmp(version, "1.0") == 0) {
@@ -477,14 +563,14 @@
         /* Connect to the server */
 
         if (localhost) {
-            if ( !iaddr.GetHostByName(localhost) ) {
+            if (!iaddr.GetHostByName(localhost)) {
                 fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", localhost);
                 exit(1);
             }
         } else {
             /* Process the remote host name to locate the Protocol required
-               in case we are being asked to link to another version of squid */
-            if ( !iaddr.GetHostByName(hostname) ) {
+             * in case we are being asked to link to another version of squid */
+            if (!iaddr.GetHostByName(hostname)) {
                 fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", hostname);
                 exit(1);
             }
@@ -502,13 +588,11 @@
             perror("client: bind");
             exit(1);
         }
-
         iaddr.SetEmpty();
-        if ( !iaddr.GetHostByName(hostname) ) {
+        if (!iaddr.GetHostByName(hostname)) {
             fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", hostname);
             exit(1);
         }
-
         iaddr.SetPort(port);
 
         if (client_comm_connect(conn, iaddr, ping ? &tv1 : NULL) < 0) {
@@ -523,7 +607,6 @@
             }
             exit(1);
         }
-
         /* Send the HTTP request */
         bytesWritten = mywrite(conn, msg, strlen(msg));
 
@@ -534,7 +617,6 @@
             fprintf(stderr, "client: ERROR: Cannot send request?: %s\n", msg);
             exit(1);
         }
-
         if (put_file) {
             int x;
             lseek(put_fd, 0, SEEK_SET);
@@ -630,7 +712,7 @@
 }
 
 static int
-client_comm_bind(int sock, const Ip::Address &addr)
+client_comm_bind(int sock, const Ip::Address & addr)
 {
 
     int res;
@@ -649,7 +731,7 @@
 }
 
 static int
-client_comm_connect(int sock, const Ip::Address &addr, struct timeval *tvp)
+client_comm_connect(int sock, const Ip::Address & addr, struct timeval *tvp)
 {
     int res;
     static struct addrinfo *AI = NULL;
@@ -736,3 +818,120 @@
     return send(fd, buf, len, 0);
 #endif
 }
+
+#if HAVE_GSSAPI
+static int
+check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function)
+{
+    if (GSS_ERROR(major_status)) {
+        OM_uint32 maj_stat, min_stat;
+        OM_uint32 msg_ctx = 0;
+        gss_buffer_desc status_string;
+        char buf[1024];
+        size_t len;
+
+        len = 0;
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert major status code (GSS-API error) to text */
+            maj_stat = gss_display_status(&min_stat, major_status,
+                                          GSS_C_GSS_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                if (sizeof(buf) > len + status_string.length + 1) {
+                    sprintf(buf + len, "%s", (char *) status_string.value);
+                    len += status_string.length;
+                }
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        if (sizeof(buf) > len + 2) {
+            sprintf(buf + len, "%s", ". ");
+            len += 2;
+        }
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert minor status code (underlying routine error) to text */
+            maj_stat = gss_display_status(&min_stat, minor_status,
+                                          GSS_C_MECH_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                if (sizeof(buf) > len + status_string.length) {
+                    sprintf(buf + len, "%s", (char *) status_string.value);
+                    len += status_string.length;
+                }
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        fprintf(stderr, "%s failed: %s\n", function, buf);
+        return (1);
+    }
+    return (0);
+}
+
+static char *
+GSSAPI_token(const char *server)
+{
+    OM_uint32 major_status, minor_status;
+    gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+    gss_name_t server_name = GSS_C_NO_NAME;
+    gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+    char *token = NULL;
+
+    setbuf(stdout, NULL);
+    setbuf(stdin, NULL);
+
+    if (!server) {
+        fprintf(stderr, "Error: No server name\n");
+        return NULL;
+    }
+    service.value = xmalloc(strlen("HTTP") + strlen(server) + 2);
+    snprintf((char *) service.value, strlen("HTTP") + strlen(server) + 2, "%s@%s", "HTTP", server);
+    service.length = strlen((char *) service.value);
+
+    major_status = gss_import_name(&minor_status, &service,
+                                   gss_nt_service_name, &server_name);
+
+    if (check_gss_err(major_status, minor_status, "gss_import_name()"))
+        goto cleanup;
+
+    major_status = gss_init_sec_context(&minor_status,
+                                        GSS_C_NO_CREDENTIAL,
+                                        &gss_context,
+                                        server_name,
+                                        gss_mech_spnego,
+                                        0,
+                                        0,
+                                        GSS_C_NO_CHANNEL_BINDINGS,
+                                        &input_token,
+                                        NULL,
+                                        &output_token,
+                                        NULL,
+                                        NULL);
+
+    if (check_gss_err(major_status, minor_status, "gss_init_sec_context()"))
+        goto cleanup;
+
+    if (output_token.length)
+        token = (char *) base64_encode_bin((const char *) output_token.value, output_token.length);
+
+cleanup:
+    if (!output_token.length)
+        token = (char *) "ERROR";
+    gss_delete_sec_context(&minor_status, &gss_context, NULL);
+    gss_release_buffer(&minor_status, &service);
+    gss_release_buffer(&minor_status, &input_token);
+    gss_release_buffer(&minor_status, &output_token);
+    gss_release_name(&minor_status, &server_name);
+
+    return token;
+}
+#endif
