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.
- 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
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
assert.h \
compat.h \
compat_shared.h \
+ debug.h \
fdsetsize.h \
osdetect.h \
stdvarargs.h \
\
assert.cc \
compat.cc \
+ debug.cc \
GnuRegex.h \
GnuRegex.c
#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"
--- /dev/null
+#include "config.h"
+
+/* default off */
+int debug_enabled = 0;
--- /dev/null
+#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 */
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]) ,
AC_MSG_RESULT([$use_loadable_modules, implicitly])
]
)
-use_loadable_modules=0
AM_CONDITIONAL(USE_LOADABLE_MODULES, test $use_loadable_modules = yes)
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])
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
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
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
])
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
<!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>
<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">.
<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>
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 \
$(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
# 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
-SUBDIRS = basic_auth ntlm_auth digest_auth negotiate_auth external_acl
+SUBDIRS = basic_auth ntlm_auth digest_auth negotiate_auth external_acl url_rewrite
}
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");
use vars qw/ %opt /;
# Disable output buffering
-$|=1;
+$|=1;
sub debug {
print STDERR "@_\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
$ans = &check($user, $group);
last if $ans eq "OK";
}
- &debug ("Sending $ans to squid");
+ &debug("Sending $ans to squid");
print "$ans\n";
}
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) {
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) {
my_program_name, my_program_name);
}
-char debug_enabled=0;
+int debug_enabled=0;
void
process_options(int argc, char *argv[])
/************* 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");
--- /dev/null
+
+DIST_SUBDIRS = fake
+SUBDIRS = @URL_REWRITE_HELPERS@
--- /dev/null
+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
--- /dev/null
+#!/bin/sh
+exit 0
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#!/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
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
## 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 \
static FILE *wordFile = NULL;
char *t, *fn;
- LOCAL_ARRAY(char, buf, 256);
+ LOCAL_ARRAY(char, buf, CONFIG_LINE_LIMIT);
do {
}
/* fromFile */
- if (fgets(buf, 256, wordFile) == NULL) {
+ if (fgets(buf, CONFIG_LINE_LIMIT, wordFile) == NULL) {
/* stop reading from file */
fclose(wordFile);
wordFile = NULL;
#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.
* in all of squid by reference. Instead the tokeniser only is
* brought in.
*/
-
class ConfigParser
{
}
/* 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 */
/**
* 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();
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 */
pconn.h \
PeerDigest.h \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@SSLLIB@ \
@XTRA_LIBS@ \
@EPOLL_LIBS@ \
- @MINGW_LIBS@
+ @MINGW_LIBS@ \
+ @KRB5LIBS@
squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \
@DISK_LIBS@ \
@DISK_LINKOBJS@ \
#
endif
+## Kerberos libraries require their include path...
+INCLUDES += @KRB5INCS@
+
unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc
-L$(top_builddir)/lib -lmiscutil \
@XTRA_LIBS@ \
@EPOLL_LIBS@ \
- @MINGW_LIBS@
+ @MINGW_LIBS@
ufsdump_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \
$(COMMON_LIBS) \
@DISK_LIBS@ \
Parsing.cc \
pconn.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@ \
Parsing.cc \
pconn.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@ \
Parsing.cc \
pconn.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@ \
neighbors.cc \
Parsing.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@
Parsing.cc \
pconn.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@ \
Parsing.cc \
pconn.cc \
peer_digest.cc \
+ peer_proxy_negotiate_auth.cc \
peer_select.cc \
peer_sourcehash.cc \
peer_userhash.cc \
@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@ \
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;
}
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;
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
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
/* 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 << "'");
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 */
*/
#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; \
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;
}
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);
--- /dev/null
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * 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 */
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);
#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 */
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;
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
--disable-digest-auth-helpers \
--disable-ntlm-fail-open \
--disable-external-acl-helpers \
+ --disable-url-rewrite-helpers \
--disable-mempools \
--disable-win32-service \
--disable-unlinkd \
--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 \
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
*/
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);
}
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);
}
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;
}
{
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;
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));
}
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)))
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)
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);
/* 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");