]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merge from trunk
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 14 Sep 2009 02:33:31 +0000 (14:33 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 14 Sep 2009 02:33:31 +0000 (14:33 +1200)
46 files changed:
CREDITS
ChangeLog
acinclude.m4
compat/Makefile.am
compat/compat.h
compat/debug.cc [new file with mode: 0644]
compat/debug.h [new file with mode: 0644]
configure.in
doc/Programming-Guide/Makefile
doc/release-notes/release-3.0.sgml
doc/release-notes/release-3.2.sgml
errors/Makefile.am
errors/alias-link.sh
helpers/Makefile.am
helpers/digest_auth/ldap/ldap_backend.c
helpers/external_acl/wbinfo_group/wbinfo_group.pl
helpers/ntlm_auth/smb_lm/libntlmssp.c
helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.c
helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.h
helpers/url_rewrite/Makefile.am [new file with mode: 0644]
helpers/url_rewrite/fake/Makefile.am [new file with mode: 0644]
helpers/url_rewrite/fake/config.test [new file with mode: 0755]
helpers/url_rewrite/fake/fake.cc [new file with mode: 0644]
helpers/url_rewrite/fake/fake.h [new file with mode: 0644]
helpers/url_rewrite/fake/url_fake_rewrite.sh [new file with mode: 0755]
squid3.dox
src/Common.am
src/ConfigParser.cc
src/ConfigParser.h
src/Debug.h
src/HttpHeaderTools.cc
src/HttpRequest.h
src/Makefile.am
src/cache_cf.cc
src/cf.data.pre
src/client_side.cc
src/fs/ufs/store_dir_ufs.cc
src/http.cc
src/peer_proxy_negotiate_auth.cc [new file with mode: 0644]
src/protos.h
src/tunnel.cc
test-builds.sh
test-suite/buildtests/layer-01-minimal.opts
test-suite/buildtests/layer-02-maximus.opts
tools/cachemgr.cc
tools/squidclient.cc

diff --git a/CREDITS b/CREDITS
index e9daf0d32d3fa88bbba022a7fc084d52a14ec374..4a00651cc0bbc047024e302015612ead910b9a60 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -391,8 +391,9 @@ lib/libTrie/*:
 include/IPAddress.h lib/IPAddress.cc:
 include/rfc3596.h lib/rfc3596.cc:
 src/ICMPv6.h src/ICMPv6.cc:
+helpers/url_rewrite/fake/ fake.h, fake.cc, url_fake_rewrite.sh:
 
- This code is copyright (C) 2007 by Treehouse Networks Ltd
+ This code is copyright (C) 2007-2009 by Treehouse Networks Ltd
  of New Zealand. It is published and Licensed as an extension of
  squid under the same conditions as the main squid application.
 
index f88b27e0c43164ae6fa471b0934f5c059f42d00d..8b4c5121b24a85335f1dec63eaf95a893b8aa1fa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -216,6 +216,19 @@ Changes to squid-3.1.0.1 (27 Oct 2008):
        - Bug #2223: Follow XFF extensions added
        - ... and many code and documentation cleanups
 
+Changes to squid-3.0.STABLE19 (06 Sep 2009):
+
+       - Bug 2745: Invalid Response error on small reads
+       - Bug 2739: DNS resolver option ndots can't be parsed from resolv.conf
+       - Bug 2734: some compile errors on Solaris
+       - Bug 2648: stateful helpers stuck in reserved if client disconnects while helper busy
+       - Bug 2541: Hang in 100% CPU loop while extacting header details using a delimiter other than comma
+       - Bug 2362: Remove support for deferred state in stateful helpers
+       - Add 0.0.0.0 as a to_localhost address
+       - Docs: Improve chroot directive documentation slightly
+       - Fixup libxml2 include magics, was failing when a configure cache was used
+       - ... and some minor testing improvements.
+
 Changes to squid-3.0.STABLE18 (04 Aug 2009):
 
        - Bug 2728: regression: assertion failed: !eof
index 3fa8a95a6f7a84964e6f5796fd4ffe03e5034c3b..95e7a8827aad661c555dcf3a9d4e786461f68f51 100644 (file)
@@ -72,8 +72,8 @@ dnl
 AC_DEFUN([AC_TEST_CHECKFORHUGEOBJECTS],[
   AC_MSG_CHECKING([whether compiler accepts -fhuge-objects])
   AC_CACHE_VAL([ac_cv_test_checkforhugeobjects],[
-    ac_cv_test_checkforhugeobjects=`echo "int foo;" > conftest.cc
-${CXX} -Werror -fhuge-objects -c conftest.cc 2>/dev/null
+    ac_cv_test_checkforhugeobjects=`echo "int main(int argc, char **argv) { int foo; }" > conftest.cc
+${CXX} -Werror -fhuge-objects -o conftest.bin conftest.cc 2>/dev/null
 res=$?
 rm -f conftest.*
 echo yes
index cf8c018e2b5f65af8da9d8ff891243d7959ca225..3aa5b9751bfc3534e776622a8e03f0449f5e490a 100644 (file)
@@ -15,6 +15,7 @@ libcompat_la_SOURCES = \
        assert.h \
        compat.h \
        compat_shared.h \
+       debug.h \
        fdsetsize.h \
        osdetect.h \
        stdvarargs.h \
@@ -37,6 +38,7 @@ libcompat_la_SOURCES = \
        \
        assert.cc \
        compat.cc \
+       debug.cc \
        GnuRegex.h \
        GnuRegex.c
 
index bacbc5aae2f75d485f401602856dad467c7e9c55..160029171180cda5f86a060f0fa4ce7f462c08e1 100644 (file)
 #include "compat/stdvarargs.h"
 #include "compat/assert.h"
 
+
 /*****************************************************/
 /* component-specific portabilities                  */
 /*****************************************************/
 
+/* helper debugging requires some hacks to be clean */
+#include "compat/debug.h"
+
 /* Valgrind API macros changed between two versions squid supports */
 #include "compat/valgrind.h"
 
diff --git a/compat/debug.cc b/compat/debug.cc
new file mode 100644 (file)
index 0000000..9d307d5
--- /dev/null
@@ -0,0 +1,4 @@
+#include "config.h"
+
+/* default off */
+int debug_enabled = 0;
diff --git a/compat/debug.h b/compat/debug.h
new file mode 100644 (file)
index 0000000..0136740
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef SQUID_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef COMPAT_DEBUG_H
+#define COMPAT_DEBUG_H
+
+/*
+ * A debug method for use of external helpers and tools.
+ * It shunts the debug messages down stderr for logging by Squid
+ * or display to the user instead of corrupting the stdout data stream.
+ */
+
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* Debugging stuff */
+
+/* the macro overload style is really a gcc-ism */
+#ifdef __GNUC__
+
+SQUIDCEXTERN int debug_enabled;
+
+#define debug(X...) \
+                     if (debug_enabled) { \
+                         fprintf(stderr, "%s(%d): pid=%ld :", __FILE__, __LINE__, (long)getpid() ); \
+                         fprintf(stderr,X); \
+                     }
+
+#else /* __GNUC__ */
+
+/* TODO: non-GCC compilers can't do the above macro define yet. */
+inline void
+debug(char *format,...)
+{
+    ; // nothing to do.
+}
+#endif
+
+
+#endif /* COMPAT_DEBUG_H */
index 5e2bd1a3e067473b974256250a9f4dc8173b000e..deed47f129e8144d8f9c6632b253ea7bf7834225 100644 (file)
@@ -34,7 +34,7 @@ new_configure_args="$ac_configure_args --with-squid=$ac_abs_confdir"
 ac_configure_args="$new_configure_args"
 
 
-use_loadable_modules=0
+use_loadable_modules=1
 AC_MSG_CHECKING(whether to use loadable modules)
 AC_ARG_ENABLE(loadable-modules,
     AS_HELP_STRING([--disable-loadable-modules],[do not support loadable modules]) ,
@@ -51,7 +51,6 @@ AC_ARG_ENABLE(loadable-modules,
         AC_MSG_RESULT([$use_loadable_modules, implicitly])
     ]
 )
-use_loadable_modules=0
 
 AM_CONDITIONAL(USE_LOADABLE_MODULES, test $use_loadable_modules = yes)
 
@@ -697,11 +696,11 @@ if test -n "$STORE_MODULES"; then
        fi
     done
     for module in $STORE_MODULES_FULL; do
-       if test "$module" = "coss"; then
-           echo "WARNING: COSS Support is not stable yet in Squid-3. Please do not use."
-           sleep 10;
-       fi
        case "$module" in
+       coss)
+           echo "WARNING: COSS Support is not stable yet in Squid-3. Please do not use."
+           sleep 10
+           ;;
        esac
     done
     AC_MSG_NOTICE([Store modules built: $STORE_MODULES])
@@ -1806,6 +1805,207 @@ if test -n "$DIGEST_AUTH_HELPERS"; then
 fi
 AC_SUBST(DIGEST_AUTH_HELPERS)
 
+dnl Check Kerberos
+SAVED_CPPFLAGS=$CPPFLAGS
+SAVED_LIBS=$LIBS
+AC_ARG_WITH(krb5-config,
+ [  --with-krb5-config=PATH specify path to krb5-config @<:@default=detect@:>@],
+[ if test "$withval" = "yes"; then
+     unset krb5confpath
+  elif test "$withval" != "no"; then
+     krb5confpath=$withval
+  else
+     krb5confpath=no
+  fi
+])
+if test x"$krb5confpath" != xno; then
+    if test x"$krb5confpath" != x; then
+        if ! test -x "$krb5confpath"; then
+            AC_MSG_WARN([krb5-config '$krb5confpath' not executable, ignoring])
+            AC_CHECK_PROG(ac_krb5_config, krb5-config, yes, no)
+            krb5confpath=krb5-config
+        fi
+        krb5_config_path=`dirname $krb5confpath`
+        AC_CHECK_PROG(ac_krb5_config, krb5-config, yes, no, $krb5_config_path)
+    else
+    AC_CHECK_PROG(ac_krb5_config,krb5-config,yes,no)
+        krb5confpath=krb5-config
+    fi
+fi
+if test "$ac_krb5_config" = "yes" ; then
+    ac_heimdal="`$krb5confpath --version 2>/dev/null | grep -i heimdal`"
+    ac_solaris="`$krb5confpath --version 2>/dev/null | grep -i solaris`"
+    if test "x$ac_heimdal" != "x" ; then
+        AC_DEFINE(HAVE_HEIMDAL_KERBEROS,1,[Define to 1 if you have Heimdal Kerberos])
+    else
+        AC_DEFINE(HAVE_MIT_KERBEROS,1,[Define to 1 if you have MIT Kerberos])
+    fi
+    if test "$ac_solaris" != "" ; then
+        KRB5INCS="`$krb5confpath --cflags krb5 2>/dev/null`"
+        KRB5LIBS="`$krb5confpath --libs krb5 2>/dev/null`"
+        KRB5INCS="-I/usr/include/gssapi $KRB5INCS"
+        KRB5LIBS="-L/usr/lib -R/usr/lib -lgss -lresolv -lsocket -lnsl $KRB5LIBS"
+    else
+        KRB5INCS="`$krb5confpath --cflags krb5 2>/dev/null`"
+        KRB5LIBS="`$krb5confpath --libs krb5 2>/dev/null`"
+        KRB5INCS="`$krb5confpath --cflags gssapi 2>/dev/null` $KRB5INCS"
+        KRB5LIBS="`$krb5confpath --libs gssapi 2>/dev/null` $KRB5LIBS"
+    fi
+    CPPFLAGS="$CPPFLAGS $KRB5INCS"
+    LIBS="$LIBS $KRB5LIBS"
+    AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h)
+    if test "x$ac_heimdal" == "x" ; then
+        AC_CHECK_HEADERS(gssapi/gssapi_generic.h)
+    fi
+    AC_CHECK_HEADERS(krb5.h com_err.h et/com_err.h)
+    AC_MSG_CHECKING([for max_skew in struct krb5_context])
+AC_TRY_COMPILE([
+#include <krb5.h>
+                ],
+                [ krb5_context kc; kc->max_skew = 1; ],
+                [ AC_DEFINE(HAVE_MAX_SKEW_IN_KRB5_CONTEXT, 1, [Define to 1 if max_skew in struct krb5_context])
+                  AC_MSG_RESULT(yes) ],
+                [ AC_MSG_RESULT(no) ]
+        )
+
+    if test "x$ac_heimdal" == "x" ; then
+        AC_CHECK_HEADERS(profile.h)
+    fi
+    AC_CHECK_LIB(com_err,error_message,
+        AC_DEFINE(HAVE_ERROR_MESSAGE,1,[Define to 1 if you have error_message]),)
+    AC_CHECK_LIB(krb5,krb5_get_err_text,
+        AC_DEFINE(HAVE_KRB5_GET_ERR_TEXT,1,[Define to 1 if you have krb5_get_err_text]),)
+    AC_CHECK_LIB(krb5,krb5_get_error_message,
+        AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE,1,[Define to 1 if you have krb5_get_error_message]),)
+    AC_CHECK_LIB(krb5,krb5_kt_free_entry,
+        AC_DEFINE(HAVE_KRB5_KT_FREE_ENTRY,1,[Define to 1 if you have krb5_kt_free_entry]),)
+    AC_CHECK_LIB(krb5,krb5_get_init_creds_keytab,
+        AC_DEFINE(HAVE_GET_INIT_CREDS_KEYTAB,1,[Define to 1 if you have krb5_get_init_creds_keytab]),)
+    AC_CHECK_LIB(krb5,krb5_get_max_time_skew,
+        AC_DEFINE(HAVE_KRB5_GET_MAX_TIME_SKEW,1,[Define to 1 if you have krb5_get_max_time_skew]),)
+    AC_CHECK_LIB(krb5,krb5_get_profile,
+        AC_DEFINE(HAVE_KRB5_GET_PROFILE,1,[Define to 1 if you have krb5_get_profile]),)
+    AC_CHECK_LIB(krb5,profile_get_integer,
+        AC_DEFINE(HAVE_PROFILE_GET_INTEGER,1,[Define to 1 if you have profile_get_integer]),)
+    AC_CHECK_LIB(krb5,profile_release,
+        AC_DEFINE(HAVE_PROFILE_RELEASE,1,[Define to 1 if you have profile_release]),)
+    AC_MSG_CHECKING([for memory cache])
+    AC_TRY_RUN([
+#include<krb5.h>
+main()
+{
+    krb5_context context;
+    krb5_ccache cc;
+
+    krb5_init_context(&context);
+    return krb5_cc_resolve(context, "MEMORY:test_cache", &cc);
+}],
+    [AC_DEFINE(HAVE_KRB5_MEMORY_CACHE,1, [Define to 1 if you have MEMORY: cache support])
+     AC_MSG_RESULT(yes)],
+    AC_MSG_RESULT(no))
+
+    AC_MSG_CHECKING([for working gssapi])
+    AC_TRY_RUN([
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif
+
+#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#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
+int
+main(void)
+{
+        OM_uint32 val;
+        gss_OID_set set;
+
+        gss_create_empty_oid_set(&val, &set);
+
+        return 0;
+}
+],  [AC_DEFINE(HAVE_GSSAPI, 1, [GSSAPI support])
+     AC_MSG_RESULT(yes)],
+    AC_MSG_RESULT(no))
+    AC_MSG_CHECKING([for spnego support])
+    AC_TRY_RUN([
+#ifdef HAVE_HEIMDAL_KERBEROS
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#endif
+#else
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#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
+#include <string.h>
+int main(int argc, char *argv[]) {
+ OM_uint32 major_status,minor_status;
+ gss_OID_set gss_mech_set;
+ int i;
+
+static gss_OID_desc _gss_mech_spnego  = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
+gss_OID gss_mech_spnego = &_gss_mech_spnego;
+
+ major_status = gss_indicate_mechs( &minor_status, &gss_mech_set);
+
+ for (i=0;i<gss_mech_set->count;i++) {
+     if (!memcmp(gss_mech_set->elements[i].elements,gss_mech_spnego->elements,gss_mech_set->elements[i].length)) {
+        return 0;
+     }
+ }
+
+ return 1;
+}],
+    [ac_cv_have_spnego=yes
+     AC_DEFINE(HAVE_SPNEGO,1, [Define to 1 if you have SPNEGO support])
+     AC_MSG_RESULT(yes)],
+    [ac_cv_have_spnego=no
+     AC_MSG_RESULT(no)])
+    AC_MSG_CHECKING([for working krb5])
+    AC_TRY_RUN([
+#ifdef HAVE_KRB5_H
+#include <krb5.h>
+#endif
+
+int
+main(void)
+{
+        krb5_context context;
+
+        krb5_init_context(&context);
+
+        return 0;
+}
+],  [AC_DEFINE(HAVE_KRB5, 1, [KRB5 support])
+     AC_MSG_RESULT(yes)],
+    AC_MSG_RESULT(no))
+   LIBS=$SAVED_LIBS
+   CPPFLAGS=$SAVED_CPPFLAGS
+   AC_SUBST(KRB5INCS)
+   AC_SUBST(KRB5LIBS)
+fi
+AM_CONDITIONAL(HAVE_SPNEGO, test x"$ac_cv_have_spnego" = x"yes" )
+
 dnl Enable "NTLM fail open"
 AC_ARG_ENABLE(ntlm-fail-open,
   AS_HELP_STRING([--enable-ntlm-fail-open],[Enable NTLM fail open, where a helper that fails one of the
@@ -1856,6 +2056,48 @@ if test -n "$EXTERNAL_ACL_HELPERS"; then
 fi
 AC_SUBST(EXTERNAL_ACL_HELPERS)
 
+dnl Select url_rewrite helpers to build
+URL_REWRITE_HELPERS=all
+AC_ARG_ENABLE(url-rewrite-helpers,
+  AC_HELP_STRING([--enable-url-rewrite-helpers="list of helpers"],
+                 [This option selects which url_rewrite helpers to
+                  build and install as part of the normal build
+                  process. For a list of available helpers see the
+                  helpers/url_rewrite directory.]),
+[ case "$enableval" in
+  yes)
+       URL_REWRITE_HELPERS=all
+       ;;
+  no)
+       URL_REWRITE_HELPERS=""
+       ;;
+  *)
+       URL_REWRITE_HELPERS="`echo $enableval| sed -e 's/,/ /g;s/  */ /g'`"
+       ;;
+  esac
+])
+if test "$URL_REWRITE_HELPERS" = "all" ; then
+       URL_REWRITE_HELPERS=""
+       for dir in $srcdir/helpers/url_rewrite/*; do
+           helper="`basename $dir`"
+           if test -f $dir/config.test && sh $dir/config.test "$@"; then
+               URL_REWRITE_HELPERS="$URL_REWRITE_HELPERS $helper"
+           fi
+       done
+fi
+if test -n "$URL_REWRITE_HELPERS"; then
+    for helper in $URL_REWRITE_HELPERS; do
+       if test -f $srcdir/helpers/url_rewrite/$helper/Makefile.in; then
+               :
+       else
+               AC_MSG_ERROR(url_rewrite helper $helper does not exist)
+       fi
+    done
+    AC_MSG_NOTICE([url_rewrite helpers built: $URL_REWRITE_HELPERS])
+fi
+AC_SUBST(URL_REWRITE_HELPERS)
+
+
 AC_ARG_WITH(valgrind-debug,
   AS_HELP_STRING([--with-valgrind-debug],[Include debug instrumentation for use with valgrind]),
 [ case $withval in
@@ -3878,6 +4120,8 @@ AC_CONFIG_FILES([\
        helpers/external_acl/wbinfo_group/Makefile \
        helpers/external_acl/mswin_ad_group/Makefile \
        helpers/external_acl/mswin_lm_group/Makefile \
+       helpers/url_rewrite/Makefile \
+       helpers/url_rewrite/fake/Makefile \
        tools/Makefile
 ])
 
index a5a9ce62e5313a240fb1b0acaec5a17c9017f23f..e5734f163caba4a98671f42225c48ffdde6b85a1 100644 (file)
@@ -6,12 +6,14 @@ all:
 dyn-docs:
        rm -f -r tmp
        cd ../../ && (cat squid3.dox ; echo HTML_FILE_EXTENSION = .dyn ; echo HTML_OUTPUT = tmp ) | doxygen - 2>doxygen.log
-       mv dyn dyn.bak && mv tmp dyn && rm -r dyn.bak
+       rm -f -r dyn
+       mv tmp dyn
 
 html-docs:
        rm -f -r tmp
        cd ../../ && (cat squid3.dox | sed s/dyn/html/g | sed s/CALL_GRAPH/#/ | sed s/CALLER_GRAPH/#/ | doxygen -) 2>doxygen.log
-       mv html html.bak && mv tmp html && rm -r html.bak
+       rm -f -r html
+       mv tmp html
 
 clean:
-       rm -f -r tmp html dyn dyn.bak html.bak
+       rm -f -r tmp html dyn
index 3b04a484b5f974cda8751fe7fd389ae64db94b63..36735095f61093f4c2059c8b0a270ac93665914d 100644 (file)
@@ -1,6 +1,6 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid 3.0.STABLE18 release notes</title>
+<title>Squid 3.0.STABLE19 release notes</title>
 <author>Squid Developers</author>
 
 <abstract>
@@ -13,7 +13,7 @@ for Applied Network Research and members of the Web Caching community.
 
 <sect>Notice
 <p>
-The Squid Team are pleased to announce the release of Squid-3.0.STABLE18.
+The Squid Team are pleased to announce the release of Squid-3.0.STABLE19.
 
 This new release is available for download from <url url="http://www.squid-cache.org/Versions/v3/3.0/"> or the <url url="http://www.squid-cache.org/Mirrors/http-mirrors.html" name="mirrors">.
 
index cfd974717ac32fa61af8d6cd272dac65a5dff297..cf35b4af4cb9e73bd5f6fc6e5b890c31aa8e6c49 100644 (file)
@@ -306,9 +306,12 @@ This section gives an account of those changes in three categories:
 <sect1>New options<label id="newoptions">
 <p>
 <descrip>
-
-       <tag>???alphabetical list within group ordered: enable, disable, with, without) ???</tag>
-       <p> ???explain??
+       <tag>--enable-url-rewrite-helpers</tag>
+       <p>Build helpers for some basic URL-rewrite actions. For use by url_rewrite_program.
+          If omitted or set to =all then all bundled helpers that are able to build will be built.
+          If set to a specific list of helpers then only those helpers will build.
+          Currently one demo helper <em>fake</em> is provided in shell and C++ forms to demonstrate
+          the helper protocol usage and provide exemplar code.
 
 </descrip>
 
index dd80a7bfc84c9eec87e57683dbe8ec7c8ab1ef27..51b52e5b780ad2a56d23fcf295d1defc0f9c25ad 100644 (file)
@@ -11,43 +11,155 @@ DEFAULT_ERROR_DIR  = $(errordir)
 DEFAULT_STYLESHEET     = $(sysconfdir)/errorpage.css
 
 ## List of automated translations possible:
-TRANSLATIONPO=`ls -1 $(top_srcdir)/errors/*.po | grep -o -E "[a-z\-]+\.po" | sed s/.po//`
-TRANSLATIONDIR=`ls -1 $(srcdir) $(builddir) | sed -e 's%$(srcdir)/%%' -e 's%$(builddir)/%%' -e 's%.po%%' `
+ERROR_TEMPLATES =  \
+       templates/ERR_FTP_PUT_MODIFIED \
+       templates/ERR_ESI \
+       templates/ERR_SECURE_CONNECT_FAIL \
+       templates/ERR_ZERO_SIZE_OBJECT \
+       templates/ERR_SHUTTING_DOWN \
+       templates/ERR_URN_RESOLVE \
+       templates/ERR_CONNECT_FAIL \
+       templates/ERR_SOCKET_FAILURE \
+       templates/ERR_FTP_NOT_FOUND \
+       templates/ERR_FTP_UNAVAILABLE \
+       templates/ERR_LIFETIME_EXP \
+       templates/ERR_READ_ERROR \
+       templates/ERR_ONLY_IF_CACHED_MISS \
+       templates/ERR_UNSUP_HTTPVERSION \
+       templates/ERR_READ_TIMEOUT \
+       templates/ERR_ICAP_FAILURE \
+       templates/ERR_FTP_LISTING \
+       templates/ERR_FTP_FORBIDDEN \
+       templates/ERR_ACCESS_DENIED \
+       templates/ERR_FORWARDING_DENIED \
+       templates/ERR_CANNOT_FORWARD \
+       templates/ERR_CACHE_MGR_ACCESS_DENIED \
+       templates/ERR_INVALID_REQ \
+       templates/ERR_CACHE_ACCESS_DENIED \
+       templates/ERR_FTP_PUT_ERROR \
+       templates/ERR_FTP_PUT_CREATED \
+       templates/ERR_TOO_BIG \
+       templates/ERR_UNSUP_REQ \
+       templates/ERR_FTP_FAILURE \
+       templates/ERR_DNS_FAIL \
+       templates/ERR_FTP_DISABLED \
+       templates/ERR_NO_RELAY \
+       templates/ERR_INVALID_URL \
+       templates/ERR_INVALID_RESP \
+       templates/ERR_WRITE_ERROR
 
-## TODO: prevent this loop installing everything twice when srcdir == builddir
-install-data-local:
-       $(mkinstalldirs) $(DESTDIR)$(DEFAULT_ERROR_DIR) ; \
-       for l in $(TRANSLATIONDIR) ; do \
-         echo "Located $$l for install..."; \
-         if test -d $(srcdir)/$$l; then \
-               $(mkinstalldirs) $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l && \
-               for f in $(srcdir)/$$l/ERR_*; do \
-                       echo "$(INSTALL_DATA) $$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l"; \
-                       $(INSTALL_DATA) $$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l; \
-               done; \
-         fi ; \
-         if test -d $(builddir)/$$l; then \
-               $(mkinstalldirs) $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l && \
-               for f in $(builddir)/$$l/ERR_*; do \
-                       echo "$(INSTALL_DATA) $$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l"; \
-                       $(INSTALL_DATA) $$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l; \
+TRANSLATE_LANGUAGES = \
+       ar.lang \
+       az.lang \
+       bg.lang \
+       ca.lang \
+       cs.lang \
+       da.lang \
+       de.lang \
+       el.lang \
+       en.lang \
+       es.lang \
+       et.lang \
+       fa.lang \
+       fi.lang \
+       fr.lang \
+       he.lang \
+       hu.lang \
+       hy.lang \
+       id.lang \
+       it.lang \
+       ja.lang \
+       ko.lang \
+       lt.lang \
+       lv.lang \
+       ms.lang \
+       nl.lang \
+       pl.lang \
+       pt-br.lang \
+       pt.lang \
+       ro.lang \
+       ru.lang \
+       sk.lang \
+       sr.lang \
+       sv.lang \
+       th.lang \
+       tr.lang \
+       uk.lang \
+       uz.lang \
+       zh-cn.lang \
+       zh-tw.lang
+
+CLEANFILES = $(TRANSLATE_LANGUAGES) translate-warn
+EXTRA_DIST = \
+       $(ERROR_TEMPLATES) \
+       aliases alias-link.sh alias-upgrade errorpage.css TRANSLATORS COPYRIGHT
+
+all: all-am
+
+translate: translate-warn $(TRANSLATE_LANGUAGES)
+
+translate-warn:
+       case "$(PO2HTML)" in \
+       off) \
+           echo "WARNING: Translation is disabled."; \
+           ;; \
+       ""|no) \
+           echo "WARNING: Translation toolkit was not detected."; \
+           ;; \
+       esac; \
+       touch translate-warn
+
+$(TRANSLATE_LANGUAGES): $(ERROR_TEMPLATES)
+
+.po.lang:
+       if test "$(PO2HTML)" != "" && test "$(PO2HTML)" != "no" && test "$(PO2HTML)" != "off" && test -f $(top_srcdir)/errors/en.po; then \
+           lang=`basename $@ .lang`; \
+           mkdir -p $(top_builddir)/errors/$$lang; \
+           echo -n "Translate '$$lang' ..."; \
+           for f in $(ERROR_TEMPLATES); do \
+                       page=`basename $$f`; \
+                       $(PO2HTML) --progress=none -i $(top_srcdir)/errors/$$lang.po -t $(top_srcdir)/errors/$$f >$(top_builddir)/errors/$$lang/$$page || exit 1; \
                done; \
-         fi \
-       done; \
-       $(INSTALL_DATA) $(srcdir)/TRANSLATORS $(DESTDIR)$(DEFAULT_ERROR_DIR)/TRANSLATORS; \
-       $(INSTALL_DATA) $(srcdir)/COPYRIGHT $(DESTDIR)$(DEFAULT_ERROR_DIR)/COPYRIGHT; \
-       $(INSTALL_DATA) $(srcdir)/errorpage.css $(DESTDIR)$(DEFAULT_STYLESHEET).default; \
+               echo "done."; \
+       fi; \
+       touch $@
+
+install-exec-local: translate
        if test -f $(DESTDIR)$(DEFAULT_STYLESHEET) ; then \
                echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_STYLESHEET)" ; \
        else \
+               $(mkinstalldirs) $(DESTDIR)`dirname $(DEFAULT_STYLESHEET)` ; \
                echo "$(INSTALL_DATA) $(srcdir)/errorpage.css $(DESTDIR)$(DEFAULT_STYLESHEET)"; \
                $(INSTALL_DATA) $(srcdir)/errorpage.css $(DESTDIR)$(DEFAULT_STYLESHEET); \
-       fi ; \
-       $(SHELL) $(srcdir)/alias-link.sh "$(LN)" "$(RM)" "$(DESTDIR)$(DEFAULT_ERROR_DIR)" "$(srcdir)/aliases" || exit 1 ;
+       fi
 
+install-data-local: translate
+       $(mkinstalldirs) $(DESTDIR)$(DEFAULT_ERROR_DIR) ; \
+       for l in $(TRANSLATE_LANGUAGES); do \
+           l=`basename $$l .lang`; \
+           echo "Located $$l for install..."; \
+           if test -d $(srcdir)/$$l || test -d $(builddir)/$$l; then \
+               $(mkinstalldirs) $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l; \
+           fi; \
+           for f in $(ERROR_TEMPLATES); do \
+               page=`basename $$f`; \
+               if test -f $(builddir)/$$l/$$f; then \
+                   echo "$(INSTALL_DATA) $(builddir)/$$l/$$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l"; \
+                           $(INSTALL_DATA) $(builddir)/$$l/$$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l; \
+               elif test -f $(srcdir)/$$l/$$f; then \
+                   echo "$(INSTALL_DATA) $(srcdir)/$$l/$$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l"; \
+                           $(INSTALL_DATA) $(srcdir)/$$l/$$f $(DESTDIR)$(DEFAULT_ERROR_DIR)/$$l; \
+               fi; \
+           done; \
+       done; \
+       $(INSTALL_DATA) $(srcdir)/TRANSLATORS $(DESTDIR)$(DEFAULT_ERROR_DIR)/TRANSLATORS; \
+       $(INSTALL_DATA) $(srcdir)/COPYRIGHT $(DESTDIR)$(DEFAULT_ERROR_DIR)/COPYRIGHT; \
+       $(INSTALL_DATA) $(srcdir)/errorpage.css $(DESTDIR)$(DEFAULT_STYLESHEET).default; \
+       $(SHELL) $(srcdir)/alias-link.sh "$(LN)" "$(RM)" "$(DESTDIR)$(DEFAULT_ERROR_DIR)" "$(srcdir)/aliases" || exit 1 ;
 
 uninstall-local:
-       for l in $(TRANSLATIONDIR) ; do \
+       for l in $(TRANSLATE_LANGUAGES) templates; do \
+         l=`basename $$l .lang`; \
          echo "Located $$l for uninstall ..."; \
          if test -d $(srcdir)/$$l; then \
                for f in $(srcdir)/$$l/ERR_*; do \
@@ -74,42 +186,21 @@ upgrade: install
        $(SHELL) $(srcdir)/alias-link.sh "$(LN)" "$(RM)" "$(DESTDIR)$(DEFAULT_ERROR_DIR)" "$(srcdir)/alias-upgrade" || exit 1 ;
 
 dist-hook: translate
-       for lang in $(TRANSLATIONPO) templates; do \
+       for lang in $(TRANSLATE_LANGUAGES); do \
+         lang=`basename $$lang .lang`; \
          if test -d $$lang ; then \
-               test -d $(distdir)/$$lang \
-                 || mkdir $(distdir)/$$lang \
-                 || exit 1; \
+               mkdir -p $(distdir)/$$lang; \
                cp -p $(top_builddir)/errors/$$lang/ERR_*  $(distdir)/$$lang \
                  || exit 1; \
          fi; \
-       done; \
-       for f in aliases alias-link.sh alias-upgrade errorpage.css TRANSLATORS COPYRIGHT; do \
-               cp -p $(srcdir)/$$f $(distdir)/`basename $$f`; \
-       done;
+       done
 
-translate:
-       @if ! test -f $(top_srcdir)/errors/en.po; then \
-         echo "Translation is not currently possible."; \
-         exit 0; \
-       fi; \
+clean: clean-am
        if test "$(PO2HTML)" != "" && test "$(PO2HTML)" != "no" && test "$(PO2HTML)" != "off" && test -f $(top_srcdir)/errors/en.po; then \
-         for lang in $(TRANSLATIONPO); do \
-               test -d $(top_builddir)/errors/$$lang && $(RM) -r $(top_builddir)/errors/$$lang; \
-               mkdir $(top_builddir)/errors/$$lang || exit 1; \
-               echo -n "Translate '$$lang' ..."; \
-               for f in `ls -1 $(top_srcdir)/errors/templates`; do \
-                       $(PO2HTML) --progress=none -i $(top_srcdir)/errors/$$lang.po -t $(top_srcdir)/errors/templates/$$f >$(top_builddir)/errors/$$lang/$$f || exit 1; \
-               done; \
-               echo "done."; \
+         for lang in $(TRANSLATE_LANGUAGES); do \
+           lang=`basename $$lang .lang`; \
+           rm -rf $$lang; \
          done; \
-       else \
-         if test "$(PO2HTML)" = "off" ; then \
-           echo "WARNING: Translation is disabled."; \
-         else \
-           echo "WARNING: Translation toolkit was not detected."; \
-         fi; \
-         echo "A drop-in bundle of pre-translated files is available from"; \
-         echo "http://www.squid-cache.org/Versions/langpack/"; \
        fi
 
 all: translate
index 384a9e1836ee74d6e7640c6039a239672eb727f1..70f6b14e90f72e6c7b902fae55aa3d82d79086da 100755 (executable)
@@ -38,6 +38,6 @@ while read base aliases; do
        # Remove and replace any pre-existing content/link
        for alia in ${aliases}; do
                ${RM} -f -r ${DIR}/${alia} || exit 1
-               ${LN} -s ${DIR}/${base} ${DIR}/${alia} || exit 1
+               ${LN} -s ${base} ${DIR}/${alia} || exit 1
        done
 done
index d509c84ed150daa1de10536f7979061f95c4a8f2..0123cb9dc75f765edc313aeac6f9ba19dc98e1af 100644 (file)
@@ -1 +1 @@
-SUBDIRS = basic_auth ntlm_auth digest_auth negotiate_auth external_acl
+SUBDIRS = basic_auth ntlm_auth digest_auth negotiate_auth external_acl url_rewrite
index 0e4a9fecdabab6452de5ff0f8b35787109ff8c62..47b440829cdbf70e0814d3a6ad6846cfcfb638f1 100644 (file)
@@ -361,10 +361,12 @@ ldapconnect(void)
         }
         if (use_tls) {
 #ifdef LDAP_OPT_X_TLS
-            if ((version == LDAP_VERSION3) && (ldap_start_tls_s(ld, NULL, NULL) == LDAP_SUCCESS)) {
+            if (version != LDAP_VERSION3) {
+                fprintf(stderr, "TLS requires LDAP version 3\n");
+                exit(1);
+            } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
                 fprintf(stderr, "Could not Activate TLS connection\n");
-                ldap_unbind(ld);
-                ld = NULL;
+                exit(1);
             }
 #else
             fprintf(stderr, "TLS not supported with your LDAP library\n");
index 06e970a7599e964cfc10a9e526784f6fbe563f35..4df2cdccdcd94d0b68bf14120eadec572635fce7 100755 (executable)
@@ -34,7 +34,7 @@
 use vars qw/ %opt /;
 
 # Disable output buffering
-$|=1;           
+$|=1;
 
 sub debug {
        print STDERR "@_\n" if $opt{d};
@@ -86,7 +86,7 @@ print STDERR "Debugging mode ON.\n" if $opt{d};
 #
 while (<STDIN>) {
         chop;
-       &debug ("Got $_ from squid");
+       &debug("Got $_ from squid");
         ($user, @groups) = split(/\s+/);
        $user =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("c",hex($1))/eg;
        # test for each group squid send in it's request
@@ -95,7 +95,7 @@ while (<STDIN>) {
                $ans = &check($user, $group);
                last if $ans eq "OK";
        }
-       &debug ("Sending $ans to squid");
+       &debug("Sending $ans to squid");
        print "$ans\n";
 }
 
index d6e58b54494da80e1e31092b83947244e9a431e9..65bc9942ca2735866ffa003070a11384b40e820a 100644 (file)
@@ -260,7 +260,7 @@ ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
     pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0';
 
 #if 1
-    debug ("Empty LM pass detection: user: '%s', ours:'%s', his: '%s'"
+    debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s'"
            "(length: %d)\n",
            user,lmencoded_empty_pass,tmp.str,tmp.l);
     if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
@@ -272,7 +272,7 @@ ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
 
     tmp = ntlm_fetch_string ((char *) auth, auth_length, &auth->ntresponse);
     if (tmp.str != NULL && tmp.l != 0) {
-        debug ("Empty NT pass detection: user: '%s', ours:'%s', his: '%s'"
+        debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s'"
                "(length: %d)\n",
                user,ntencoded_empty_pass,tmp.str,tmp.l);
         if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
index 80a9c3008c8a57ca3adfe233836e9051a4f3e6c2..597150bf8f42dc05a0603f9f31b17d87eb15a5bd 100644 (file)
@@ -155,7 +155,7 @@ usage()
             my_program_name, my_program_name);
 }
 
-char debug_enabled=0;
+int debug_enabled=0;
 
 void
 process_options(int argc, char *argv[])
index de63809b057bf5f146a8296f6795e8e4d6498ccc..bfb296760c9f76eed2f2821eae4cd9abd12f94ea 100644 (file)
 
 /************* END CONFIGURATION ***************/
 
-#include <sys/types.h>
-
-
-/* Debugging stuff */
-
-#ifdef __GNUC__                        /* this is really a gcc-ism */
-#ifdef DEBUG
-#include <stdio.h>
-#include <unistd.h>
-static const char *__foo;
-extern char debug_enabled;
-#define debug(X...) if (debug_enabled) { \
-                    fprintf(stderr,"ntlm-auth[%ld](%s:%d): ", (long)getpid(), \
-                    ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\
-                    __LINE__);\
-                    fprintf(stderr,X); }
-#else /* DEBUG */
-#define debug(X...)            /* */
-#endif /* DEBUG */
-#else /* __GNUC__ */
-static void
-debug(char *format,...)
-{
-}
-
-#endif
-
 
 /* A couple of harmless helper macros */
 #define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
diff --git a/helpers/url_rewrite/Makefile.am b/helpers/url_rewrite/Makefile.am
new file mode 100644 (file)
index 0000000..f439bcb
--- /dev/null
@@ -0,0 +1,3 @@
+
+DIST_SUBDIRS   = fake
+SUBDIRS                = @URL_REWRITE_HELPERS@
diff --git a/helpers/url_rewrite/fake/Makefile.am b/helpers/url_rewrite/fake/Makefile.am
new file mode 100644 (file)
index 0000000..eb1040e
--- /dev/null
@@ -0,0 +1,10 @@
+include $(top_srcdir)/src/Common.am
+libexec_PROGRAMS = url_fake_rewrite
+url_fake_rewrite_SOURCES = fake.cc
+
+url_fake_rewrite_LDADD = $(COMPAT_LIB)
+
+libexec_SCRIPTS = url_fake_rewrite.sh
+
+EXTRA_DIST = url_fake_rewrite.sh
diff --git a/helpers/url_rewrite/fake/config.test b/helpers/url_rewrite/fake/config.test
new file mode 100755 (executable)
index 0000000..039e4d0
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 0
diff --git a/helpers/url_rewrite/fake/fake.cc b/helpers/url_rewrite/fake/fake.cc
new file mode 100644 (file)
index 0000000..59604cc
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * AUTHOR: Amos Jeffries <squid3@treenet.co.nz>
+ *
+ * Example url re-writer program for Squid.
+ *
+ * This code gets the url and returns it. No re-writing is done.
+ * It is intended for testing use and as a base for further implementation.
+ *
+ *
+ * This code is copyright (C) 2009 by Treehouse Networks Ltd
+ * of New Zealand. It is published and Licensed as an extension of
+ * squid under the same conditions as the main squid application.
+ */
+
+#include "config.h"
+
+#if HAVE_CSTRING
+#include <cstring>
+#endif
+
+#define BUFFER_SIZE 10240
+
+/**
+ * options:
+ * -d enable debugging.
+ * -h interface help.
+ */
+char *my_program_name = NULL;
+int debug_enabled = 0;
+
+static void
+usage(void)
+{
+    fprintf(stderr,
+            "Usage: %s [-d] [-v] [-h]\n"
+            " -d  enable debugging.\n"
+            " -h  this message\n\n",
+            my_program_name);
+}
+
+static void
+process_options(int argc, char *argv[])
+{
+    int opt, had_error = 0;
+
+    opterr = 0;
+    while (-1 != (opt = getopt(argc, argv, "hd"))) {
+        switch (opt) {
+        case 'd':
+            debug_enabled = 1;
+            break;
+        case 'h':
+            usage();
+            exit(0);
+        case '?':
+            opt = optopt;
+            /* fall thru to default */
+        default:
+            fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
+            usage();
+            had_error = 1;
+        }
+    }
+    if (had_error)
+        exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+    char buf[BUFFER_SIZE];
+    int buflen = 0;
+
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+
+    my_program_name = argv[0];
+
+    process_options(argc, argv);
+
+    debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name);
+
+    while (fgets(buf, BUFFER_SIZE, stdin) != NULL) {
+        char *p;
+
+        if ((p = strchr(buf, '\n')) != NULL) {
+            *p = '\0';         /* strip \n */
+            buflen = p - buf;   /* length is known already */
+        }
+        else
+            buflen = strlen(buf);   /* keep this so we only scan the buffer for \0 once per loop */
+
+        debug("Got %d bytes '%s' from Squid\n", buflen, buf);
+
+        /* send 'no-change' result back to Squid */
+        fprintf(stdout,"\n");
+    }
+    debug("%s build " __DATE__ ", " __TIME__ " shutting down...\n", my_program_name);
+    exit(0);
+}
diff --git a/helpers/url_rewrite/fake/fake.h b/helpers/url_rewrite/fake/fake.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/helpers/url_rewrite/fake/url_fake_rewrite.sh b/helpers/url_rewrite/fake/url_fake_rewrite.sh
new file mode 100755 (executable)
index 0000000..08f7f69
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Author: Amos Jeffries <squid3@treenet.co.nz>
+#
+# This code is copyright (C) 2009 by Treehouse Networks Ltd
+# of New Zealand. It is published and Licensed as an extension of
+# squid under the same conditions as the main squid application.
+#
+
+if test "${1}" = "-h" ; then
+       echo "Usage: $0 [-h] [-c] [-d logfile]"
+       echo "  -h           Help: this help text"
+       echo "  -c           Accept concurrent request format"
+       echo "  -d logfile   Debug: log all data received to the named file"
+       exit 1
+fi
+
+concurrent=0
+if test "${1}" = "-c" ; then
+       concurrent=1
+       shift
+fi
+
+DEBUG=0
+if test "${1}" = "-d" ; then
+       DEBUG=1
+       LOG="${2}"
+fi
+
+if test "$concurrent" = "1"; then
+       # read concurrent input format
+       while read id url rest; do
+               if test "${DEBUG}" = "1" ; then
+                       echo "ID:$id URL:$url EXTRAS:$rest" >>${LOG}
+               fi
+               # blank URL for no change, or replace with another URL.
+               echo "${id} "
+       done
+else
+       # read old non-concurrent input format
+       while read url rest; do
+               if test "${DEBUG}" = "1" ; then
+                       echo "URL:$url EXTRAS:$rest" >>${LOG}
+               fi
+               # blank line/URL for no change, or replace with another URL.
+               echo
+       done
+fi
index 647255503d448f20d2508c147b86e4a84d87a362..c0b6126beaeeeacbff03e95591db8425b8468b73 100644 (file)
@@ -1304,7 +1304,8 @@ EXPAND_AS_DEFINED      = AsyncCallWrapper \
                          AsyncCallEnter \
                          AsyncCallExit \
                          CBDATA_CLASS2 \
-                         MEMPROXY_CLASS_INLINE
+                         MEMPROXY_CLASS_INLINE \
+                         MEMPROXY_CLASS
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 
index 7f4c8d7fc21278f57105ffab0aa80ba2c39c7252..dd10d15c5c05542e0b058b860b940e991e2fc587 100644 (file)
@@ -24,7 +24,6 @@ INCLUDES = \
 ## XXX: Do we really need this? Does auto-dependency tracking work?
 $(OBJS): $(top_srcdir)/include/version.h $(top_builddir)/include/autoconf.h
 
-
 ## Because compatibility is almost universal. And the link order is important.
 COMPAT_LIB = \
        -L$(top_builddir)/lib -lmiscutil \
index 9853875c3c8a570b9567388cfcc0eef17422eee3..2453344c55a27eefe8ba3443cf272be718269034 100644 (file)
@@ -51,7 +51,7 @@ ConfigParser::strtokFile(void)
     static FILE *wordFile = NULL;
 
     char *t, *fn;
-    LOCAL_ARRAY(char, buf, 256);
+    LOCAL_ARRAY(char, buf, CONFIG_LINE_LIMIT);
 
     do {
 
@@ -86,7 +86,7 @@ ConfigParser::strtokFile(void)
         }
 
         /* fromFile */
-        if (fgets(buf, 256, wordFile) == NULL) {
+        if (fgets(buf, CONFIG_LINE_LIMIT, wordFile) == NULL) {
             /* stop reading from file */
             fclose(wordFile);
             wordFile = NULL;
index 2c466ed86fc0a4045e1b3fef66adb503469e7a86..4d5a25ba6abdeca4ad4282f0a5343fd52409aaaa 100644 (file)
 
 #include "squid.h"
 
-/*
+/**
+ * Limit to how long any given config line may be.
+ * This affects squid.conf and all included files.
+ *
+ * Behaviour when setting larger than 2KB is unknown.
+ * The config parser read mechanism can cope, but the other systems
+ * receiving the data from its buffers on such lines may not.
+ */
+#define CONFIG_LINE_LIMIT      2048
+
+/**
  * A configuration file Parser. Instances of this class track
  * parsing state and perform tokenisation. Syntax is currently
  * taken care of outside this class.
@@ -48,7 +58,6 @@
  * in all of squid by reference. Instead the tokeniser only is
  * brought in.
  */
-
 class ConfigParser
 {
 
index b2134c1bc333298506e4ac0a9a49b9b2f5b09b34..1a30f17c9a2c22c4aba80c26fd6ccf301823b5c9 100644 (file)
@@ -137,9 +137,10 @@ inline std::ostream& operator <<(std::ostream &os, const uint8_t d)
 }
 
 /* Legacy debug style. Still used in some places. needs to die... */
-#define do_debug(SECTION, LEVEL) ((Debug::level = (LEVEL)) > Debug::Levels[SECTION])
-#define old_debug(SECTION, LEVEL) \
-        do_debug(SECTION, LEVEL) ? (void) 0 : _db_print
+#define do_debug(SECTION, LEVEL)   ((Debug::level = (LEVEL)) > Debug::Levels[SECTION])
+#define old_debug(SECTION, LEVEL)  if( (Debug::level=(LEVEL)) <= Debug::Levels[SECTION] ) _db_print
 
+/* Legacy debug function definitions */
+SQUIDCEXTERN void _db_print(const char *,...) PRINTF_FORMAT_ARG1;
 
 #endif /* SQUID_DEBUG_H */
index 4384b3be2949a40adc3e38c8a322303edcd0f668..3a2b7d3ad02956acf4ee51395f199e9c896be4e4 100644 (file)
@@ -327,11 +327,11 @@ httpHeaderParseOffset(const char *start, int64_t * value)
 /**
  * Parses a quoted-string field (RFC 2616 section 2.2), complains if
  * something went wrong, returns non-zero on success.
- * start should point at the first ".
+ * start should point at the first double-quote.
  * RC TODO: This is too looose. We should honour the BNF and exclude CTL's
  */
 int
-httpHeaderParseQuotedString (const char *start, String *val)
+httpHeaderParseQuotedString(const char *start, String *val)
 {
     const char *end, *pos;
     val->clean();
index 98d98716aa6e5651f528d380d2fb3e2825cf549b..3b241ec23a1c5b7d5026c7038206bb97ef37336e 100644 (file)
@@ -175,6 +175,8 @@ public:
 
     char *peer_login;          /* Configured peer login:password */
 
+    char *peer_host;           /* Selected peer host*/
+
     time_t lastmod;            /* Used on refreshes */
 
     const char *vary_headers;  /* Used when varying entities are detected. Changes how the store key is calculated */
index 4db4ec7b78d8114d47ac74c4ecf74c23c3c54772..f4874bfb57b1bf6ae6a53a0db252f2d124bbcd00 100644 (file)
@@ -392,6 +392,7 @@ squid_SOURCES = \
        pconn.h \
        PeerDigest.h \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -543,7 +544,8 @@ squid_LDADD = \
        @SSLLIB@ \
        @XTRA_LIBS@ \
        @EPOLL_LIBS@ \
-       @MINGW_LIBS@ 
+       @MINGW_LIBS@ \
+       @KRB5LIBS@
 squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \
        @DISK_LIBS@ \
        @DISK_LINKOBJS@ \
@@ -565,6 +567,9 @@ squid_LDFLAGS = \
 #
 endif
 
+## Kerberos libraries require their include path...
+INCLUDES += @KRB5INCS@
+
 
 unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc
 
@@ -629,7 +634,7 @@ ufsdump_LDADD = \
        -L$(top_builddir)/lib -lmiscutil \
        @XTRA_LIBS@ \
        @EPOLL_LIBS@ \
-       @MINGW_LIBS@ 
+       @MINGW_LIBS@
 ufsdump_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \
        $(COMMON_LIBS) \
        @DISK_LIBS@ \
@@ -1143,6 +1148,7 @@ tests_testCacheManager_SOURCES = \
        Parsing.cc \
        pconn.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -1203,7 +1209,8 @@ tests_testCacheManager_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_testCacheManager_LDFLAGS = $(LIBADD_DL)
 tests_testCacheManager_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @REPL_OBJS@ \
@@ -1313,6 +1320,7 @@ tests_testEvent_SOURCES = \
        Parsing.cc \
        pconn.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -1372,7 +1380,8 @@ tests_testEvent_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_testEvent_LDFLAGS = $(LIBADD_DL)
 tests_testEvent_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @REPL_OBJS@ \
@@ -1460,6 +1469,7 @@ tests_testEventLoop_SOURCES = \
        Parsing.cc \
        pconn.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -1519,7 +1529,8 @@ tests_testEventLoop_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_testEventLoop_LDFLAGS = $(LIBADD_DL)
 tests_testEventLoop_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @REPL_OBJS@ \
@@ -1596,6 +1607,7 @@ tests_test_http_range_SOURCES = \
        neighbors.cc \
        Parsing.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -1661,7 +1673,8 @@ tests_test_http_range_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_test_http_range_LDFLAGS = $(LIBADD_DL)
 tests_test_http_range_DEPENDENCIES = \
        @SQUID_CPPUNIT_LA@
@@ -1748,6 +1761,7 @@ tests_testHttpRequest_SOURCES = \
        Parsing.cc \
        pconn.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -1808,7 +1822,8 @@ tests_testHttpRequest_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_testHttpRequest_LDFLAGS = $(LIBADD_DL)
 tests_testHttpRequest_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @REPL_OBJS@ \
@@ -2097,6 +2112,7 @@ tests_testURL_SOURCES = \
        Parsing.cc \
        pconn.cc \
        peer_digest.cc \
+       peer_proxy_negotiate_auth.cc \
        peer_select.cc \
        peer_sourcehash.cc \
        peer_userhash.cc \
@@ -2154,7 +2170,8 @@ tests_testURL_LDADD = \
        @SQUID_CPPUNIT_LIBS@ \
        @SQUID_CPPUNIT_LA@ \
        @SSLLIB@ \
-       @XTRA_LIBS@
+       @XTRA_LIBS@ \
+       @KRB5LIBS@
 tests_testURL_LDFLAGS = $(LIBADD_DL)
 tests_testURL_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @REPL_OBJS@ \
index 22a8d9fe90d0cf0116f18aacac332aa84309d2a1..2689d2f0a21fd3036919f0a439eca85eda992229 100644 (file)
@@ -430,6 +430,12 @@ configDoConfigure(void)
     memConfigure();
     /* Sanity checks */
 
+    if (Config.cacheSwap.swapDirs == NULL) {
+        /* Memory-only cache probably in effect. */
+        /* turn off the cache rebuild delays... */
+        StoreController::store_dirs_rebuilding = 0;
+    }
+
     if (Debug::rotateNumber < 0) {
         Debug::rotateNumber = Config.Log.rotateNumber;
     }
@@ -1889,7 +1895,7 @@ parse_peer(peer ** head)
         p->weight = 1;
 
     if (p->connect_fail_limit < 1)
-        p->connect_fail_limit = 1;
+        p->connect_fail_limit = 10;
 
     p->icp.version = ICP_VERSION_CURRENT;
 
@@ -3082,16 +3088,7 @@ parse_http_port_option(http_port_list * s, char *token)
         IpInterceptor.StartTransparency();
         /* Log information regarding the port modes under transparency. */
         debugs(3, DBG_IMPORTANT, "Starting IP Spoofing on port " << s->s);
-        debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (Ip spoofing enabled)");
-
-#if USE_IPV6
-        /* INET6: until target TPROXY is known to work on IPv6 SOCKET, force wildcard to IPv4 */
-        debugs(3, DBG_IMPORTANT, "Disabling IPv6 on port " << s->s << " (interception enabled)");
-        if ( s->s.IsIPv6() && !s->s.SetIPv4() ) {
-            debugs(3, DBG_CRITICAL, "http(s)_port: IPv6 addresses cannot be transparent (protocol does not provide NAT)" << s->s );
-            self_destruct();
-        }
-#endif
+        debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (IP spoofing enabled)");
 
     } else if (strcmp(token, "ipv4") == 0) {
 #if USE_IPV6
index c27c9a29eec0ce6070b624799af94d167f35bcc5..4de0b74cfe39260f36162614ad302e5235e8bbdd 100644 (file)
@@ -1822,6 +1822,19 @@ DOC_START
                        be used to identify this proxy to the peer, similar to
                        the login=username:password option above.
        
+       login=NEGOTIATE
+                       If this is a personal/workgroup proxy and your parent
+                       requires a secure proxy authentication.
+                       The first principal from the default keytab or defined by
+                       the environment variable KRB5_KTNAME will be used. 
+       
+       login=NEGOTIATE:principal_name
+                       If this is a personal/workgroup proxy and your parent
+                       requires a secure proxy authentication. 
+                       The principal principal_name from the default keytab or
+                       defined by the environment variable KRB5_KTNAME will be
+                       used.
+       
        connection-auth=on|off
                        Tell Squid that this peer does or not support Microsoft
                        connection oriented authentication, and any such
index 6d5d77c598742df24e275001723ecb357c941f10..1b05a9000360eb05a14309e7c1858bae85dc7205 100644 (file)
@@ -1989,6 +1989,15 @@ parseHttpRequest(ConnStateData *conn, HttpParser *hp, HttpRequestMethod * method
     /* Set method_p */
     *method_p = HttpRequestMethod(&hp->buf[hp->m_start], &hp->buf[hp->m_end]+1);
 
+    /* deny CONNECT via accelerated ports */
+    if (*method_p == METHOD_CONNECT && conn && conn->port && conn->port->accel) {
+        debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << conn->port->protocol << " Accelerator port " << conn->port->s.GetPort() );
+        /* XXX need a way to say "this many character length string" */
+        debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf);
+        /* XXX need some way to set 405 status on the error reply */
+        return parseHttpRequestAbort(conn, "error:method-not-allowed");
+    }
+
     if (*method_p == METHOD_NONE) {
         /* XXX need a way to say "this many character length string" */
         debugs(33, 1, "clientParseRequestMethod: Unsupported method in request '" << hp->buf << "'");
index 6ba640b3786ea803f436bc857233de57421eb82e..1f40f900aadca20a3bee7f7b1f7c2dff07746b8f 100644 (file)
@@ -144,7 +144,7 @@ UFSSwapDir::changeIO(DiskIOModule *module)
     IO->io = anIO;
     /* Change the IO Options */
 
-    if (currentIOOptions->options.size() > 2)
+    if (currentIOOptions && currentIOOptions->options.size() > 2)
         delete currentIOOptions->options.pop_back();
 
     /* TODO: factor out these 4 lines */
index 24b3ee8ed5aa08c3a6482e02b329bc511d91e0ec..dca3be0c1326a0274e7ff88c4dacebfa321de90c 100644 (file)
  */
 
 #include "squid.h"
+
+#include "acl/FilledChecklist.h"
+#include "auth/UserRequest.h"
+#if DELAY_POOLS
+#include "DelayPools.h"
+#endif
 #include "errorpage.h"
-#include "MemBuf.h"
+#include "fde.h"
 #include "http.h"
-#include "auth/UserRequest.h"
-#include "Store.h"
-#include "HttpReply.h"
-#include "HttpRequest.h"
-#include "MemObject.h"
 #include "HttpHdrContRange.h"
 #include "HttpHdrSc.h"
 #include "HttpHdrScTarget.h"
-#include "acl/FilledChecklist.h"
-#include "fde.h"
-#if DELAY_POOLS
-#include "DelayPools.h"
-#endif
+#include "HttpReply.h"
+#include "HttpRequest.h"
+#include "MemBuf.h"
+#include "MemObject.h"
+#include "protos.h"
 #include "SquidTime.h"
+#include "Store.h"
 #include "TextException.h"
 
+
 #define SQUID_ENTER_THROWING_CODE() try {
 #define SQUID_EXIT_THROWING_CODE(status) \
        status = true; \
@@ -1511,6 +1514,22 @@ httpFixupAuthentication(HttpRequest * request, HttpRequest * orig_request, const
        return;
     }
 
+    /* Kerberos login to peer */
+#if HAVE_KRB5 && HAVE_GSSAPI
+    if (strncmp(orig_request->peer_login, "NEGOTIATE",strlen("NEGOTIATE")) == 0) {
+        char *Token=NULL;
+        char *PrincipalName=NULL,*p;
+        if ((p=strchr(orig_request->peer_login,':')) != NULL ) {
+            PrincipalName=++p;
+        }
+        Token = peer_proxy_negotiate_auth(PrincipalName,request->peer_host);
+        if (Token) {
+            httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Negotiate %s",Token);
+        }
+        return;
+    }
+#endif /* HAVE_KRB5 && HAVE_GSSAPI */
+
     httpHeaderPutStrf(hdr_out, header, "Basic %s",
                      base64_encode(orig_request->peer_login));
     return;
@@ -1990,6 +2009,7 @@ HttpStateData::sendRequest()
     }
 
     mb.init();
+    request->peer_host=_peer?_peer->host:NULL;
     buildRequestPrefix(request, orig_request, entry, &mb, flags);
     debugs(11, 6, "httpSendRequest: FD " << fd << ":\n" << mb.buf);
     comm_write_mbuf(fd, &mb, requestSender);
diff --git a/src/peer_proxy_negotiate_auth.cc b/src/peer_proxy_negotiate_auth.cc
new file mode 100644 (file)
index 0000000..d1e2028
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * Author: Markus Moeller (markus_moeller at compuserve.com)
+ *
+ * Copyright (C) 2007 Markus Moeller. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * -----------------------------------------------------------------------------
+ */
+/*
+ * Hosted at http://sourceforge.net/projects/squidkerbauth
+ */
+
+#include <squid.h>
+
+#if HAVE_KRB5 && HAVE_GSSAPI
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if HAVE_PROFILE_H
+#include <profile.h>
+#endif                         /* HAVE_PROFILE_H */
+#if HAVE_KRB5_H
+#include <krb5.h>
+#elif HAVE_ET_COM_ERR_H
+#include <et/com_err.h>
+#endif                          /* HAVE_COM_ERR_H */
+#if HAVE_COM_ERR_H
+#include <com_err.h>
+#endif                         /* HAVE_COM_ERR_H */
+
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif                         /* HAVE_GSSAPI_H */
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif                         /* HAVE_GSSAPI_GSSAPI_EXT_H */
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif                         /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif                         /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+
+#ifndef gss_nt_service_name
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#endif
+
+#if !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERR_TEXT
+#define error_message(code) krb5_get_err_text(kparam.context,code)
+#elif  !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERROR_MESSAGE
+#define error_message(code) krb5_get_error_message(kparam.context,code)
+#elif !HAVE_ERROR_MESSAGE
+static char err_code[17];
+const char *KRB5_CALLCONV
+error_message(long code)
+{
+    snprintf(err_code,16,"%ld",code);
+    return err_code;
+}
+#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
+
+#if HAVE_NAS_KERBEROS
+#include <ibm_svc/krb5_svc.h>
+    const char *KRB5_CALLCONV error_message(long code)
+    {
+       char *msg = NULL;
+       krb5_svc_get_msg(code, &msg);
+       return msg;
+    }
+#endif
+
+/*
+ * Kerberos context and cache structure
+ * Caches authentication details to reduce
+ * number of authentication requests to kdc
+ */
+    static struct kstruct
+    {
+       krb5_context context;
+       krb5_ccache cc;
+    } kparam = {
+    NULL, NULL};
+
+/*
+ * krb5_create_cache creates a Kerberos file credential cache or a memory 
+ * credential cache if supported. The initial key for the principal 
+ * principal_name is extracted from the keytab keytab_filename.
+ *
+ * If keytab_filename is NULL the default will be used.
+ * If principal_name is NULL the first working entry of the keytab will be used.
+ */
+    int krb5_create_cache(char *keytab_filename, char *principal_name);
+
+/*
+ * krb5_cleanup clears used Keberos memory
+ */
+    void krb5_cleanup(void);
+
+/*
+ * check_gss_err checks for gssapi error codes, extracts the error message 
+ * and prints it.
+ */
+    int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+       const char *function);
+
+    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) {
+                       memcpy(buf + len, status_string.value,
+                           status_string.length);
+                       len += status_string.length;
+                   }
+                   gss_release_buffer(&min_stat, &status_string);
+                   break;
+               }
+               gss_release_buffer(&min_stat, &status_string);
+           }
+           if (sizeof(buf) > len + 2) {
+               strcpy(buf + len, ". ");
+               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) {
+                       memcpy(buf + len, status_string.value,
+                           status_string.length);
+                       len += status_string.length;
+                   }
+                   gss_release_buffer(&min_stat, &status_string);
+                   break;
+               }
+               gss_release_buffer(&min_stat, &status_string);
+           }
+           debugs(11, 5, HERE << function << "failed: " << buf);
+           return (1);
+       }
+       return (0);
+    }
+
+    void krb5_cleanup()
+    {
+       debugs(11, 5, HERE << "Cleanup kerberos context");
+       if (kparam.context) {
+           if (kparam.cc)
+               krb5_cc_destroy(kparam.context, kparam.cc);
+           kparam.cc = NULL;
+           krb5_free_context(kparam.context);
+           kparam.context = NULL;
+       }
+    }
+
+    int krb5_create_cache(char *kf, char *pn)
+    {
+
+#define KT_PATH_MAX 256
+#define MAX_RENEW_TIME "365d"
+#define DEFAULT_SKEW (krb5_deltat) 600
+
+       static char *keytab_filename = NULL, *principal_name = NULL;
+       static krb5_keytab keytab = 0;
+       static krb5_keytab_entry entry;
+       static krb5_kt_cursor cursor;
+       static krb5_creds *creds = NULL;
+#if HAVE_HEIMDAL_KERBEROS
+       static krb5_creds creds2;
+#endif
+       static krb5_principal principal = NULL;
+       static krb5_deltat skew;
+
+       krb5_get_init_creds_opt options;
+       krb5_error_code code = 0;
+       krb5_deltat rlife;
+#if HAVE_PROFILE_H && HAVE_KRB5_GET_PROFILE && HAVE_PROFILE_GET_INTEGER && HAVE_PROFILE_RELEASE 
+       profile_t profile;
+#endif
+#if HAVE_HEIMDAL_KERBEROS
+       krb5_kdc_flags flags;
+       krb5_realm *client_realm;
+#endif
+       char *mem_cache;
+
+      restart:
+/*
+ * Check if credentials need to be renewed
+ */
+       if (creds &&
+           (creds->times.endtime - time(0) > skew) &&
+           (creds->times.renew_till - time(0) > 2 * skew)) {
+           if (creds->times.endtime - time(0) < 2 * skew) {
+#if !HAVE_HEIMDAL_KERBEROS
+               /* renew ticket */
+               code =
+                   krb5_get_renewed_creds(kparam.context, creds, principal,
+                   kparam.cc, NULL);
+#else
+               /* renew ticket */
+               flags.i = 0;
+               flags.b.renewable = flags.b.renew = 1;
+
+               code =
+                   krb5_cc_get_principal(kparam.context, kparam.cc,
+                   &creds2.client);
+               if (code) {
+                   debugs(11, 5,
+                       HERE <<
+                       "Error while getting principal from credential cache : "
+                       << error_message(code));
+                   return (1);
+               }
+               client_realm = krb5_princ_realm(kparam.context, creds2.client);
+               code =
+                   krb5_make_principal(kparam.context, &creds2.server,
+                   *client_realm, KRB5_TGS_NAME, *client_realm, NULL);
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while getting krbtgt principal : " <<
+                       error_message(code));
+                   return (1);
+               }
+               code =
+                   krb5_get_kdc_cred(kparam.context, kparam.cc, flags, NULL,
+                   NULL, &creds2, &creds);
+               krb5_free_creds(kparam.context, &creds2);
+#endif
+               if (code) {
+                   if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) {
+                       krb5_free_creds(kparam.context, creds);
+                       creds = NULL;
+                       /* this can happen because of clock skew */
+                       goto restart;
+                   }
+                   debugs(11, 5,
+                       HERE << "Error while get credentials : " <<
+                       error_message(code));
+                   return (1);
+               }
+           }
+       } else {
+           /* reinit */
+           if (!kparam.context) {
+               code = krb5_init_context(&kparam.context);
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while initialising Kerberos library : "
+                       << error_message(code));
+                   return (1);
+               }
+           }
+#if HAVE_PROFILE_H && HAVE_KRB5_GET_PROFILE && HAVE_PROFILE_GET_INTEGER && HAVE_PROFILE_RELEASE 
+           code = krb5_get_profile(kparam.context, &profile);
+           if (code) {
+               if (profile)
+                   profile_release(profile);
+               debugs(11, 5,
+                   HERE << "Error while getting profile : " <<
+                   error_message(code));
+               return (1);
+           }
+           code =
+               profile_get_integer(profile, "libdefaults", "clockskew", 0,
+               5 * 60, &skew);
+           if (profile)
+               profile_release(profile);
+           if (code) {
+               debugs(11, 5,
+                   HERE << "Error while getting clockskew : " <<
+                   error_message(code));
+               return (1);
+           }
+#elif HAVE_KRB5_GET_MAX_TIME_SKEW && HAVE_HEIMDAL_KERBEROS
+           skew = krb5_get_max_time_skew(kparam.context);
+#elif HAVE_MAX_SKEW_IN_KRB5_CONTEXT && HAVE_HEIMDAL_KERBEROS
+           skew = kparam.context->max_skew;
+#else
+           skew = DEFAULT_SKEW;
+#endif
+
+           if (!kf) {
+               char buf[KT_PATH_MAX], *p;
+
+               krb5_kt_default_name(kparam.context, buf, KT_PATH_MAX);
+               p = strchr(buf, ':');
+               if (p)
+                   p++;
+               if (keytab_filename)
+                   xfree(keytab_filename);
+               keytab_filename = xstrdup(p ? p : buf);
+           } else {
+               keytab_filename = xstrdup(kf);
+           }
+
+           code = krb5_kt_resolve(kparam.context, keytab_filename, &keytab);
+           if (code) {
+               debugs(11, 5,
+                   HERE << "Error while resolving keytab filename " <<
+                   keytab_filename << " : " << error_message(code));
+               return (1);
+           }
+
+           if (!pn) {
+               code = krb5_kt_start_seq_get(kparam.context, keytab, &cursor);
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while starting keytab scan : " <<
+                       error_message(code));
+                   return (1);
+               }
+               code =
+                   krb5_kt_next_entry(kparam.context, keytab, &entry, &cursor);
+               krb5_copy_principal(kparam.context, entry.principal,
+                   &principal);
+               if (code && code != KRB5_KT_END) {
+                   debugs(11, 5,
+                       HERE << "Error while scanning keytab : " <<
+                       error_message(code));
+                   return (1);
+               }
+
+               code = krb5_kt_end_seq_get(kparam.context, keytab, &cursor);
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while ending keytab scan : " <<
+                       error_message(code));
+                   return (1);
+               }
+#if HAVE_HEIMDAL_KERBEROS || ( HAVE_KRB5_KT_FREE_ENTRY && HAVE_DECL_KRB5_KT_FREE_ENTRY)
+               code = krb5_kt_free_entry(kparam.context, &entry);
+#else
+               code = krb5_free_keytab_entry_contents(kparam.context, &entry);
+#endif
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while freeing keytab entry : " <<
+                       error_message(code));
+                   return (1);
+               }
+
+           } else {
+               principal_name = xstrdup(pn);
+           }
+
+           if (!principal) {
+               code =
+                   krb5_parse_name(kparam.context, principal_name, &principal);
+               if (code) {
+                   debugs(11, 5,
+                       HERE << "Error while parsing principal name " <<
+                       principal_name << " : " << error_message(code));
+                   return (1);
+               }
+           }
+
+           creds = (krb5_creds *) xmalloc(sizeof(*creds));
+           memset(creds, 0, sizeof(*creds));
+           krb5_get_init_creds_opt_init(&options);
+           code = krb5_string_to_deltat((char *) MAX_RENEW_TIME, &rlife);
+           if (code != 0 || rlife == 0) {
+               debugs(11, 5,
+                   HERE << "Error bad lifetime value " << MAX_RENEW_TIME <<
+                   " : " << error_message(code));
+               return (1);
+           }
+           krb5_get_init_creds_opt_set_renew_life(&options, rlife);
+
+           code =
+               krb5_get_init_creds_keytab(kparam.context, creds, principal,
+               keytab, 0, NULL, &options);
+           if (code) {
+               debugs(11, 5,
+                   HERE <<
+                   "Error while initializing credentials from keytab : " <<
+                   error_message(code));
+               return (1);
+           }
+#if !HAVE_KRB5_MEMORY_CACHE
+           mem_cache =
+               (char *) xmalloc(strlen("FILE:/tmp/peer_proxy_negotiate_auth_")
+               + 16);
+           snprintf(mem_cache,
+               strlen("FILE:/tmp/peer_proxy_negotiate_auth_") + 16,
+               "FILE:/tmp/peer_proxy_negotiate_auth_%d", (int) getpid());
+#else
+           mem_cache =
+               (char *) xmalloc(strlen("MEMORY:peer_proxy_negotiate_auth_") +
+               16);
+           snprintf(mem_cache,
+               strlen("MEMORY:peer_proxy_negotiate_auth_") + 16,
+               "MEMORY:peer_proxy_negotiate_auth_%d", (int) getpid());
+#endif
+
+           setenv("KRB5CCNAME", mem_cache, 1);
+           code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc);
+           if (mem_cache)
+               xfree(mem_cache);
+           if (code) {
+               debugs(11, 5,
+                   HERE << "Error while resolving memory credential cache : "
+                   << error_message(code));
+               return (1);
+           }
+           code = krb5_cc_initialize(kparam.context, kparam.cc, principal);
+           if (code) {
+               debugs(11, 5,
+                   HERE <<
+                   "Error while initializing memory credential cache : " <<
+                   error_message(code));
+               return (1);
+           }
+           code = krb5_cc_store_cred(kparam.context, kparam.cc, creds);
+           if (code) {
+               debugs(11, 5,
+                   HERE << "Error while storing credentials : " <<
+                   error_message(code));
+               return (1);
+           }
+
+           if (!creds->times.starttime)
+               creds->times.starttime = creds->times.authtime;
+       }
+       return (0);
+    }
+
+/*
+ * peer_proxy_negotiate_auth gets a GSSAPI token for principal_name
+ * and base64 encodes it.
+ */
+    char *peer_proxy_negotiate_auth(char *principal_name, char *proxy)
+    {
+       int rc = 0;
+       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 (!proxy) {
+           debugs(11, 5, HERE << "Error : No proxy server name");
+           return NULL;
+       }
+
+       if (principal_name)
+           debugs(11, 5,
+               HERE << "Creating credential cache for " << principal_name);
+       else
+           debugs(11, 5, HERE << "Creating credential cache");
+       rc = krb5_create_cache(NULL, principal_name);
+       if (rc) {
+           debugs(11, 5, HERE << "Error : Failed to create Kerberos cache");
+           krb5_cleanup();
+           return NULL;
+       }
+
+       service.value = (void *) xmalloc(strlen("HTTP") + strlen(proxy) + 2);
+       snprintf((char *) service.value, strlen("HTTP") + strlen(proxy) + 2,
+           "%s@%s", "HTTP", proxy);
+       service.length = strlen((char *) service.value);
+
+       debugs(11, 5, HERE << "Import gss name");
+       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;
+
+       debugs(11, 5, HERE << "Initialize gss security context");
+       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;
+
+       debugs(11, 5, HERE << "Got token with length " << output_token.length);
+       if (output_token.length) {
+
+           token =
+               (char *) base64_encode_bin((const char *) output_token.value,
+               output_token.length);
+       }
+
+
+      cleanup:
+       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;
+    }
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* HAVE_KRB5 && HAVE_GSSAPI */
index 459820d3bc0766cbb8620526a10e49fc2af91e85..46f5ba37392cf10230b172a5bf5353f6d6058920 100644 (file)
@@ -106,8 +106,6 @@ SQUIDCEXTERN void _db_set_syslog(const char *facility);
 SQUIDCEXTERN void _db_init(const char *logfile, const char *options);
 SQUIDCEXTERN void _db_rotate_log(void);
 
-SQUIDCEXTERN void _db_print(const char *,...) PRINTF_FORMAT_ARG1;
-
 /* packs, then prints an object using debugs() */
 SQUIDCEXTERN void debugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm);
 
@@ -797,4 +795,8 @@ class external_acl;
 
 #endif
 
+#if HAVE_KRB5 && HAVE_GSSAPI
+            /* upstream proxy authentication */
+            SQUIDCEXTERN char *peer_proxy_negotiate_auth(char *principal_name, char *proxy);
+#endif
 #endif /* SQUID_PROTOS_H */
index a6bab679f4142e72a0c06261b8877dcd8a52c9f8..8d74df00b92d28572b5f1d3c10b9971ee7b8a666 100644 (file)
@@ -745,6 +745,7 @@ tunnelPeerSelectComplete(FwdServer * fs, void *data)
 
     tunnelState->servers = fs;
     tunnelState->host = fs->_peer ? fs->_peer->host : xstrdup(request->GetHost());
+    request->peer_host = fs->_peer ? fs->_peer->host : NULL;
 
     if (fs->_peer == NULL) {
         tunnelState->port = request->port;
index 68f2b2b3ab1089da5763fd18f9f2b71fc1ae5cf4..8aaf47b476cdec1af8c3dbf05b99f66fd6129fcc 100755 (executable)
@@ -90,7 +90,7 @@ buildtest() {
            echo "Build OK. Global result is $globalResult."
        fi
     else
-        if test "${verbose}" = "yes" ; then
+        if test "${verbose}" != "yes" ; then
             echo "Build Failed. Last log lines are:"
             tail -20 ${log}
         else
index 07ab7b0b1c95590aac6054331ff6a26770974111..076ae0666f79f14726d2cc89c38eff1683235c86 100644 (file)
@@ -76,6 +76,7 @@ OPTS=" \
        --disable-digest-auth-helpers \
        --disable-ntlm-fail-open \
        --disable-external-acl-helpers \
+       --disable-url-rewrite-helpers \
        --disable-mempools \
        --disable-win32-service \
        --disable-unlinkd \
index e85113e0bd0750ec8a055a31f3e12dd4a8f81292..3653230c95d204eadfc02b7a16c1dbb4cd46e50c 100644 (file)
@@ -86,6 +86,7 @@ OPTS=" \
        --enable-digest-auth-helpers=all \
        --enable-ntlm-fail-open \
        --enable-external-acl-helpers=all \
+       --enable-url-rewrite-helpers=all \
        --enable-mempools \
        --enable-unlinkd \
        --enable-stacktraces \
index d36e9935c7e73c9b517417e9c5761f925beb3129..c868acf1cb9e77dfc83a0d6af81bc81710e158b4 100644 (file)
@@ -146,17 +146,6 @@ typedef struct {
     char *pub_auth;
 } cachemgr_request;
 
-/*
- * Debugging macros (info goes to error_log on your web server)
- * Note: do not run cache manager with non zero debugging level
- *       if you do not debug, it may write a lot of [sensitive]
- *       information to your error log.
- */
-
-/* debugging level 0 (disabled) - 3 (max) */
-#define DEBUG_LEVEL 0
-#define debug(level) if ((level) <= DEBUG_LEVEL && DEBUG_LEVEL > 0)
-
 /*
  * Static variables and constants
  */
@@ -871,9 +860,9 @@ process_request(cachemgr_request * req)
                  req->action,
                  make_auth_header(req));
     if (write(s, buf, l) < 0) {
-        debug(1) fprintf(stderr, "ERROR: (%d) writing request: '%s'\n", errno, buf);
+        fprintf(stderr,"ERROR: (%d) writing request: '%s'\n", errno, buf);
     } else {
-        debug(1) fprintf(stderr, "wrote request: '%s'\n", buf);
+        debug("wrote request: '%s'\n", buf);
     }
     return read_reply(s, req);
 }
@@ -906,6 +895,31 @@ main(int argc, char *argv[])
     if ((s = getenv("SCRIPT_NAME")) != NULL)
         script_name = xstrdup(s);
 
+   char **args = argv;
+   while (argc > 1 && args[1][0] == '-') {
+//        const char *value = "";
+        char option = args[1][1];
+        switch (option) {
+        case 'd':
+            debug_enabled = 1;
+            break;
+        default:
+#if 0 // unused for now.
+            if (strlen(args[1]) > 2) {
+                value = args[1] + 2;
+            } else if (argc > 2) {
+                value = args[2];
+                args++;
+                argc--;
+            } else
+                value = "";
+#endif
+            break;
+        }
+        args++;
+        argc--;
+    }
+
     req = read_request();
 
     return process_request(req);
@@ -1019,7 +1033,7 @@ read_request(void)
     }
 
     make_pub_auth(req);
-    debug(1) fprintf(stderr, "cmgr: got req: host: '%s' port: %d uname: '%s' passwd: '%s' auth: '%s' oper: '%s'\n",
+    debug("cmgr: got req: host: '%s' port: %d uname: '%s' passwd: '%s' auth: '%s' oper: '%s'\n",
                      safe_str(req->hostname), req->port, safe_str(req->user_name), safe_str(req->passwd), safe_str(req->pub_auth), safe_str(req->action));
     return req;
 }
@@ -1036,7 +1050,7 @@ make_pub_auth(cachemgr_request * req)
 {
     static char buf[1024];
     safe_free(req->pub_auth);
-    debug(3) fprintf(stderr, "cmgr: encoding for pub...\n");
+    debug("cmgr: encoding for pub...\n");
 
     if (!req->passwd || !strlen(req->passwd))
         return;
@@ -1048,9 +1062,8 @@ make_pub_auth(cachemgr_request * req)
              req->user_name ? req->user_name : "",
              req->passwd);
 
-    debug(3) fprintf(stderr, "cmgr: pre-encoded for pub: %s\n", buf);
-
-    debug(3) fprintf(stderr, "cmgr: encoded: '%s'\n", base64_encode(buf));
+    debug("cmgr: pre-encoded for pub: %s\n", buf);
+    debug("cmgr: encoded: '%s'\n", base64_encode(buf));
 
     req->pub_auth = xstrdup(base64_encode(buf));
 }
@@ -1064,7 +1077,7 @@ decode_pub_auth(cachemgr_request * req)
     const char *user_name;
     const char *passwd;
 
-    debug(2) fprintf(stderr, "cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth));
+    debug("cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth));
     safe_free(req->passwd);
 
     if (!req->pub_auth || strlen(req->pub_auth) < 4 + strlen(safe_str(req->hostname)))
@@ -1072,28 +1085,28 @@ decode_pub_auth(cachemgr_request * req)
 
     buf = xstrdup(base64_decode(req->pub_auth));
 
-    debug(3) fprintf(stderr, "cmgr: length ok\n");
+    debug("cmgr: length ok\n");
 
     /* parse ( a lot of memory leaks, but that is cachemgr style :) */
     if ((host_name = strtok(buf, "|")) == NULL)
         return;
 
-    debug(3) fprintf(stderr, "cmgr: decoded host: '%s'\n", host_name);
+    debug("cmgr: decoded host: '%s'\n", host_name);
 
     if ((time_str = strtok(NULL, "|")) == NULL)
         return;
 
-    debug(3) fprintf(stderr, "cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);
+    debug("cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);
 
     if ((user_name = strtok(NULL, "|")) == NULL)
         return;
 
-    debug(3) fprintf(stderr, "cmgr: decoded uname: '%s'\n", user_name);
+    debug("cmgr: decoded uname: '%s'\n", user_name);
 
     if ((passwd = strtok(NULL, "|")) == NULL)
         return;
 
-    debug(2) fprintf(stderr, "cmgr: decoded passwd: '%s'\n", passwd);
+    debug("cmgr: decoded passwd: '%s'\n", passwd);
 
     /* verify freshness and validity */
     if (atoi(time_str) + passwd_ttl < now)
@@ -1102,7 +1115,7 @@ decode_pub_auth(cachemgr_request * req)
     if (strcasecmp(host_name, req->hostname))
         return;
 
-    debug(1) fprintf(stderr, "cmgr: verified auth. info.\n");
+    debug("cmgr: verified auth. info.\n");
 
     /* ok, accept */
     xfree(req->user_name);
index 999648cecd68bf93fa59475b24845acb37e7adbd..547dfe093de34ffc3e021c5f191adede1955e34c 100644 (file)
@@ -436,16 +436,16 @@ main(int argc, char *argv[])
         /* HTTP/1.0 may need keep-alive */
         if (strcmp(version, "1.0") == 0) {
             if (keep_alive) {
-                if (strchr(url, ':'))
+                if (strchr(url, ':')) {
                     snprintf(buf, BUFSIZ, "Proxy-Connection: keep-alive\r\n");
-                else
+                    strcat(msg, buf);
+                } else
                     strcat(msg, "Connection: keep-alive\r\n");
             }
         } else {
             if (!keep_alive)
                 strcat(msg, "Connection: close\r\n");
         }
-        strcat(msg, buf);
 
         strcat(msg, extra_hdrs);
         strcat(msg, "\r\n");