dansguardian-2.10.1.1/0000777001165000116500000000000011212164550011374 500000000000000dansguardian-2.10.1.1/NEWS0000644001165000116500000000012111110523211011767 00000000000000For news go to http://dansguardian.org/ This file is required by the autotools. dansguardian-2.10.1.1/missing0000644001165000116500000002453311110523211012701 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2004-09-07.08 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit 0 ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit 0 ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: dansguardian-2.10.1.1/data/0000777001165000116500000000000011212164547012313 500000000000000dansguardian-2.10.1.1/data/scripts/0000777001165000116500000000000011212164547014002 500000000000000dansguardian-2.10.1.1/data/scripts/Makefile.in0000644001165000116500000003761111212164522015764 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ subdir = data/scripts DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/bsd-init.in $(srcdir)/dansguardian.in \ $(srcdir)/logrotation.in $(srcdir)/solaris-init.in \ $(srcdir)/systemv-init.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = bsd-init dansguardian logrotation solaris-init \ systemv-init SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in SUBDIRS = . DATATOPDIR = $(datadir)/$(PACKAGE_NAME)/scripts FLISTS = dansguardian logrotation bsd-init\ solaris-init systemv-init EXTRA_DIST = dansguardian.in logrotation.in bsd-init.in\ solaris-init.in systemv-init.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu data/scripts/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu data/scripts/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh bsd-init: $(top_builddir)/config.status $(srcdir)/bsd-init.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ dansguardian: $(top_builddir)/config.status $(srcdir)/dansguardian.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ logrotation: $(top_builddir)/config.status $(srcdir)/logrotation.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ solaris-init: $(top_builddir)/config.status $(srcdir)/solaris-init.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ systemv-init: $(top_builddir)/config.status $(srcdir)/systemv-init.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local install-data-local: $(mkinstalldirs) $(DESTDIR)$(DATATOPDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DATATOPDIR)/$$l ; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/data/scripts/bsd-init.in0000644001165000116500000000142311110523211015737 00000000000000#!/bin/sh # # BSD startup script for dansguardian # partly based on httpd startup script # # description: A web content filtering plugin for web \ # proxies, developed to filter using lists of \ # banned phrases, MIME types, filename \ # extensions and PICS labelling. # processname: dansguardian # See how we were called. case "$1" in start) [ -x @DGBINDIR@/dansguardian ] && @DGBINDIR@/dansguardian > /dev/null && echo -e ' dansguardian\c' ;; stop) @DGBINDIR@/dansguardian -q [ -r /tmp/.dguardianipc ] && echo -e ' dansguardian\c' rm -f /tmp/.dguardianipc ;; restart) $0 stop $0 start ;; *) echo "Usage: configure {start|stop|restart}" >&2 ;; esac exit 0 dansguardian-2.10.1.1/data/scripts/Makefile.am0000644001165000116500000000111611110523211015731 00000000000000MAINTAINERCLEANFILES = Makefile.in SUBDIRS= . DATATOPDIR = $(datadir)/$(PACKAGE_NAME)/scripts FLISTS = dansguardian logrotation bsd-init\ solaris-init systemv-init EXTRA_DIST = dansguardian.in logrotation.in bsd-init.in\ solaris-init.in systemv-init.in install-data-local: $(mkinstalldirs) $(DESTDIR)$(DATATOPDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DATATOPDIR)/$$l ; \ done dansguardian-2.10.1.1/data/scripts/solaris-init.in0000644001165000116500000000221511110523211016643 00000000000000#!/bin/sh # # Solaris startup script for dansguardian # partly based on httpd startup script # # description: A web content filtering plugin for web \ # proxies, developed to filter using lists of \ # banned phrases, MIME types, filename \ # extensions and PICS labelling. #ident "@(#)dansguardian @PACKAGE_VERSION@ 02/08/05 DB" # See how we were called. case "$1" in start) if [ -f @DGBINDIR@/dansguardian ] && [ -f @DGCONFDIR@/dansguardian.conf ]; then @DGBINDIR@/dansguardian echo "DansGuardian started." fi ;; stop) if [ -f @DGPIDDIR@/dansguardian.pid ]; then @DGBINDIR@/dansguardian -q /bin/rm -f @DGPIDDIR@/dansguardian.pid /bin/rm -f /tmp/.dguardianipc echo "DansGuardian stopped." fi ;; restart) $0 stop sleep 3 $0 start ;; status) if [ -f @DGBINDIR@/dansguardian ]; then @DGBINDIR@/dansguardian -s fi ;; *) echo "Usage: $0 {start|stop|restart}" >&2 ;; esac exit 0 dansguardian-2.10.1.1/data/scripts/systemv-init.in0000644001165000116500000000673011110523211016707 00000000000000#!/bin/sh # # Startup script for dansguardian # # chkconfig: 35 92 8 # description: A web content filtering plugin for web \ # proxies, developed to filter using lists of \ # banned phrases, MIME types, filename \ # extensions and PICS labelling. # processname: dansguardian # pidfile: @DGPIDDIR@/dansguardian.pid # config: @DGCONFDIR@/dansguardian.conf ### BEGIN INIT INFO # Provides: dansguardian # Required-Start: squid # Should-Start: # Required-Stop: squid # Should-Stop: # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: Dansguardian web content filter # Description: Dansguardian web content filter ### END INIT INFO # File includes changes by Thomas Jarosch function wait_for_pid() { local PID=$1 local RET=0 if [ $PID -eq 0 ] ; then return $RET fi # give 60 secs then KILL local COUNTDOWN=60 while [ -d /proc/${PID} ] && [ $COUNTDOWN -gt 0 ] ; do sleep 1 COUNTDOWN=$[$COUNTDOWN-1] done if [ -d /proc/${PID} ]; then COMMAND=`ps h -o command ${PID}` logger "dansguardian: timeout waiting for PID ${PID}: ${COMMAND}; sending SIGKILL" kill -KILL $PID >/dev/null 2>&1 RET=1 fi return $RET } # See how we were called. case "$1" in start) if [ -f @DGBINDIR@/dansguardian ] && [ -f @DGCONFDIR@/dansguardian.conf ]; then echo -n "Starting dansguardian: " if @DGBINDIR@/dansguardian 2> /dev/null; then echo -e "\\033[60G\c" echo -e "[ \\033[1;32m\c" echo -e "OK\c" echo -e "\\033[0;39m\c" echo " ]" [ -d /var/lock/subsys ] && touch /var/lock/subsys/dansguardian else echo -e "\\033[60G\c" echo -e "[ \\033[1;31m\c" echo -e "FAILED\c" echo -e "\\033[0;39m\c" echo " ]" fi fi ;; stop) echo -n "Shutting down dansguardian: " WAITPID=0 if [ -f @DGPIDDIR@/dansguardian.pid ] ; then WAITPID=`cat @DGPIDDIR@/dansguardian.pid` fi if @DGBINDIR@/dansguardian -q 2> /dev/null; then if wait_for_pid $WAITPID ; then echo -e "\\033[60G\c" echo -e "[ \\033[1;32m\c" echo -e "OK\c" echo -e "\\033[0;39m\c" echo " ]" else echo -e "\\033[60G\c" echo -e "[ \\033[1;31m\c" echo -e "FAILED\c" echo -e "\\033[0;39m\c" echo " ]" fi /bin/rm -f @DGPIDDIR@/dansguardian.pid /bin/rm -f /tmp/.dguardianipc [ -d /var/lock/subsys ] && /bin/rm -f /var/lock/subsys/dansguardian else echo -e "\\033[60G\c" echo -e "[ \\033[1;31m\c" echo -e "FAILED\c" echo -e "\\033[0;39m\c" echo " ]" fi ;; restart) $0 stop $0 start ;; status) if [ -f @DGBINDIR@/dansguardian ]; then @DGBINDIR@/dansguardian -s fi ;; *) echo "Usage: $0 {start|stop|restart|status}" >&2 ;; esac exit 0 dansguardian-2.10.1.1/data/scripts/logrotation.in0000644001165000116500000000073011110523211016567 00000000000000#!/bin/sh # DansGuardian logrotation script for version @PACKAGE_VERSION@ LOG_DIR=@DGLOGLOCATION@ NUM_LOGS=4 LOG=$LOG_DIR/access.log @DGBINDIR@/dansguardian -q # Keep a maximum of $NUM_LOGS logs around. if [ -f $LOG.$NUM_LOGS ]; then rm -f $LOG.$NUM_LOGS; fi n=$(( $NUM_LOGS - 1 )) while [ $n -gt 0 ]; do if [ -f $LOG.$n ]; then mv $LOG.$n $LOG.$(( $n + 1 )) fi n=$(( $n - 1 )) done if [ -f $LOG ]; then mv $LOG $LOG.1 fi sleep 5 @DGBINDIR@/dansguardian dansguardian-2.10.1.1/data/scripts/dansguardian.in0000644001165000116500000000031611110523211016666 00000000000000@DGLOGLOCATION@/access.log { rotate 4 weekly sharedscripts prerotate killall dansguardian > /dev/null sleep 5 endscript postrotate @DGBINDIR@/dansguardian > /dev/null endscript } dansguardian-2.10.1.1/data/Makefile.in0000644001165000116500000003603011212164522014267 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ subdir = data DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in SUBDIRS = languages . scripts DATATOPDIR = $(datadir)/$(PACKAGE_NAME) FLISTS = transparent1x1.gif dansguardian.pl EXTRA_DIST = $(FLISTS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu data/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu data/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local install-data-local: $(mkinstalldirs) $(DESTDIR)$(DATATOPDIR) && \ $(mkinstalldirs) $(DESTDIR)$(DGLOGLOCATION) && \ $(mkinstalldirs) $(DESTDIR)$(DGPIDDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DATATOPDIR)/$$l ; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/data/Makefile.am0000644001165000116500000000110011110523211014233 00000000000000MAINTAINERCLEANFILES = Makefile.in SUBDIRS= languages . scripts DATATOPDIR = $(datadir)/$(PACKAGE_NAME) FLISTS = transparent1x1.gif dansguardian.pl EXTRA_DIST = $(FLISTS) install-data-local: $(mkinstalldirs) $(DESTDIR)$(DATATOPDIR) && \ $(mkinstalldirs) $(DESTDIR)$(DGLOGLOCATION) && \ $(mkinstalldirs) $(DESTDIR)$(DGPIDDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DATATOPDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DATATOPDIR)/$$l ; \ done dansguardian-2.10.1.1/data/dansguardian.pl0000644001165000116500000000505711110523211015213 00000000000000#!/usr/bin/perl $allow_html_code = 0; &ReadEnvs; $deniedurl = $in{'DENIEDURL'}; $reason = $in{'REASON'}; $user = $in{'USER'}; $ip = $in{'IP'}; $cats = $in{'CATEGORIES'}; # originating hostname - can be undefined $host = $in{'HOST'}; # virus/filter bypass hashes # if bypass modes have been set to > 0, # then the GBYPASS or GIBYPASS variable will contain the filter/infection bypass hash. # if bypass modes have been set to -1, # then the HASH variable will be set to 1 if the CGI should generate a GBYPASS hash (filter bypass), # or 2 if the CGI should generate a GIBYPASS hash (infection bypass). $fbypasshash = $in{'GBYPASS'}; # filter bypass hash - can be undefined $ibypasshash = $in{'GIBYPASS'}; # infection bypass hash - can be undefined $hashflag = $in{'HASH'}; # hash flag - can be undefined; 1 = generate GBYPASS; 2 = generate GIBYPASS print "Content-type: text/html\n\n"; print 'DansGuardian - Access Denied'; print '

ACCESS HAS BEEN DENIED

'; if (length($user) > 0) { print "
$user, access to the page:

"; } else { print '
Access to the page:

'; } print "$deniedurl"; print '

... has been denied for the following reason:

'; print "$reason"; if (length($cats) > 0) { print '

Categories:

'; print "$cats"; } print '

Your username, IP address, date, time and URL have been logged.'; print '

You are seeing this error because the page you attempted
'; print 'to access contains, or is labelled as containing, material that'; print '
has been deemed inappropriate.
'; print '

If you have any queries contact your ICT Co-ordinator or Network Manager.
'; print '

Powered by DansGuardian'; print '

'; exit; sub ReadEnvs { local($cl, @clp, $pair, $name, $value); if ( $ENV{'REQUEST_METHOD'} eq 'POST' ) { read(STDIN, $cl, $ENV{'CONTENT_LENGTH'} ); } else { $cl = $ENV{'QUERY_STRING'}; } @clp = split(/::/, $cl); foreach $pair (@clp) { ($name, $value) = split(/==/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s///g; if ($allow_html_code != 1) { $value =~ s/<([^>]|\n)*>//g; } $in{$name} = $value; } } dansguardian-2.10.1.1/data/transparent1x1.gif0000644001165000116500000000006711110523211015574 00000000000000GIF89a!,ڋ>;dansguardian-2.10.1.1/data/languages/0000777001165000116500000000000011212164547014261 500000000000000dansguardian-2.10.1.1/data/languages/malay/0000777001165000116500000000000011212164547015364 500000000000000dansguardian-2.10.1.1/data/languages/malay/messages0000644001165000116500000000423411110523211017015 00000000000000# DansGuardian 2.8 messages file in Malay language # Edited by Sazarul Izam "1","Akses Tidak Dibenarkan" # Access Denied "100","IP anda tidak dibenarkan untuk melayari web: " "101","IP anda tidak dibenarkan untuk melayari web." "102","Nama pengguna anda tidak dibenarkan untuk melayari web: " "200","URL yang diminta adalah malformed." "300","Frasa larangan dikesan: " # Banned Phrase found: "301","Frasa larangan dikesan." # Banned phrase found. "400","Kombinasi frasa larangan dikesan: " # Banned combination phrase found: "401","Kombinasi frasa larangan dikesan." # Banned combination phrase found. "402","Had beban frasa oleh " # Weighted phrase limit of "403","Melebihi had beban frasa." # Weighted phrase limit exceeded. "500","Laman larangan: " # Banned site: "501","URL larangan: " # Banned URL: "502","Blok Blanket adalah aktif dan laman tersebut tidak tersenarai dalam white atau grey list." # Blanket Block is active and that site is not on the white or grey list. "503","URL Ekspresi Biasa larangan: " # Banned Regular Expression URL: "504","URL Ekspresi Biasa larangan dikesan." # Banned Regular Expression URL found. "505","Blok Blanket IP adalah aktif dan alamat tersebut hanyalah alamat IP." #Blanket IP Block is active and that address is an IP only address. "600","IP pengecualian klien sepadan." # Exception client IP match. "601","Pengguna pengecualian klien sepadan." # Exception client user match. "602","Laman pengecualian sepadan." # Exception site match. "603","URL pengecualian sepadan." # Exception URL match. "604","Frasa pengecualian sepadan: " # Exception phrase found: "605","Kombinasi frasa pengecualian sepadan: " # Combination exception phrase found: "606","URL pintasan sepadan." # Bypass URL exception. "607","Cookie pintasan sepadan." # Bypass cookie exception. "700","Muatnaik laman dilarang." # Web upload is banned. "701","Muatnaik laman melebihi had." # Web upload limit exceeded. "800","Jenis MIME larangan: " # Banned MIME Type: "900","Extension larangan: " # Banned extension: "1000","Penglabelan PICS melebihi peringkat pada laman di atas." # PICS labeling level exceeded on the above site. dansguardian-2.10.1.1/data/languages/malay/fancydmtemplate.html0000644001165000116500000001422611110523211021330 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/malay/template.html0000644001165000116500000000417511110523211017770 00000000000000DansGuardian - Akses Tidak Dibenarkan
D a n s G u a r d i a n   h a l a m a n   t i d a k   b a i k   b e r h e n t i   d i   s i n i
H A L A N G A N
Akses ke halaman berkenaan tidak dibenarkan

URL: -URL-
-REASONGIVEN-

Sila hubungi Pentadbir Rangkaian jika terdapat kesilapan berhubung perkara ini

Penapis Kandungan Web oleh DansGuardian
dansguardian-2.10.1.1/data/languages/japanese/0000777001165000116500000000000011212164547016047 500000000000000dansguardian-2.10.1.1/data/languages/japanese/messages0000644001165000116500000000676011110523211017506 00000000000000# DansGuardian messages file in 日本語 "1","アクセス拒否" "100","あなたのIPアドレスは閲覧の許可がありません: " "101","あなたのIPアドレスは閲覧の許可がありません。" "102","あなたのユーザ名は閲覧の許可がありません: " "200","要求されたURLは不適切です。" "300","禁止されたフレーズが見つかりました: " "301","禁止されたフレーズが見つかりました。" "400","拒否された結合フレーズが見つかりました: " "401","拒否された結合フレーズが見つかりました。" "402","重み付けされたフレーズの制限を越えました(規定値:測定値) " "403","重み付けされたフレーズの制限を越えました。" "500","拒否されたサイト: " "501","拒否されたURL: " "502","統括的な遮断は有効です。そしてそれらのサイトはホワイトリストかグレーリストにありません。" "503","拒否された正規表現のURL: " "504","拒否された正規表現のURLが見つかりました。" "505","統括的なIPの遮断は有効です。そしてそれらのアドレスはIPのみのアドレスです。" "506","統括的なSSLの遮断は有効です。そしてそれらのサイトはホワイトリストかグレーリストにありません。" "507","統括的なSSL IPの遮断は有効です。そしてそれらのアドレスはIPのみのアドレスです。" "600","例外クライアントIPマッチ。" "601","例外クライアントユーザマッチ。" "602","例外サイトマッチ。" "603","例外URLマッチ。" "604","例外フレーズが見つかりました: " "605","結合例外フレーズがみつかりました: " "606","例外迂回URL" "607","例外迂回Cookie。" "608","例外スキャン迂回URL" "609","例外正規表現URLマッチ: " "700","Webのアップロードは拒否されました。" "701","Webのアップロードは制限を越えました。" "750","統括的なファイルのダウンロードは有効です。そしてこのMIMEタイプはホワイトリストにありません: " "751","統括的なファイルのダウンロードは有効です。そしてこのファイルはホワイトリストにマッチしませんでした。" "800","拒否されたMIMEタイプ: " "900","拒否された拡張: " "1000","PICSラベリングレベルは上のサイトで超えました。" "1100","ウィルスか不正なコンテンツを検出しました。" "1101","広告は拒否されました" "1200","お待ちください。 - ダウンロードファイルのスキャン中です・・・" "1201","警告: ファイルはスキャンするのに大きすぎます。 このふぁいるが" "1202","より大きいと疑うならば直接ダウンロードするためにこのページをリフレッシュしてください。" "1210","ダウンロード完了。スキャンを開始します..." "1220","スキャンが完了しました。

ダウンロードをするにはここをクリックしてください: " "1221","ダウンロードは完了しました。ファイルはスキャンされませんでした。

ダウンロードをするにはここをクリックしてください: " "1222","ファイルはキャッシュするのに大きすぎます。

スキャンを迂回させて、再ダウンロードするためにここをクリックしてください: " "1230","ファイルは長いこと利用可能ではありません" dansguardian-2.10.1.1/data/languages/japanese/fancydmtemplate.html0000644001165000116500000001422611110523211022013 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/japanese/template.html0000644001165000116500000000305011110523211020442 00000000000000 Access Denied

アクセスは拒否されました。
-USER- 
www.shonbori.com アクセス先URL:

-URL-

は以下の理由により拒否されました。:

-REASONGIVEN-

カテゴリ:

-CATEGORIES-



不適切と思われるコンテンツがページ内に含まれている・含まれていると思われる場合に このエラーページが表示されます

何か質問がありましたら、以下に連絡してください。
webmaster@shonbori.com



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/ptbrazilian/0000777001165000116500000000000011212164547016600 500000000000000dansguardian-2.10.1.1/data/languages/ptbrazilian/messages0000644001165000116500000000414411110523211020231 00000000000000# DansGuardian 2.10 messages in Brazilian Portuguese # Mensagens do DansGuardian 2.10 file em Portugus do Brasil (pt-BR) # Translated/traduzido (?) by/por Henrique Araujo - Sys Admin # Updated/atualizado by/por Allan Cassaro Gomes # henrique@colegiosaogoncalo.g12.br / allan.cassaro@gmail.com # Cuiab - MT, Brasil / Brasilia - DF, Brasil "1","Acesso negado." "100","Seu endereo IP no tem permisso de acesso web: " "101","Seu endereo IP no tem permisso de acesso web: " "102","Esse nome de usurio no tem permisso de acesso web: " "200","A URL requerida est mal formada." "300","Encontrada frase proibida: " "301","Encontrada frase proibida: " "400","Encontrada combinao de frases proibida: " "401","Encontrada combinao de frases proibida: " "402","Limite de frase ponderada de " "403","Limite de frase ponderada excedido." "500","Stio proibido: " "501","URL proibida: " "502","Bloqueio geral est ativo e aquele stio no est na lista livre." "503","Expresso Regular proibida em URL: " "504","Encontrada Expresso Regular proibida em URL: " "505","Bloqueio geral de IP est ativo e aquele endereo no possui nome." "600","Cliente IP est na lista de excees." "601","Usurio est na lista de excees." "602","Stio est na lista de excees." "603","URL est na lista de excees." "604","Encontrada frase na lista de excees: " "605","Encontrada combinao de frases na lista de excees: " "606","Desvio temporrio de bloqueio (Bypass URL.)" "607","Desvio temporrio de bloqueio (Bypass cookie.)" "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Transferncia de arquivos para web proibida." "701","Limite de transferncia de arquivos para web excedido." "800","Tipo MIME proibido: " "900","Extenso proibida: " "1000","Nvel de rotulagem PICS excedido no stio acima." "1100","Vrus ou contedo perigoso encontrado." "1101","Advert blocked" "1200","Por favor espere - O download ser verificado..." "1210","Download Completo. Iniciando a verificao..." "1220","Verificao completa.

Clique aqui para baixar: " "1230","O arquivo no est mais disponvel" dansguardian-2.10.1.1/data/languages/ptbrazilian/fancydmtemplate.html0000644001165000116500000001422611110523211022544 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/ptbrazilian/template.html0000644001165000116500000000437611110523211021207 00000000000000 DansGuardian - Access Denied

Access has been Denied!
-USER- 
YOUR ORG NAME Access to the page:

-URL-

... has been denied for the following reason:

-REASONGIVEN-

Categories:

-CATEGORIES-



You are seeing this error because what you attempted to access appears to contain, or is labeled as containing, material that has been deemed inappropriate.

If you have any queries contact your ICT Co-ordinator or Network Manager.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/slovak/0000777001165000116500000000000011212164547015560 500000000000000dansguardian-2.10.1.1/data/languages/slovak/messages0000644001165000116500000000331011110523211017203 00000000000000# DansGuardian messages file in Slovak # by Duan Birok biroscak@gmail.com "1","Prstup zamietnut" "100","Vaej IP adrese neni povolen prehliada: " "101","Vaa IP adresa nem povolen prohliadanie." "102","Vae uvatesk meno nem povolen prohliada: " "200","Poadovan URL je patne zadan." "300","Njden zakzan frza: " "301","Njdena zakzan frza." "400","Njden zakzan kombinacia frz: " "401","Najden zakzan kombinacia frz." "402","Limit vench frz: " "403","Bol prekroen limit pre ven frzy." "500","Zakzan webov sdlo: " "501","Zakzan URL adresa: " "502","Celoplon blokovnie prstupu je aktivovan a toto webov sdlo neni povolen." "503","Njdena zakzan URL adresa poda regularneho vrazu: " "504","Njdena zakzan URL adresa poda regularneho vrazu." "505","Celoplon blokovanie IP adries je aktivovan a bola zadna IP adresa." "600","Njden vnmkov IP adresa." "601","Njden vnimkov uvate." "602","Njden vnimkov webov sdlo." "603","Njden vnimkov URL adresa." "604","Njden vnimkov frza: " "605","Njden kombinacia vnimkovch frz: " "606","Nahradi vnimku URL." "607","Nahradi cookie vnimku." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Web upload je zakzan." "701","Web upload limit bol prekroen." "800","Zakzan obsah sboru: " "900","Zakzan prpona sboru: " "1000","roven PICS oznaenia bola prekroen na tomto webovm sdle." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/slovak/fancydmtemplate.html0000644001165000116500000001422611110523211021524 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/slovak/template.html0000644001165000116500000000300211110523211020150 00000000000000DansGuardian - Prstup zakzan

PRSTUP ZAKZAN -USER-


Prstup na tuto strnku:

-URL-

... bol zakzan z dvodu:

-REASONGIVEN-

Zobrazenie tohoto chybovho hlsenia spsobila strnka,
na ktoru ste se pokusil(a) pristpi a obsahuje alebo je oznaena ako obsahujca
nepatrin materil.

Ak mte nejak otzky, obrte se prosm na vaeho sprvcu siete i osobu poveren sprvou siete.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/french/0000777001165000116500000000000011212164547015526 500000000000000dansguardian-2.10.1.1/data/languages/french/messages0000644001165000116500000000355311110523211017162 00000000000000# DansGuardian messages file in French # Translated by: Bernard Wanadoo and Jacques Theys # Improvements by Jeanuel "1","Acces interdit" "100","Votre addresse IP n'est pas autoris&ecute;e à afficher le site: " "101","Votre addresse IP n'est pas autoris&ecute;e à naviguer sur le WEB." "102","Votre compte utilisateur n'est pas autoris&ecute; à afficher le site: " "200","L'URL demandee n'est pas bien form&ecute;e." "300","Phrase interdite: " "301","Phrase interdite trouv&ecute;e." "400","Combinaison interdite de mots: " "401","Combinaison interdite de mots trouv&ecute;e." "402","Limite de pond&ecute;ration " "403","Limite de pondération dépassée." "500","Site interdit: " "501","URL interdite: " "502","Blanket Block est actif et ce site n'est pas dans la liste autoris&ecute;e." "503","Cette URL comprend des mots prohib&ecute;s: " "504","L'URL comprend des mots prohib&ecute;s." "505","Blanket IP Block est actif et cette addresse est une adresse IP uniquement." "600","Adresse IP interdite trouv&ecute;e." "601","Client interdit trouv&ecute;." "602","Site interdit trouv&ecute;." "603","URL interdite trouv&ecute;e." "604","Phrase interdite trouv&ecute;e: " "605","Combinaison de mots interdits trouv&ecute;e: " "606","URL sans controle trouv&ecute;e." "607","Cookie sans controle trouv&ecute;." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","L'upload WEB est interdit." "701","D&ecute;passement de limite d'upload Web." "800","Type MIME interdit: " "900","Type de fichier interdit: " "1000","Niveau PICS depass&ecute; sur le site entier." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/french/fancydmtemplate.html0000644001165000116500000001422611110523211021472 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/french/template.html0000644001165000116500000000347711110523211020136 00000000000000DansGuardian - Access Denied

L'ACCES EST INTERDIT-UTLISATEUR-


L'accès à la page:

-URL-

... est interdit pour les raisons suivantes:

-REASONGIVEN-

Vous voyez ce message parce que vous tentez d'accéder à une page qui contient, ou est réputée contenir des choses qui ont été déclarées inappropriées.

 

Si vous avez des questions, ou si vous pensez que la page ne devrait pas poser de problèmes, contactez votre administrateur réseau

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/spanish/0000777001165000116500000000000011212164547015726 500000000000000dansguardian-2.10.1.1/data/languages/spanish/messages0000644001165000116500000000364011110523211017357 00000000000000# DansGuardian 2.10 messages file in Spanish # Translated by Roberto Quiroga, adapted for Unicode by Peter Vollmar "1","Acceso Denegado" "100","Su dirección IP no está autorizada a visitar: " "101","Su dirección IP no está autorizada a navegar." "102","El usuario no está autorizado a visitar: " "200","La URL solicitada está mal formada." "300","Se encontró la frase no permitida: " "301","Se encontró una frase no permitida" "400","Combinación de frases no permitida: " "401","Combinación de frases no permitida." "402","Límite de ponderación de frases de " "403","Límite de ponderación de frases excedido" "500","Sitio no permitido: " "501","URL no permitida: " "502","Bloqueo general de IP está activo y el sitio deseado no está en la lista de IPs permitidas." "503","URL bloqueada por expresión regular: " "504","URL bloqueada por expresión regular." "505","Bloqueo general de IP está activo y la dirección deseada consiste únicamente en IP." "600","Dirección IP del cliente presente en la lista de excepciones." "601","Usuario presente en la lista de excepciones." "602","Sitio presente en la lista de excepciones." "603","URL presente en la lista de excepciones." "604","Frase presente en la lista de excepciones." "605","Combinación de frases presente en la lista de excepciones: " "606","Puente URL en la lista de excepciones." "607","Puente cookie en la lista de excepciones." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","La subida está bloqueada." "701","Límite de subida excedido." "800","Clase MIME bloqueada: " "900","Extensión bloqueada: " "1000","Clasificación PICS excedida en el sitio indicado." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/spanish/fancydmtemplate.html0000644001165000116500000001422611110523211021672 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/spanish/template.html0000644001165000116500000000441111110523211020323 00000000000000 DansGuardian Acceso denegado

Acceso denegado!
-USER- 
SU COMPANIA El acceso a la página web

-URL-

ha sido denegado por la siguiente razón:

-REASONGIVEN-



Usted está viendo este mensaje de error porque la página a la que
intenta acceder contiene, o está clasificada como conteniendo,
material que se considera inapropiado.

Si tiene preguntas, por favor póngase en contacto
con el Administrador de Sistemas o el Administrador de la Red.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/dutch/0000777001165000116500000000000011212164547015370 500000000000000dansguardian-2.10.1.1/data/languages/dutch/messages0000644001165000116500000000475111110523211017025 00000000000000# DansGuardian berichten in het Nederlands # Door S.A. de Heer # Updates door Eric Hameleers "1","Toegang geweigerd" "100","Uw IP adres mag niet websurfen: " "101","Uw IP adres mag niet websurfen." "102","Uw gebruikersnaam mag niet websurfen: " "200","De gevraagde URL is syntactisch incorrect." "300","Geblokkeerd woord gevonden: " "301","Geblokkeerd woord gevonden." "400","Geblokkerde combinatie van woorden gevonden: " "401","Geblokkerde combinatie van woorden gevonden." "402","Gewogen woorden limiet van: " "403","Gewogen woorden limiet overschreden." "500","Geblokkeerde website: " "501","Geblokkeerde URL: " "502","Web blokkade is actief en deze website is niet in de toegangslijst." "503","Geblokkeerde reguliere expressie in de URL: " "504","Geblokkeerde reguliere expressie in de URL gevonden." "505","IP adressen zijn geblokkeerd en dat adres is enkel een IP adres." "506","SSL is geblokkeerd en deze website komt niet voor op de toegangslijsten." "507","SSL IP adressen zijn geblokkeerd en dat adres is enkel een IP addres." "600","Uitzonderings IP adres gevonden." "601","Uitzonderings gebruiker gevonden." "602","Uitzonderings website gevonden." "603","Uitzonderings URL gevonden." "604","Uitzonderings woord gevonden: " "605","Uitzonderings combinatie van woorden gevonden: " "606","URL omzeiling uitzondering." "607","Cookie omzeiling uitzondering." "608","Scan omzeiling URL uitzondering." "609","Uitzondering reguliere expressie URL gevonden: " "700","Uploaden via het web is geblokkerd." "701","Web upload limiet overschreden." "750","Bestands-download is geblokkeerd en dit MIME type komt niet voor op de goedkeuringslijst: " "751","Bestands-download is geblokkeerd en dit bestand komt niet voor op de goedkeuringslijsten: " "800","Geblokkeerd MIME Type: " "900","Geblokkeerd bestandstype: " "1000","'PICS labeling' niveau overschrijding op bovenvermelde site." "1100","Virus of onbetamelijke inhoud ontdekt." "1101","Advertentie geblokkeerd." "1200","Geduld a.u.b. - bezig met downloaden om te scannen..." "1201","Waarschuwing: bestand te groot om te scannen. Vermoedt u dat dit bestand groter is dan " "1202",", ververs dan deze pagina om direct te downloaden." "1210","Download Compleet. Scan wordt gestart..." "1220","Scan compleet.

Klik hier om te downloaden: " "1221","Download compleet; bestand niet gescand.

Klik hier om te downloaden: " "1222","Bestand te groot voor tussenopslag.

Klik hier om opnieuw te downloaden zonder scan: " "1230","Bestand niet langer beschikbaar" dansguardian-2.10.1.1/data/languages/dutch/fancydmtemplate.html0000644001165000116500000001422611110523211021334 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/dutch/template.html0000644001165000116500000000512111110523211017764 00000000000000 DansGuardian - toegang geweigerd

De toegang werd geweigerd!!
-USER- 
YOUR ORG NAME Toegang tot de pagina:

-URL-

... werd geweigerd om de volgende reden:

-REASONGIVEN-

Categorieën:

-CATEGORIES-



U ziet deze melding omdat de pagina die u probeerde te benaderen, materiaal lijkt te bevatten dat ongeschikt is om te bekijken, of gemarkeerd is als ongeschikt om te bekijken.

Als u hier vragen over heeft neem dan contact op met uw netwerkbeheerder.



Verzorgd door DansGuardian
dansguardian-2.10.1.1/data/languages/polish/0000777001165000116500000000000011212164547015557 500000000000000dansguardian-2.10.1.1/data/languages/polish/messages0000644001165000116500000000357711110523211017221 00000000000000# DansGuardian messages file # Polish version by Piotr Kapczuk # charset=iso-8859-2 "1","Dostp Zabroniony" "100","Zakazano dostpu z twojego adresu IP do strony: " "101","Przegldanie stron www z twojego adresu IP jest niedozwolone." "102","Zakazano dostpu z twoj nazw uytkownika do strony: " "200","dany URL jest le skonstruowany." "300","Znaleziono zakazan fraz: " "301","Znaleziono zakazan fraz." "400","Znaleziono zakazan kombinacj fraz: " "401","Znaleziono zakazan kombinacj fraz." "402","Limit fraz liczonych wagowo " "403","Przekroczono limit fraz liczonych wagowo." "500","Zakazany adres (site): " "501","Zakazany URL: " "502","Dostp zezwolony jedynie do wybranych stron, a ta strona nie jest na licie dozwolonych." "503","Zakazane Wyraenie Regularne dla URL: " "504","Znaleziono zakazane Wyraenie Regularne w URL." "505","Dostp po samych adresach IP jest zakazany, a ten adres jest jedynie adresem IP." "600","IP klienta pasuje do wyjtkw." "601","Nazwa uytkownika pasuje do wyjtkw." "602","Adres pasuje do wyjtkw." "603","URL pasuje do wyjtkw." "604","Znaleziono fraz, ktra pasuje do wyjtkw: " "605","Znaleziono kombinacj fraz, ktra pasuje do wyjtkw: " "606","Bypass URL wyjtkw." "607","Bypass cookie wyjtkw." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","Wgrywanie do sieci jest zakazane." "701","Przekroczono limit wgrywanych danych." "800","Zakazany typ MIME: " "900","Zakazane rozszerzenie: " "1000","Wedle etykietowania PICS przekroczono dopuszczalny poziom zakazanych treci." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/polish/fancydmtemplate.html0000644001165000116500000001422611110523211021523 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/polish/template.html0000644001165000116500000000317311110523211020160 00000000000000DansGuardian - Dostp Zabroniony

ZABRONIONO DOSTPU -USER-


Dostp do strony:

-URL-

... zosta zabroniony z nastpujcego powodu:

-REASONGIVEN-

Ten bd pojawia si, poniewa strona, do ktrej prbowano uzyska dostp,
zawiera lub te jest oznakowana jako zawierajca treci uznane za nieodpowiednie.

Jeli masz jakie pytania lub wtpliwoci skontaktuj si ze swoim Administratorem Sieci

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/german/0000777001165000116500000000000011212164547015532 500000000000000dansguardian-2.10.1.1/data/languages/german/messages0000644001165000116500000000356211110523211017166 00000000000000# DansGuardian 2.10 messages file in German # # Translated and adapted to Unicode by Peter Vollmar "1","Zugriff verweigert" "100","Ihre Arbeitsstation hat keine Erlaubnis zum Surfen auf: " "101","Ihre Arbeitsstation hat keine Erlaubnis zum Surfen" "102","Ihr Benutzername hat keine Erlaubnis zum Surfen auf: " "200","Die angeforderte URL ist ungültig" "300","Verbotener Ausdruck gefunden: " "301","Verbotener Ausdruck gefunden" "400","Verbotene Kombination von Ausdrücken gefunden: " "401","Verbotene Kombination von Ausdrücken gefunden" "402","Gewichtete Ausdrucksbeschränkung von " "403","Gewichtete Ausdrucksbeschränkung überschritten" "500","Verbotene Seite: " "501","Verbotene URL: " "502","Totalsperre für Nur-IP-Adressen aktiv, diese Seite ist nicht auf der Erlaubt-Liste" "503","Aufgrund von regulären Ausdrücken verbotene URL: " "504","Aufgrund von regulären Ausdrücken verbotene URL gefunden" "505","Totalsperre für IP-Adressen aktiv, diese Adresse ist nur eine IP." "600","Übereinstimmung mit Client-IP in Ausnahmeliste" "601","Übereinstimmung mit Client-Benutzer in Ausnahmeliste" "602","Übereinstimmung mit Seite in Ausnahmeliste" "603","Übereinstimmung mit URL in Ausnahmeliste" "604","Ausnahme-Ausdruck gefunden: " "605","Kombination von Ausnahme-Ausdrücken gefunden: " "606","Umgehungs-URL gefunden" "607","Umgehungs-Cookie gefunden" "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Web-Upload verboten" "701","Web-Upload-Schwellwert erreicht" "800","Verbotener MIME-Typ: " "900","Verbotene Datei-Erweiterung: " "1000","PICS-Kennzeichnungsschwellwert überschritten" "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/german/fancydmtemplate.html0000644001165000116500000001422611110523211021476 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/german/template.html0000644001165000116500000000423411110523211020132 00000000000000 DansGuardian - Zugriff verweigert

Zugriff verweigert!
-USER- 
IHRE FIRMA Der Zugriff auf die Seite

-URL-

wurde mit folgender Begründung verweigert:

-REASONLOGGED-



Sie sehen diese Fehlermeldung, weil die von Ihnen gewünschte Seite unangebrachte Inhalte aufweist oder als solche gekennzeichnet ist.

Bei Fragen oder Beschwerden wenden Sie sich bitte an Ihren Netzwerkadministrator.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/turkish/0000777001165000116500000000000011212164547015752 500000000000000dansguardian-2.10.1.1/data/languages/turkish/messages0000644001165000116500000000361411110523211017404 00000000000000# DansGuardian messages file in Turkish # Translation by Ozgur Karatas # trdocmaster at dansguardian dot org "1","Erisim Engellendi" "100","Bu IP adresi ile internete erisim engellenmistir: " "101","Bu IP ile internete erisim engellenmistir." "102","Bu kullanici adi ile internete erisim engellenmistir.: " "200","Gitmek istediginiz URL hatalidir." "300","Yasaklanmis bir ifade iceren sayfaya girmeye calisiyorsunuz: " "301","Sistem yoneticisi tarafindan engellenmis bir ifade tespit edildi." "400","Yasaklanmis kelimeler bulundu: " "401","Yasaklanmis kelimeler tespit edildi." "402","Engellenmis ifadelerin limiti asildi: " "403","Engellenmis kelime limiti asildi." "500","Yasaklanmis Site: " "501","Yasaklanmis URL: " "502","Erisilebilir listesinde bulunmayan bir siteye giremezsiniz." "503","Yasaklanmis dzensiz ifade (URL): " "504","Yasaklanmis duzensiz ifadeye rastlandi." "505","Bu IP adresinin asagidaki siteye girisi engellenmistir." "600","Ayricalikli IP adresine sahipsiniz." "601","Ayricalikli kullanici adina sahipsiniz." "602","Ayricalikli bir siteye girdiniz." "603","Ayricalikli bir URL adresine girdiniz." "604","Ayricalikli ifade bulundu: " "605","Kombinasyonu ertelenmis ifade bulundu: " "606","URL adresi ayricalikli listesine alinmalidir." "607","Bu sitede cookie kesfedildi." "608","Ayricalikli URL adresi taraniyor." "609","Ayricalikli duzenlenmis url adresi: " "700","Internet zerinden dosya gnderimi yasaklanmistir." "701","Internet zerinden dosya gnderimi sinirini astiniz." "800","Yasaklanmis MIME Tr: " "900","Yasaklanmis dosya uzantisi: " "1000","Bu sitedeki resim siniri asildi." "1100","Virus ve kotu icerige rastlandi." "1101","Site bloklandi. Adware veya spyware tespit edildi." "1200","Lutfen bekleyiniz, icerik taranarak yukleniyor.." "1210","Yukleme bitti, taramadan geciriliyor.." "1220","Tarama bitti.

Yuklemek icin tiklayiniz: " "1230","Dosya uzunlugu gecersizdir." dansguardian-2.10.1.1/data/languages/turkish/fancydmtemplate.html0000644001165000116500000001422611110523211021716 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/turkish/template.html0000644001165000116500000000327611110523211020357 00000000000000 DansGuardian - Erisim Engellendi

Erisim Engellendi -USER-


Asagidaki adrese erisiminiz engellenmistir:

-URL-

Erisim kisitlama sebebi:

-REASONGIVEN-

Sistem yneticiniz tarafindan girilmesine izin verilmeyen
bir sayfaya erisim yapmaya calisiyorsunuz.

Bu konuyla ilgili tum sikayet, istek ve onerilerinizi ag/sistem yoneticinize iletiniz.

Bu sistem DansGuardian ile calismaktadir.

dansguardian-2.10.1.1/data/languages/Makefile.in0000644001165000116500000002457011212164522016243 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ subdir = data/languages DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in LANGDIR = $(datadir)/$(PACKAGE_NAME)/languages LANGUAGES = czech hebrew turkish \ bulgarian danish indonesian russian-1251 ukenglish \ chinesebig5 dutch italian russian-koi8-r \ chinesegb2312 french lithuanian polish slovak \ german portuguese swedish spanish hungarian \ ptbrazilian japanese malay mxspanish arspanish EXTRA_DIST = ReadMe all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu data/languages/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu data/languages/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic dist-hook \ distclean distclean-generic distdir dvi dvi-am html html-am \ info info-am install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local install-data-local: @for l in $(LANGUAGES); do \ $(mkinstalldirs) $(DESTDIR)$(LANGDIR)/$$l && \ for f in $(srcdir)/$$l/messages $(srcdir)/$$l/template.html $(srcdir)/$$l/fancydmtemplate.html; do \ echo "$(INSTALL_DATA) $$f $(DESTDIR)$(LANGDIR)/$$l"; \ $(INSTALL_DATA) $$f $(DESTDIR)$(LANGDIR)/$$l; \ done \ done uninstall-local: @for l in $(LANGUAGES); do \ for f in $(srcdir)/$$l/messages $(srcdir)/$$l/template.html $(srcdir)/$$l/fancydmtemplate.html; do \ rm -f $(DESTDIR)$(LANGDIR)/$$l/`basename $$f`; \ done \ done dist-hook: @ for lang in $(LANGUAGES); do \ if test "$$lang" = .; then :; else \ test -d $(distdir)/$$lang \ || mkdir $(distdir)/$$lang \ || exit 1; \ cp -p $(srcdir)/$$lang/messages $(srcdir)/$$lang/template.html $(srcdir)/$$lang/fancydmtemplate.html $(distdir)/$$lang \ || exit 1; \ fi; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/data/languages/chinesebig5/0000777001165000116500000000000011212164547016446 500000000000000dansguardian-2.10.1.1/data/languages/chinesebig5/messages0000644001165000116500000000266511110523211020105 00000000000000# DansGuardian messages file # Translated to Traditional Chinese (Big5) by: Fr. Visminlu Vicente L. Chua, S.J. 2002-10-10 # 2004-08-20: Translated 606 and 607 # 2008/10/16: Translated 608, 609, 1100, 1101, 1200, 1210, 1220, 1230 "1","ڵŪ" "100","zϥΪ IP }\sںG" "101","zϥΪ IP }\sںC" "102","zϥΪbW٤\sںG" "200","zҽШD URL 榡~C" "300","QTyryG" "301","QTyryC" "400","QTզXyryG" "401","QTզXyryC" "402","[vyry" "403","WL[vyryC" "500","QT}G" "501","QT URLG" "502","ͮġAӨ}buզWv̡C" "503","uWܡvoOQT URLG" "504","uWܡvQT URLC" "505","ϥ IP ͮġAӨӦa}uO@IPa}C" "600","Pҥ~Ȥ IP ۦPC" "601","Pҥ~ȤbۦPC" "602","Pҥ~}ۦPC" "603","Pҥ~URLۦPC" "604","ҥ~yryG" "605","զXҥ~yryG" "606","VL URL ҥ~C" "607","VL cookie ҥ~C" "608","yɲL URL ҥ~C" "609","Wܨҥ~ URL kXG" "700","TWǡC" "701","WLWǷC" "800","QTMIMEwAG" "900","QTɦWG" "1000","W}WLFPICSХܼhC" "1100","frΤ}eC" "1101","si" "1200","еy - bUAԱy ..." "1210","UC}ly ..." "1220","yC

Io̤UG " "1230","ɮפwsb" dansguardian-2.10.1.1/data/languages/chinesebig5/fancydmtemplate.html0000644001165000116500000001422611110523211022412 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/chinesebig5/template.html0000644001165000116500000000267711110523211021057 00000000000000 DansGuardian - TŪ

T -USER- Ū


ŪG

-URL-

... QT]FHUzѡG

-REASONGIVEN-

zݨoӿ~]znŪAơC

pzDpICTխκ޲zC

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/lithuanian/0000777001165000116500000000000011212164547016415 500000000000000dansguardian-2.10.1.1/data/languages/lithuanian/messages0000644001165000116500000000325011110523211020043 00000000000000# DansGuardian messages file # Lithuanian version by Nerijus Balinas # charset=windows-1257 "1","Tinklalapis udraustas" "100","I js IP adreso negalima pasiekti tinklalapio: " "101","Draudiama naryti i js IP adreso." "102","iam vartotojui negalima pasiekti tinklalapio: " "200","Neteisingas URL." "300","Rasta udrausta fraz: " "301","Rasta udrausta fraz." "400","Rasta udrausta frazi kombinacija: " "401","Rasta udrausta frazi kombinacija." "402","Sumuojam frazi limitas " "403","Virytas sumuojam frazi limitas." "500","Udraustas adresas (site): " "501","Udraustas URL: " "502","Leidiamas prijimas tik prie tinklalapi, esani 'baltame' srae, bet io tinklalapio jame nra." "503","Draudiamas URL regexp: " "504","Rastas draudiamas URL regexp." "505","Prijimas prie IP adres udraustas, o is adresas yra tik IP adresas." "600","Kliento IP yra iimi srae." "601","Kliento vardas yra iimi srae." "602","Adresas yra iimi srae." "603","URL yra iimi srae." "604","Rasta fraz i iimi srao: " "605","Rasta frazi kombinacija i iimi srao: " "606","URL apjimo iimtis." "607","Slapuko apjimo iimtis." "608","URL skanavimo apjimo iimtis." "609","Regexp URL yra iimi srae: " "700","Nusiuntimas (upload) yra udraustas." "701","Virytas nusiuntimo (upload) limitas." "800","Udraustas MIME tipas: " "900","Udraustas prapltimas: " "1000","Virytas io tinklalapio PICS vertinimo kriterijus." "1100","Turinys ukrstas virusu." "1101","Reklama ublokuota" "1200","Palaukite - siuniame tikrinimui nuo virus..." "1210","Atsista. Tikriname nuo virus..." "1220","Patikrinta.

Atsisiskite: " "1230","Failas neprieinamas" dansguardian-2.10.1.1/data/languages/lithuanian/fancydmtemplate.html0000644001165000116500000001422611110523211022361 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/lithuanian/template.html0000644001165000116500000000272511110523211021020 00000000000000DansGuardian - Tinklalapis udraustas

TINKLALAPIS UDRAUSTAS -USER-


Interneto turinio filtravimo sistema neleidia Jums atidaryti io tinklalapio:

-URL-

dl ios prieasties:

-REASONGIVEN-

Tinklalapis, kur Js bandte pasiekti, pripaintas nepriimtinu.

Jei turite klausim, kreipkits tinklo administratori.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/Makefile.am0000644001165000116500000000244211110523211016213 00000000000000MAINTAINERCLEANFILES = Makefile.in LANGDIR = $(datadir)/$(PACKAGE_NAME)/languages LANGUAGES = czech hebrew turkish \ bulgarian danish indonesian russian-1251 ukenglish \ chinesebig5 dutch italian russian-koi8-r \ chinesegb2312 french lithuanian polish slovak \ german portuguese swedish spanish hungarian \ ptbrazilian japanese malay mxspanish arspanish EXTRA_DIST= ReadMe install-data-local: @for l in $(LANGUAGES); do \ $(mkinstalldirs) $(DESTDIR)$(LANGDIR)/$$l && \ for f in $(srcdir)/$$l/messages $(srcdir)/$$l/template.html $(srcdir)/$$l/fancydmtemplate.html; do \ echo "$(INSTALL_DATA) $$f $(DESTDIR)$(LANGDIR)/$$l"; \ $(INSTALL_DATA) $$f $(DESTDIR)$(LANGDIR)/$$l; \ done \ done uninstall-local: @for l in $(LANGUAGES); do \ for f in $(srcdir)/$$l/messages $(srcdir)/$$l/template.html $(srcdir)/$$l/fancydmtemplate.html; do \ rm -f $(DESTDIR)$(LANGDIR)/$$l/`basename $$f`; \ done \ done dist-hook: @ for lang in $(LANGUAGES); do \ if test "$$lang" = .; then :; else \ test -d $(distdir)/$$lang \ || mkdir $(distdir)/$$lang \ || exit 1; \ cp -p $(srcdir)/$$lang/messages $(srcdir)/$$lang/template.html $(srcdir)/$$lang/fancydmtemplate.html $(distdir)/$$lang \ || exit 1; \ fi; \ done dansguardian-2.10.1.1/data/languages/danish/0000777001165000116500000000000011212164547015527 500000000000000dansguardian-2.10.1.1/data/languages/danish/messages0000644001165000116500000000326011110523211017156 00000000000000# DansGuardian messages file in Danish # # Translated by Peter Kilsgaard "1","Adgang ngtet" "100","Din IP address har ikke lov til at bruge internet: " "101","Din IP address har ikke lov til at bruge internet." "102","Dit brugernavn har ikke lov til at bruge internet: " "200","Den indtastede adresse er ikke valid." "300","Forbudt stning fundet: " "301","Forbudt stning fundet." "400","Forbudt stningskombination fundet: " "401","Forbudt stningskombination fundet." "402","Vgtede stningsgrnse p " "403","Vgtede stningsgrnse overskredet." "500","Forbudt side: " "501","Forbudt Adresse: " "502","Total blokering er aktiveret og den forspurgte side er ikke p positiv listen." "503","Forbudt ord i adressefelt: " "504","Forbudt ord i adressefelt fundet." "505","IP Blokering er aktiveret og den forspurgte side har IP ingen DNS navn." "600","Undtagelse PC IP match." "601","Undtagelse brugernavn match." "602","Undtagelse side match." "603","Undtagelse adresse match." "604","Undtagelses stning fundet: " "605","Kombinations undtagelse stning fundet: " "606","Bypass URL undtagelse." "607","Bypass cookie undtagelse." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","Web upload er forbudt." "701","Web upload grnse overskredet." "800","Forbudt MIME Type: " "900","Forbudt fil format: " "1000","PICS niveau overskredet p den pgldende side." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/danish/fancydmtemplate.html0000644001165000116500000001422611110523211021473 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/danish/template.html0000644001165000116500000000437211110523211020132 00000000000000 DansGuardian - Access Denied

ADGANG NÆGTET -USER-


Adgang til denne side:

-URL-

... er blevet nægtet på grund af:

-REASONGIVEN-

Denne meddelse kommer fordi, siden du forsøger at få adgang til indeholder, eller er blevet katagoriseret som, uegnet materiale .

Hvis du har spørgsmål til ovennævnte,
bedes du kontakte netværksadministratoren

Powered by DansGuardian


dansguardian-2.10.1.1/data/languages/russian-koi8-r/0000777001165000116500000000000011212164547017054 500000000000000dansguardian-2.10.1.1/data/languages/russian-koi8-r/messages0000644001165000116500000000314411110523211020504 00000000000000# DansGuardian messages file in Russian KOI8-R "1"," " "100"," IP- web: " "101"," IP- web." "102"," web: " "200"," URL ." "300"," : " "301"," ." "400"," : " "401"," ." "402","Weighted phrase limit of " "403"," ." "500"," : " "501"," URL: " "502","Blanket Block is active and that site is not on the white list." "503","URL, : " "504"," URL, ." "505","Blanket IP Block is active and that address is an IP only address." "600","Exception client IP match." "601","Exception client user match." "602","Exception site match." "603","Exception URL match." "604","Exception phrase found: " "605","Combination exception phrase found: " "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700"," ." "701"," ." "800"," MIME-: " "900"," : " "1000","PICS labeling level exceeded on the above site." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/russian-koi8-r/fancydmtemplate.html0000644001165000116500000001422611110523211023020 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/russian-koi8-r/template.html0000644001165000116500000000421411110523211021452 00000000000000 DansGuardian - Access Denied

!
-USER- 
:

-URL-

... :

-REASONGIVEN-



, , ( , ) .

, .



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/czech/0000777001165000116500000000000011212164547015355 500000000000000dansguardian-2.10.1.1/data/languages/czech/messages0000644001165000116500000000337311110523211017011 00000000000000# DansGuardian messages file in Czech # by Richard Bukovansky bukovansky@atcomp.cz "1","Pstup zamtnut" "100","Vai IP adrese nen povoleno prohlet: " "101","Vae IP adresa nem povoleno prohlen." "102","Vae uivatelsk jmno nem povoleno prohlet: " "200","Poadovan URL je patn zadna." "300","Nalezena zakzan frze: " "301","Nalezena zakzan frze." "400","Nalezena zakzan kombinace frzi: " "401","Nalezena zakzan kombinace frzi." "402","Limit vench frz: " "403","Byl pekroen limit pro ven frze." "500","Zakzan webov sdlo: " "501","Zakzan URL adresa: " "502","Celoplon blokovn pstupu je aktivovno a toto webov sdlo nen povoleno." "503","Nalezena zakzan URL adresa dle regularnho vrazu: " "504","Nalezena zakzan URL adresa dle regularnho vrazu." "505","Celoplon blokovan IP adres je aktivovno a byla zadna IP adresa." "600","Nalezena vyjmkov IP adresa." "601","Nalezen vyjmkov uivatel." "602","Nalezeno vyjmkov webov sdlo." "603","Nalezena vyjmkov URL adresa." "604","Nalezena vyjmkov frze: " "605","Nalezena kombinace vyjmkovch frzi: " "606","Bypass URL exception." "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","Web upload je zakzn." "701","Web upload limit byl pekroen." "800","Zakzan obsah souboru: " "900","Zakzan ppona souboru: " "1000","rove PICS oznaen byla pekroena na tomto webovm sdle." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/czech/fancydmtemplate.html0000644001165000116500000001422611110523211021321 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/czech/template.html0000644001165000116500000000300511110523211017750 00000000000000DansGuardian - Pstup zakzn

PRISTUP ZAKZN -USER-


Pstup na tuto strnku:

-URL-

... byl zakzn z dvodu:

-REASONGIVEN-

Zobrazen tohoto chybovho hlen zpsobila strnka,
na kterou jste se pokusil(a) pistoupit a obsahuje nebo je oznaena jako obsahujc
nepatin materil.

Mte-li njak dotazy, obrate se prosm na vaeho sprvce st i osobu povenou sprvou st.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/mxspanish/0000777001165000116500000000000011212164547016273 500000000000000dansguardian-2.10.1.1/data/languages/mxspanish/messages0000644001165000116500000000403511110523211017723 00000000000000# DansGuardian messages file in MX Spanish # Translated by Vladimir Gomez # Typo corrected by Pedro Fortuny 2003/10/13 "1","Acceso Denegado" "100","Su dirección IP no tiene permiso para ver: " "101","Su dirección IP no esta autorizada a navegar en Internet." "102","Su usuario no tiene autorizació para ver: " "200","El URL solicitado esta mal formado." "300","Frase no permitida: " "301","Frase no permitida." "400","Combinación de palabras/frases no permitida: " "401","Combinación de palabras/frases no permitida." "402","La frase excede el nivel " "403","La página solicitada excede el nivel de frases permitidas." "500","Sitio no permitido: " "501","URL no permitido: " "502","Blanket Block esta activado y el sitio no se encuentra en la lista de permitidos." "503","URL bloqueada por Expresión Regular: " "504","URL bloqueada por Expresión Regular." "505","No se puede accesar un sitio por su dirección IP cuando Blanket IP Block está activado." "600","Dirección ip del cliente presente en la lista de excepciones." "601","Usuario presente en la lista de excepciones." "602","Sitio presente en la lista de excepciones." "603","URL presente en la lista de excepciones." "604","Frase presente en la lista de excepciones." "605","Combinación de frases presente en la lista de excepciones: " "606","Puente URL excepciones." "607","Puente cookie excepciones." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","No esta permitido enviar archivos a sitios en Internet." "701","El archivo que intenta enviar excede el tamaño permitido." "800","Clase MIME no permitida: " "900","Extensión de archivo bloqueada: " "1000","Las etiquetas del sitio exceden el nivel PICS." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/mxspanish/fancydmtemplate.html0000644001165000116500000001422611110523211022237 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/mxspanish/template.html0000644001165000116500000000306211110523211020671 00000000000000DansGuardian - Acceso Denegado

ACCESO DENEGADO -USER-


El acceso a la páina:

-URL-

... ha sido denegado por la siguiente razón:

-REASONGIVEN-

Usted esta viendo esta página de error porque
el sitio que está tratando de ver o su contenido
han sido catalogados como inapropiados.

Si requiere acceso a esta página por favor pongase en contacto
con el Administrador de Sistemas o el Administrador de la Red.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/russian-1251/0000777001165000116500000000000011212164547016333 500000000000000dansguardian-2.10.1.1/data/languages/russian-1251/messages0000644001165000116500000000334411110523211017765 00000000000000# DansGuardian 2.8 messages file in russian # charset=windows-1251 # version by Shipitsin Igor "1"," " "100"," IP :" "101"," IP ." "102"," :" "200"," URL ." "300"," :" "301"," ." "400"," :" "401"," ." "402"," " "403"," ." "500"," :" "501"," URL:" "502"," - ." "503"," URL:" "504"," URL." "505"," IP - IP, ." "600"," IP ." "601"," ." "602"," ." "603"," URL." "604"," :" "605"," :" "606"," URL ." "607"," cookie ." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700"," ." "701"," ." "800"," MIME:" "900"," :" "1000"," PICS ." "1100"," " "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/russian-1251/fancydmtemplate.html0000644001165000116500000001422611110523211022277 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/russian-1251/template.html0000644001165000116500000000432111110523211020730 00000000000000 DansGuardian -

!
-USER- 
:

-URL-

... :

-REASONGIVEN-



, , , , .

.



DansGuardian
dansguardian-2.10.1.1/data/languages/hungarian/0000777001165000116500000000000011212164547016235 500000000000000dansguardian-2.10.1.1/data/languages/hungarian/messages0000644001165000116500000000326711110523211017673 00000000000000# DansGuardian 2.8 messages file in Hungarian "1","A hozzfrs tiltott" "100","Az n IP cme nem engedlyezett ehhez a bngszhz: " "101","Az n IP cme nem engedlyezett ehhez a bngszhz." "102","A felhasznlneve nem engedlyezett ehhez e abngszhz: " "200","A krt URL formtuma nem tnik biztonsgosnak." "300","Tiltott kifejezs: " "301","Tiltott kifejezs." "400","Tiltott sszettel kifejezs: " "401","Tiltott sszettel kifejezs." "402","A slyozott kifejezs hatra " "403","A slyozott kifejezs elrte a hatrt." "500","Tiltott oldal: " "501","Tiltott URL: " "502","A domain-alap szrs aktv s ez az oldal sem a 'fehr', sem a 'szrke' listn nincs fent." "503","Tiltott regulris kifejezs URL: " "504","Tiltott regulris kifejezs URL." "505","A cmtartomny alap szrs aktv s ez csak egy egyszer IP-cm." "600","Kifogsolhat kliens IP egyezs." "601","Kifogsolhat kliens felhasznl egyezs." "602","Kifogsolhat oldalegyezs." "603","Kifogsolhat URL-egyezs." "604","Kifogsolhat kifejezs: " "605","Kombincis kifogsolhat kifejezs: " "606","Tovbbugrat URL kifogs." "607","Tovbbugrat sti kifogs." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","A Webre trtn feltlts tiltva." "701","A Webre trtn feltlts korltjt elrte." "800","Tiltott MIME Tpus: " "900","Tiltott kiterjeszts: " "1000","A PICS szervezet jellsi szintjt elrte a fels oldal." "1100","Vrussal fetztt llomny." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/hungarian/fancydmtemplate.html0000644001165000116500000001422611110523211022201 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/hungarian/template.html0000644001165000116500000000423511110523211020636 00000000000000 DansGuardian - A hozzfrs tiltva

A hozzfrs tiltva!
-USER- 
YOUR ORG NAME A hozzfrs ehhez az oldalhoz:

-URL-

... nem lehetsges a kvetkez ok miatt:

-REASONGIVEN-



n azrt ltja ezt a hibazenetet, mert gy tnik, amit n megksrelt elrni tartalmaz vagy besorolsa alapjn tartalmazhat helytelennek vlt anyagokat.

Amennyiben nnek ezzel kapcsolatban agglyai merltek fel, vegye fel a kapcsolatot az n Informcis- s kommunkcitechnolgiai koordintorval vagy a hlzati menedzservel.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/arspanish/0000777001165000116500000000000011212164547016251 500000000000000dansguardian-2.10.1.1/data/languages/arspanish/messages0000644001165000116500000000377411110523211017712 00000000000000# DansGuardian messages file in AR Spanish # Translated by Roberto Quiroga "1","Acceso Denegado" "100","Su dirección IP no esta autorizada a visitar: " "101","Su dirección IP no esta autorizada navegar." "102","El usuario no esta autorizado a visitar: " "200","La URL solicitada esta mal formada." "300","Se encontró la frase no permitida: " "301","Se encontró una frase no permitida" "400","Combinación de frases no permitida: " "401","Combinación de frases no permitida." "402","Límite de ponderación de frases de " "403","Límite de ponderación de frases excedido" "500","Sitio no permitido: " "501","URL no permitida: " "502","El sitio no esta en la lista permitida por el bloqueo activo." "503","Banned Regular Expression URL: " "503","URL bloqueada por Expresion Regular: " "504","URL bloqueada por Expresion Regular." "505","Solo se suministro la direccion IP y el bloqueo esta activo." "600","Se encontró una excepción por IP de origen." "601","Se encontró una excepción por usuario de origen." "602","Se encontró una excepción por lugar." "603","Se encontró una excepción por URL." "604","Se encontró una excepción por la frase: " "605","Se encontró una excepción por la combinación de frases: " "606","Bypass URL excepción." "607","Bypass cookie excepción." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","La subida esta bloqueada." "701","Límite de subida excedido." "800","Clase MIME bloqueada: " "900","Extension bloqueada: " "1000","Clasificación PICS excedida en el sitio indicado." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/arspanish/fancydmtemplate.html0000644001165000116500000001422611110523211022215 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/arspanish/template.html0000644001165000116500000000276711110523211020662 00000000000000DansGuardian - Acceso Denegado

EL ACCESO HA SIDO DENEGADO -USER-


EL ACCESO A LA PAGINA:

-URL-

... ha sido denegado por la siguiente razón:

-REASONGIVEN-

Ud. esta viendo este mensaje de error porque la página a la que
intenta acceder contiene, o esta clasificada como conteniendo,
material que se considera inapropiado.

Si lo desea contacte al Administrador de Sistemas.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/ukenglish/0000777001165000116500000000000011212164547016252 500000000000000dansguardian-2.10.1.1/data/languages/ukenglish/messages0000644001165000116500000000441011110523211017677 00000000000000# DansGuardian messages file in UK English "1","Access Denied" "100","Your IP address is not allowed to web browse: " "101","Your IP address is not allowed to web browse." "102","Your username is not allowed to web browse: " "200","The requested URL is malformed." "300","Banned Phrase found: " "301","Banned phrase found." "400","Banned combination phrase found: " "401","Banned combination phrase found." "402","Weighted phrase limit of " "403","Weighted phrase limit exceeded." "500","Banned site: " "501","Banned URL: " "502","Blanket Block is active and that site is not on the white or grey list." "503","Banned Regular Expression URL: " "504","Banned Regular Expression URL found." "505","Blanket IP Block is active and that address is an IP only address." "506","Blanket SSL Block is active and that site is not on the white or grey list." "507","Blanket SSL IP Block is active and that address is an IP only address." "508","Banned Regular Expression HTTP header: ", "509","Banned Regular Expression HTTP header found." "600","Exception client IP match." "601","Exception client user match." "602","Exception site match." "603","Exception URL match." "604","Exception phrase found: " "605","Combination exception phrase found: " "606","Bypass URL exception." "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Web upload is banned." "701","Web upload limit exceeded." "750","Blanket file download is active and this MIME type is not on the white list: " "751","Blanket file download is active and this file is not matched by the white lists." "800","Banned MIME Type: " "900","Banned extension: " "1000","PICS labeling level exceeded on the above site." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading file for scanning..." "1201","Warning: file too large to scan. If you suspect that this file is larger than " "1202",", then refresh this page to download directly." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1221","Download complete; file not scanned.

Click here to download: " "1222","File too large to cache.

Click here to re-download, bypassing scan: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/ukenglish/fancydmtemplate.html0000644001165000116500000001422611110523211022216 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/ukenglish/template.html0000644001165000116500000000466111110523211020656 00000000000000 DansGuardian - Access Denied

Access has been Denied!
-USER- 
YOUR ORG NAME Access to the page:

-URL-

... has been denied for the following reason:

-REASONGIVEN-

Categories:

-CATEGORIES-



You are seeing this error because what you attempted to access appears to contain, or is labeled as containing, material that has been deemed inappropriate.

If you have any queries contact your ICT Coordinator or Network Manager.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/italian/0000777001165000116500000000000011212164547015702 500000000000000dansguardian-2.10.1.1/data/languages/italian/messages0000644001165000116500000000331211110523211017327 00000000000000# DansGuardian messages file in IT Italian # Translated by andrea at diclemente.net "1","Accesso Negato" "100","Al tuo indirizzo IP non e' permesso di navigare il web: " "101","Al tuo indirizzo IP non e' permesso di navigare il web." "102","Al tuo username non permesso di navigare il web: " "200","L'URL richiesta e' malformata." "300","Trovata una frase vietata: " "301","Trovata una frase vietata." "400","Trovata una combinazione di frasi vietata: " "401","Trovata una combinazione di frasi vietata." "402","Il limite di frasi pesate di " "403","E' stato superato il limite per le frasi pesate." "500","Sito vietato: " "501","URL vietato: " "502","Il blocco 'Blanket' e' attivo e il sito non e' nella white list." "503","URL con espressione regolare vietata: " "504","URL con espressione regolare vietata trovato." "505","Il blocco 'Blanket' e' attivo e l'indirizzo e' formato dal solo indirizzo IP." "600","Exception client IP match." "601","Exception client user match." "602","Exception site match." "603","Exception URL match." "604","Exception phrase found: " "605","Combination exception phrase found: " "606","Bypass URL exception." "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Il Web-upload e' vietato." "701","E' stato superato il limite per il Web upload." "800","MIME Type vietato: " "900","Extensione vietata: " "1000","Si e' oltrepassato il limite del livello PICS sul sito." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/italian/fancydmtemplate.html0000644001165000116500000001422611110523211021646 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/italian/template.html0000644001165000116500000000300711110523211020277 00000000000000DansGuardian - Accesso Negato

L'ACCESSO E' STATO NEGATO -USER-


L'accesso alla pagina:

-URL-

... e' stato negato per il seguente motivo:

-REASONGIVEN-

Stai vedendo questo errore perche' la pagina che hai cercato
di accedere contiene, o e' marcata come contenente, materiale che
e' stato ritenuto non appropriato.

Se hai ulteriori domande, contatta il tuo coordinatore ICT o Network Manager.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/indonesian/0000777001165000116500000000000011212164547016410 500000000000000dansguardian-2.10.1.1/data/languages/indonesian/messages0000644001165000116500000000341211110523211020036 00000000000000# DansGuardian messages file in Indonesian # # Indonesian translation by: Kumoro Wisnu Wibowo # "1","Akses Ditolak" "100","Alamat IP Anda tidak diperbolehkan untuk browsing: " "101","Alamat IP Anda tidak diperbolehkan untuk browsing." "102","Username Anda tidak diperbolehkan untuk browsing: " "200","Format alamat URL yang diminta tidak benar." "300","Frase yang ditolak ditemukan: " "301","Frase yang ditolak ditemukan." "400","Kombinasi frase yang ditolak ditemukan: " "401","Kombinasi frase yang ditolak ditemukan." "402","Bobot batas frase dari " "403","Bobot batas frase terlewati." "500","Situs yang ditolak: " "501","Alamat URL yang ditolak: " "502","Blanket Block aktif dan situs tersebut tidak dalam white list." "503","Alamat Regular Expression URL yang ditolak: " "504","Alamat Regular Expression URL ditemukan." "505","Blanket IP Block aktif dan alamat tersebut adalah hanya alamat IP saja." "600","IP klien pengecualian cocok." "601","User klien pengecualian cocok." "602","Situs pengecualian cocok." "603","Alamat URL pengecualian cocok." "604","Frase pengecualian ditemukan: " "605","Kombinasi frase pengecualian ditemukan: " "606","Bypass URL cocok." "607","Bypass cookie cocok." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","Web upload ditolak." "701","Batas untuk web upload terlewati." "800","Tipe MIME yang ditolak: " "900","Ekstensi yang ditolak: " "1000","Level Label PICS terlewati pada situs di atas." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/indonesian/fancydmtemplate.html0000644001165000116500000001422611110523211022354 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/indonesian/template.html0000644001165000116500000000300111110523211020777 00000000000000DansGuardian - Akses Ditolak

ACCESS DITOLAK -USER-


Akses ke halaman:

-URL-

... telah ditolak untuk alasan sebagai berikut:

-REASONGIVEN-

Anda melihat pesan kesalahan ini karena halaman yang ingin Anda akses
mengandung isi yang telah dianggap sebagai tidak pantas.

Apabila Anda mempunyai pertanyaan-pertanyaan, silakan kontak Manager IT atau Manager Network Anda.

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/chinesegb2312/0000777001165000116500000000000011212164547016520 500000000000000dansguardian-2.10.1.1/data/languages/chinesegb2312/messages0000644001165000116500000000257611110523211020160 00000000000000# DansGuardian messages file in chinese gb2312 # By Chen YiFei "1","ܾ" "100"," IP ַȨ web : " "101"," IP ַȨ web ʡ" "102","ʺȨ web ʡ " "200"," URL ʽд" "300","ֱֹĶ: " "301","ֱֹĶ" "400","ֱֹ϶: " "401","ֱֹ϶" "402"," ȨΪ: " "403","Ȩơ" "500","ֹվ: " "501","ֹ URL: " "502","ȫֹЧվ㲢ڰС" "503","ʽֹ URL: " "504","ֱʽֹ URL" "505","ȫֹʹ IP Чõַһ IP ַ" "600","ƥһĿͻ IP ַ" "601","ƥһĿͻʺš" "602","ƥһվ㡣" "603","ƥһ URL" "604","Ķ:" "605","϶: " "606","Bypass URL exception." "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700","ֹϴļ" "701","ļϴ޶" "800","ֹ MIME : " "900","ֹļչ: " "1000","վ PICS ǩ" "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/chinesegb2312/fancydmtemplate.html0000644001165000116500000001422611110523211022464 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/chinesegb2312/template.html0000644001165000116500000000244211110523211021117 00000000000000DansGuardian - Access Denied

ʱܾ -USER-


ʸҳ:

-URL-

... ԭܾ:

-REASONGIVEN-

Ϣԭͼʵҳвʵݡ

κʣϵ ICT ЭԱܡ

Powered by DansGuardian

dansguardian-2.10.1.1/data/languages/ReadMe0000644001165000116500000000125411110523211015237 00000000000000To use these messages files edit the language option in the dansguardian.conf file. If your language is not here, please email author@dansguardian.org with your translation and it will be included in a later release. Or, if you want to improve the existing messages I will consider using ones you submit instead. When editing, the line may not contain a " as this is used to denote the start and end. Instead use a '. Daniel Barron Thu 16th January 2003 Update Mon 2nd February 2004: I have added messages 606 and 607. Please review and send me the correction. Update Dec 2004: I have added messages 1100, 1200, 1210, 1220, 1230. Please review and send me the correction. dansguardian-2.10.1.1/data/languages/hebrew/0000777001165000116500000000000011212164547015535 500000000000000dansguardian-2.10.1.1/data/languages/hebrew/messages0000644001165000116500000000270511110523211017167 00000000000000# DansGuardian messages file in Hebrew # by Nitzo Tomer "1"," " "100"," -IP : " "101"," -IP ." "102"," : " "200"," ." "300"," : " "301"," ." "400"," : " "401"," ." "402"," " "403"," ." "500"," : " "501"," : " "502"," " ." "503"," : " "504"," ." "505"," " ." "600"," IP ." "601"," ." "602"," ." "603"," ." "604"," : " "605"," : " "606"," ." "607"," ." "608"," URL ." "609"," URL : " "700"," ." "701"," ." "800"," MIME : " "900"," : " "1000"," PICS " ." "1100"," ." "1101"," " "1200"," - ..." "1210"," . ..." "1220"," .

: " "1230"," " dansguardian-2.10.1.1/data/languages/hebrew/fancydmtemplate.html0000644001165000116500000001422611110523211021501 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/hebrew/template.html0000644001165000116500000000617411110523211020142 00000000000000 DansGuardian -

!
-USER-
YOUR ORG NAME :

-URL-

... :

-REASONGIVEN-



, , .

.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/portuguese/0000777001165000116500000000000011212164547016463 500000000000000dansguardian-2.10.1.1/data/languages/portuguese/messages0000644001165000116500000000460411110523211020115 00000000000000# DansGuardian 2.8 messages in Brazilian Portuguese # Mensagens do DansGuardian 2.8 file em Portugus do Brasil (pt-BR) # Translated/traduzido (?) by/por Henrique Araujo - Sys Admin # henrique@colegiosaogoncalo.g12.br # Cuiab - MT, Brasil "1","Acesso negado." "100","Seu endereço IP não tem permissão de acesso à  web: " "101","Seu endereço IP não tem permissão de acesso à  web: " "102","Esse nome de usuário não tem permissão de acesso à  web: " "200","A URL requerida está mal formada." "300","Encontrada frase proibida: " "301","Encontrada frase proibida: " "400","Encontrada combinação de frases proibida: " "401","Encontrada combinação de frases proibida: " "402","Limite de frase ponderada de " "403","Limite de frase ponderada excedido." "500","Sítio proibido: " "501","URL proibida: " "502","Bloqueio geral está ativo e aquele sítio não está na lista livre." "503","Expressão Regular proibida em URL: " "504","Encontrada Expressão Regular proibida em URL: " "505","Bloqueio geral de IP está ativo e aquele endereço não possui nome." "600","Cliente IP está na lista de exceções." "601","Usuário está na lista de exceções." "602","Sítio está na lista de exceções." "603","URL está na lista de exceções." "604","Encontrada frase na lista de exceções: " "605","Encontrada combinação de frases na lista de exceções: " "606","Desvio temporário de bloqueio (Bypass URL.)" "607","Desvio temporário de bloqueio (Bypass cookie.)" "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Transferência de arquivos para web proibida." "701","Limite de transferência de arquivos para web excedido." "800","Tipo MIME proibido: " "900","Extensão proibida: " "1000","Nível de rotulagem PICS excedido no sítio acima." # 1,1000 by Andson Gomes - html internet "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/portuguese/fancydmtemplate.html0000644001165000116500000001422611110523211022427 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/portuguese/template.html0000644001165000116500000000433511110523211021065 00000000000000 DansGuardian - Access Denied

O acesso foi negado!
Usurio: -USER- 
Empresa S/A O acesso a pgina:

-URL-

... foi negado devido a seguinte razo:

-REASONGIVEN-

Categorias:

-CATEGORIES-



Voc est vendo esta mensagem porque o que voc tentou acessar parece conter material que foi julgado imprprio.

Se voc tiver alguma dvida favor entrar em contato com a equipe de suporte de sua rede.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/swedish/0000777001165000116500000000000011212164547015727 500000000000000dansguardian-2.10.1.1/data/languages/swedish/messages0000644001165000116500000000361011110523211017355 00000000000000# DansGuardian messages file in Swedish # Swedish translation by: David Hed "1","åtkomst nekad" "100","Din IP adress har inte tillstånd att surfa: " "101","Din IP adress har inte tillstånd att surfa." "102","Din användaridentitet har inte tillstånd att surfa: " "200","Begärd URL är felformaterad." "300","Förbjuden fras funnen: " "301","Förbjuden fras funnen." "400","Förbjuden kombination av fraser funnen: " "401","Förbjuden kombination av fraser funnen." "402","Viktad frasbedömning av " "403","Viktad fras begränsning överskriden." "500","Förbjuden webbplats: " "501","Förbjuden adress: " "502","Blanket Block är aktiverat och webbplatsen är inte grå eller vitlistad." "503","Förbjudet ord i adressfältet: " "504","Förbjudet ord i adressfältet funnen." "505","Blanket IP Block är aktiverat och denna adress är en endast IP adress." "600","Undantagen Dators IP-adress matchar." "601","Undantagen användaridentitet matchar." "602","Undantagen webbplats matchar." "603","Undantagen URL matchar." "604","Undantagsfras funnen: " "605","Kombinerad undantagsfras funnen: " "606","Kringgå URL begränsning." "607","Kringgå cookie begränsning." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " "700","Webbuppladdning är förbjuden." "701","Storlek för webbuppladdning är överskriden." "800","Förbjuden MIME typ: " "900","Förbjuden filändelse: " "1000","PICS klassificiering överskriden på ovanstående webbplats." "1100","Virusinfekterat innehåll funnet." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/swedish/fancydmtemplate.html0000644001165000116500000001422611110523211021673 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/swedish/template.html0000644001165000116500000000473211110523211020332 00000000000000 DansGuardian - Åtkomst nekad

Åtkomst förhindrad av proxy!
-USER- 
YOUR ORG NAME Åtkomst till sidan:

-URL-

... har blivit nekad på grund av följande skäl:

-REASONGIVEN-



Den centrala proxyservern är inställd på att filtrera undan eventuell skadlig kod eller av policyskäl begränsade nerladdningar. Bedömningen är automatisk så programmet kan ibland på felaktiga grunder förhindra åtkomst.

Anser du att denna blockering är felaktig eller har andra frågor, kontakta din systemadministratör.



Powered by DansGuardian
dansguardian-2.10.1.1/data/languages/bulgarian/0000777001165000116500000000000011212164547016225 500000000000000dansguardian-2.10.1.1/data/languages/bulgarian/messages0000644001165000116500000000360511110523211017657 00000000000000# DansGuardian messages file in Bulgarian # by Pavel Constantinov "1"," " "100"," IP : " "101"," IP ." "102"," : " "200"," URL ." "300"," : " "301"," ." "400"," : " "401"," ." "402"," " "403"," ." "500"," : " "501"," URL: " "502"," Blanket Block ." "503"," URL : " "504"," URL ." "505"," Blanket IP Block IP address." "600"," IP ." "601"," IP ." "602"," ." "603"," URL-." "604"," : " "605"," : " "606","Bypass URL exception." "607","Bypass cookie exception." "608","Scan bypass URL exception." "609","Exception regular expression URL match: " # 606,607 by Daniel Barron - corrections welcome "700"," ." "701"," ." "800"," MIME: " "900"," : " "1000"," ." "1100","Virus or bad content detected." "1101","Advert blocked" "1200","Please wait - downloading to be scanned..." "1210","Download Complete. Starting scan..." "1220","Scan complete.

Click here to download: " "1230","File no longer available" dansguardian-2.10.1.1/data/languages/bulgarian/fancydmtemplate.html0000644001165000116500000001422611110523211022171 00000000000000 Downloading -FILENAME- (-FILESIZE- bytes) dansguardian-2.10.1.1/data/languages/bulgarian/template.html0000644001165000116500000000343111110523211020623 00000000000000 DansGuardian - Access Denied

, -USER-

:

-URL-

... :

-REASONGIVEN-

, ,
, .
, ICT .

Powered by DansGuardian

dansguardian-2.10.1.1/README0000644001165000116500000000216111110523211012156 00000000000000For all support, instructions and copyright go to: http://dansguardian.org/ Read the INSTALL for installation instructions. DansGuardian is a content filtering proxy that works in conjunction with another caching proxy such as Squid or Oops. More information can be found in the dansguardian(8) man page, the "doc" subdirectory of the distribution, and the comments in the configuration and list files themselves. 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 dansguardian-2.10.1.1/src/0000777001165000116500000000000011212164550012163 500000000000000dansguardian-2.10.1.1/src/FOptionContainer.hpp0000644001165000116500000002520511110523210016022 00000000000000// FOptionContainer class - contains the options for a filter group, // including the banned/grey/exception site lists and the content/site/url regexp lists //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_FOPTIONCONTAINER #define __HPP_FOPTIONCONTAINER // INCLUDES #include "String.hpp" #include "HTMLTemplate.hpp" #include "ListContainer.hpp" #include "LanguageContainer.hpp" #include "ImageContainer.hpp" #include "RegExp.hpp" #include #include // DECLARATIONS std::deque *ipToHostname(const char *ip); class FOptionContainer { public: int reporting_level; int category_threshold; bool infection_bypass_errors_only; bool disable_content_scan; int weighted_phrase_mode; int group_mode; int embedded_url_weight; int naughtyness_limit; bool createlistcachefiles; bool enable_PICS; bool deep_url_analysis; #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier bool notifyav; bool notifycontent; bool use_smtp; int violations; int current_violations; int threshold; long threshold_stamp; bool byuser; #endif // File filtering mode - should banned or exception lists be used? // if true, use exception lists & exception file site list; otherwise, // use banned MIME type & extension lists. bool block_downloads; bool reverse_lookups; bool force_quick_search; int bypass_mode; int infection_bypass_mode; int pics_rsac_violence; int pics_rsac_sex; int pics_rsac_nudity; int pics_rsac_language; int pics_icra_chat; int pics_icra_moderatedchat; int pics_icra_languagesexual; int pics_icra_languageprofanity; int pics_icra_languagemildexpletives; int pics_icra_nuditygraphic; int pics_icra_nuditymalegraphic; int pics_icra_nudityfemalegraphic; int pics_icra_nuditytopless; int pics_icra_nuditybottoms; int pics_icra_nuditysexualacts; int pics_icra_nudityobscuredsexualacts; int pics_icra_nuditysexualtouching; int pics_icra_nuditykissing; int pics_icra_nudityartistic; int pics_icra_nudityeducational; int pics_icra_nuditymedical; int pics_icra_drugstobacco; int pics_icra_drugsalcohol; int pics_icra_drugsuse; int pics_icra_gambling; int pics_icra_weaponuse; int pics_icra_intolerance; int pics_icra_badexample; int pics_icra_pgmaterial; int pics_icra_violencerape; int pics_icra_violencetohumans; int pics_icra_violencetoanimals; int pics_icra_violencetofantasy; int pics_icra_violencekillinghumans; int pics_icra_violencekillinganimals; int pics_icra_violencekillingfantasy; int pics_icra_violenceinjuryhumans; int pics_icra_violenceinjuryanimals; int pics_icra_violenceinjuryfantasy; int pics_icra_violenceartisitic; int pics_icra_violenceeducational; int pics_icra_violencemedical; int pics_icra_violencesports; int pics_icra_violenceobjects; int pics_evaluweb_rating; int pics_cybernot_sex; int pics_cybernot_other; int pics_safesurf_agerange; int pics_safesurf_profanity; int pics_safesurf_heterosexualthemes; int pics_safesurf_homosexualthemes; int pics_safesurf_nudity; int pics_safesurf_violence; int pics_safesurf_sexviolenceandprofanity; int pics_safesurf_intolerance; int pics_safesurf_druguse; int pics_safesurf_otheradultthemes; int pics_safesurf_gambling; int pics_weburbia_rating; int pics_vancouver_multiculturalism; int pics_vancouver_educationalcontent; int pics_vancouver_environmentalawareness; int pics_vancouver_tolerance; int pics_vancouver_violence; int pics_vancouver_sex; int pics_vancouver_profanity; int pics_vancouver_safety; int pics_vancouver_canadiancontent; int pics_vancouver_commercialcontent; int pics_vancouver_gambling; // new Korean PICS support int pics_icec_rating; int pics_safenet_nudity; int pics_safenet_sex; int pics_safenet_violence; int pics_safenet_language; int pics_safenet_gambling; int pics_safenet_alcoholtobacco; std::string name; std::string magic; std::string imagic; std::string cookie_magic; #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier std::string mailfrom; std::string avadmin; std::string contentadmin; std::string avsubject; std::string contentsubject; std::string violationbody; #endif unsigned int banned_phrase_list; unsigned int exception_site_list; unsigned int exception_url_list; unsigned int banned_extension_list; unsigned int banned_mimetype_list; unsigned int banned_site_list; unsigned int banned_url_list; unsigned int grey_site_list; unsigned int grey_url_list; unsigned int banned_regexpurl_list; unsigned int exception_regexpurl_list; unsigned int banned_regexpheader_list; unsigned int content_regexp_list; unsigned int url_regexp_list; unsigned int header_regexp_list; unsigned int exception_extension_list; unsigned int exception_mimetype_list; unsigned int exception_file_site_list; unsigned int exception_file_url_list; unsigned int log_site_list; unsigned int log_url_list; unsigned int log_regexpurl_list; // regex match lists std::deque banned_regexpurl_list_comp; std::deque banned_regexpurl_list_source; std::deque banned_regexpurl_list_ref; std::deque exception_regexpurl_list_comp; std::deque exception_regexpurl_list_source; std::deque exception_regexpurl_list_ref; std::deque banned_regexpheader_list_comp; std::deque banned_regexpheader_list_source; std::deque banned_regexpheader_list_ref; std::deque log_regexpurl_list_comp; std::deque log_regexpurl_list_source; std::deque log_regexpurl_list_ref; // regex search & replace lists std::deque content_regexp_list_comp; std::deque content_regexp_list_rep; std::deque url_regexp_list_comp; std::deque url_regexp_list_rep; std::deque header_regexp_list_comp; std::deque header_regexp_list_rep; // precompiled reg exps for speed RegExp pics1; RegExp pics2; RegExp isiphost; // access denied address & domain - if they override the defaults std::string access_denied_address; String access_denied_domain; FOptionContainer(): block_downloads(false), banned_page(NULL), banned_phrase_flag(false), exception_site_flag(false), exception_url_flag(false), banned_extension_flag(false), banned_mimetype_flag(false), banned_site_flag(false), banned_url_flag(false), grey_site_flag(false), grey_url_flag(false), banned_regexpurl_flag(false), exception_regexpurl_flag(false), banned_regexpheader_flag(false), content_regexp_flag(false), url_regexp_flag(false), header_regexp_flag(false), exception_extension_flag(false), exception_mimetype_flag(false), exception_file_site_flag(false), exception_file_url_flag(false), log_site_flag(false), log_url_flag(false), log_regexpurl_flag(false) {}; ~FOptionContainer(); bool read(const char *filename); void reset(); bool isOurWebserver(String url); char *inBannedSiteList(String url, bool doblanket = false, bool ip = false, bool ssl = false); char *inBannedURLList(String url, bool doblanket = false, bool ip = false, bool ssl = false); bool inGreySiteList(String url, bool doblanket = false, bool ip = false, bool ssl = false); bool inGreyURLList(String url, bool doblanket = false, bool ip = false, bool ssl = false); bool inExceptionSiteList(String url, bool doblanket = false, bool ip = false, bool ssl = false); bool inExceptionURLList(String url, bool doblanket = false, bool ip = false, bool ssl = false); bool inExceptionFileSiteList(String url); int inBannedRegExpURLList(String url); int inExceptionRegExpURLList(String url); int inBannedRegExpHeaderList(std::deque &header); char *inExtensionList(unsigned int list, String url); bool isIPHostname(String url); // log-only lists - return category const char* inLogURLList(String url); const char* inLogSiteList(String url); const char* inLogRegExpURLList(String url); // get HTML template for this group HTMLTemplate *getHTMLTemplate(); private: // HTML template - if it overrides the default HTMLTemplate *banned_page; bool banned_phrase_flag; bool exception_site_flag; bool exception_url_flag; bool banned_extension_flag; bool banned_mimetype_flag; bool banned_site_flag; bool banned_url_flag; bool grey_site_flag; bool grey_url_flag; bool banned_regexpurl_flag; bool exception_regexpurl_flag; bool banned_regexpheader_flag; bool content_regexp_flag; bool url_regexp_flag; bool header_regexp_flag; bool exception_extension_flag; bool exception_mimetype_flag; bool exception_file_site_flag; bool exception_file_url_flag; bool log_site_flag; bool log_url_flag; bool log_regexpurl_flag; std::deque banned_phrase_list_index; std::deque conffile; bool precompileregexps(); bool readbplfile(const char *banned, const char *exception, const char *weighted); bool readFile(const char *filename, unsigned int* whichlist, bool sortsw, bool cache, const char *listname); bool readRegExMatchFile(const char *filename, const char *listname, unsigned int& listref, std::deque &list_comp, std::deque &list_source, std::deque &list_ref); bool compileRegExMatchFile(unsigned int list, std::deque &list_comp, std::deque &list_source, std::deque &list_ref); bool readRegExReplacementFile(const char *filename, const char *listname, unsigned int& listid, std::deque &list_rep, std::deque &list_comp); int findoptionI(const char *option); std::string findoptionS(const char *option); bool realitycheck(int l, int minl, int maxl, const char *emessage); int inRegExpURLList(String &url, std::deque &list_comp, std::deque &list_ref, unsigned int list); char *inURLList(String &url, unsigned int list, bool doblanket = false, bool ip = false, bool ssl = false); char *inSiteList(String &url, unsigned int list, bool doblanket = false, bool ip = false, bool ssl = false); char *testBlanketBlock(unsigned int list, bool ip, bool ssl); }; #endif dansguardian-2.10.1.1/src/DataBuffer.hpp0000644001165000116500000000570211110523210014604 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@/jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_DATABUFFER #define __HPP_DATABUFFER #include #include "Socket.hpp" #include "String.hpp" #include "FDFuncs.hpp" class DMPlugin; class DataBuffer { public: char *data; off_t buffer_length; char *compresseddata; off_t compressed_buffer_length; off_t tempfilesize; String tempfilepath; bool dontsendbody; // used for fancy download manager for example int tempfilefd; // the download manager we used during the last "in" DMPlugin *dm_plugin; DataBuffer(); DataBuffer(const void* indata, off_t length); ~DataBuffer(); int length() { return buffer_length; }; void copyToMemory(char *location) { memcpy(location, data, buffer_length); }; // read body in from proxy // gives true if it pauses due to too much data bool in(Socket * sock, Socket * peersock, class HTTPHeader * requestheader, class HTTPHeader * docheader, bool runav, int *headersent); // send body to client void out(Socket * sock) throw(std::exception); void setTimeout(int t) { timeout = t; }; void setDecompress(String d) { decompress = d; }; // swap back to compressed version of body data (if data was decompressed but not modified; saves bandwidth) void swapbacktocompressed(); // content regexp search and replace bool contentRegExp(int filtergroup); // create a temp file and return its FD - NOT a simple accessor function int getTempFileFD(); void reset(); private: // DM plugins do horrible things to our innards - this is acceptable pending a proper cleanup friend class DMPlugin; friend class dminstance; #ifdef ENABLE_FANCYDM friend class fancydm; #endif #ifdef ENABLE_TRICKLEDM friend class trickledm; #endif int timeout; off_t bytesalreadysent; bool preservetemp; String decompress; void zlibinflate(bool header); // buffered socket reads - one with an extra "global" timeout within which all individual reads must complete int bufferReadFromSocket(Socket * sock, char *buffer, int size, int sockettimeout); int bufferReadFromSocket(Socket * sock, char *buffer, int size, int sockettimeout, int timeout); }; #endif dansguardian-2.10.1.1/src/OptionContainer.hpp0000644001165000116500000001240211151226431015721 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 // //for the license for this code. //Written by Daniel Barron (daniel@jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_OPTIONCONTAINER #define __HPP_OPTIONCONTAINER // INCLUDES #include "DownloadManager.hpp" #include "ContentScanner.hpp" #include "String.hpp" #include "HTMLTemplate.hpp" #include "ListContainer.hpp" #include "ListManager.hpp" #include "FOptionContainer.hpp" #include "LanguageContainer.hpp" #include "ImageContainer.hpp" #include "RegExp.hpp" #include "Auth.hpp" #include "IPList.hpp" #include // DECLARATIONS class OptionContainer { public: // all our many, many options int filter_groups; int log_exception_hits; bool non_standard_delimiter; int log_file_format; int weighted_phrase_mode; bool show_weighted_found; bool forwarded_for; bool createlistcachefiles; bool use_custom_banned_image; std::string custom_banned_image_file; bool reverse_lookups; bool reverse_client_ip_lookups; bool log_client_hostnames; bool use_xforwardedfor; bool logconerror; bool logchildprocs; int url_cache_number; int url_cache_age; int phrase_filter_mode; int preserve_case; bool hex_decode_content; bool force_quick_search; int filter_port; int proxy_port; std::string proxy_ip; std::deque filter_ip; #ifdef ENABLE_ORIG_IP bool get_orig_ip; #endif int ll; int max_children; int min_children; int maxspare_children; int prefork_children; int minspare_children; int maxage_children; std::string daemon_user_name; std::string daemon_group_name; int proxy_user; int proxy_group; int root_user; int max_ips; bool recheck_replaced_urls; bool use_filter_groups_list; bool use_group_names_list; bool auth_needs_proxy_query; std::string languagepath; std::string filter_groups_list_location; std::string access_denied_address; std::string log_location; std::string stat_location; std::string ipc_filename; std::string urlipc_filename; std::string ipipc_filename; std::string pid_filename; bool no_daemon; bool no_logger; bool log_syslog; unsigned int max_logitem_length; bool anonymise_logs; bool log_ad_blocks; bool log_timestamp; bool log_user_agent; bool soft_restart; #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier std::string mailer; #endif std::string daemon_user; std::string daemon_group; off_t max_upload_size; off_t max_content_filter_size; off_t max_content_ramcache_scan_size; off_t max_content_filecache_scan_size; bool scan_clean_cache; bool content_scan_exceptions; bool delete_downloaded_temp_files; std::string download_dir; int initial_trickle_delay; int trickle_delay; int content_scanner_timeout; HTMLTemplate html_template; ListContainer filter_groups_list; IPList exception_ip_list; IPList banned_ip_list; LanguageContainer language_list; ImageContainer banned_image; std::deque dmplugins; std::deque csplugins; std::deque authplugins; std::deque::iterator dmplugins_begin; std::deque::iterator dmplugins_end; std::deque::iterator csplugins_begin; std::deque::iterator csplugins_end; std::deque::iterator authplugins_begin; std::deque::iterator authplugins_end; ListManager lm; FOptionContainer **fg; int numfg; // access denied domain (when using the CGI) String access_denied_domain; bool loadCSPlugins(); bool loadAuthPlugins(); void deletePlugins(std::deque &list); void deleteFilterGroups(); //...and the functions that read them OptionContainer(); ~OptionContainer(); bool read(const char *filename, int type); void reset(); bool inExceptionIPList(const std::string *ip, std::string *&host); bool inBannedIPList(const std::string *ip, std::string *&host); bool readFilterGroupConf(); // public so fc_controlit can reload filter group config files bool doReadItemList(const char *filename, ListContainer *lc, const char *fname, bool swsort); private: std::deque conffile; String conffilename; int reporting_level; std::string html_template_location; std::string group_names_list_location; bool loadDMPlugins(); bool precompileregexps(); long int findoptionI(const char *option); std::string findoptionS(const char *option); bool realitycheck(long int l, long int minl, long int maxl, const char *emessage); bool readAnotherFilterGroupConf(const char *filename, const char *groupname, bool &need_html); std::deque findoptionM(const char *option); bool inIPList(const std::string *ip, ListContainer& list, std::string *&host); }; #endif dansguardian-2.10.1.1/src/IPList.cpp0000644001165000116500000001430111133377313013753 00000000000000// INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "OptionContainer.hpp" #include "FOptionContainer.hpp" #include #include #include #include #include #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // INPLEMENTATION // clear out the list void IPList::reset() { iplist.clear(); iprangelist.clear(); ipsubnetlist.clear(); hostlist.clear(); } // search for IP in list of individual IPs, ranges, subnets and - if reverse lookups are enabled - hostnames. bool IPList::inList(const std::string &ipstr, std::string *&host) const { struct in_addr addr; inet_aton(ipstr.c_str(), &addr); uint32_t ip = ntohl(addr.s_addr); // start with individual IPs if (std::binary_search(iplist.begin(), iplist.end(), ip)) { // only return a hostname if that's what we matched against delete host; host = NULL; return true; } // ranges for(std::list::const_iterator i = iprangelist.begin(); i != iprangelist.end(); ++i) { if ((ip >= i->startaddr) && (ip <= i->endaddr)) { delete host; host = NULL; return true; } } // subnets for(std::list::const_iterator i = ipsubnetlist.begin(); i != ipsubnetlist.end(); ++i) { if (i->maskedaddr == (ip & i->mask)) { delete host; host = NULL; return true; } } // hostnames // TODO - take in a suggested hostname, look up only if not supplied, and return suggestion if found if (o.reverse_client_ip_lookups) { std::auto_ptr > hostnames; if (host == NULL) hostnames.reset(ipToHostname(ipstr.c_str())); else { hostnames.reset(new std::deque); hostnames->push_back(*host); } for (std::deque::iterator i = hostnames->begin(); i != hostnames->end(); ++i) { if (std::binary_search(hostlist.begin(), hostlist.end(), *i)) { delete host; host = new std::string(i->toCharArray()); return true; } } // Even if we don't match anything, return a hostname // if desired for logging and we don't already have one. if (o.log_client_hostnames && (host == NULL) && (hostnames->size() > 0)) host = new std::string(hostnames->front().toCharArray()); } return false; } // read in a list linking IPs, subnets & IP ranges to filter groups bool IPList::readIPMelangeList(const char *filename) { // load in the list file std::ifstream input ( filename ); if (!input) { if (!is_daemonised) { std::cerr << "Error reading file (does it exist?): " << filename << std::endl; } syslog(LOG_ERR, "%s%s","Error reading file (does it exist?): ",filename); return false; } // compile regexps for determining whether a list entry is an IP, a subnet (IP + mask), or a range RegExp matchIP, matchSubnet, matchRange; #ifdef HAVE_PCRE matchIP.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); matchSubnet.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); matchRange.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}-\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); #else matchIP.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); matchSubnet.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); matchRange.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}-[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); #endif // read in the file String line; char buffer[ 2048 ]; while (input) { if (!input.getline(buffer, sizeof( buffer ))) { break; } // ignore comments if (buffer[0] == '#') continue; // ignore blank lines if (strlen(buffer) < 7) continue; line = buffer; #ifdef DGDEBUG std::cout << "line: " << line << std::endl; #endif // store the IP address (numerically, not as a string) and filter group in either the IP list, subnet list or range list if (matchIP.match(line.toCharArray())) { struct in_addr address; if (inet_aton(line.toCharArray(), &address)) { uint32_t addr = ntohl(address.s_addr); iplist.push_back(addr); } } else if (matchSubnet.match(line.toCharArray())) { struct in_addr address; struct in_addr addressmask; String subnet(line.before("/")); String mask(line.after("/")); if (inet_aton(subnet.toCharArray(), &address) && inet_aton(mask.toCharArray(), &addressmask)) { ipl_subnetstruct s; uint32_t addr = ntohl(address.s_addr); s.mask = ntohl(addressmask.s_addr); // pre-mask the address for quick comparison s.maskedaddr = addr & s.mask; ipsubnetlist.push_back(s); } } else if (matchRange.match(line.toCharArray())) { struct in_addr addressstart; struct in_addr addressend; String start(line.before("-")); String end(line.after("-")); if (inet_aton(start.toCharArray(), &addressstart) && inet_aton(end.toCharArray(), &addressend)) { ipl_rangestruct r; r.startaddr = ntohl(addressstart.s_addr); r.endaddr = ntohl(addressend.s_addr); iprangelist.push_back(r); } } // hmmm. the line didn't match any of our regular expressions. // assume it's a hostname. else { hostlist.push_back(line); } } input.close(); #ifdef DGDEBUG std::cout << "starting sort" << std::endl; #endif std::sort(iplist.begin(), iplist.end()); std::sort(hostlist.begin(), hostlist.end()); #ifdef DGDEBUG std::cout << "sort complete" << std::endl; std::cout << "ip list dump:" << std::endl; std::vector::iterator i = iplist.begin(); while (i != iplist.end()) { std::cout << "IP: " << *i << std::endl; ++i; } std::cout << "subnet list dump:" << std::endl; std::list::iterator j = ipsubnetlist.begin(); while (j != ipsubnetlist.end()) { std::cout << "Masked IP: " << j->maskedaddr << " Mask: " << j->mask << std::endl; ++j; } std::cout << "range list dump:" << std::endl; std::list::iterator k = iprangelist.begin(); while (k != iprangelist.end()) { std::cout << "Start IP: " << k->startaddr << " End IP: " << k->endaddr << std::endl; ++k; } std::cout << "host list dump:" << std::endl; std::vector::iterator l = hostlist.begin(); while (l != hostlist.end()) { std::cout << "Hostname: " << *l << std::endl; ++l; } #endif return true; } dansguardian-2.10.1.1/src/dansguardian.cpp0000644001165000116500000003350511133377302015254 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "FatController.hpp" #include "SysV.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __BENCHMARK #include #include "NaughtyFilter.hpp" #endif // GLOBALS #ifndef FD_SETSIZE #define FD_SETSIZE 256 #endif OptionContainer o; bool is_daemonised; // regexp used during URL decoding by HTTPHeader // we want it compiled once, not every time it's used, so do so on startup RegExp urldecode_re; #ifdef HAVE_PCRE // regexes used for embedded URL extraction by NaughtyFilter RegExp absurl_re, relurl_re; #endif // DECLARATIONS // get the OptionContainer to read in the given configuration file void read_config(const char *configfile, int type); // IMPLEMENTATION // get the OptionContainer to read in the given configuration file void read_config(const char *configfile, int type) { int rc = open(configfile, 0, O_RDONLY); if (rc < 0) { syslog(LOG_ERR, "Error opening %s", configfile); std::cerr << "Error opening " << configfile << std::endl; exit(1); // could not open conf file for reading, exit with error } close(rc); if (!o.read(configfile, type)) { syslog(LOG_ERR, "%s", "Error parsing the dansguardian.conf file or other DansGuardian configuration files"); std::cerr << "Error parsing the dansguardian.conf file or other DansGuardian configuration files" << std::endl; exit(1); // OptionContainer class had an error reading the conf or other files so exit with error } } // program entry point int main(int argc, char *argv[]) { is_daemonised = false; bool nodaemon = false; bool needreset = false; std::string configfile(__CONFFILE); srand(time(NULL)); int rc; openlog("dansguardian", LOG_PID | LOG_CONS, LOG_USER); #ifdef DGDEBUG std::cout << "Running in debug mode..." << std::endl; #endif #ifdef __BENCHMARK char benchmark = '\0'; #endif for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (unsigned int j = 1; j < strlen(argv[i]); j++) { char option = argv[i][j]; bool dobreak = false; switch (option) { case 'q': read_config(configfile.c_str(), 0); return sysv_kill(o.pid_filename); case 'Q': read_config(configfile.c_str(), 0); sysv_kill(o.pid_filename, false); // give the old process time to die while(sysv_amirunning(o.pid_filename)) sleep(1); unlink(o.pid_filename.c_str()); unlink(o.ipc_filename.c_str()); unlink(o.urlipc_filename.c_str()); // remember to reset config before continuing needreset = true; break; case 's': read_config(configfile.c_str(), 0); return sysv_showpid(o.pid_filename); case 'r': read_config(configfile.c_str(), 0); return sysv_hup(o.pid_filename); case 'g': read_config(configfile.c_str(), 0); return sysv_usr1(o.pid_filename); case 'v': std::cout << "DansGuardian " << PACKAGE_VERSION << std::endl << std::endl << "Built with: " << DG_CONFIGURE_OPTIONS << std::endl; return 0; case 'N': nodaemon = true; break; case 'c': if ((i+1) < argc) { configfile = argv[i+1]; dobreak = true; // broken-ness of this option reported by Jason Gauthier 2006-03-09 } else { std::cerr << "No config file specified!" << std::endl; return 1; } break; case 'h': std::cout << "Usage: " << argv[0] << " [{-c ConfigFileName|-v|-P|-h|-N|-q|-s|-r|-g}]" << std::endl; std::cout << " -v gives the version number and build options." << std::endl; std::cout << " -h gives this message." << std::endl; std::cout << " -c allows you to specify a different configuration file location." << std::endl; std::cout << " -N Do not go into the background." << std::endl; std::cout << " -q causes DansGuardian to kill any running copy." << std::endl; std::cout << " -Q kill any running copy AND start a new one with current options." << std::endl; std::cout << " -s shows the parent process PID and exits." << std::endl; std::cout << " -r closes all connections and reloads config files by issuing a HUP," << std::endl; std::cout << " but this does not reset the maxchildren option (amongst others)." << std::endl; std::cout << " -g gently restarts by not closing all current connections; only reloads" << std::endl << " filter group config files. (Issues a USR1)" << std::endl; #ifdef __BENCHMARK std::cout << " --bs benchmark searching filter group 1's bannedsitelist" << std::endl; std::cout << " --bu benchmark searching filter group 1's bannedurllist" << std::endl; std::cout << " --bp benchmark searching filter group 1's phrase lists" << std::endl; std::cout << " --bn benchmark filter group 1's NaughtyFilter in its entirety" << std::endl; #endif return 0; #ifdef __BENCHMARK case '-': if (strlen(argv[i]) != 4) { std::cerr << "Invalid benchmark option" << std::endl; return 1; } benchmark = argv[i][3]; dobreak = true; break; #endif } if (dobreak) break; // skip to the next argument } } } // Set current locale for proper character conversion setlocale(LC_ALL, ""); if (needreset) { o.reset(); } read_config(configfile.c_str(), 2); #ifdef __BENCHMARK // run benchmarks instead of starting the daemon if (benchmark) { std::string results; char* found; struct tms then, now; std::string line; std::deque lines; while (!std::cin.eof()) { std::getline(std::cin, line); String* strline = new String(line); lines.push_back(strline); } String* strline = NULL; times(&then); switch (benchmark) { case 's': // bannedsitelist while (!lines.empty()) { strline = lines.back(); lines.pop_back(); if ((found = o.fg[0]->inBannedSiteList(*strline))) { results += found; results += '\n'; } delete strline; } break; case 'u': // bannedurllist while (!lines.empty()) { strline = lines.back(); lines.pop_back(); if ((found = o.fg[0]->inBannedURLList(*strline))) { results += found; results += '\n'; } delete strline; } break; case 'p': { // phraselists std::deque found; std::string file; while (!lines.empty()) { strline = lines.back(); lines.pop_back(); file += strline->toCharArray(); delete strline; } char cfile[file.length() + 129]; memcpy(cfile, file.c_str(), sizeof(char)*file.length()); o.lm.l[o.fg[0]->banned_phrase_list]->graphSearch(found, cfile, file.length()); for (std::deque::iterator i = found.begin(); i != found.end(); i++) { results += o.lm.l[o.fg[0]->banned_phrase_list]->getItemAtInt(*i); results += '\n'; } } break; case 'n': { // NaughtyFilter std::string file; NaughtyFilter n; while (!lines.empty()) { strline = lines.back(); lines.pop_back(); file += strline->toCharArray(); delete strline; } DataBuffer d(file.c_str(), file.length()); String f; n.checkme(&d, f, f); std::cout << n.isItNaughty << std::endl << n.whatIsNaughty << std::endl << n.whatIsNaughtyLog << std::endl << n.whatIsNaughtyCategories << std::endl; } break; default: std::cerr << "Invalid benchmark option" << std::endl; return 1; } times(&now); std::cout << results << std::endl << "time: " << now.tms_utime - then.tms_utime << std::endl; return 0; } #endif if (sysv_amirunning(o.pid_filename)) { syslog(LOG_ERR, "%s", "I seem to be running already!"); std::cerr << "I seem to be running already!" << std::endl; return 1; // can't have two copies running!! } if (nodaemon) { o.no_daemon = 1; } if ((o.max_children + 6) > FD_SETSIZE) { syslog(LOG_ERR, "%s", "maxchildren option in dansguardian.conf has a value too high."); std::cerr << "maxchildren option in dansguardian.conf has a value too high." << std::endl; std::cerr << "Dammit Jim, I'm a filtering proxy, not a rabbit." << std::endl; return 1; // we can't have rampant proccesses can we? } unsigned int rootuid; // prepare a struct for use later rootuid = geteuid(); o.root_user = rootuid; struct passwd *st; // prepare a struct struct group *sg; // "daemongroup" option exists, but never used to be honoured. this is now // an important feature, however, because we need to be able to create temp // files with suitable permissions for scanning by AV daemons - we do this // by becoming a member of a specified AV group and setting group read perms if ((sg = getgrnam(o.daemon_group_name.c_str())) != 0) { o.proxy_group = sg->gr_gid; } else { syslog(LOG_ERR, "Unable to getgrnam(): %s", strerror(errno)); std::cerr << "Unable to getgrnam(): " << strerror(errno) << std::endl; return 1; } if ((st = getpwnam(o.daemon_user_name.c_str())) != 0) { // find uid for proxy user o.proxy_user = st->pw_uid; rc = setgid(o.proxy_group); // change to rights of proxy user group // i.e. low - for security if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to setgid()"); std::cerr << "Unable to setgid()" << std::endl; return 1; // setgid failed for some reason so exit with error } #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, st->pw_uid); #else rc = seteuid(o.proxy_user); // need to be euid so can su back // (yes it negates but no choice) #endif if (rc == -1) { syslog(LOG_ERR, "Unable to seteuid()"); std::cerr << "Unable to seteuid()" << std::endl; return 1; // seteuid failed for some reason so exit with error } } else { syslog(LOG_ERR, "Unable to getpwnam() - does the proxy user exist?"); std::cerr << "Unable to getpwnam() - does the proxy user exist?" << std::endl; std::cerr << "Proxy user looking for is '" << o.daemon_user_name << "'" << std::endl; return 1; // was unable to lockup the user id from passwd // for some reason, so exit with error } if (!o.no_logger && !o.log_syslog) { std::ofstream logfiletest(o.log_location.c_str(), std::ios::app); if (logfiletest.fail()) { syslog(LOG_ERR, "Error opening/creating log file. (check ownership and access rights)."); std::cout << "Error opening/creating log file. (check ownership and access rights)." << std::endl; std::cout << "I am running as " << o.daemon_user_name << " and I am trying to open " << o.log_location << std::endl; return 1; // opening the log file for writing failed } logfiletest.close(); } urldecode_re.comp("%[0-9a-fA-F][0-9a-fA-F]"); // regexp for url decoding #ifdef HAVE_PCRE // todo: these only work with PCRE enabled (non-greedy matching). // change them, or make them a feature for which you need PCRE? absurl_re.comp("[\"'](http|ftp)://.*?[\"']"); // find absolute URLs in quotes relurl_re.comp("(href|src)\\s*=\\s*[\"'].*?[\"']"); // find relative URLs in quotes #endif // this is no longer a class, but the comment has been retained for historical reasons. PRA 03-10-2005 //FatController f; // Thomas The Tank Engine while (true) { rc = fc_controlit(); // its a little messy, but I wanted to split // all the ground work and non-daemon stuff // away from the daemon class // However the line is not so fine. if (rc == 2) { // In order to re-read the conf files and create cache files // we need to become root user again #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, rootuid); #else rc = seteuid(rootuid); #endif if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to seteuid() to read conf files."); #ifdef DGDEBUG std::cerr << "Unable to seteuid() to read conf files." << std::endl; #endif return 1; } #ifdef DGDEBUG std::cout << "About to re-read conf file." << std::endl; #endif o.reset(); if (!o.read(configfile.c_str(), 2)) { syslog(LOG_ERR, "%s", "Error re-parsing the dansguardian.conf file or other DansGuardian configuration files"); #ifdef DGDEBUG std::cerr << "Error re-parsing the dansguardian.conf file or other DansGuardian configuration files" << std::endl; #endif return 1; // OptionContainer class had an error reading the conf or // other files so exit with error } #ifdef DGDEBUG std::cout << "conf file read." << std::endl; #endif if (nodaemon) { o.no_daemon = 1; } while (waitpid(-1, NULL, WNOHANG) > 0) { } // mop up defunts #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, st->pw_uid); #else rc = seteuid(st->pw_uid); // become low priv again #endif if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to re-seteuid()"); #ifdef DGDEBUG std::cerr << "Unable to re-seteuid()" << std::endl; #endif return 1; // seteuid failed for some reason so exit with error } continue; } if (rc > 0) { if (!is_daemonised) { std::cerr << "Exiting with error" << std::endl; } syslog(LOG_ERR, "%s", "Exiting with error"); return rc; // exit returning the error number } return 0; // exit without error } } dansguardian-2.10.1.1/src/BaseSocket.hpp0000644001165000116500000001031111110523210014614 00000000000000// BaseSocket class - inherit & implement to make UNIX/INET domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_BASESOCKET #define __HPP_BASESOCKET // INCLUDES #include #include #include #include #include #include #include int selectEINTR(int numfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout, bool honour_reloadconfig = false); class BaseSocket { public: // create socket from FD - must be overridden to clear the relevant address structs in derived classes BaseSocket(int fd); // make a socket a listening server socket int listen(int queue); // grab socket's FD, e.g. for passing to selectEINTR // use sparingly, and DO NOT do manual data transfer with it int getFD(); // close socket void close(); // set socket-wide timeout (is this actually used? all methods accept their own individual timeouts) void setTimeout(int t); // get timeout (is this actually used?) int getTimeout(); // close & reset the connection - these must clear address structures & call baseReset/baseAccept virtual void reset()=0; virtual BaseSocket* accept()=0; // non-blocking check for input data bool checkForInput(); // blocking check for data, can be told to break on signal triggered config reloads (-r) void checkForInput(int timeout, bool honour_reloadconfig = false) throw(std::exception); // non-blocking check for writable socket bool readyForOutput(); // blocking check, can break on config reloads void readyForOutput(int timeout, bool honour_reloadconfig = false) throw(std::exception); // get a line from the socket - can break on config reloads int getLine(char *buff, int size, int timeout, bool honour_reloadconfig = false, bool *chopped = NULL) throw(std::exception); // write buffer to string - throws std::exception on error void writeString(const char *line) throw(std::exception); // write buffer to string - can be told not to do an initial readyForOutput, and told to break on -r bool writeToSocket(const char *buff, int len, unsigned int flags, int timeout, bool check_first = true, bool honour_reloadconfig = false); // read from socket, returning number of bytes read int readFromSocketn(char *buff, int len, unsigned int flags, int timeout); // read from socket, returning error status - can be told to skip initial checkForInput, and to break on -r int readFromSocket(char *buff, int len, unsigned int flags, int timeout, bool check_first = true, bool honour_reloadconfig = false); // write to socket, throwing std::exception on error - can be told to break on -r void writeToSockete(const char *buff, int len, unsigned int flags, int timeout, bool honour_reloadconfig = false) throw(std::exception); protected: // socket-wide timeout (is this actually used?) int timeout; // length of address of other end of socket (e.g. size of sockaddr_in or sockaddr_un) socklen_t peer_adr_length; // socket FD int sck; // internal buffer char buffer[1024]; int buffstart; int bufflen; // constructor - sets default values. override this if you actually wish to create a default socket. BaseSocket(); // destructor - closes socket virtual ~BaseSocket(); // performs accept(). call from derived classes' accept method int baseAccept(struct sockaddr *acc_adr, socklen_t *acc_adr_length); // closes socket & resets timeout to default - call from derived classes' reset method void baseReset(); }; #endif dansguardian-2.10.1.1/src/IPList.hpp0000644001165000116500000000304711110523210013745 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 // //for the license for this code. //Written by Daniel Barron (daniel@jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_IPLIST #define __HPP_IPLIST // INCLUDES #include // DECLARATIONS // convenience structs for subnets and IP ranges struct ipl_subnetstruct { uint32_t maskedaddr; uint32_t mask; }; struct ipl_rangestruct { uint32_t startaddr; uint32_t endaddr; }; // IP subnet/range/mask & hostname list class IPList { public: void reset(); bool inList(const std::string &ipstr, std::string *&host) const; bool readIPMelangeList(const char *filename); private: std::vector iplist; std::vector hostlist; std::list iprangelist; std::list ipsubnetlist; }; #endif dansguardian-2.10.1.1/src/ImageContainer.hpp0000644001165000116500000000257311110523210015471 00000000000000// ImageContainer - container class for custom banned image //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_IMAGECONTAINER #define __HPP_IMAGECONTAINER // INCLUDES #include "Socket.hpp" #include "String.hpp" class ImageContainer { public: ImageContainer(); ~ImageContainer(); // wipe loaded image void reset(); // read image from file bool read(const char *filename); // send image to client void display(Socket * s); private: long int imagelength; String mimetype; char *image; }; #endif dansguardian-2.10.1.1/src/ContentScanner.cpp0000644001165000116500000002626211133377311015542 00000000000000// Implements CSPlugin class and cs_plugin_loader base class //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "ContentScanner.hpp" #include "ConfigVar.hpp" #include "OptionContainer.hpp" #include #include #include #include #include #include #include #include // GLOBALS extern bool is_daemonised; extern OptionContainer o; // find the class factory functions for the CS plugins we've been configured to build #ifdef ENABLE_CLAMD extern cscreate_t clamdcreate; #endif #ifdef HAVE_CLAMAV extern cscreate_t clamavcreate; #endif #ifdef ENABLE_ICAP extern cscreate_t icapcreate; #endif #ifdef HAVE_KAVCLIENT extern cscreate_t kavavcreate; #endif #ifdef ENABLE_KAVD extern cscreate_t kavdcreate; #endif #ifdef ENABLE_COMMANDLINE extern cscreate_t commandlinecreate; #endif // IMPLEMENTATION // CSPlugin class CSPlugin::CSPlugin(ConfigVar & definition) { cv = definition; } // start the plugin - i.e. read in the configuration int CSPlugin::init(void* args) { if (!readStandardLists()) { //always return DGCS_ERROR; //include } // these return DGCS_OK; } // make a temporary file for storing data which is to be scanned // returns FD in int and saves filename to String pointer // filename is not used as input int CSPlugin::makeTempFile(String * filename) { int tempfilefd; String tempfilepath(o.download_dir.c_str()); tempfilepath += "/tfXXXXXX"; char *tempfilepatharray = new char[tempfilepath.length() + 1]; strcpy(tempfilepatharray, tempfilepath.toCharArray()); if ((tempfilefd = mkstemp(tempfilepatharray)) < 1) { #ifdef DGDEBUG std::cerr << "error creating cs temp " << tempfilepath << ": " << strerror(errno) << std::endl; #endif syslog(LOG_ERR, "%s", "Could not create cs temp file."); tempfilefd = -1; } else { (*filename) = tempfilepatharray; } delete[]tempfilepatharray; return tempfilefd; } // write a temporary file containing the memory buffer which is to be scanned // if your CS plugin does not have the ability to scan memory directly (e.g. clamdscan), this gets used by the default scanMemory to turn it into a file int CSPlugin::writeMemoryTempFile(const char *object, unsigned int objectsize, String * filename) { int tempfd = makeTempFile(filename); // String gets modified if (tempfd < 0) { #ifdef DGDEBUG std::cerr << "Error creating temp file in writeMemoryTempFile." << std::endl; #endif syslog(LOG_ERR, "%s", "Error creating temp file in writeMemoryTempFile."); return DGCS_ERROR; } errno = 0; #ifdef DGDEBUG std::cout << "About to writeMemoryTempFile " << (*filename) << " size: " << objectsize << std::endl; #endif while (true) { if (write(tempfd, object, objectsize) < 0) { if (errno == EINTR) { continue; // was interupted by a signal so restart } } break; // end the while } close(tempfd); // finished writing so close file return DGCS_OK; // all ok } // default implementation of scanMemory, which defers to scanFile. int CSPlugin::scanMemory(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize) { // there is no capability to scan memory with some AV as we pass it // a file name to scan. So we save the memory to disk and pass that. // Then delete the temp file. String tempfilepath; if (writeMemoryTempFile(object, objectsize, &tempfilepath) != DGCS_OK) { #ifdef DGDEBUG std::cerr << "Error creating/writing temp file for scanMemory." << std::endl; #endif syslog(LOG_ERR, "%s", "Error creating/writing temp file for scanMemory."); return DGCS_SCANERROR; } int rc = scanFile(requestheader, docheader, user, filtergroup, ip, tempfilepath.toCharArray()); #ifndef DGDEBUG unlink(tempfilepath.toCharArray()); // delete temp file #endif return rc; } // read in all the lists of various things we do not wish to scan bool CSPlugin::readStandardLists() { exceptionvirusmimetypelist.reset(); // incase this is a reload exceptionvirusextensionlist.reset(); exceptionvirussitelist.reset(); exceptionvirusurllist.reset(); if (!exceptionvirusmimetypelist.readItemList(cv["exceptionvirusmimetypelist"].toCharArray(), false, 0)) { if (!is_daemonised) { std::cerr << "Error opening exceptionvirusmimetypelist" << std::endl; } syslog(LOG_ERR, "%s", "Error opening exceptionvirusmimetypelist"); return false; } exceptionvirusmimetypelist.doSort(false); if (!exceptionvirusextensionlist.readItemList(cv["exceptionvirusextensionlist"].toCharArray(), false, 0)) { if (!is_daemonised) { std::cerr << "Error opening exceptionvirusextensionlist" << std::endl; } syslog(LOG_ERR, "%s", "Error opening exceptionvirusextensionlist"); return false; } exceptionvirusextensionlist.doSort(false); if (!exceptionvirussitelist.readItemList(cv["exceptionvirussitelist"].toCharArray(), false, 0)) { if (!is_daemonised) { std::cerr << "Error opening exceptionvirussitelist" << std::endl; } syslog(LOG_ERR, "%s", "Error opening exceptionvirussitelist"); return false; } exceptionvirussitelist.doSort(false); if (!exceptionvirusurllist.readItemList(cv["exceptionvirusurllist"].toCharArray(), true, 0)) { if (!is_daemonised) { std::cerr << "Error opening exceptionvirusurllist" << std::endl; } syslog(LOG_ERR, "%s", "Error opening exceptionvirusurllist"); return false; } exceptionvirusurllist.doSort(true); return true; } // test whether or not a request should be scanned based on sent & received headers int CSPlugin::scanTest(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip) { char *i; //exceptionvirusmimetypelist String mimetype(docheader->getContentType()); #ifdef DGDEBUG std::cout<<"mimetype: "<disposition()); #ifdef DGDEBUG std::cout<<"disposition: "<url()); String urld(requestheader->decode(url)); urld.removeWhiteSpace(); urld.toLower(); urld.removePTP(); String domain, tempurl, foundurl, path, extension; unsigned int fl; if (urld.contains("/")) { domain = urld.before("/"); path = "/" + urld.after("/"); path.hexDecode(); path.realPath(); } else { domain = urld; } // don't scan our web server if (((o.fg[filtergroup]->reporting_level == 1) || (o.fg[filtergroup]->reporting_level == 2)) && domain.startsWith(o.fg[filtergroup]->access_denied_domain)) { return DGCS_NOSCAN; } //exceptionvirusextensionlist if (disposition.length() > 2) { extension = disposition; while (extension.contains(".")) { extension = extension.after("."); } extension = "." + extension; } else { if (!path.contains("?")) { extension = path; } else if (mimetype.contains("application/")) { extension = path; if (extension.contains("?")) { extension = extension.before("?"); } } } #ifdef DGDEBUG std::cout<<"extension: "< 1) { // allows matching of .tld tempurl = "." + tempurl; i = exceptionvirussitelist.findInList(tempurl.toCharArray()); if (i != NULL) { return DGCS_NOSCAN; // exact match } } // exceptionvirusurllist tempurl = domain + path; if (tempurl.endsWith("/")) { tempurl.chop(); // chop off trailing / if any } while (tempurl.before("/").contains(".")) { i = exceptionvirusurllist.findStartsWith(tempurl.toCharArray()); if (i != NULL) { foundurl = i; fl = foundurl.length(); if (tempurl.length() > fl) { unsigned char c = tempurl[fl]; if (c == '/' || c == '?' || c == '&' || c == '=') { return DGCS_NOSCAN; // matches /blah/ or /blah/foo but not /blahfoo } } else { return DGCS_NOSCAN; // exact match } } tempurl = tempurl.after("."); // check for being in higher level domains } #ifdef DGDEBUG std::cout << "URL " << url << " is going to need AV scanning." << std::endl; #endif return DGCS_NEEDSCAN; } // take in a configuration file, find the CSPlugin class associated with the plugname variable, and return an instance CSPlugin* cs_plugin_load(const char *pluginConfigPath) { ConfigVar cv; if (cv.readVar(pluginConfigPath, "=") > 0) { if (!is_daemonised) { std::cerr << "Unable to load plugin config: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable to load plugin config %s", pluginConfigPath); return NULL; } String plugname(cv["plugname"]); if (plugname.length() < 1) { if (!is_daemonised) { std::cerr << "Unable read plugin config plugname variable: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable read plugin config plugname variable %s", pluginConfigPath); return NULL; } #ifdef ENABLE_CLAMD if (plugname == "clamdscan") { #ifdef DGDEBUG std::cout << "Enabling ClamDscan CS plugin" << std::endl; #endif return clamdcreate(cv); } #endif #ifdef HAVE_CLAMAV if (plugname == "clamav") { #ifdef DGDEBUG std::cout << "Enabling ClamAV CS plugin" << std::endl; #endif return clamavcreate(cv); } #endif #ifdef HAVE_KAVCLIENT if (plugname == "kavav") { #ifdef DGDEBUG std::cout << "Enabling KAVClient CS plugin" << std::endl; #endif return kavavcreate(cv); } #endif #ifdef ENABLE_KAVD if (plugname == "kavdscan") { #ifdef DGDEBUG std::cout << "Enabling KAVDscan CS plugin" << std::endl; #endif return kavdcreate(cv); } #endif #ifdef ENABLE_ICAP if (plugname == "icapscan") { #ifdef DGDEBUG std::cout << "Enabling ICAPscan CS plugin" << std::endl; #endif return icapcreate(cv); } #endif #ifdef ENABLE_COMMANDLINE if (plugname == "commandlinescan") { #ifdef DGDEBUG std::cout << "Enabling command-line CS plugin" << std::endl; #endif return commandlinecreate(cv); } #endif if (!is_daemonised) { std::cerr << "Unable to load plugin: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable to load plugin %s\n", pluginConfigPath); return NULL; } dansguardian-2.10.1.1/src/DownloadManager.cpp0000644001165000116500000001543211110523210015637 00000000000000// Implements dm_plugin_load and base DMPlugin methods //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "DownloadManager.hpp" #include "ConfigVar.hpp" #include "OptionContainer.hpp" #include "RegExp.hpp" #include #include #include #include #include #include // GLOBALS extern bool is_daemonised; extern OptionContainer o; extern dmcreate_t defaultdmcreate; // find the class factory functions for any DM plugins we've been configured to build #ifdef ENABLE_FANCYDM extern dmcreate_t fancydmcreate; #endif #ifdef ENABLE_TRICKLEDM extern dmcreate_t trickledmcreate; #endif // IMPLEMENTATION // // DMPlugin // // constructor DMPlugin::DMPlugin(ConfigVar &definition):alwaysmatchua(false), cv(definition) { } // default initialisation procedure int DMPlugin::init(void* args) { bool lastplugin = *((bool*)args); if (!lastplugin) { // compile regex for matching supported user agents String r(cv["useragentregexp"]); if (r.length() > 0) { #ifdef DGDEBUG std::cout<<"useragent regexp: "<Scan complete.

Click here to download: " String message(o.language_list.getTranslation(1220)); message += "" + prettyurl + "

\n"; peersock.writeString(message.toCharArray()); } // default method for deciding whether we will handle a request bool DMPlugin::willHandle(HTTPHeader *requestheader, HTTPHeader *docheader) { // match user agent first (quick) if (!(alwaysmatchua || ua_match.match(requestheader->userAgent().toCharArray()))) return false; // then check standard lists (mimetypes & extensions) // mimetypes String mimetype(""); bool matchedmime = false; if (mimelistenabled) { mimetype = docheader->getContentType(); #ifdef DGDEBUG std::cout<<"mimetype: "<decode(requestheader->url())); path.removeWhiteSpace(); path.toLower(); path.removePTP(); path = path.after("/"); path.hexDecode(); path.realPath(); String disposition(docheader->disposition()); String extension; if (disposition.length() > 2) { extension = disposition; while (extension.contains(".")) { extension = extension.after("."); } extension = "." + extension; } else { if (!path.contains("?")) { extension = path; } else { if (mimetype.length() == 0) mimetype = docheader->getContentType(); if (mimetype.contains("application/")) { extension = path; if (extension.contains("?")) { extension = extension.before("?"); } } } } #ifdef DGDEBUG std::cout<<"extension: "< 0) { if (!mimetypelist.readItemList(filename.toCharArray(), false, 0)) { if (!is_daemonised) { std::cerr << "Error opening managedmimetypelist" << std::endl; } syslog(LOG_ERR, "Error opening managedmimetypelist"); return false; } mimetypelist.doSort(false); mimelistenabled = true; } else { mimelistenabled = false; } filename = cv["managedextensionlist"]; if (filename.length() > 0) { if (!extensionlist.readItemList(filename.toCharArray(), false, 0)) { if (!is_daemonised) { std::cerr << "Error opening managedextensionlist" << std::endl; } syslog(LOG_ERR, "Error opening managedextensionlist"); return false; } extensionlist.doSort(false); extensionlistenabled = true; } else { extensionlistenabled = false; } return true; } // take in a DM plugin configuration file, find the DMPlugin descendent matching the value of plugname, and store its class factory funcs for later use DMPlugin* dm_plugin_load(const char *pluginConfigPath) { ConfigVar cv; if (cv.readVar(pluginConfigPath, "=") > 0) { if (!is_daemonised) { std::cerr << "Unable to load plugin config: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable to load plugin config %s", pluginConfigPath); return NULL; } String plugname(cv["plugname"]); if (plugname.length() < 1) { if (!is_daemonised) { std::cerr << "Unable read plugin config plugname variable: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable read plugin config plugname variable %s", pluginConfigPath); return NULL; } if (plugname == "default") { #ifdef DGDEBUG std::cout << "Enabling default DM plugin" << std::endl; #endif return defaultdmcreate(cv); } #ifdef ENABLE_FANCYDM if (plugname == "fancy") { #ifdef DGDEBUG std::cout << "Enabling fancy DM plugin" << std::endl; #endif return fancydmcreate(cv); } #endif #ifdef ENABLE_TRICKLEDM if (plugname == "trickle") { #ifdef DGDEBUG std::cout << "Enabling trickle DM plugin" << std::endl; #endif return trickledmcreate(cv); } #endif if (!is_daemonised) { std::cerr << "Unable to load plugin: " << plugname << std::endl; } syslog(LOG_ERR, "Unable to load plugin %s", plugname.toCharArray()); return NULL; } dansguardian-2.10.1.1/src/SysV.cpp0000644001165000116500000001347711110523210013510 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@ //jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "SysV.hpp" #include #include #include #include #include #include #include #include #include // GLOBALS extern OptionContainer o; // DECLARATIONS // get the PID from the given file, or by looking for "dansguardian" process by name - returns -1 if process not running pid_t getpid(std::string pidfile); // read process number from file (straight file read, no is-it-running check) pid_t getpidfromfile(std::string pidfile); // get PID from processes matching this command name (UNIMPLEMENTED) pid_t getpidfromcommand(const char *command); // confirm pid corresponds to a currently running process bool confirmname(pid_t p); // IMPLEMENTATION // grab the PID from the file & check it's running (returns -1 on failure) // (also checks process names if file method fails, but this is unimplemented) pid_t getpid(std::string pidfile) { pid_t p = getpidfromfile(pidfile); if (p > 1) { if (confirmname(p)) { // is that pid really DG and running? return p; // it is so return it } } pid_t t = getpidfromcommand("dansguardian"); // pid file method failed // so try a search from the // command return t; // if it failed t will be -1 } // grab process number from file (no run check) pid_t getpidfromfile(std::string pidfile) { int handle = open(pidfile.c_str(), O_RDONLY); if (handle < 0) { // Unable to open the pid file. return -1; } char pidbuff[32]; int rc = read(handle, pidbuff, sizeof(pidbuff) - 1); if (rc < 1) { // pid file must be at least 1 byte long close(handle); return -1; } pidbuff[rc] = '\0'; close(handle); return atoi(pidbuff); // convert the string to a pid } // grab process number from processes matching the given command pid_t getpidfromcommand(const char *command) { return -1; // ******** NOT IMPLEMENTED YET ************ // only needed if the pid file gets deleted. //I KNOW HOW TO DO THIS IN A PORTABLE LINUX/BSD WAY //BUT I HAVE NOT HAD THE TIME TO ADD IT YET AS THIS //IS FUNCTIONAL ENOUGH TO WORK } // check the given PID is alive and running bool confirmname(pid_t p) { int rc =::kill(p, 0); // just a test if (rc != 0) { if (errno == EPERM) { return true; // we got no perms to test it but it must be there } return false; // no process running at that pid } // ******** NOT FULLY IMPLEMENTED YET ************ //I KNOW HOW TO DO THIS IN A PORTABLE LINUX/BSD WAY //BUT I HAVE NOT HAD THE TIME TO ADD IT YET AS THIS //IS FUNCTIONAL ENOUGH TO WORK return true; } // kill process in the pidfile, optionally deleting the pidfile & URL cache/logger IPC sockets int sysv_kill(std::string pidfile, bool dounlink) { pid_t p = getpid(pidfile); if (p > 1) { int rc =::kill(p, SIGTERM); if (rc == -1) { std::cerr << "Error trying to kill pid:" << p << std::endl; if (errno == EPERM) { std::cerr << "Permission denied." << std::endl; } return 1; } if (dounlink) { unlink(pidfile.c_str()); unlink(o.ipc_filename.c_str()); unlink(o.urlipc_filename.c_str()); } return 0; } std::cerr << "No DansGuardian process found." << std::endl; return 1; } // send HUP to process int sysv_hup(std::string pidfile) { pid_t p = getpid(pidfile); if (p > 1) { int rc =::kill(p, SIGHUP); if (rc == -1) { std::cerr << "Error trying to hup pid:" << p << std::endl; if (errno == EPERM) { std::cerr << "Permission denied." << std::endl; } return 1; } return 0; } std::cerr << "No DansGuardian process found." << std::endl; return 1; } // send USR1 to process int sysv_usr1(std::string pidfile) { pid_t p = getpid(pidfile); if (p > 1) { int rc =::kill(p, SIGUSR1); if (rc == -1) { std::cerr << "Error trying to sig1 pid:" << p << std::endl; if (errno == EPERM) { std::cerr << "Permission denied." << std::endl; } return 1; } return 0; } std::cerr << "No DansGuardian process found." << std::endl; return 1; } // show PID of running DG process int sysv_showpid(std::string pidfile) { pid_t p = getpid(pidfile); if (p > 1) { std::cout << "Parent DansGuardian pid:" << p << std::endl; return 0; } std::cerr << "No DansGuardian process found." << std::endl; return 1; } // create a new pidfile int sysv_openpidfile(std::string pidfile) { unlink(pidfile.c_str()); return open(pidfile.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); } // write pid to file & close it int sysv_writepidfile(int pidfilefd) { pid_t p = getpid(); char pidbuff[32]; sprintf(pidbuff, "%d", (int) p); // Messy, but it works! int len = strlen(pidbuff) + 1; pidbuff[len - 1] = '\n'; int rc = write(pidfilefd, pidbuff, len); if (rc < len) { // failed to write close(pidfilefd); return 1; } close(pidfilefd); return 0; } // check process in pidfile is running bool sysv_amirunning(std::string pidfile) { if (getpid(pidfile) > 1) { return true; } return false; } dansguardian-2.10.1.1/src/ConfigVar.cpp0000644001165000116500000000433611110523210014454 00000000000000//Implements the ConfigVar class //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "ConfigVar.hpp" #include // IMPLEMENTATION // constructor ConfigVar::ConfigVar() { } // construct & read in the given config file ConfigVar::ConfigVar(const char *filename, const char *delimiter) { readVar(filename, delimiter); } // return the value for the named option String ConfigVar::entry(const char *reference) { return params[reference]; } // same as above, but in handy operator form String ConfigVar::operator[] (const char *reference) { return params[reference]; } // read in options from the given file, splitting option/value at delimiter int ConfigVar::readVar(const char *filename, const char *delimiter) { std::ifstream input(filename); char buffer[2048]; params.clear(); if (!input) return 1; while (input.getline(buffer, sizeof(buffer))) { char *command = strtok(buffer, delimiter); if (!command) continue; char *parameter = strtok(NULL, delimiter); if (!parameter) continue; // strip delimiters while (*parameter == '"' || *parameter == '\'' || *parameter == ' ') parameter++; int offset = strlen(parameter) - 1; while (parameter[offset] == '"' || parameter[offset] == '\'') parameter[offset--] = '\0'; offset = strlen(command) - 1; while (command[offset] == ' ') command[offset--] = '\0'; params[command] = parameter; } input.close(); return 0; } dansguardian-2.10.1.1/src/FDTunnel.cpp0000644001165000116500000001662011110523210014254 00000000000000//Please refer to http://dansguardian.org/?page=copyright //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // This class is a generic multiplexing tunnel // that uses blocking select() to be as efficient as possible. It tunnels // between the two supplied FDs. // Linux Application Development by Michael K. Johnson and Erik W. Troan // was used extensivly to produce this class // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include #include #include #include #include #include #include #ifdef DGDEBUG #include #endif #include "FDTunnel.hpp" // IMPLEMENTATION FDTunnel::FDTunnel() : throughput(0) { } void FDTunnel::reset() { throughput = 0; } // tunnel data from fdfrom to fdto (unfiltered) // return false if throughput larger than target throughput bool FDTunnel::tunnel(Socket &sockfrom, Socket &sockto, bool twoway, off_t targetthroughput, bool ignore) { if (targetthroughput == 0) { #ifdef DGDEBUG std::cout << "No data expected, tunnelling aborted." << std::endl; #endif return true; } #ifdef DGDEBUG if (targetthroughput < 0) std::cout << "Tunnelling without known content-length" << std::endl; else std::cout << "Tunnelling with content length " << targetthroughput << std::endl; #endif if ((sockfrom.bufflen - sockfrom.buffstart) > 0) { #ifdef DGDEBUG std::cout << "Data in fdfrom's buffer; sending " << (sockfrom.bufflen - sockfrom.buffstart) << " bytes" << std::endl; #endif sockto.writeToSocket(sockfrom.buffer + sockfrom.buffstart, sockfrom.bufflen - sockfrom.buffstart, 0, 120, false); throughput += sockfrom.bufflen - sockfrom.buffstart; sockfrom.bufflen = 0; sockfrom.buffstart = 0; } int maxfd, rc, fdfrom, fdto; fdfrom = sockfrom.getFD(); fdto = sockto.getFD(); maxfd = fdfrom > fdto ? fdfrom : fdto; // find the maximum file // descriptor. As Linux normally allows each process // to have up to 1024 file descriptors, maxfd // prevents the kernel having to look through all // 1024 fds each fdSet could contain char buff[32768]; // buffer for the input timeval timeout; // timeval struct timeout.tv_sec = 120; // modify the struct so its a 120 sec timeout timeout.tv_usec = 0; fd_set fdSet; // file descriptor set FD_ZERO(&fdSet); // clear the set FD_SET(fdto, &fdSet); // add fdto to the set FD_SET(fdfrom, &fdSet); // add fdfrom to the set timeval t; // we need a 2nd copy used later fd_set inset; // we need a 2nd copy used later fd_set outset; // we need a 3rd copy used later bool done = false; // so we get past the first while while (!done && (targetthroughput > -1 ? throughput < targetthroughput : true)) { done = true; // if we don't make a sucessful read and write this // flag will stay true and so the while() will exit inset = fdSet; // as select() can modify the sets we need to take t = timeout; // a copy each time round and use that if (ignore && !twoway) FD_CLR(fdto, &inset); if (selectEINTR(maxfd + 1, &inset, NULL, NULL, &t) < 1) { break; // an error occured or it timed out so end while() } if (FD_ISSET(fdfrom, &inset)) { // fdfrom is ready to be read from if (targetthroughput > -1) // we have a target throughput - only read in the exact amount of data we've been told to // plus 2 bytes to "solve" an IE post bug with multipart/form-data forms: // adds an extra CRLF on certain requests, that it doesn't count in reported content-length rc = sockfrom.readFromSocket(buff, (((int)sizeof(buff) < ((targetthroughput - throughput)/*+2*/)) ? sizeof(buff) : (targetthroughput - throughput)/* + 2*/), 0, 0, false); else rc = sockfrom.readFromSocket(buff, sizeof(buff), 0, 0, false); // read as much as is available if (rc < 0) { break; // an error occured so end the while() } else if (!rc) { done = true; // none received so pipe is closed so flag it } else { // some data read throughput += rc; // increment our counter used to log outset = fdSet; // take a copy to work with FD_CLR(fdfrom, &outset); // remove fdfrom from the set // as we are only interested in writing to fdto t = timeout; // take a copy to work with if (selectEINTR(fdto + 1, NULL, &outset, NULL, &t) < 1) { break; // an error occured or timed out so end while() } if (FD_ISSET(fdto, &outset)) { // fdto ready to write to if (!sockto.writeToSocket(buff, rc, 0, 0, false)) { // write data break; // was an error writing } done = false; // flag to say data still to be handled } else { break; // should never get here } } } if (FD_ISSET(fdto, &inset)) { // fdto is ready to be read from if (!twoway) { // since HTTP works on a simple request/response basis, with no explicit // communications from the client until the response has been completed // (just TCP cruft, which is of no interest to us here), tunnels only // need to be one way. As soon as the client tries to send data, break // the tunnel, as it will be a new request, possibly to an entirely // different webserver. This is important for proper filtering when // persistent connection support gets implemented. PRA 2005-11-14 #ifdef DGDEBUG std::cout << "fdto is sending data; closing tunnel. (This must be a persistent connection.)" << std::endl; #endif break; } // read as much as is available rc = sockto.readFromSocket(buff, sizeof(buff), 0, 0, false); if (rc < 0) { break; // an error occured so end the while() } else if (!rc) { done = true; // none received so pipe is closed so flag it break; } else { // some data read outset = fdSet; // take a copy to work with FD_CLR(fdto, &outset); // remove fdto from the set // as we are only interested in writing to fdfrom t = timeout; // take a copy to work with if (selectEINTR(fdfrom + 1, NULL, &outset, NULL, &t) < 1) { break; // an error occured or timed out so end while() } if (FD_ISSET(fdfrom, &outset)) { // fdfrom ready to write to if (!sockfrom.writeToSocket(buff, rc, 0, 0, false)) { // write data break; // was an error writing } done = false; // flag to say data still to be handled } else { break; // should never get here } } } } #ifdef DGDEBUG if ((throughput >= targetthroughput) && (targetthroughput > -1)) std::cout << "All expected data tunnelled. (expected " << targetthroughput << "; tunnelled " << throughput << ")" << std::endl; else std::cout <<"Tunnel closed."<< std::endl; #endif return (targetthroughput > -1) ? (throughput <= targetthroughput) : true; } dansguardian-2.10.1.1/src/RegExp.hpp0000644001165000116500000000466211110523210013777 00000000000000// RegExp class - search text using regular expressions //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@// jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_REGEXP #define __HPP_REGEXP // INCLUDES #include // needed for size_t used in regex.h #ifdef HAVE_PCRE #include #else #include #endif #include #include // DECLARATIONS class RegExp { public: // constructor - set sensible defaults RegExp(); // destructor - delete regexp if compiled ~RegExp(); // copy constructor RegExp(const RegExp & r); // compile the given regular expression bool comp(const char *exp); // match the given text against the pre-compiled expression bool match(const char *text); // how many matches did the last run generate? int numberOfMatches(); // did it generate any at all? bool matched(); // the i'th match from the last run std::string result(int i); // position of the i'th match in the overall text unsigned int offset(int i); // length of the i'th match unsigned int length(int i); // faster equivalent of STL::Search char *search(char *file, char *fileend, char *phrase, char *phraseend); private: // the match results, their positions in the text & their lengths std::deque results; std::deque offsets; std::deque lengths; // have we matched something yet? bool imatched; // the expression itself regex_t reg; // whether it's been pre-compiled bool wascompiled; // the uncompiled form of the expression (checkme: is this only used // for debugging purposes?) std::string searchstring; }; #endif dansguardian-2.10.1.1/src/String.hpp0000644001165000116500000000762611110523210014056 00000000000000// String - guess what: it's a string class! Cut down version of Java string // class interface //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@ jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_STRING #define __HPP_STRING // INCLUDES #include #include #include // DECLARATIONS class String:public std::string { public: String():std::string() {}; //~String(); // constructor from c-string String(const char* bs):std::string(bs) {}; // copy constructor String(const String &s):std::string(s) {}; // construct string represenations of numbers String(const int num); String(const long num); String(const long unsigned num); String(const unsigned int num); # ifndef OFFT_COLLISION // If large file support is not enabled (and possibly even if it is), // the type of off_t may be a typedef of a type for which we already // have a constructor. In that case, don't define one which takes an // off_t, or we get compiler errors. String(const off_t num); # endif // substring constructors String(const char *bs, int len):std::string(bs, len) {}; String(const char *bs, int start, int len):std::string(bs+start, len) {}; // construct from c++ string String(const std::string &s):std::string(s) {}; String operator+(const int& i) { return (*this) + String(i); }; // return c-string const char* toCharArray() const { return (this->c_str()); }; // return substring of length l from start String subString(int start, int l) const { return this->substr(start, l); }; // convert to integer/long integer int toInteger(); long int toLong(); off_t toOffset(); // return integer from hex string int hexToInteger(); // case conversions void toLower(); void toUpper(); // decode %xx to characters (checkme: duplicate code?) void hexDecode(); // does the string start/end with this text? bool startsWith(const String& s); bool endsWith(const String& s); // does this string start with the given text after conversion to lowercase? // (pass the search string in in lowercase; only the text being searched // is converted) bool startsWithLower(const String& s); // return offset of substring s within the string int indexOf(const char *s); // does it contain this text? bool contains(const char *s); // index operator mark 2 unsigned char charAt(int index) { return (*this)[index]; }; // return string following first occurrence of bs String after(const char *bs) const; // return string preceding first occurrence of bs String before(const char *bs) const; // search & replace void replaceall(const char *what, const char *with); // remove character from end/beginning void chop(); void lop(); // remove leading & trailing whitespace void removeWhiteSpace(); // remove protocol prefix (e.g. http://) void removePTP(); // truncate to given length int limitLength(unsigned int l); // remove repeated occurrences of this character void removeMultiChar(unsigned char c); // clean up slashes, trailing dots, etc. in file paths void realPath(); // generate MD5 hash of string (using given salt) String md5(); String md5(const char *salt); }; #endif dansguardian-2.10.1.1/src/UDSocket.cpp0000644001165000116500000000647511110523210014265 00000000000000// UDSocket class - implements BaseSocket for UNIX domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "UDSocket.hpp" #include #include #include #include #include #include #include #include #include #ifdef DGDEBUG #include #endif // necessary for calculating size of sockaddr_un in a portable manner #ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) #endif // IMPLEMENTATION // constructor - creates default UNIX domain socket & clears address structs UDSocket::UDSocket() { sck = socket(PF_UNIX, SOCK_STREAM, 0); memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sun_family = AF_UNIX; peer_adr.sun_family = AF_UNIX; } // create socket from pre-existing FD (address structs will be invalid!) UDSocket::UDSocket(int fd):BaseSocket(fd) { memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sun_family = AF_UNIX; peer_adr.sun_family = AF_UNIX; } // create socket from given FD & local address (checkme: is it local or remote that gets passed in here?) UDSocket::UDSocket(int newfd, struct sockaddr_un myadr):BaseSocket(newfd) { my_adr = myadr; my_adr_length = sizeof(my_adr.sun_family) + strlen(my_adr.sun_path); } // close socket & clear address structs void UDSocket::reset() { this->baseReset(); sck = socket(PF_UNIX, SOCK_STREAM, 0); memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sun_family = AF_UNIX; peer_adr.sun_family = AF_UNIX; } // accept incoming connection & return new UDSocket UDSocket* UDSocket::accept() { my_adr_length = sizeof(my_adr.sun_family) + strlen(my_adr.sun_path); int newfd = this->baseAccept((struct sockaddr*) &my_adr, &my_adr_length); UDSocket* s = new UDSocket(newfd, my_adr); return s; } // connect to given server (following default constructor) int UDSocket::connect(const char *path) { #ifdef DGDEBUG std::cout << "uds connect:" << path << std::endl; #endif strcpy(my_adr.sun_path, path); my_adr_length = offsetof(struct sockaddr_un, sun_path) + strlen(path); return ::connect(sck, (struct sockaddr *) &my_adr, my_adr_length); } // bind socket to given path int UDSocket::bind(const char *path) { // to bind a unix domain socket to a path unlink(path); strcpy(my_adr.sun_path, path); my_adr_length = offsetof(struct sockaddr_un, sun_path) + strlen(path); return ::bind(sck, (struct sockaddr *) &my_adr, my_adr_length); } dansguardian-2.10.1.1/src/SocketArray.hpp0000644001165000116500000000350311110523210015025 00000000000000// SocketArray - wrapper for clean handling of an array of Sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_SOCKETARRAY #define __HPP_SOCKETARRAY // INCLUDES #include "Socket.hpp" #include "String.hpp" #include // DECLARATIONS class SocketArray { public: // set sensible defaults SocketArray():drawer(NULL),socknum(0) {}; // delete all sockets ~SocketArray(); // close all old socks & create specified amount of new ones void reset(int sockcount); // just delete the lot of 'em void deleteAll(); // bind our sockets to the given IPs int bindAll(std::deque &ips, int port); // bind just the one, to all available IPs int bindSingle(int port); // set all sockets listening with given kernel queue length int listenAll(int queue); // shove all socket FDs into the given array (pass in unallocated) int* getFDAll(); // array dereference operator Socket* operator[] (int i) { return &(drawer[i]); }; private: // our sock collection container Socket* drawer; // how many sockets we have unsigned int socknum; }; #endif dansguardian-2.10.1.1/src/contentscanners/0000777001165000116500000000000011212164550015372 500000000000000dansguardian-2.10.1.1/src/contentscanners/commandlinescan.cpp0000644001165000116500000002617511110523210021145 00000000000000// Command line content scanning plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../ContentScanner.hpp" #include "../UDSocket.hpp" #include "../OptionContainer.hpp" #include "../RegExp.hpp" #include #include #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // IMPLEMENTATION // class name is relevant class commandlineinstance:public CSPlugin { public: commandlineinstance(ConfigVar & definition):CSPlugin(definition), usevirusregexp(false), submatch(0), arguments(NULL), numarguments(0), infectedcodes(NULL), numinfectedcodes(0), cleancodes(NULL), numcleancodes(0), defaultresult(-1) {}; int scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename); int init(void* args); ~commandlineinstance() { delete[] infectedcodes; delete[] cleancodes; for (int i = 0; i < numarguments; i++) delete arguments[i]; delete[] arguments; }; private: // regular expression for finding virus names in program output RegExp virusregexp; // whether or not the above is in use bool usevirusregexp; // which sub-match to take from the match int submatch; // path to command-line scanning program (+ initial arguments) String progname; // argument array (the above must be split on space for passing to exec) char** arguments; int numarguments; // return code(s) for infected files int* infectedcodes; int numinfectedcodes; // return code(s) for uninfected files int* cleancodes; int numcleancodes; // optional default result - can be used to e.g. define only cleancodes, // and have everything else default to infected. int defaultresult; }; // class factory code *MUST* be included in every plugin CSPlugin *commandlinecreate(ConfigVar & definition) { return new commandlineinstance(definition); } // end of Class factory // initialise plugin int commandlineinstance::init(void* args) { // always include these lists if (!readStandardLists()) { return DGCS_ERROR; } // read in program name progname = cv["progname"]; if (progname.length() == 0) { if (!is_daemonised) std::cerr << "Command-line scanner: No program specified" << std::endl; syslog(LOG_ERR, "Command-line scanner: No program specified"); return DGCS_ERROR; } // split into an argument array std::list temparguments; char* tempprogname = new char[progname.length() + 1]; tempprogname[progname.length()] = '\0'; strncpy(tempprogname, progname.c_str(), progname.length()); char* result = strtok(tempprogname," "); while (result) { temparguments.push_back(std::string(result)); result = strtok(NULL," "); } delete[] tempprogname; for (int i = 0; i < numarguments; i++) delete arguments[i]; delete[] arguments; numarguments = temparguments.size(); arguments = new char* [numarguments + 2]; arguments[numarguments + 1] = NULL; int count = 0; for (std::list::iterator i = temparguments.begin(); i != temparguments.end(); i++) { char* newthing = new char[i->length()]; strcpy(newthing, i->c_str()); arguments[count++] = newthing; } progname = cv["progname"]; #ifdef DGDEBUG std::cout << "Program and arguments: "; for (int i = 0; i < numarguments; i++) { std::cout << arguments[i] << " "; } std::cout << std::endl; #endif // read in virus name regular expression String ucvirusregexp(cv["virusregexp"]); if (ucvirusregexp.length()) { usevirusregexp = true; if (!virusregexp.comp(ucvirusregexp.toCharArray())) { if (!is_daemonised) std::cerr << "Command-line scanner: Could not compile regular expression for extracting virus names" << std::endl; syslog(LOG_ERR, "Command-line scanner: Could not compile regular expression for extracting virus names"); return DGCS_ERROR; } String ssubmatch(cv["submatch"]); if (ssubmatch.length()) submatch = ssubmatch.toInteger(); } // read in the lists of good and bad program return codes String sinfectedcodes(cv["infectedcodes"]); String scleancodes(cv["cleancodes"]); std::list tempinfectedcodes; std::list tempcleancodes; char* tempcodes = new char[sinfectedcodes.length() + 1]; tempcodes[sinfectedcodes.length()] = '\0'; strncpy(tempcodes, sinfectedcodes.c_str(), sinfectedcodes.length()); result = strtok(tempcodes,","); #ifdef DGDEBUG std::cout << "Infected file return codes: "; #endif while (result) { tempinfectedcodes.push_back(atoi(result)); #ifdef DGDEBUG std::cout << tempinfectedcodes.back() << " "; #endif result = strtok(NULL,","); } delete[] tempcodes; tempcodes = new char[scleancodes.length() + 1]; tempcodes[scleancodes.length()] = '\0'; strncpy(tempcodes, scleancodes.c_str(), scleancodes.length()); result = strtok(tempcodes,","); #ifdef DGDEBUG std::cout << std::endl << "Clean file return codes: "; #endif while (result) { tempcleancodes.push_back(atoi(result)); #ifdef DGDEBUG std::cout << tempcleancodes.back() << " "; #endif result = strtok(NULL,","); } delete[] tempcodes; #ifdef DGDEBUG std::cout << std::endl; #endif // we need at least one of our three mechanisms (cleancodes, infectedcodes and virus names) // to be defined in order to make a decision about the nature of a scanning result. numcleancodes = tempcleancodes.size(); numinfectedcodes = tempinfectedcodes.size(); if (!(usevirusregexp || numcleancodes || numinfectedcodes)) { if (!is_daemonised) std::cerr << "Command-line scanner requires some mechanism for interpreting results. Please define cleancodes, infectedcodes, and/or a virusregexp." << std::endl; syslog(LOG_ERR,"Command-line scanner requires some mechanism for interpreting results. Please define cleancodes, infectedcodes, and/or a virusregexp."); return DGCS_ERROR; } // Copy return code lists out into static arrays delete[] infectedcodes; delete[] cleancodes; infectedcodes = new int[numinfectedcodes]; cleancodes = new int[numcleancodes]; count = 0; for (std::list::iterator i = tempinfectedcodes.begin(); i != tempinfectedcodes.end(); i++) infectedcodes[count++] = *i; count = 0; for (std::list::iterator i = tempcleancodes.begin(); i != tempcleancodes.end(); i++) cleancodes[count++] = *i; // read in default result type String sdefaultresult(cv["defaultresult"]); if (sdefaultresult.length()) { if (sdefaultresult == "clean") { defaultresult = 1; } else if (sdefaultresult == "infected") { defaultresult = 0; } else { if (!is_daemonised) std::cerr << "Command-line scanner: Default result value not understood" << std::endl; syslog(LOG_ERR,"Command-line scanner: Default result value not understood"); return DGCS_WARNING; } } return DGCS_OK; } // no need to replace the inheritied scanMemory() which just calls scanFile() // there is no capability to scan memory with commandlinescan as we pass it // a file name to scan. So we save the memory to disk and pass that. // Then delete the temp file. int commandlineinstance::scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename) { // create socket pairs for child (scanner) process's stdout & stderr int scannerstdout[2]; int scannerstderr[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, scannerstdout) == -1) { lastmessage = "Cannot create sockets for communicating with scanner"; syslog(LOG_ERR, "Cannot open socket pair for command-line scanner's stdout: %s", strerror(errno)); return DGCS_SCANERROR; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, scannerstderr) == -1) { lastmessage = "Cannot create sockets for communicating with scanner"; syslog(LOG_ERR, "Cannot open socket pair for command-line scanner's stderr: %s", strerror(errno)); return DGCS_SCANERROR; } int f = fork(); if (f == 0) { #ifdef DGDEBUG std::cout << "Running: " << progname.toCharArray() << " " << filename << std::endl; #endif // close read ends of sockets close(scannerstdout[0]); close(scannerstderr[0]); // bind stdout & stderr dup2(scannerstdout[1], 1); dup2(scannerstderr[1], 2); // execute scanner arguments[numarguments] = (char*)filename; execv(arguments[0], arguments); // if we get here, an error occurred! syslog(LOG_ERR, "Cannot exec command-line scanner (command \"%s %s\"): %s", progname.toCharArray(), filename, strerror(errno)); _exit(255); } else if (f == -1) { lastmessage = "Cannot launch scanner"; syslog(LOG_ERR, "Cannot fork to launch command-line scanner (command \"%s %s\"): %s", progname.toCharArray(), filename, strerror(errno)); return DGCS_SCANERROR; } // close write ends of sockets close(scannerstdout[1]); close(scannerstderr[1]); char buff[8192]; std::string result; FILE *readme = fdopen(scannerstdout[0], "r"); while (fgets(buff, 8192, readme) != NULL) { #ifndef DGDEBUG if (usevirusregexp) #endif result += buff; } fclose(readme); readme = fdopen(scannerstderr[0], "r"); while (fgets(buff, 8192, readme) != NULL) { #ifndef DGDEBUG if (usevirusregexp) #endif result += buff; } fclose(readme); // close read ends too now close(scannerstdout[0]); close(scannerstderr[0]); // wait for scanner to quit & retrieve exit status int returncode; if (waitpid(f,&returncode,0) == -1) { lastmessage = "Cannot get scanner return code"; syslog(LOG_ERR, "Cannot get command-line scanner return code: %s", strerror(errno)); return DGCS_SCANERROR; } returncode = WEXITSTATUS(returncode); #ifdef DGDEBUG std::cout << "Scanner result" << std::endl << "--------------" << std::endl << result << std::endl << "--------------" << std::endl << "Code: " << returncode << std::endl; #endif if (returncode == 255) { lastmessage = "Cannot get scanner return code"; syslog(LOG_ERR, "Cannot get command-line scanner return code: scanner exec failed"); return DGCS_SCANERROR; } lastvirusname = "Unknown"; if (usevirusregexp) { virusregexp.match(result.c_str()); if (virusregexp.matched()) { lastvirusname = virusregexp.result(submatch); return DGCS_INFECTED; } } if (cleancodes) { for (int i = 0; i < numcleancodes; i++) { if (returncode == cleancodes[i]) return DGCS_CLEAN; } } if (infectedcodes) { for (int i = 0; i < numinfectedcodes; i++) { if (returncode == infectedcodes[i]) return DGCS_INFECTED; } } if (defaultresult == 1) return DGCS_CLEAN; else if (defaultresult == 0) return DGCS_INFECTED; return DGCS_SCANERROR; } dansguardian-2.10.1.1/src/contentscanners/icapscan.cpp0000644001165000116500000005062611110523210017571 00000000000000// ICAP server content scanning plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // dgav.sf.net and openantivirus.org were a great help in providing example // code to show how to connect to an ICAP server // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../ContentScanner.hpp" #include "../OptionContainer.hpp" #include #include #include //#include #include #include #include // for gethostby // DEFINES #define ICAP_CONTINUE DGCS_MAX+1 #define ICAP_NODATA DGCS_MAX+2 // GLOBALS extern OptionContainer o; extern bool is_daemonised; // DECLARATIONS // class name is relevant! class icapinstance:public CSPlugin { public: icapinstance(ConfigVar & definition):CSPlugin(definition), usepreviews(false), previewsize(0), supportsXIF(false), needsBody(false) {}; int scanMemory(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize); int scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename); int init(void* args); private: // ICAP server hostname, IP and port String icaphost; String icapip; unsigned int icapport; // URL for the AV service String icapurl; // whether or not to send ICAP message previews, and the preview object size bool usepreviews; unsigned int previewsize; // supports X-Infection-Found and/or needs us to look at the whole body bool supportsXIF; bool needsBody; // Send ICAP request headers to server bool doHeaders(Socket & icapsock, HTTPHeader *reqheader, HTTPHeader *respheader, unsigned int objectsize); // Check data returned from ICAP server and return one of our standard return codes int doScan(Socket & icapsock, HTTPHeader * docheader, const char* object, unsigned int objectsize); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin CSPlugin *icapcreate(ConfigVar & definition) { return new icapinstance(definition); } // end of Class factory // initialise the plugin - determine icap ip, port & url int icapinstance::init(void* args) { // always include these lists if (!readStandardLists()) { return DGCS_ERROR; } icapurl = cv["icapurl"]; // format: icap://icapserver:1344/avscan if (icapurl.length() < 3) { if (!is_daemonised) std::cerr << "Error reading icapurl option." << std::endl; syslog(LOG_ERR, "Error reading icapurl option."); return DGCS_ERROR; // it would be far better to do a test connection } icaphost = icapurl.after("//"); icapport = icaphost.after(":").before("/").toInteger(); if (icapport == 0) { icapport = 1344; } icaphost = icaphost.before("/"); if (icaphost.contains(":")) { icaphost = icaphost.before(":"); } struct hostent *host; if ((host = gethostbyname(icaphost.toCharArray())) == 0) { if (!is_daemonised) std::cerr << "Error resolving icap host address." << std::endl; syslog(LOG_ERR, "Error resolving icap host address."); return DGCS_ERROR; } icapip = inet_ntoa(*(struct in_addr *) host->h_addr_list[0]); #ifdef DGDEBUG std::cerr << "ICAP server address:" << icapip << std::endl; #endif // try to connect to the ICAP server and perform an OPTIONS request Socket icapsock; try { if (icapsock.connect(icapip.toCharArray(), icapport) < 0) { throw std::runtime_error("Could not connect to server"); } String line("OPTIONS " + icapurl + " ICAP/1.0\r\nHost: " + icaphost + "\r\n\r\n"); icapsock.writeString(line.toCharArray()); // parse the response char buff[8192]; // first line - look for 200 OK icapsock.getLine(buff, 8192, o.content_scanner_timeout); line = buff; #ifdef DGDEBUG std::cout << "ICAP/1.0 OPTIONS response:" << std::endl << line << std::endl; #endif if (line.after(" ").before(" ") != "200") { if (!is_daemonised) std::cerr << "ICAP response not 200 OK" << std::endl; syslog(LOG_ERR, "ICAP response not 200 OK"); return DGCS_WARNING; //throw std::runtime_error("Response not 200 OK"); } while (icapsock.getLine(buff, 8192, o.content_scanner_timeout) > 0) { line = buff; #ifdef DGDEBUG std::cout << line << std::endl; #endif if (line.startsWith("\r")) { break; } else if (line.startsWith("Preview:")) { usepreviews = true; previewsize = line.after(": ").toInteger(); } else if (line.startsWith("Server:")) { if (line.contains("AntiVir-WebGate")) { needsBody = true; } } else if (line.startsWith("X-Allow-Out:")) { if (line.contains("X-Infection-Found")) { supportsXIF = true; } } } icapsock.close(); } catch(std::exception& e) { if (!is_daemonised) std::cerr << "ICAP server did not respond to OPTIONS request: " << e.what() << std::endl; syslog(LOG_ERR, "ICAP server did not respond to OPTIONS request: %s", e.what()); return DGCS_ERROR; } #ifdef DGDEBUG if (usepreviews) std::cout << "Message previews enabled; size: " << previewsize << std::endl; else std::cout << "Message previews disabled" << std::endl; #endif return DGCS_OK; } // send memory buffer to ICAP server for scanning int icapinstance::scanMemory(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize) { lastvirusname = lastmessage = ""; Socket icapsock; if (not doHeaders(icapsock, requestheader, docheader, objectsize)) { icapsock.close(); return DGCS_SCANERROR; } #ifdef DGDEBUG std::cerr << "About to send memory data to icap" << std::endl; if (usepreviews && (objectsize > previewsize)) std::cerr << "Sending preview first" << std::endl; #endif unsigned int sent = 0; if (usepreviews && (objectsize > previewsize)) { try { if (!icapsock.writeToSocket(object, previewsize, 0, o.content_scanner_timeout)) { throw std::runtime_error("standard error"); } sent += previewsize; icapsock.writeString("\r\n0\r\n\r\n"); int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_CONTINUE) return rc; // some servers send "continue" immediately followed by another response if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) return rc; } char objectsizehex[32]; snprintf(objectsizehex, sizeof(objectsizehex), "%x\r\n", objectsize-previewsize); icapsock.writeString(objectsizehex); } catch (std::exception& e) { #ifdef DGDEBUG std::cerr << "Exception sending message preview to ICAP: " << e.what() << std::endl; #endif // this *might* just be an early response & closed connection if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) return rc; } icapsock.close(); lastmessage = "Exception sending message preview to ICAP"; syslog(LOG_ERR, "Exception sending message preview to ICAP: %s", e.what()); return DGCS_SCANERROR; } } try { icapsock.writeToSockete(object + sent, objectsize - sent, 0, o.content_scanner_timeout); #ifdef DGDEBUG std::cout << "total sent to icap: " << objectsize << std::endl; #endif icapsock.writeString("\r\n0\r\n\r\n"); // end marker #ifdef DGDEBUG std::cout << "memory was sent to icap" << std::endl; #endif } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception sending memory file to ICAP: " << e.what() << std::endl; #endif // this *might* just be an early response & closed connection if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) return rc; } icapsock.close(); lastmessage = "Exception sending memory file to ICAP"; syslog(LOG_ERR, "Exception sending memory file to ICAP: %s", e.what()); return DGCS_SCANERROR; } return doScan(icapsock, docheader, object, objectsize); } // send file contents for scanning int icapinstance::scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename) { lastmessage = lastvirusname = ""; int filefd = open(filename, O_RDONLY); if (filefd < 0) { #ifdef DGDEBUG std::cerr << "Error opening file (" << filename << "): " << strerror(errno) << std::endl; #endif lastmessage = "Error opening file to send to ICAP"; syslog(LOG_ERR, "Error opening file to send to ICAP: %s", strerror(errno)); return DGCS_SCANERROR; } lseek(filefd, 0, SEEK_SET); unsigned int filesize = lseek(filefd, 0, SEEK_END); Socket icapsock; if (not doHeaders(icapsock, requestheader, docheader, filesize)) { icapsock.close(); close(filefd); return DGCS_SCANERROR; } lseek(filefd, 0, SEEK_SET); unsigned int sent = 0; char *data = new char[previewsize]; char *object = new char[100]; int objectsize = 0; #ifdef DGDEBUG std::cerr << "About to send file data to icap" << std::endl; if (usepreviews && (filesize > previewsize)) std::cerr << "Sending preview first" << std::endl; #endif if (usepreviews && (filesize > previewsize)) { try { while (sent < previewsize) { int rc = readEINTR(filefd, data, previewsize); if (rc < 0) { throw std::runtime_error("could not read from file"); } if (rc == 0) { break; // should never happen } if (!icapsock.writeToSocket(data, rc, 0, o.content_scanner_timeout)) { throw std::runtime_error("could not write to socket"); } memcpy(object, data, (rc > 100) ? 100 : rc); objectsize += (rc > 100) ? 100 : rc; sent += rc; } icapsock.writeString("\r\n0\r\n\r\n"); int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_CONTINUE) { delete[] data; close(filefd); return rc; } // some servers send "continue" immediately followed by another response if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) { delete[] data; close(filefd); return rc; } } char objectsizehex[32]; snprintf(objectsizehex, sizeof(objectsizehex), "%x\r\n", filesize-previewsize); icapsock.writeString(objectsizehex); } catch (std::exception& e) { #ifdef DGDEBUG std::cerr << "Exception sending message preview to ICAP: " << e.what() << std::endl; #endif icapsock.close(); lastmessage = "Exception sending message preview to ICAP"; syslog(LOG_ERR, "Exception sending message preview to ICAP: %s", e.what()); delete[] data; close(filefd); // this *might* just be an early response & closed connection if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) return rc; } return DGCS_SCANERROR; } } delete[] data; data = new char[256 * 1024]; // 256k try { while (sent < filesize) { int rc = readEINTR(filefd, data, 256 * 1024); #ifdef DGDEBUG std::cout << "reading icap file rc: " << rc << std::endl; #endif if (rc < 0) { #ifdef DGDEBUG std::cout << "error reading icap file so throwing exception" << std::endl; #endif throw std::runtime_error("could not read from file"); } if (rc == 0) { #ifdef DGDEBUG std::cout << "got zero bytes reading icap file" << std::endl; #endif break; // should never happen } memcpy(object + objectsize, data, (rc > (100-objectsize)) ? (100-objectsize) : rc); objectsize += (rc > (100-objectsize)) ? (100-objectsize) : rc; icapsock.writeToSockete(data, rc, 0, o.content_scanner_timeout); sent += rc; } #ifdef DGDEBUG std::cout << "total sent to icap: " << sent << std::endl; #endif icapsock.writeString("\r\n0\r\n\r\n"); // end marker #ifdef DGDEBUG std::cout << "file was sent to icap" << std::endl; #endif } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception sending file to ICAP: " << e.what() << std::endl; #endif lastmessage = "Exception sending file to ICAP"; syslog(LOG_ERR, "Exception sending file to ICAP: %s", e.what()); delete[]data; close(filefd); // this *might* just be an early response & closed connection if (icapsock.checkForInput()) { int rc = doScan(icapsock, docheader, object, objectsize); if (rc != ICAP_NODATA) return rc; } return DGCS_SCANERROR; } close(filefd); delete[] data; return doScan(icapsock, docheader, object, objectsize); } // send ICAP request headers, returning success or failure bool icapinstance::doHeaders(Socket & icapsock, HTTPHeader *reqheader, HTTPHeader *respheader, unsigned int objectsize) { int rc = icapsock.connect(icapip.toCharArray(), icapport); if (rc) { #ifdef DGDEBUG std::cerr << "Error connecting to ICAP server" << std::endl; #endif lastmessage = "Error connecting to ICAP server"; syslog(LOG_ERR, "Error connecting to ICAP server"); return false; } char objectsizehex[32]; // encapsulated HTTP request header: // use a dummy unless it proves absolutely necessary to do otherwise, // as using real data could lead to e.g. yet another source of password // leakage over the network. String encapsulatedheader("GET " + reqheader->url() + " HTTP/1.0\r\n\r\n"); // body chunk size in hex - either full body, or just preview if (usepreviews && (objectsize > previewsize)) { snprintf(objectsizehex, sizeof(objectsizehex), "%x\r\n", previewsize); } else { snprintf(objectsizehex, sizeof(objectsizehex), "%x\r\n", objectsize); } // encapsulated HTTP response header: // use real data, because scanners can use this to aid the process /*String httpresponseheader; for (std::deque::iterator i = respheader->header.begin(); i != respheader->header.end(); i++) { httpresponseheader += (*i) + "\r\n"; } httpresponseheader += "\r\n";*/ String httpresponseheader("HTTP/1.0 200 OK\r\n\r\n"); // ICAP header itself String icapheader("RESPMOD " + icapurl + " ICAP/1.0\r\nHost: " + icaphost + "\r\nAllow: 204\r\nEncapsulated: req-hdr=0, res-hdr=" + String(encapsulatedheader.length()) + ", res-body=" + String(httpresponseheader.length() + encapsulatedheader.length())); if (usepreviews && (objectsize > previewsize)) { icapheader += "\r\nPreview: " + String(previewsize); } icapheader += "\r\n\r\n"; #ifdef DGDEBUG std::cerr << "About to send icapheader:\n" << icapheader << encapsulatedheader << httpresponseheader << objectsizehex << std::endl; #endif try { icapsock.writeString(icapheader.toCharArray()); icapsock.writeString(encapsulatedheader.toCharArray()); icapsock.writeString(httpresponseheader.toCharArray()); icapsock.writeString(objectsizehex); } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception sending headers to ICAP: " << e.what() << std::endl; #endif lastmessage = "Exception sending headers to ICAP"; syslog(LOG_ERR, "Exception sending headers to ICAP: %s", e.what()); return false; } return true; } // check data received from ICAP server and interpret as virus name & return value int icapinstance::doScan(Socket & icapsock, HTTPHeader * docheader, const char* object, unsigned int objectsize) { char *data = new char[8192]; try { String line; int rc = icapsock.getLine(data, 8192, o.content_scanner_timeout); if (rc == 0) return ICAP_NODATA; line = data; #ifdef DGDEBUG std::cout << "reply from icap: " << line << std::endl; #endif // reply is of the format: // ICAP/1.0 204 No Content Necessary (etc) String returncode(line.after(" ").before(" ")); if (returncode == "204") { #ifdef DGDEBUG std::cerr << "ICAP says clean!" << std::endl; #endif delete[]data; return DGCS_CLEAN; } else if (returncode == "100") { #ifdef DGDEBUG std::cerr << "ICAP says continue!" << std::endl; #endif // discard rest of headers (usually just a blank line) // this is so we are in the right place in the data stream to // call doScan() again later, because people like Symantec seem // to think sending code 100 then code 204 one after the other // is not an abuse of the ICAP specification. while (icapsock.getLine(data, 8192, o.content_scanner_timeout) > 0) { if (data[0] == 13) break; } delete[]data; return ICAP_CONTINUE; } else if (returncode == "200") { #ifdef DGDEBUG std::cerr << "ICAP says maybe not clean!" << std::endl; #endif while (icapsock.getLine(data, 8192, o.content_scanner_timeout) > 0) { if (data[0] == 13) // end marker break; line = data; // Symantec's engine gives us the virus name in the ICAP headers if (supportsXIF && line.startsWith("X-Infection-Found")) { #ifdef DGDEBUG std::cout << "ICAP says infected! (X-Infection-Found)" << std::endl; #endif lastvirusname = line.after("Threat=").before(";"); delete[]data; return DGCS_INFECTED; } } // AVIRA's Antivir gives us 200 in all cases, so // - unfortunately - we must pay attention to the encapsulated // header/body. if (needsBody) { // grab & compare the HTTP return code from modified response // if it's been modified, assume there's an infection icapsock.getLine(data, 8192, o.content_scanner_timeout); line = data; #ifdef DGDEBUG std::cout << "Comparing original return code to modified:" << std::endl << docheader->header.front() << std::endl << line << std::endl; #endif int respmodReturnCode = line.after(" ").before(" ").toInteger(); if (respmodReturnCode != docheader->returnCode()) { #ifdef DGDEBUG std::cerr << "ICAP says infected! (returned header comparison)" << std::endl; #endif delete[] data; lastvirusname = "Unknown"; return DGCS_INFECTED; } // ok - headers were identical, so look at encapsulated body // discard the rest of the encapsulated headers while (icapsock.getLine(data, 8192, o.content_scanner_timeout) > 0) { if (data[0] == 13) break; } // grab body chunk size #ifdef DGDEBUG std::cout << "Comparing original body data to modified" << std::endl; #endif icapsock.getLine(data, 8192, o.content_scanner_timeout); line = data; int bodysize = line.hexToInteger(); // get, say, the first 100 bytes and compare them to what we // originally sent to see if it has been modified unsigned int chunksize = (bodysize < 100) ? bodysize : 100; if (chunksize > objectsize) chunksize = objectsize; icapsock.readFromSocket(data, chunksize, 0, o.content_scanner_timeout); if (memcmp(data, object, chunksize) == 0) { #ifdef DGDEBUG std::cerr << "ICAP says clean!" << std::endl; #endif delete[]data; return DGCS_CLEAN; } else { #ifdef DGDEBUG std::cerr << "ICAP says infected! (body byte comparison)" << std::endl; #endif delete[] data; lastvirusname = "Unknown"; return DGCS_INFECTED; } } // even if we don't find an X-Infection-Found header, // the file is still infected! #ifdef DGDEBUG std::cerr << "ICAP says infected! (no further tests)" << std::endl; #endif delete[] data; lastvirusname = "Unknown"; return DGCS_INFECTED; } else if (returncode == "404") { #ifdef DGDEBUG std::cerr << "ICAP says no such service!" << std::endl; #endif lastmessage = "ICAP reports no such service"; syslog(LOG_ERR, "ICAP reports no such service; check your server URL"); delete[]data; return DGCS_SCANERROR; } else { #ifdef DGDEBUG std::cerr << "ICAP returned unrecognised response code: " << returncode << std::endl; #endif lastmessage = "ICAP returned unrecognised response code."; syslog(LOG_ERR, "ICAP returned unrecognised response code: %s", returncode.toCharArray()); delete[]data; return DGCS_SCANERROR; } delete[]data; } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception getting reply from ICAP: " << e.what() << std::endl; #endif lastmessage = "Exception getting reply from ICAP."; syslog(LOG_ERR, "Exception getting reply from ICAP: %s", e.what()); delete[]data; return DGCS_SCANERROR; } // it is generally NOT a good idea, when using virus scanning, // to continue as if nothing went wrong by default! return DGCS_SCANERROR; } dansguardian-2.10.1.1/src/contentscanners/clamdscan.cpp0000644001165000116500000001437111110523210017732 00000000000000// ClamD content scanning plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../ContentScanner.hpp" #include "../UDSocket.hpp" #include "../OptionContainer.hpp" #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // DECLARATIONS // class name is relevant! class clamdinstance:public CSPlugin { public: clamdinstance(ConfigVar & definition):CSPlugin(definition), archivewarn(false) {}; // we are not replacing scanTest or scanMemory // but for scanFile and the default scanMemory to work, we need a working scanFile implementation int scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename); int init(void* args); private: // ClamD UNIX domain socket path String udspath; // File path prefix for chrooted ClamD String pathprefix; // Whether or not to just issue a warning on archive limit/encryption warnings bool archivewarn; }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin CSPlugin *clamdcreate(ConfigVar & definition) { return new clamdinstance(definition); } // end of Class factory // initialise the plugin int clamdinstance::init(void* args) { // always include these lists if (!readStandardLists()) { return DGCS_ERROR; } // read in ClamD UNIX domain socket path udspath = cv["clamdudsfile"]; if (udspath.length() < 3) { if (!is_daemonised) std::cerr << "Error reading clamdudsfile option." << std::endl; syslog(LOG_ERR, "Error reading clamdudsfile option."); return DGCS_ERROR; // it would be far better to do a test connection to the file but // could not be arsed for now } // read in path prefix pathprefix = cv["pathprefix"]; archivewarn = cv["archivewarn"] == "on"; return DGCS_OK; } // no need to replace the inheritied scanMemory() which just calls scanFile() // there is no capability to scan memory with clamdscan as we pass it // a file name to scan. So we save the memory to disk and pass that. // Then delete the temp file. int clamdinstance::scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename) { lastmessage = lastvirusname = ""; // mkstemp seems to only set owner permissions, so our AV daemon won't be // able to read the file, unless it's running as the same user as us. that's // not usually very convenient. so instead, just allow group read on the // file, and tell users to make sure the daemongroup option is friendly to // the AV daemon's group membership. // TODO? chmod can error out with EINTR, we may wish to ignore this if (chmod(filename, S_IRGRP|S_IRUSR) != 0) { lastmessage = "Error giving ClamD read access to temp file"; syslog(LOG_ERR, "Could not change file ownership to give ClamD read access: %s", strerror(errno)); return DGCS_SCANERROR; }; String command("SCAN "); if (pathprefix.length()) { String fname(filename); command += fname.after(pathprefix.toCharArray()); } else { command += filename; } command += "\r\n"; #ifdef DGDEBUG std::cerr << "clamdscan command:" << command << std::endl; #endif UDSocket stripedsocks; if (stripedsocks.getFD() < 0) { lastmessage = "Error opening socket to talk to ClamD"; syslog(LOG_ERR, "Error creating socket for talking to ClamD"); return DGCS_SCANERROR; } if (stripedsocks.connect(udspath.toCharArray()) < 0) { lastmessage = "Error connecting to ClamD socket"; syslog(LOG_ERR, "Error connecting to ClamD socket"); stripedsocks.close(); return DGCS_SCANERROR; } try { stripedsocks.writeString(command.toCharArray()); } catch(std::exception &e) { stripedsocks.close(); lastmessage = "Exception whilst writing to ClamD socket: "; lastmessage += e.what(); syslog(LOG_ERR, "Exception whilst writing to ClamD socket: %s", e.what()); return DGCS_SCANERROR; } char *buff = new char[4096]; int rc; try { rc = stripedsocks.getLine(buff, 4096, o.content_scanner_timeout); } catch(std::exception & e) { delete[]buff; stripedsocks.close(); lastmessage = "Exception whist reading ClamD socket: "; lastmessage += e.what(); syslog(LOG_ERR, "Exception whilst reading ClamD socket: %s", e.what()); return DGCS_SCANERROR; } String reply(buff); delete[]buff; reply.removeWhiteSpace(); #ifdef DGDEBUG std::cout << "Got from clamdscan: " << reply << std::endl; #endif stripedsocks.close(); if (reply.endsWith("ERROR")) { lastmessage = reply; syslog(LOG_ERR, "ClamD error: %s", reply.toCharArray()); return DGCS_SCANERROR; } else if (reply.endsWith("FOUND")) { lastvirusname = reply.after(": ").before(" FOUND"); // format is: // /foo/path/file: foovirus FOUND #ifdef DGDEBUG std::cerr << "clamdscan INFECTED! with: " << lastvirusname << std::endl; #endif if (archivewarn && (lastvirusname.contains(".Exceeded") || lastvirusname.contains(".Encrypted"))) { #ifdef DGDEBUG std::cerr << "clamdscan: detected an ArchiveBlockMax \"virus\"; logging warning only" << std::endl; #endif lastmessage = "Archive not fully scanned: "+lastvirusname; return DGCS_WARNING; } return DGCS_INFECTED; } // must be clean // Note: we should really check what the output of a "clean" message actually looks like, // and check explicitly for that, but the ClamD documentation is sparse on output formats. #ifdef DGDEBUG std::cerr << "clamdscan - he say yes (clean)" << std::endl; #endif return DGCS_CLEAN; } dansguardian-2.10.1.1/src/contentscanners/clamav.cpp0000644001165000116500000002051311110523210017243 00000000000000// LibClamAV content scanning plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../ContentScanner.hpp" #include "../OptionContainer.hpp" #include #include #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // DECLARATIONS // class name is relevant! class clamavinstance:public CSPlugin { public: clamavinstance(ConfigVar & definition):CSPlugin(definition) #ifdef HAVE_CLAMAV_SHM , use_shm(false) #endif {}; // we are replacing the inherited scanMemory as it has support for it int scanMemory(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize); int scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename); // could be useful, but doesn't yet do anything - see comments on implementation //int scanTest(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip); int init(void* args); int quit(); private: // virus database root node // Update to support ClamAV 0.90 // Based on patch supplied by Aecio F. Neto struct cl_engine *root; // archive limit options struct cl_limits limits; #ifdef HAVE_CLAMAV_SHM // use POSIX shared memory bool use_shm; #endif // directory for storing memory buffers (if not shm) std::string memdir; // convert clamav return value to standard return value int doRC(int rc, const char *vn); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin CSPlugin *clamavcreate(ConfigVar & definition) { return new clamavinstance(definition); } // end of Class factory // destroy plugin int clamavinstance::quit() { cl_free(root); return DGCS_OK; } // does the given request need virus scanning? // this could do clever things to return true only when something matches the // options we pass to libclamav - but for now, it just calls the default, // and so is unnecessary. PRA 13-10-2005 /*int clamavinstance::scanTest(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip) { return CSPlugin::scanTest(requestheader, docheader, user, filtergroup, ip); }*/ // override the inherited scanMemory, since libclamav can actually scan memory areas directly // ... but we don't want it to! cl_scanbuff is crippled (no archive unpacking, only basic signature scanning) // and scheduled for removal. instead, use shm_open to create an "in memory" file, and use cl_scandesc. // !!! this may not prove to be very portable !!! int clamavinstance::scanMemory(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize) { lastmessage = lastvirusname = ""; const char *vn = NULL; int fd; std::string fname; #ifdef HAVE_CLAMAV_SHM if (use_shm) { // use POSIX shared memory to get the FD fname = tmpnam(NULL); fname = fname.substr(fname.find_last_of('/')); fd = shm_open(fname.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); } else { #endif fname = memdir + "/tfXXXXXX"; char* fnamearray = new char[fname.length() + 1]; strcpy(fnamearray, fname.c_str()); fd = mkstemp(fnamearray); fname = fnamearray; delete[] fnamearray; #ifdef HAVE_CLAMAV_SHM } #endif #ifdef DGDEBUG std::cout << "Clamav plugin buffer store: " << fname << std::endl; #endif if (fd == -1) { #ifdef DGDEBUG std::cerr << "ClamAV plugin error during buffer store creation: " << fname << ", " << strerror(errno) << std::endl; #endif syslog(LOG_ERR, "ClamAV plugin error during buffer store creation: %s, %s", fname.c_str(), strerror(errno)); return DGCS_SCANERROR; } int rc = write(fd, object, objectsize); if (fd == -1) { #ifdef DGDEBUG std::cerr << "ClamAV plugin error during write: " << strerror(errno) << std::endl; #endif syslog(LOG_ERR, "ClamAV plugin error during write: %s", strerror(errno)); return DGCS_SCANERROR; } rc = cl_scandesc(fd, &vn, NULL, root, &limits, CL_SCAN_STDOPT); close(fd); #ifdef HAVE_CLAMAV_SHM if (use_shm) fd = shm_unlink(fname.c_str()); else #endif fd = unlink(fname.c_str()); if (fd == -1) { #ifdef DGDEBUG std::cerr << "ClamAV plugin error during unlink: " << strerror(errno) << std::endl; #endif syslog(LOG_ERR, "ClamAV plugin error during unlink: %s", strerror(errno)); return DGCS_SCANERROR; } return doRC(rc, vn); } // scan given filename int clamavinstance::scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename) { lastmessage = lastvirusname = ""; const char *vn = NULL; int rc = cl_scanfile(filename, &vn, NULL, root, &limits, CL_SCAN_STDOPT ); return doRC(rc, vn); } // convert libclamav return values into our own standard return values int clamavinstance::doRC(int rc, const char *vn) { if (rc == CL_VIRUS) { lastvirusname = vn; #ifdef DGDEBUG std::cerr << "INFECTED! with: " << lastvirusname << std::endl; #endif return DGCS_INFECTED; } else if (rc != CL_CLEAN) { lastmessage = cl_strerror(rc); #ifdef DGDEBUG std::cerr << "ClamAV error: " << lastmessage << std::endl; #endif syslog(LOG_ERR, "ClamAV error: %s", lastmessage.toCharArray()); return DGCS_SCANERROR; } #ifdef DGDEBUG std::cerr << "ClamAV - he say yes (clean)" << std::endl; #endif return DGCS_CLEAN; } // initialise libclamav int clamavinstance::init(void* args) { // always include these lists if (!readStandardLists()) { return DGCS_ERROR; } // pick method for storing memory buffers String smethod(cv["scanbuffmethod"]); if (smethod == "file") { memdir = cv["scanbuffdir"].toCharArray(); if (memdir.length() == 0) memdir = o.download_dir; } #ifdef HAVE_CLAMAV_SHM else if (smethod == "shm") { use_shm = true; } #endif else { if (!is_daemonised) std::cerr << "Unsupported scanbuffmethod: " << smethod << std::endl; syslog(LOG_ERR, "Unsupported scanbuffmethod: %s", smethod.toCharArray()); return DGCS_ERROR; } // set clam's own temp dir if (cv["tempdir"].length() > 0) cl_settempdir(cv["tempdir"].toCharArray(), 0); #ifdef DGDEBUG std::cout << "Scanbuffmethod: " << smethod << std::endl; std::cout << "Scanbuffdir: " << memdir << std::endl; std::cout << "Tempdir: " << cv["tempdir"] << std::endl; #endif // set file, recursion and compression ratio limits for scanning archives root = NULL; limits.maxfiles = cv["maxfiles"].toInteger(); limits.maxfilesize = o.max_content_filecache_scan_size + 1024 * 1024; limits.maxreclevel = cv["maxreclevel"].toInteger(); limits.maxscansize = cv["maxscansize"].toInteger() * 1024; #ifdef DGDEBUG std::cerr << "maxfiles: " << limits.maxfiles << " maxfilesize: " << limits.maxfilesize << " maxreclevel: " << limits.maxreclevel << " maxscansize: " << limits.maxscansize << std::endl; #endif // load virus database unsigned int virnum = 0; int rc = cl_load(cl_retdbdir(), &root, &virnum, CL_DB_STDOPT); #ifdef DGDEBUG std::cout << "engine: " << root << " virnum: " << virnum << std::endl; #endif if (rc != 0) { if (!is_daemonised) std::cerr << "Error loading clamav db: " << cl_strerror(rc) << std::endl; syslog(LOG_ERR, "Error loading clamav db: %s", cl_strerror(rc)); return DGCS_ERROR; } rc = cl_build(root); if (rc != 0) { if (!is_daemonised) std::cerr << "Error building clamav db: " << cl_strerror(rc) << std::endl; syslog(LOG_ERR, "Error building clamav db: %s", cl_strerror(rc)); return DGCS_ERROR; } return DGCS_OK; } dansguardian-2.10.1.1/src/contentscanners/kavdscan.cpp0000644001165000116500000001374411110523210017602 00000000000000// Kaspersky AV Daemon content scanning plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 //TODO: Replace error reporting with detailed entries in syslog(LOG_ERR), short entries in lastmessage. // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../ContentScanner.hpp" #include "../UDSocket.hpp" #include "../OptionContainer.hpp" #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // IMPLEMENTATION // class name is relevant class kavdinstance:public CSPlugin { public: kavdinstance(ConfigVar & definition):CSPlugin(definition) {}; int scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename); int init(void* args); private: // UNIX domain socket path for KAVD String udspath; // File path prefix for chrooted KAVD String pathprefix; }; // class factory code *MUST* be included in every plugin CSPlugin *kavdcreate(ConfigVar & definition) { return new kavdinstance(definition); } // end of Class factory // initialise plugin int kavdinstance::init(void* args) { // always include these lists if (!readStandardLists()) { return DGCS_ERROR; } udspath = cv["kavdudsfile"]; if (udspath.length() < 3) { if (!is_daemonised) std::cerr << "Error reading kavdudsfile option." << std::endl; syslog(LOG_ERR, "%s", "Error reading kavdudsfile option."); return DGCS_ERROR; // it would be far better to do a test connection to the file but // could not be arsed for now } // read in path prefix pathprefix = cv["pathprefix"]; return DGCS_OK; } // no need to replace the inheritied scanMemory() which just calls scanFile() // there is no capability to scan memory with kavdscan as we pass it // a file name to scan. So we save the memory to disk and pass that. // Then delete the temp file. int kavdinstance::scanFile(HTTPHeader * requestheader, HTTPHeader * docheader, const char *user, int filtergroup, const char *ip, const char *filename) { lastvirusname = lastmessage = ""; // mkstemp seems to only set owner permissions, so our AV daemon won't be // able to read the file, unless it's running as the same user as us. that's // not usually very convenient. so instead, just allow group read on the // file, and tell users to make sure the daemongroup option is friendly to // the AV daemon's group membership. // chmod can error with EINTR, ignore this? if (chmod(filename, S_IRGRP|S_IRUSR) != 0) { syslog(LOG_ERR, "Could not change file ownership to give kavd read access: %s", strerror(errno)); return DGCS_SCANERROR; }; String command("SCAN bPQRSTUW "); if (pathprefix.length()) { String fname(filename); command += fname.after(pathprefix.toCharArray()); } else { command += filename; } command += "\r\n"; #ifdef DGDEBUG std::cerr << "kavdscan command:" << command << std::endl; #endif UDSocket stripedsocks; if (stripedsocks.getFD() < 0) { syslog(LOG_ERR, "%s", "Error creating socket for talking to kavdscan"); return DGCS_SCANERROR; } if (stripedsocks.connect(udspath.toCharArray()) < 0) { syslog(LOG_ERR, "%s", "Error connecting to kavdscan socket"); stripedsocks.close(); return DGCS_SCANERROR; } char *buff = new char[4096]; memset(buff, 0, 4096); int rc; try { // read kaspersky kavdscan (AV Enging Server) - format: 2xx greeting rc = stripedsocks.getLine(buff, 4096, o.content_scanner_timeout); } catch(std::exception & e) { } if (buff[0] != '2') { delete[]buff; stripedsocks.close(); syslog(LOG_ERR, "%s", "kavdscan did not return ok"); return DGCS_SCANERROR; } try { stripedsocks.writeString(command.toCharArray()); } catch(std::exception & e) { delete[]buff; stripedsocks.close(); syslog(LOG_ERR, "%s", "unable to write to kavdscan"); return DGCS_SCANERROR; } try { rc = stripedsocks.getLine(buff, 4096, o.content_scanner_timeout); } catch(std::exception & e) { delete[]buff; stripedsocks.close(); syslog(LOG_ERR, "%s", "Error reading kavdscan socket"); return DGCS_SCANERROR; } String reply(buff); #ifdef DGDEBUG std::cout << "Got from kavdscan:" << reply << std::endl; #endif if (reply[0] == '2') { // clean #ifdef DGDEBUG std::cerr << "kavdscan - clean" << std::endl; #endif delete[]buff; stripedsocks.close(); return DGCS_CLEAN; } if (reply.startsWith("322")) { // infected // patch to handle multiple virii in kavd response // originally submitted by cahya while(reply[0] != '2' && rc != 0) { reply.removeWhiteSpace(); lastvirusname = lastvirusname + " " + reply.after("322-").before(" "); try { rc = stripedsocks.getLine(buff, 4096, o.content_scanner_timeout); } catch(std::exception & e) { delete[]buff; stripedsocks.close(); syslog(LOG_ERR, "%s", "Error reading kavdscan socket"); return DGCS_SCANERROR; } reply = buff; #ifdef DGDEBUG std::cout << "Got from kavdscan:" << reply << std::endl; #endif } std::cout << "lastvirusname: " << lastvirusname << std::endl; delete[]buff; stripedsocks.close(); // format: 322 nastyvirus blah return DGCS_INFECTED; } delete[]buff; stripedsocks.close(); // must be an error then lastmessage = reply; return DGCS_SCANERROR; } dansguardian-2.10.1.1/src/ListManager.hpp0000644001165000116500000000360511173344204015024 00000000000000// ListManager - for creating & containing all ListContainers of item & phrase lists //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@/jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_LISTMANAGER #define __HPP_LISTMANAGER // INCLUDES #include "String.hpp" #include "ListContainer.hpp" #include // DECLARATION class ListManager { public: // the lists we manage std::deque l; ~ListManager(); // create a new item list. re-uses existing lists if a reload is not necessary. // calls readItemList. int newItemList(const char *filename, bool startswith, int filters, bool parent); // create a new phrase list. re-uses existing lists, but cannot check nested lists (known limitation). // does not call readPhraseList. (checkme: why?) int newPhraseList(const char *exception, const char *banned, const char *weighted); void deRefList(size_t item); // delete lists with refcount zero void garbageCollect(); private: // find an empty slot in our collection of listcontainters int findNULL(); void refList(size_t item); }; #endif dansguardian-2.10.1.1/src/FDTunnel.hpp0000644001165000116500000000315211110523210014255 00000000000000// This class is a generic multiplexing tunnel // that uses blocking select() to be as efficient as possible. It tunnels // between the two supplied FDs. //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_FDTUNNEL #define __HPP_FDTUNNEL // INCLUDES #include "Socket.hpp" // DECLARATIONS // transparently forward data from one FD to another, i.e. tunnel between them class FDTunnel { public: off_t throughput; // used to log total data from from to to FDTunnel(); // tunnel from fdfrom to fdto // return false if throughput larger than target throughput (for post upload size checking) bool tunnel(Socket &sockfrom, Socket &sockto, bool twoway = false, off_t targetthroughput = -1, bool ignore = false); void reset(); }; #endif dansguardian-2.10.1.1/src/Makefile.in0000644001165000116500000033061511212164523014154 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ sbin_PROGRAMS = dansguardian$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(sbin_PROGRAMS) am__dansguardian_SOURCES_DIST = String.cpp String.hpp FDTunnel.cpp \ FDTunnel.hpp ConnectionHandler.cpp ConnectionHandler.hpp \ DataBuffer.cpp DataBuffer.hpp HTTPHeader.cpp HTTPHeader.hpp \ NaughtyFilter.cpp NaughtyFilter.hpp RegExp.cpp RegExp.hpp \ FDFuncs.cpp FDFuncs.hpp BaseSocket.cpp BaseSocket.hpp \ Socket.cpp Socket.hpp FatController.cpp FatController.hpp \ UDSocket.cpp UDSocket.hpp SysV.cpp SysV.hpp ListContainer.cpp \ ListContainer.hpp Auth.cpp Auth.hpp HTMLTemplate.cpp \ HTMLTemplate.hpp LanguageContainer.cpp LanguageContainer.hpp \ DynamicURLList.cpp DynamicURLList.hpp DynamicIPList.cpp \ DynamicIPList.hpp ImageContainer.cpp ImageContainer.hpp \ IPList.cpp IPList.hpp OptionContainer.cpp OptionContainer.hpp \ FOptionContainer.cpp FOptionContainer.hpp ListManager.cpp \ ListManager.hpp md5.cpp md5.hpp DownloadManager.cpp \ DownloadManager.hpp ConfigVar.cpp ConfigVar.hpp \ ContentScanner.cpp ContentScanner.hpp SocketArray.cpp \ SocketArray.hpp dansguardian.cpp Plugin.hpp \ contentscanners/clamav.cpp contentscanners/icapscan.cpp \ contentscanners/kavdscan.cpp contentscanners/clamdscan.cpp \ contentscanners/commandlinescan.cpp \ downloadmanagers/default.cpp downloadmanagers/fancy.cpp \ downloadmanagers/trickle.cpp authplugins/proxy.cpp \ authplugins/ident.cpp authplugins/ip.cpp authplugins/ntlm.cpp \ authplugins/digest.cpp @HAVE_CLAMAV_TRUE@am__objects_1 = dansguardian-clamav.$(OBJEXT) @ENABLE_ICAP_TRUE@am__objects_2 = dansguardian-icapscan.$(OBJEXT) @ENABLE_KAVD_TRUE@am__objects_3 = dansguardian-kavdscan.$(OBJEXT) @ENABLE_CLAMD_TRUE@am__objects_4 = dansguardian-clamdscan.$(OBJEXT) @ENABLE_COMMANDLINE_TRUE@am__objects_5 = dansguardian-commandlinescan.$(OBJEXT) am__objects_6 = dansguardian-default.$(OBJEXT) @ENABLE_FANCYDM_TRUE@am__objects_7 = dansguardian-fancy.$(OBJEXT) @ENABLE_TRICKLEDM_TRUE@am__objects_8 = dansguardian-trickle.$(OBJEXT) am__objects_9 = dansguardian-proxy.$(OBJEXT) am__objects_10 = dansguardian-ident.$(OBJEXT) am__objects_11 = dansguardian-ip.$(OBJEXT) @ENABLE_NTLM_TRUE@am__objects_12 = dansguardian-ntlm.$(OBJEXT) am__objects_13 = dansguardian-digest.$(OBJEXT) am_dansguardian_OBJECTS = dansguardian-String.$(OBJEXT) \ dansguardian-FDTunnel.$(OBJEXT) \ dansguardian-ConnectionHandler.$(OBJEXT) \ dansguardian-DataBuffer.$(OBJEXT) \ dansguardian-HTTPHeader.$(OBJEXT) \ dansguardian-NaughtyFilter.$(OBJEXT) \ dansguardian-RegExp.$(OBJEXT) dansguardian-FDFuncs.$(OBJEXT) \ dansguardian-BaseSocket.$(OBJEXT) \ dansguardian-Socket.$(OBJEXT) \ dansguardian-FatController.$(OBJEXT) \ dansguardian-UDSocket.$(OBJEXT) dansguardian-SysV.$(OBJEXT) \ dansguardian-ListContainer.$(OBJEXT) \ dansguardian-Auth.$(OBJEXT) \ dansguardian-HTMLTemplate.$(OBJEXT) \ dansguardian-LanguageContainer.$(OBJEXT) \ dansguardian-DynamicURLList.$(OBJEXT) \ dansguardian-DynamicIPList.$(OBJEXT) \ dansguardian-ImageContainer.$(OBJEXT) \ dansguardian-IPList.$(OBJEXT) \ dansguardian-OptionContainer.$(OBJEXT) \ dansguardian-FOptionContainer.$(OBJEXT) \ dansguardian-ListManager.$(OBJEXT) dansguardian-md5.$(OBJEXT) \ dansguardian-DownloadManager.$(OBJEXT) \ dansguardian-ConfigVar.$(OBJEXT) \ dansguardian-ContentScanner.$(OBJEXT) \ dansguardian-SocketArray.$(OBJEXT) \ dansguardian-dansguardian.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) $(am__objects_3) $(am__objects_4) \ $(am__objects_5) $(am__objects_6) $(am__objects_7) \ $(am__objects_8) $(am__objects_9) $(am__objects_10) \ $(am__objects_11) $(am__objects_12) $(am__objects_13) dansguardian_OBJECTS = $(am_dansguardian_OBJECTS) am__DEPENDENCIES_1 = dansguardian_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) dansguardian_LINK = $(CXXLD) $(dansguardian_CXXFLAGS) $(CXXFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(dansguardian_SOURCES) DIST_SOURCES = $(am__dansguardian_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ clean_SUBDIRS = . downloadmanagers contentscanners authplugins @HAVE_CLAMAV_FALSE@CLAMAV_SOURCE = # A MASSIVE thank you to Lawrence Manning for pointing out the # -export-dynamic option was needed to solve a long problem # which stopped DG2.9 from actually running ever. # Daniel Barron Fri 18th March 2005 # Unfortunately, since it was never made to work on anything # other than Linux, libtool support has been removed in favour # of configure-time options (at DB's request). @HAVE_CLAMAV_TRUE@CLAMAV_SOURCE = contentscanners/clamav.cpp @ENABLE_CLAMD_FALSE@CLAMDSCAN_SOURCE = #if HAVE_KAVCLIENT #KAVAV_SOURCES = contentscanners/kavav.cpp #else #KAVAV_SOURCES = #endif @ENABLE_CLAMD_TRUE@CLAMDSCAN_SOURCE = contentscanners/clamdscan.cpp @ENABLE_ICAP_FALSE@ICAPSCAN_SOURCE = @ENABLE_ICAP_TRUE@ICAPSCAN_SOURCE = contentscanners/icapscan.cpp @ENABLE_KAVD_FALSE@KAVDSCAN_SOURCE = @ENABLE_KAVD_TRUE@KAVDSCAN_SOURCE = contentscanners/kavdscan.cpp @ENABLE_COMMANDLINE_FALSE@COMMANDLINE_SOURCE = @ENABLE_COMMANDLINE_TRUE@COMMANDLINE_SOURCE = contentscanners/commandlinescan.cpp DEFAULTDM_SOURCE = downloadmanagers/default.cpp @ENABLE_FANCYDM_FALSE@FANCYDM_SOURCE = @ENABLE_FANCYDM_TRUE@FANCYDM_SOURCE = downloadmanagers/fancy.cpp @ENABLE_TRICKLEDM_FALSE@TRICKLEDM_SOURCE = @ENABLE_TRICKLEDM_TRUE@TRICKLEDM_SOURCE = downloadmanagers/trickle.cpp PROXYAUTH_SOURCE = authplugins/proxy.cpp IDENTAUTH_SOURCE = authplugins/ident.cpp IPAUTH_SOURCE = authplugins/ip.cpp DIGESTAUTH_SOURCE = authplugins/digest.cpp @ENABLE_NTLM_FALSE@NTLMAUTH_SOURCE = @ENABLE_NTLM_TRUE@NTLMAUTH_SOURCE = authplugins/ntlm.cpp dansguardian_CXXFLAGS = $(PCRE_CFLAGS) $(CLAMAV_CFLAGS) $(AM_CXXFLAGS) dansguardian_LDADD = $(PCRE_LIBS) $(CLAMAV_LIBS) $(AM_LIBS) dansguardian_CPPFLAGS = -D__CONFFILE='"$(DGCONFFILE)"' \ -D__LOGLOCATION='"$(DGLOGLOCATION)/"' \ -D__PIDDIR='"$(DGPIDDIR)"' \ -D__PROXYUSER='"$(DGPROXYUSER)"' \ -D__PROXYGROUP='"$(DGPROXYGROUP)"' \ -D__CONFDIR='"$(DGCONFDIR)"' \ $(AM_CPPFLAGS) dansguardian_SOURCES = String.cpp String.hpp \ FDTunnel.cpp FDTunnel.hpp \ ConnectionHandler.cpp ConnectionHandler.hpp \ DataBuffer.cpp DataBuffer.hpp \ HTTPHeader.cpp HTTPHeader.hpp \ NaughtyFilter.cpp NaughtyFilter.hpp \ RegExp.cpp RegExp.hpp \ FDFuncs.cpp FDFuncs.hpp \ BaseSocket.cpp BaseSocket.hpp \ Socket.cpp Socket.hpp \ FatController.cpp FatController.hpp \ UDSocket.cpp UDSocket.hpp \ SysV.cpp SysV.hpp \ ListContainer.cpp ListContainer.hpp \ Auth.cpp Auth.hpp \ HTMLTemplate.cpp HTMLTemplate.hpp \ LanguageContainer.cpp LanguageContainer.hpp \ DynamicURLList.cpp DynamicURLList.hpp \ DynamicIPList.cpp DynamicIPList.hpp \ ImageContainer.cpp ImageContainer.hpp \ IPList.cpp IPList.hpp \ OptionContainer.cpp OptionContainer.hpp \ FOptionContainer.cpp FOptionContainer.hpp \ ListManager.cpp ListManager.hpp \ md5.cpp md5.hpp \ DownloadManager.cpp DownloadManager.hpp \ ConfigVar.cpp ConfigVar.hpp \ ContentScanner.cpp ContentScanner.hpp \ SocketArray.cpp SocketArray.hpp \ dansguardian.cpp \ Plugin.hpp \ $(CLAMAV_SOURCE) $(ICAPSCAN_SOURCE) \ $(KAVDSCAN_SOURCE) $(CLAMDSCAN_SOURCE) \ $(COMMANDLINE_SOURCE) \ $(DEFAULTDM_SOURCE) $(FANCYDM_SOURCE) \ $(TRICKLEDM_SOURCE) $(PROXYAUTH_SOURCE) \ $(IDENTAUTH_SOURCE) $(IPAUTH_SOURCE) \ $(NTLMAUTH_SOURCE) $(DIGESTAUTH_SOURCE) all: all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ rm -f "$(DESTDIR)$(sbindir)/$$f"; \ done clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) dansguardian$(EXEEXT): $(dansguardian_OBJECTS) $(dansguardian_DEPENDENCIES) @rm -f dansguardian$(EXEEXT) $(dansguardian_LINK) $(dansguardian_OBJECTS) $(dansguardian_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-Auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-BaseSocket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ConfigVar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ConnectionHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ContentScanner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-DataBuffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-DownloadManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-DynamicIPList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-DynamicURLList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-FDFuncs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-FDTunnel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-FOptionContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-FatController.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-HTMLTemplate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-HTTPHeader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-IPList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ImageContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-LanguageContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ListContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ListManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-NaughtyFilter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-OptionContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-RegExp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-Socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-SocketArray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-String.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-SysV.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-UDSocket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-clamav.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-clamdscan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-commandlinescan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-dansguardian.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-default.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-fancy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-icapscan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ident.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-kavdscan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-ntlm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-proxy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dansguardian-trickle.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` dansguardian-String.o: String.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-String.o -MD -MP -MF $(DEPDIR)/dansguardian-String.Tpo -c -o dansguardian-String.o `test -f 'String.cpp' || echo '$(srcdir)/'`String.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-String.Tpo $(DEPDIR)/dansguardian-String.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='String.cpp' object='dansguardian-String.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-String.o `test -f 'String.cpp' || echo '$(srcdir)/'`String.cpp dansguardian-String.obj: String.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-String.obj -MD -MP -MF $(DEPDIR)/dansguardian-String.Tpo -c -o dansguardian-String.obj `if test -f 'String.cpp'; then $(CYGPATH_W) 'String.cpp'; else $(CYGPATH_W) '$(srcdir)/String.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-String.Tpo $(DEPDIR)/dansguardian-String.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='String.cpp' object='dansguardian-String.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-String.obj `if test -f 'String.cpp'; then $(CYGPATH_W) 'String.cpp'; else $(CYGPATH_W) '$(srcdir)/String.cpp'; fi` dansguardian-FDTunnel.o: FDTunnel.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FDTunnel.o -MD -MP -MF $(DEPDIR)/dansguardian-FDTunnel.Tpo -c -o dansguardian-FDTunnel.o `test -f 'FDTunnel.cpp' || echo '$(srcdir)/'`FDTunnel.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FDTunnel.Tpo $(DEPDIR)/dansguardian-FDTunnel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FDTunnel.cpp' object='dansguardian-FDTunnel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FDTunnel.o `test -f 'FDTunnel.cpp' || echo '$(srcdir)/'`FDTunnel.cpp dansguardian-FDTunnel.obj: FDTunnel.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FDTunnel.obj -MD -MP -MF $(DEPDIR)/dansguardian-FDTunnel.Tpo -c -o dansguardian-FDTunnel.obj `if test -f 'FDTunnel.cpp'; then $(CYGPATH_W) 'FDTunnel.cpp'; else $(CYGPATH_W) '$(srcdir)/FDTunnel.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FDTunnel.Tpo $(DEPDIR)/dansguardian-FDTunnel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FDTunnel.cpp' object='dansguardian-FDTunnel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FDTunnel.obj `if test -f 'FDTunnel.cpp'; then $(CYGPATH_W) 'FDTunnel.cpp'; else $(CYGPATH_W) '$(srcdir)/FDTunnel.cpp'; fi` dansguardian-ConnectionHandler.o: ConnectionHandler.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ConnectionHandler.o -MD -MP -MF $(DEPDIR)/dansguardian-ConnectionHandler.Tpo -c -o dansguardian-ConnectionHandler.o `test -f 'ConnectionHandler.cpp' || echo '$(srcdir)/'`ConnectionHandler.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ConnectionHandler.Tpo $(DEPDIR)/dansguardian-ConnectionHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConnectionHandler.cpp' object='dansguardian-ConnectionHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ConnectionHandler.o `test -f 'ConnectionHandler.cpp' || echo '$(srcdir)/'`ConnectionHandler.cpp dansguardian-ConnectionHandler.obj: ConnectionHandler.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ConnectionHandler.obj -MD -MP -MF $(DEPDIR)/dansguardian-ConnectionHandler.Tpo -c -o dansguardian-ConnectionHandler.obj `if test -f 'ConnectionHandler.cpp'; then $(CYGPATH_W) 'ConnectionHandler.cpp'; else $(CYGPATH_W) '$(srcdir)/ConnectionHandler.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ConnectionHandler.Tpo $(DEPDIR)/dansguardian-ConnectionHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConnectionHandler.cpp' object='dansguardian-ConnectionHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ConnectionHandler.obj `if test -f 'ConnectionHandler.cpp'; then $(CYGPATH_W) 'ConnectionHandler.cpp'; else $(CYGPATH_W) '$(srcdir)/ConnectionHandler.cpp'; fi` dansguardian-DataBuffer.o: DataBuffer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DataBuffer.o -MD -MP -MF $(DEPDIR)/dansguardian-DataBuffer.Tpo -c -o dansguardian-DataBuffer.o `test -f 'DataBuffer.cpp' || echo '$(srcdir)/'`DataBuffer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DataBuffer.Tpo $(DEPDIR)/dansguardian-DataBuffer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DataBuffer.cpp' object='dansguardian-DataBuffer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DataBuffer.o `test -f 'DataBuffer.cpp' || echo '$(srcdir)/'`DataBuffer.cpp dansguardian-DataBuffer.obj: DataBuffer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DataBuffer.obj -MD -MP -MF $(DEPDIR)/dansguardian-DataBuffer.Tpo -c -o dansguardian-DataBuffer.obj `if test -f 'DataBuffer.cpp'; then $(CYGPATH_W) 'DataBuffer.cpp'; else $(CYGPATH_W) '$(srcdir)/DataBuffer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DataBuffer.Tpo $(DEPDIR)/dansguardian-DataBuffer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DataBuffer.cpp' object='dansguardian-DataBuffer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DataBuffer.obj `if test -f 'DataBuffer.cpp'; then $(CYGPATH_W) 'DataBuffer.cpp'; else $(CYGPATH_W) '$(srcdir)/DataBuffer.cpp'; fi` dansguardian-HTTPHeader.o: HTTPHeader.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-HTTPHeader.o -MD -MP -MF $(DEPDIR)/dansguardian-HTTPHeader.Tpo -c -o dansguardian-HTTPHeader.o `test -f 'HTTPHeader.cpp' || echo '$(srcdir)/'`HTTPHeader.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-HTTPHeader.Tpo $(DEPDIR)/dansguardian-HTTPHeader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HTTPHeader.cpp' object='dansguardian-HTTPHeader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-HTTPHeader.o `test -f 'HTTPHeader.cpp' || echo '$(srcdir)/'`HTTPHeader.cpp dansguardian-HTTPHeader.obj: HTTPHeader.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-HTTPHeader.obj -MD -MP -MF $(DEPDIR)/dansguardian-HTTPHeader.Tpo -c -o dansguardian-HTTPHeader.obj `if test -f 'HTTPHeader.cpp'; then $(CYGPATH_W) 'HTTPHeader.cpp'; else $(CYGPATH_W) '$(srcdir)/HTTPHeader.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-HTTPHeader.Tpo $(DEPDIR)/dansguardian-HTTPHeader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HTTPHeader.cpp' object='dansguardian-HTTPHeader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-HTTPHeader.obj `if test -f 'HTTPHeader.cpp'; then $(CYGPATH_W) 'HTTPHeader.cpp'; else $(CYGPATH_W) '$(srcdir)/HTTPHeader.cpp'; fi` dansguardian-NaughtyFilter.o: NaughtyFilter.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-NaughtyFilter.o -MD -MP -MF $(DEPDIR)/dansguardian-NaughtyFilter.Tpo -c -o dansguardian-NaughtyFilter.o `test -f 'NaughtyFilter.cpp' || echo '$(srcdir)/'`NaughtyFilter.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-NaughtyFilter.Tpo $(DEPDIR)/dansguardian-NaughtyFilter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='NaughtyFilter.cpp' object='dansguardian-NaughtyFilter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-NaughtyFilter.o `test -f 'NaughtyFilter.cpp' || echo '$(srcdir)/'`NaughtyFilter.cpp dansguardian-NaughtyFilter.obj: NaughtyFilter.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-NaughtyFilter.obj -MD -MP -MF $(DEPDIR)/dansguardian-NaughtyFilter.Tpo -c -o dansguardian-NaughtyFilter.obj `if test -f 'NaughtyFilter.cpp'; then $(CYGPATH_W) 'NaughtyFilter.cpp'; else $(CYGPATH_W) '$(srcdir)/NaughtyFilter.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-NaughtyFilter.Tpo $(DEPDIR)/dansguardian-NaughtyFilter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='NaughtyFilter.cpp' object='dansguardian-NaughtyFilter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-NaughtyFilter.obj `if test -f 'NaughtyFilter.cpp'; then $(CYGPATH_W) 'NaughtyFilter.cpp'; else $(CYGPATH_W) '$(srcdir)/NaughtyFilter.cpp'; fi` dansguardian-RegExp.o: RegExp.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-RegExp.o -MD -MP -MF $(DEPDIR)/dansguardian-RegExp.Tpo -c -o dansguardian-RegExp.o `test -f 'RegExp.cpp' || echo '$(srcdir)/'`RegExp.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-RegExp.Tpo $(DEPDIR)/dansguardian-RegExp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RegExp.cpp' object='dansguardian-RegExp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-RegExp.o `test -f 'RegExp.cpp' || echo '$(srcdir)/'`RegExp.cpp dansguardian-RegExp.obj: RegExp.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-RegExp.obj -MD -MP -MF $(DEPDIR)/dansguardian-RegExp.Tpo -c -o dansguardian-RegExp.obj `if test -f 'RegExp.cpp'; then $(CYGPATH_W) 'RegExp.cpp'; else $(CYGPATH_W) '$(srcdir)/RegExp.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-RegExp.Tpo $(DEPDIR)/dansguardian-RegExp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RegExp.cpp' object='dansguardian-RegExp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-RegExp.obj `if test -f 'RegExp.cpp'; then $(CYGPATH_W) 'RegExp.cpp'; else $(CYGPATH_W) '$(srcdir)/RegExp.cpp'; fi` dansguardian-FDFuncs.o: FDFuncs.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FDFuncs.o -MD -MP -MF $(DEPDIR)/dansguardian-FDFuncs.Tpo -c -o dansguardian-FDFuncs.o `test -f 'FDFuncs.cpp' || echo '$(srcdir)/'`FDFuncs.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FDFuncs.Tpo $(DEPDIR)/dansguardian-FDFuncs.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FDFuncs.cpp' object='dansguardian-FDFuncs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FDFuncs.o `test -f 'FDFuncs.cpp' || echo '$(srcdir)/'`FDFuncs.cpp dansguardian-FDFuncs.obj: FDFuncs.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FDFuncs.obj -MD -MP -MF $(DEPDIR)/dansguardian-FDFuncs.Tpo -c -o dansguardian-FDFuncs.obj `if test -f 'FDFuncs.cpp'; then $(CYGPATH_W) 'FDFuncs.cpp'; else $(CYGPATH_W) '$(srcdir)/FDFuncs.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FDFuncs.Tpo $(DEPDIR)/dansguardian-FDFuncs.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FDFuncs.cpp' object='dansguardian-FDFuncs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FDFuncs.obj `if test -f 'FDFuncs.cpp'; then $(CYGPATH_W) 'FDFuncs.cpp'; else $(CYGPATH_W) '$(srcdir)/FDFuncs.cpp'; fi` dansguardian-BaseSocket.o: BaseSocket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-BaseSocket.o -MD -MP -MF $(DEPDIR)/dansguardian-BaseSocket.Tpo -c -o dansguardian-BaseSocket.o `test -f 'BaseSocket.cpp' || echo '$(srcdir)/'`BaseSocket.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-BaseSocket.Tpo $(DEPDIR)/dansguardian-BaseSocket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BaseSocket.cpp' object='dansguardian-BaseSocket.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-BaseSocket.o `test -f 'BaseSocket.cpp' || echo '$(srcdir)/'`BaseSocket.cpp dansguardian-BaseSocket.obj: BaseSocket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-BaseSocket.obj -MD -MP -MF $(DEPDIR)/dansguardian-BaseSocket.Tpo -c -o dansguardian-BaseSocket.obj `if test -f 'BaseSocket.cpp'; then $(CYGPATH_W) 'BaseSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/BaseSocket.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-BaseSocket.Tpo $(DEPDIR)/dansguardian-BaseSocket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BaseSocket.cpp' object='dansguardian-BaseSocket.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-BaseSocket.obj `if test -f 'BaseSocket.cpp'; then $(CYGPATH_W) 'BaseSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/BaseSocket.cpp'; fi` dansguardian-Socket.o: Socket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-Socket.o -MD -MP -MF $(DEPDIR)/dansguardian-Socket.Tpo -c -o dansguardian-Socket.o `test -f 'Socket.cpp' || echo '$(srcdir)/'`Socket.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-Socket.Tpo $(DEPDIR)/dansguardian-Socket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Socket.cpp' object='dansguardian-Socket.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-Socket.o `test -f 'Socket.cpp' || echo '$(srcdir)/'`Socket.cpp dansguardian-Socket.obj: Socket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-Socket.obj -MD -MP -MF $(DEPDIR)/dansguardian-Socket.Tpo -c -o dansguardian-Socket.obj `if test -f 'Socket.cpp'; then $(CYGPATH_W) 'Socket.cpp'; else $(CYGPATH_W) '$(srcdir)/Socket.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-Socket.Tpo $(DEPDIR)/dansguardian-Socket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Socket.cpp' object='dansguardian-Socket.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-Socket.obj `if test -f 'Socket.cpp'; then $(CYGPATH_W) 'Socket.cpp'; else $(CYGPATH_W) '$(srcdir)/Socket.cpp'; fi` dansguardian-FatController.o: FatController.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FatController.o -MD -MP -MF $(DEPDIR)/dansguardian-FatController.Tpo -c -o dansguardian-FatController.o `test -f 'FatController.cpp' || echo '$(srcdir)/'`FatController.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FatController.Tpo $(DEPDIR)/dansguardian-FatController.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FatController.cpp' object='dansguardian-FatController.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FatController.o `test -f 'FatController.cpp' || echo '$(srcdir)/'`FatController.cpp dansguardian-FatController.obj: FatController.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FatController.obj -MD -MP -MF $(DEPDIR)/dansguardian-FatController.Tpo -c -o dansguardian-FatController.obj `if test -f 'FatController.cpp'; then $(CYGPATH_W) 'FatController.cpp'; else $(CYGPATH_W) '$(srcdir)/FatController.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FatController.Tpo $(DEPDIR)/dansguardian-FatController.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FatController.cpp' object='dansguardian-FatController.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FatController.obj `if test -f 'FatController.cpp'; then $(CYGPATH_W) 'FatController.cpp'; else $(CYGPATH_W) '$(srcdir)/FatController.cpp'; fi` dansguardian-UDSocket.o: UDSocket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-UDSocket.o -MD -MP -MF $(DEPDIR)/dansguardian-UDSocket.Tpo -c -o dansguardian-UDSocket.o `test -f 'UDSocket.cpp' || echo '$(srcdir)/'`UDSocket.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-UDSocket.Tpo $(DEPDIR)/dansguardian-UDSocket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='UDSocket.cpp' object='dansguardian-UDSocket.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-UDSocket.o `test -f 'UDSocket.cpp' || echo '$(srcdir)/'`UDSocket.cpp dansguardian-UDSocket.obj: UDSocket.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-UDSocket.obj -MD -MP -MF $(DEPDIR)/dansguardian-UDSocket.Tpo -c -o dansguardian-UDSocket.obj `if test -f 'UDSocket.cpp'; then $(CYGPATH_W) 'UDSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/UDSocket.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-UDSocket.Tpo $(DEPDIR)/dansguardian-UDSocket.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='UDSocket.cpp' object='dansguardian-UDSocket.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-UDSocket.obj `if test -f 'UDSocket.cpp'; then $(CYGPATH_W) 'UDSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/UDSocket.cpp'; fi` dansguardian-SysV.o: SysV.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-SysV.o -MD -MP -MF $(DEPDIR)/dansguardian-SysV.Tpo -c -o dansguardian-SysV.o `test -f 'SysV.cpp' || echo '$(srcdir)/'`SysV.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-SysV.Tpo $(DEPDIR)/dansguardian-SysV.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SysV.cpp' object='dansguardian-SysV.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-SysV.o `test -f 'SysV.cpp' || echo '$(srcdir)/'`SysV.cpp dansguardian-SysV.obj: SysV.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-SysV.obj -MD -MP -MF $(DEPDIR)/dansguardian-SysV.Tpo -c -o dansguardian-SysV.obj `if test -f 'SysV.cpp'; then $(CYGPATH_W) 'SysV.cpp'; else $(CYGPATH_W) '$(srcdir)/SysV.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-SysV.Tpo $(DEPDIR)/dansguardian-SysV.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SysV.cpp' object='dansguardian-SysV.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-SysV.obj `if test -f 'SysV.cpp'; then $(CYGPATH_W) 'SysV.cpp'; else $(CYGPATH_W) '$(srcdir)/SysV.cpp'; fi` dansguardian-ListContainer.o: ListContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ListContainer.o -MD -MP -MF $(DEPDIR)/dansguardian-ListContainer.Tpo -c -o dansguardian-ListContainer.o `test -f 'ListContainer.cpp' || echo '$(srcdir)/'`ListContainer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ListContainer.Tpo $(DEPDIR)/dansguardian-ListContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListContainer.cpp' object='dansguardian-ListContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ListContainer.o `test -f 'ListContainer.cpp' || echo '$(srcdir)/'`ListContainer.cpp dansguardian-ListContainer.obj: ListContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ListContainer.obj -MD -MP -MF $(DEPDIR)/dansguardian-ListContainer.Tpo -c -o dansguardian-ListContainer.obj `if test -f 'ListContainer.cpp'; then $(CYGPATH_W) 'ListContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/ListContainer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ListContainer.Tpo $(DEPDIR)/dansguardian-ListContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListContainer.cpp' object='dansguardian-ListContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ListContainer.obj `if test -f 'ListContainer.cpp'; then $(CYGPATH_W) 'ListContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/ListContainer.cpp'; fi` dansguardian-Auth.o: Auth.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-Auth.o -MD -MP -MF $(DEPDIR)/dansguardian-Auth.Tpo -c -o dansguardian-Auth.o `test -f 'Auth.cpp' || echo '$(srcdir)/'`Auth.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-Auth.Tpo $(DEPDIR)/dansguardian-Auth.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Auth.cpp' object='dansguardian-Auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-Auth.o `test -f 'Auth.cpp' || echo '$(srcdir)/'`Auth.cpp dansguardian-Auth.obj: Auth.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-Auth.obj -MD -MP -MF $(DEPDIR)/dansguardian-Auth.Tpo -c -o dansguardian-Auth.obj `if test -f 'Auth.cpp'; then $(CYGPATH_W) 'Auth.cpp'; else $(CYGPATH_W) '$(srcdir)/Auth.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-Auth.Tpo $(DEPDIR)/dansguardian-Auth.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Auth.cpp' object='dansguardian-Auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-Auth.obj `if test -f 'Auth.cpp'; then $(CYGPATH_W) 'Auth.cpp'; else $(CYGPATH_W) '$(srcdir)/Auth.cpp'; fi` dansguardian-HTMLTemplate.o: HTMLTemplate.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-HTMLTemplate.o -MD -MP -MF $(DEPDIR)/dansguardian-HTMLTemplate.Tpo -c -o dansguardian-HTMLTemplate.o `test -f 'HTMLTemplate.cpp' || echo '$(srcdir)/'`HTMLTemplate.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-HTMLTemplate.Tpo $(DEPDIR)/dansguardian-HTMLTemplate.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HTMLTemplate.cpp' object='dansguardian-HTMLTemplate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-HTMLTemplate.o `test -f 'HTMLTemplate.cpp' || echo '$(srcdir)/'`HTMLTemplate.cpp dansguardian-HTMLTemplate.obj: HTMLTemplate.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-HTMLTemplate.obj -MD -MP -MF $(DEPDIR)/dansguardian-HTMLTemplate.Tpo -c -o dansguardian-HTMLTemplate.obj `if test -f 'HTMLTemplate.cpp'; then $(CYGPATH_W) 'HTMLTemplate.cpp'; else $(CYGPATH_W) '$(srcdir)/HTMLTemplate.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-HTMLTemplate.Tpo $(DEPDIR)/dansguardian-HTMLTemplate.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HTMLTemplate.cpp' object='dansguardian-HTMLTemplate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-HTMLTemplate.obj `if test -f 'HTMLTemplate.cpp'; then $(CYGPATH_W) 'HTMLTemplate.cpp'; else $(CYGPATH_W) '$(srcdir)/HTMLTemplate.cpp'; fi` dansguardian-LanguageContainer.o: LanguageContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-LanguageContainer.o -MD -MP -MF $(DEPDIR)/dansguardian-LanguageContainer.Tpo -c -o dansguardian-LanguageContainer.o `test -f 'LanguageContainer.cpp' || echo '$(srcdir)/'`LanguageContainer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-LanguageContainer.Tpo $(DEPDIR)/dansguardian-LanguageContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LanguageContainer.cpp' object='dansguardian-LanguageContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-LanguageContainer.o `test -f 'LanguageContainer.cpp' || echo '$(srcdir)/'`LanguageContainer.cpp dansguardian-LanguageContainer.obj: LanguageContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-LanguageContainer.obj -MD -MP -MF $(DEPDIR)/dansguardian-LanguageContainer.Tpo -c -o dansguardian-LanguageContainer.obj `if test -f 'LanguageContainer.cpp'; then $(CYGPATH_W) 'LanguageContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/LanguageContainer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-LanguageContainer.Tpo $(DEPDIR)/dansguardian-LanguageContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LanguageContainer.cpp' object='dansguardian-LanguageContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-LanguageContainer.obj `if test -f 'LanguageContainer.cpp'; then $(CYGPATH_W) 'LanguageContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/LanguageContainer.cpp'; fi` dansguardian-DynamicURLList.o: DynamicURLList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DynamicURLList.o -MD -MP -MF $(DEPDIR)/dansguardian-DynamicURLList.Tpo -c -o dansguardian-DynamicURLList.o `test -f 'DynamicURLList.cpp' || echo '$(srcdir)/'`DynamicURLList.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DynamicURLList.Tpo $(DEPDIR)/dansguardian-DynamicURLList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DynamicURLList.cpp' object='dansguardian-DynamicURLList.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DynamicURLList.o `test -f 'DynamicURLList.cpp' || echo '$(srcdir)/'`DynamicURLList.cpp dansguardian-DynamicURLList.obj: DynamicURLList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DynamicURLList.obj -MD -MP -MF $(DEPDIR)/dansguardian-DynamicURLList.Tpo -c -o dansguardian-DynamicURLList.obj `if test -f 'DynamicURLList.cpp'; then $(CYGPATH_W) 'DynamicURLList.cpp'; else $(CYGPATH_W) '$(srcdir)/DynamicURLList.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DynamicURLList.Tpo $(DEPDIR)/dansguardian-DynamicURLList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DynamicURLList.cpp' object='dansguardian-DynamicURLList.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DynamicURLList.obj `if test -f 'DynamicURLList.cpp'; then $(CYGPATH_W) 'DynamicURLList.cpp'; else $(CYGPATH_W) '$(srcdir)/DynamicURLList.cpp'; fi` dansguardian-DynamicIPList.o: DynamicIPList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DynamicIPList.o -MD -MP -MF $(DEPDIR)/dansguardian-DynamicIPList.Tpo -c -o dansguardian-DynamicIPList.o `test -f 'DynamicIPList.cpp' || echo '$(srcdir)/'`DynamicIPList.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DynamicIPList.Tpo $(DEPDIR)/dansguardian-DynamicIPList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DynamicIPList.cpp' object='dansguardian-DynamicIPList.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DynamicIPList.o `test -f 'DynamicIPList.cpp' || echo '$(srcdir)/'`DynamicIPList.cpp dansguardian-DynamicIPList.obj: DynamicIPList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DynamicIPList.obj -MD -MP -MF $(DEPDIR)/dansguardian-DynamicIPList.Tpo -c -o dansguardian-DynamicIPList.obj `if test -f 'DynamicIPList.cpp'; then $(CYGPATH_W) 'DynamicIPList.cpp'; else $(CYGPATH_W) '$(srcdir)/DynamicIPList.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DynamicIPList.Tpo $(DEPDIR)/dansguardian-DynamicIPList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DynamicIPList.cpp' object='dansguardian-DynamicIPList.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DynamicIPList.obj `if test -f 'DynamicIPList.cpp'; then $(CYGPATH_W) 'DynamicIPList.cpp'; else $(CYGPATH_W) '$(srcdir)/DynamicIPList.cpp'; fi` dansguardian-ImageContainer.o: ImageContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ImageContainer.o -MD -MP -MF $(DEPDIR)/dansguardian-ImageContainer.Tpo -c -o dansguardian-ImageContainer.o `test -f 'ImageContainer.cpp' || echo '$(srcdir)/'`ImageContainer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ImageContainer.Tpo $(DEPDIR)/dansguardian-ImageContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ImageContainer.cpp' object='dansguardian-ImageContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ImageContainer.o `test -f 'ImageContainer.cpp' || echo '$(srcdir)/'`ImageContainer.cpp dansguardian-ImageContainer.obj: ImageContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ImageContainer.obj -MD -MP -MF $(DEPDIR)/dansguardian-ImageContainer.Tpo -c -o dansguardian-ImageContainer.obj `if test -f 'ImageContainer.cpp'; then $(CYGPATH_W) 'ImageContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/ImageContainer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ImageContainer.Tpo $(DEPDIR)/dansguardian-ImageContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ImageContainer.cpp' object='dansguardian-ImageContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ImageContainer.obj `if test -f 'ImageContainer.cpp'; then $(CYGPATH_W) 'ImageContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/ImageContainer.cpp'; fi` dansguardian-IPList.o: IPList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-IPList.o -MD -MP -MF $(DEPDIR)/dansguardian-IPList.Tpo -c -o dansguardian-IPList.o `test -f 'IPList.cpp' || echo '$(srcdir)/'`IPList.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-IPList.Tpo $(DEPDIR)/dansguardian-IPList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='IPList.cpp' object='dansguardian-IPList.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-IPList.o `test -f 'IPList.cpp' || echo '$(srcdir)/'`IPList.cpp dansguardian-IPList.obj: IPList.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-IPList.obj -MD -MP -MF $(DEPDIR)/dansguardian-IPList.Tpo -c -o dansguardian-IPList.obj `if test -f 'IPList.cpp'; then $(CYGPATH_W) 'IPList.cpp'; else $(CYGPATH_W) '$(srcdir)/IPList.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-IPList.Tpo $(DEPDIR)/dansguardian-IPList.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='IPList.cpp' object='dansguardian-IPList.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-IPList.obj `if test -f 'IPList.cpp'; then $(CYGPATH_W) 'IPList.cpp'; else $(CYGPATH_W) '$(srcdir)/IPList.cpp'; fi` dansguardian-OptionContainer.o: OptionContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-OptionContainer.o -MD -MP -MF $(DEPDIR)/dansguardian-OptionContainer.Tpo -c -o dansguardian-OptionContainer.o `test -f 'OptionContainer.cpp' || echo '$(srcdir)/'`OptionContainer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-OptionContainer.Tpo $(DEPDIR)/dansguardian-OptionContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='OptionContainer.cpp' object='dansguardian-OptionContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-OptionContainer.o `test -f 'OptionContainer.cpp' || echo '$(srcdir)/'`OptionContainer.cpp dansguardian-OptionContainer.obj: OptionContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-OptionContainer.obj -MD -MP -MF $(DEPDIR)/dansguardian-OptionContainer.Tpo -c -o dansguardian-OptionContainer.obj `if test -f 'OptionContainer.cpp'; then $(CYGPATH_W) 'OptionContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/OptionContainer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-OptionContainer.Tpo $(DEPDIR)/dansguardian-OptionContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='OptionContainer.cpp' object='dansguardian-OptionContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-OptionContainer.obj `if test -f 'OptionContainer.cpp'; then $(CYGPATH_W) 'OptionContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/OptionContainer.cpp'; fi` dansguardian-FOptionContainer.o: FOptionContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FOptionContainer.o -MD -MP -MF $(DEPDIR)/dansguardian-FOptionContainer.Tpo -c -o dansguardian-FOptionContainer.o `test -f 'FOptionContainer.cpp' || echo '$(srcdir)/'`FOptionContainer.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FOptionContainer.Tpo $(DEPDIR)/dansguardian-FOptionContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FOptionContainer.cpp' object='dansguardian-FOptionContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FOptionContainer.o `test -f 'FOptionContainer.cpp' || echo '$(srcdir)/'`FOptionContainer.cpp dansguardian-FOptionContainer.obj: FOptionContainer.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-FOptionContainer.obj -MD -MP -MF $(DEPDIR)/dansguardian-FOptionContainer.Tpo -c -o dansguardian-FOptionContainer.obj `if test -f 'FOptionContainer.cpp'; then $(CYGPATH_W) 'FOptionContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/FOptionContainer.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-FOptionContainer.Tpo $(DEPDIR)/dansguardian-FOptionContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='FOptionContainer.cpp' object='dansguardian-FOptionContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-FOptionContainer.obj `if test -f 'FOptionContainer.cpp'; then $(CYGPATH_W) 'FOptionContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/FOptionContainer.cpp'; fi` dansguardian-ListManager.o: ListManager.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ListManager.o -MD -MP -MF $(DEPDIR)/dansguardian-ListManager.Tpo -c -o dansguardian-ListManager.o `test -f 'ListManager.cpp' || echo '$(srcdir)/'`ListManager.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ListManager.Tpo $(DEPDIR)/dansguardian-ListManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListManager.cpp' object='dansguardian-ListManager.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ListManager.o `test -f 'ListManager.cpp' || echo '$(srcdir)/'`ListManager.cpp dansguardian-ListManager.obj: ListManager.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ListManager.obj -MD -MP -MF $(DEPDIR)/dansguardian-ListManager.Tpo -c -o dansguardian-ListManager.obj `if test -f 'ListManager.cpp'; then $(CYGPATH_W) 'ListManager.cpp'; else $(CYGPATH_W) '$(srcdir)/ListManager.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ListManager.Tpo $(DEPDIR)/dansguardian-ListManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListManager.cpp' object='dansguardian-ListManager.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ListManager.obj `if test -f 'ListManager.cpp'; then $(CYGPATH_W) 'ListManager.cpp'; else $(CYGPATH_W) '$(srcdir)/ListManager.cpp'; fi` dansguardian-md5.o: md5.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-md5.o -MD -MP -MF $(DEPDIR)/dansguardian-md5.Tpo -c -o dansguardian-md5.o `test -f 'md5.cpp' || echo '$(srcdir)/'`md5.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-md5.Tpo $(DEPDIR)/dansguardian-md5.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='md5.cpp' object='dansguardian-md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-md5.o `test -f 'md5.cpp' || echo '$(srcdir)/'`md5.cpp dansguardian-md5.obj: md5.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-md5.obj -MD -MP -MF $(DEPDIR)/dansguardian-md5.Tpo -c -o dansguardian-md5.obj `if test -f 'md5.cpp'; then $(CYGPATH_W) 'md5.cpp'; else $(CYGPATH_W) '$(srcdir)/md5.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-md5.Tpo $(DEPDIR)/dansguardian-md5.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='md5.cpp' object='dansguardian-md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-md5.obj `if test -f 'md5.cpp'; then $(CYGPATH_W) 'md5.cpp'; else $(CYGPATH_W) '$(srcdir)/md5.cpp'; fi` dansguardian-DownloadManager.o: DownloadManager.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DownloadManager.o -MD -MP -MF $(DEPDIR)/dansguardian-DownloadManager.Tpo -c -o dansguardian-DownloadManager.o `test -f 'DownloadManager.cpp' || echo '$(srcdir)/'`DownloadManager.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DownloadManager.Tpo $(DEPDIR)/dansguardian-DownloadManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DownloadManager.cpp' object='dansguardian-DownloadManager.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DownloadManager.o `test -f 'DownloadManager.cpp' || echo '$(srcdir)/'`DownloadManager.cpp dansguardian-DownloadManager.obj: DownloadManager.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-DownloadManager.obj -MD -MP -MF $(DEPDIR)/dansguardian-DownloadManager.Tpo -c -o dansguardian-DownloadManager.obj `if test -f 'DownloadManager.cpp'; then $(CYGPATH_W) 'DownloadManager.cpp'; else $(CYGPATH_W) '$(srcdir)/DownloadManager.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-DownloadManager.Tpo $(DEPDIR)/dansguardian-DownloadManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DownloadManager.cpp' object='dansguardian-DownloadManager.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-DownloadManager.obj `if test -f 'DownloadManager.cpp'; then $(CYGPATH_W) 'DownloadManager.cpp'; else $(CYGPATH_W) '$(srcdir)/DownloadManager.cpp'; fi` dansguardian-ConfigVar.o: ConfigVar.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ConfigVar.o -MD -MP -MF $(DEPDIR)/dansguardian-ConfigVar.Tpo -c -o dansguardian-ConfigVar.o `test -f 'ConfigVar.cpp' || echo '$(srcdir)/'`ConfigVar.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ConfigVar.Tpo $(DEPDIR)/dansguardian-ConfigVar.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConfigVar.cpp' object='dansguardian-ConfigVar.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ConfigVar.o `test -f 'ConfigVar.cpp' || echo '$(srcdir)/'`ConfigVar.cpp dansguardian-ConfigVar.obj: ConfigVar.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ConfigVar.obj -MD -MP -MF $(DEPDIR)/dansguardian-ConfigVar.Tpo -c -o dansguardian-ConfigVar.obj `if test -f 'ConfigVar.cpp'; then $(CYGPATH_W) 'ConfigVar.cpp'; else $(CYGPATH_W) '$(srcdir)/ConfigVar.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ConfigVar.Tpo $(DEPDIR)/dansguardian-ConfigVar.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConfigVar.cpp' object='dansguardian-ConfigVar.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ConfigVar.obj `if test -f 'ConfigVar.cpp'; then $(CYGPATH_W) 'ConfigVar.cpp'; else $(CYGPATH_W) '$(srcdir)/ConfigVar.cpp'; fi` dansguardian-ContentScanner.o: ContentScanner.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ContentScanner.o -MD -MP -MF $(DEPDIR)/dansguardian-ContentScanner.Tpo -c -o dansguardian-ContentScanner.o `test -f 'ContentScanner.cpp' || echo '$(srcdir)/'`ContentScanner.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ContentScanner.Tpo $(DEPDIR)/dansguardian-ContentScanner.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ContentScanner.cpp' object='dansguardian-ContentScanner.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ContentScanner.o `test -f 'ContentScanner.cpp' || echo '$(srcdir)/'`ContentScanner.cpp dansguardian-ContentScanner.obj: ContentScanner.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ContentScanner.obj -MD -MP -MF $(DEPDIR)/dansguardian-ContentScanner.Tpo -c -o dansguardian-ContentScanner.obj `if test -f 'ContentScanner.cpp'; then $(CYGPATH_W) 'ContentScanner.cpp'; else $(CYGPATH_W) '$(srcdir)/ContentScanner.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ContentScanner.Tpo $(DEPDIR)/dansguardian-ContentScanner.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ContentScanner.cpp' object='dansguardian-ContentScanner.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ContentScanner.obj `if test -f 'ContentScanner.cpp'; then $(CYGPATH_W) 'ContentScanner.cpp'; else $(CYGPATH_W) '$(srcdir)/ContentScanner.cpp'; fi` dansguardian-SocketArray.o: SocketArray.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-SocketArray.o -MD -MP -MF $(DEPDIR)/dansguardian-SocketArray.Tpo -c -o dansguardian-SocketArray.o `test -f 'SocketArray.cpp' || echo '$(srcdir)/'`SocketArray.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-SocketArray.Tpo $(DEPDIR)/dansguardian-SocketArray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SocketArray.cpp' object='dansguardian-SocketArray.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-SocketArray.o `test -f 'SocketArray.cpp' || echo '$(srcdir)/'`SocketArray.cpp dansguardian-SocketArray.obj: SocketArray.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-SocketArray.obj -MD -MP -MF $(DEPDIR)/dansguardian-SocketArray.Tpo -c -o dansguardian-SocketArray.obj `if test -f 'SocketArray.cpp'; then $(CYGPATH_W) 'SocketArray.cpp'; else $(CYGPATH_W) '$(srcdir)/SocketArray.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-SocketArray.Tpo $(DEPDIR)/dansguardian-SocketArray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SocketArray.cpp' object='dansguardian-SocketArray.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-SocketArray.obj `if test -f 'SocketArray.cpp'; then $(CYGPATH_W) 'SocketArray.cpp'; else $(CYGPATH_W) '$(srcdir)/SocketArray.cpp'; fi` dansguardian-dansguardian.o: dansguardian.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-dansguardian.o -MD -MP -MF $(DEPDIR)/dansguardian-dansguardian.Tpo -c -o dansguardian-dansguardian.o `test -f 'dansguardian.cpp' || echo '$(srcdir)/'`dansguardian.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-dansguardian.Tpo $(DEPDIR)/dansguardian-dansguardian.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dansguardian.cpp' object='dansguardian-dansguardian.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-dansguardian.o `test -f 'dansguardian.cpp' || echo '$(srcdir)/'`dansguardian.cpp dansguardian-dansguardian.obj: dansguardian.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-dansguardian.obj -MD -MP -MF $(DEPDIR)/dansguardian-dansguardian.Tpo -c -o dansguardian-dansguardian.obj `if test -f 'dansguardian.cpp'; then $(CYGPATH_W) 'dansguardian.cpp'; else $(CYGPATH_W) '$(srcdir)/dansguardian.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-dansguardian.Tpo $(DEPDIR)/dansguardian-dansguardian.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dansguardian.cpp' object='dansguardian-dansguardian.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-dansguardian.obj `if test -f 'dansguardian.cpp'; then $(CYGPATH_W) 'dansguardian.cpp'; else $(CYGPATH_W) '$(srcdir)/dansguardian.cpp'; fi` dansguardian-clamav.o: contentscanners/clamav.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-clamav.o -MD -MP -MF $(DEPDIR)/dansguardian-clamav.Tpo -c -o dansguardian-clamav.o `test -f 'contentscanners/clamav.cpp' || echo '$(srcdir)/'`contentscanners/clamav.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-clamav.Tpo $(DEPDIR)/dansguardian-clamav.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/clamav.cpp' object='dansguardian-clamav.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-clamav.o `test -f 'contentscanners/clamav.cpp' || echo '$(srcdir)/'`contentscanners/clamav.cpp dansguardian-clamav.obj: contentscanners/clamav.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-clamav.obj -MD -MP -MF $(DEPDIR)/dansguardian-clamav.Tpo -c -o dansguardian-clamav.obj `if test -f 'contentscanners/clamav.cpp'; then $(CYGPATH_W) 'contentscanners/clamav.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/clamav.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-clamav.Tpo $(DEPDIR)/dansguardian-clamav.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/clamav.cpp' object='dansguardian-clamav.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-clamav.obj `if test -f 'contentscanners/clamav.cpp'; then $(CYGPATH_W) 'contentscanners/clamav.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/clamav.cpp'; fi` dansguardian-icapscan.o: contentscanners/icapscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-icapscan.o -MD -MP -MF $(DEPDIR)/dansguardian-icapscan.Tpo -c -o dansguardian-icapscan.o `test -f 'contentscanners/icapscan.cpp' || echo '$(srcdir)/'`contentscanners/icapscan.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-icapscan.Tpo $(DEPDIR)/dansguardian-icapscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/icapscan.cpp' object='dansguardian-icapscan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-icapscan.o `test -f 'contentscanners/icapscan.cpp' || echo '$(srcdir)/'`contentscanners/icapscan.cpp dansguardian-icapscan.obj: contentscanners/icapscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-icapscan.obj -MD -MP -MF $(DEPDIR)/dansguardian-icapscan.Tpo -c -o dansguardian-icapscan.obj `if test -f 'contentscanners/icapscan.cpp'; then $(CYGPATH_W) 'contentscanners/icapscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/icapscan.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-icapscan.Tpo $(DEPDIR)/dansguardian-icapscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/icapscan.cpp' object='dansguardian-icapscan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-icapscan.obj `if test -f 'contentscanners/icapscan.cpp'; then $(CYGPATH_W) 'contentscanners/icapscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/icapscan.cpp'; fi` dansguardian-kavdscan.o: contentscanners/kavdscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-kavdscan.o -MD -MP -MF $(DEPDIR)/dansguardian-kavdscan.Tpo -c -o dansguardian-kavdscan.o `test -f 'contentscanners/kavdscan.cpp' || echo '$(srcdir)/'`contentscanners/kavdscan.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-kavdscan.Tpo $(DEPDIR)/dansguardian-kavdscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/kavdscan.cpp' object='dansguardian-kavdscan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-kavdscan.o `test -f 'contentscanners/kavdscan.cpp' || echo '$(srcdir)/'`contentscanners/kavdscan.cpp dansguardian-kavdscan.obj: contentscanners/kavdscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-kavdscan.obj -MD -MP -MF $(DEPDIR)/dansguardian-kavdscan.Tpo -c -o dansguardian-kavdscan.obj `if test -f 'contentscanners/kavdscan.cpp'; then $(CYGPATH_W) 'contentscanners/kavdscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/kavdscan.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-kavdscan.Tpo $(DEPDIR)/dansguardian-kavdscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/kavdscan.cpp' object='dansguardian-kavdscan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-kavdscan.obj `if test -f 'contentscanners/kavdscan.cpp'; then $(CYGPATH_W) 'contentscanners/kavdscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/kavdscan.cpp'; fi` dansguardian-clamdscan.o: contentscanners/clamdscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-clamdscan.o -MD -MP -MF $(DEPDIR)/dansguardian-clamdscan.Tpo -c -o dansguardian-clamdscan.o `test -f 'contentscanners/clamdscan.cpp' || echo '$(srcdir)/'`contentscanners/clamdscan.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-clamdscan.Tpo $(DEPDIR)/dansguardian-clamdscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/clamdscan.cpp' object='dansguardian-clamdscan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-clamdscan.o `test -f 'contentscanners/clamdscan.cpp' || echo '$(srcdir)/'`contentscanners/clamdscan.cpp dansguardian-clamdscan.obj: contentscanners/clamdscan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-clamdscan.obj -MD -MP -MF $(DEPDIR)/dansguardian-clamdscan.Tpo -c -o dansguardian-clamdscan.obj `if test -f 'contentscanners/clamdscan.cpp'; then $(CYGPATH_W) 'contentscanners/clamdscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/clamdscan.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-clamdscan.Tpo $(DEPDIR)/dansguardian-clamdscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/clamdscan.cpp' object='dansguardian-clamdscan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-clamdscan.obj `if test -f 'contentscanners/clamdscan.cpp'; then $(CYGPATH_W) 'contentscanners/clamdscan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/clamdscan.cpp'; fi` dansguardian-commandlinescan.o: contentscanners/commandlinescan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-commandlinescan.o -MD -MP -MF $(DEPDIR)/dansguardian-commandlinescan.Tpo -c -o dansguardian-commandlinescan.o `test -f 'contentscanners/commandlinescan.cpp' || echo '$(srcdir)/'`contentscanners/commandlinescan.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-commandlinescan.Tpo $(DEPDIR)/dansguardian-commandlinescan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/commandlinescan.cpp' object='dansguardian-commandlinescan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-commandlinescan.o `test -f 'contentscanners/commandlinescan.cpp' || echo '$(srcdir)/'`contentscanners/commandlinescan.cpp dansguardian-commandlinescan.obj: contentscanners/commandlinescan.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-commandlinescan.obj -MD -MP -MF $(DEPDIR)/dansguardian-commandlinescan.Tpo -c -o dansguardian-commandlinescan.obj `if test -f 'contentscanners/commandlinescan.cpp'; then $(CYGPATH_W) 'contentscanners/commandlinescan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/commandlinescan.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-commandlinescan.Tpo $(DEPDIR)/dansguardian-commandlinescan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='contentscanners/commandlinescan.cpp' object='dansguardian-commandlinescan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-commandlinescan.obj `if test -f 'contentscanners/commandlinescan.cpp'; then $(CYGPATH_W) 'contentscanners/commandlinescan.cpp'; else $(CYGPATH_W) '$(srcdir)/contentscanners/commandlinescan.cpp'; fi` dansguardian-default.o: downloadmanagers/default.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-default.o -MD -MP -MF $(DEPDIR)/dansguardian-default.Tpo -c -o dansguardian-default.o `test -f 'downloadmanagers/default.cpp' || echo '$(srcdir)/'`downloadmanagers/default.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-default.Tpo $(DEPDIR)/dansguardian-default.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/default.cpp' object='dansguardian-default.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-default.o `test -f 'downloadmanagers/default.cpp' || echo '$(srcdir)/'`downloadmanagers/default.cpp dansguardian-default.obj: downloadmanagers/default.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-default.obj -MD -MP -MF $(DEPDIR)/dansguardian-default.Tpo -c -o dansguardian-default.obj `if test -f 'downloadmanagers/default.cpp'; then $(CYGPATH_W) 'downloadmanagers/default.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/default.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-default.Tpo $(DEPDIR)/dansguardian-default.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/default.cpp' object='dansguardian-default.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-default.obj `if test -f 'downloadmanagers/default.cpp'; then $(CYGPATH_W) 'downloadmanagers/default.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/default.cpp'; fi` dansguardian-fancy.o: downloadmanagers/fancy.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-fancy.o -MD -MP -MF $(DEPDIR)/dansguardian-fancy.Tpo -c -o dansguardian-fancy.o `test -f 'downloadmanagers/fancy.cpp' || echo '$(srcdir)/'`downloadmanagers/fancy.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-fancy.Tpo $(DEPDIR)/dansguardian-fancy.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/fancy.cpp' object='dansguardian-fancy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-fancy.o `test -f 'downloadmanagers/fancy.cpp' || echo '$(srcdir)/'`downloadmanagers/fancy.cpp dansguardian-fancy.obj: downloadmanagers/fancy.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-fancy.obj -MD -MP -MF $(DEPDIR)/dansguardian-fancy.Tpo -c -o dansguardian-fancy.obj `if test -f 'downloadmanagers/fancy.cpp'; then $(CYGPATH_W) 'downloadmanagers/fancy.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/fancy.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-fancy.Tpo $(DEPDIR)/dansguardian-fancy.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/fancy.cpp' object='dansguardian-fancy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-fancy.obj `if test -f 'downloadmanagers/fancy.cpp'; then $(CYGPATH_W) 'downloadmanagers/fancy.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/fancy.cpp'; fi` dansguardian-trickle.o: downloadmanagers/trickle.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-trickle.o -MD -MP -MF $(DEPDIR)/dansguardian-trickle.Tpo -c -o dansguardian-trickle.o `test -f 'downloadmanagers/trickle.cpp' || echo '$(srcdir)/'`downloadmanagers/trickle.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-trickle.Tpo $(DEPDIR)/dansguardian-trickle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/trickle.cpp' object='dansguardian-trickle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-trickle.o `test -f 'downloadmanagers/trickle.cpp' || echo '$(srcdir)/'`downloadmanagers/trickle.cpp dansguardian-trickle.obj: downloadmanagers/trickle.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-trickle.obj -MD -MP -MF $(DEPDIR)/dansguardian-trickle.Tpo -c -o dansguardian-trickle.obj `if test -f 'downloadmanagers/trickle.cpp'; then $(CYGPATH_W) 'downloadmanagers/trickle.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/trickle.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-trickle.Tpo $(DEPDIR)/dansguardian-trickle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='downloadmanagers/trickle.cpp' object='dansguardian-trickle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-trickle.obj `if test -f 'downloadmanagers/trickle.cpp'; then $(CYGPATH_W) 'downloadmanagers/trickle.cpp'; else $(CYGPATH_W) '$(srcdir)/downloadmanagers/trickle.cpp'; fi` dansguardian-proxy.o: authplugins/proxy.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-proxy.o -MD -MP -MF $(DEPDIR)/dansguardian-proxy.Tpo -c -o dansguardian-proxy.o `test -f 'authplugins/proxy.cpp' || echo '$(srcdir)/'`authplugins/proxy.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-proxy.Tpo $(DEPDIR)/dansguardian-proxy.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/proxy.cpp' object='dansguardian-proxy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-proxy.o `test -f 'authplugins/proxy.cpp' || echo '$(srcdir)/'`authplugins/proxy.cpp dansguardian-proxy.obj: authplugins/proxy.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-proxy.obj -MD -MP -MF $(DEPDIR)/dansguardian-proxy.Tpo -c -o dansguardian-proxy.obj `if test -f 'authplugins/proxy.cpp'; then $(CYGPATH_W) 'authplugins/proxy.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/proxy.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-proxy.Tpo $(DEPDIR)/dansguardian-proxy.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/proxy.cpp' object='dansguardian-proxy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-proxy.obj `if test -f 'authplugins/proxy.cpp'; then $(CYGPATH_W) 'authplugins/proxy.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/proxy.cpp'; fi` dansguardian-ident.o: authplugins/ident.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ident.o -MD -MP -MF $(DEPDIR)/dansguardian-ident.Tpo -c -o dansguardian-ident.o `test -f 'authplugins/ident.cpp' || echo '$(srcdir)/'`authplugins/ident.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ident.Tpo $(DEPDIR)/dansguardian-ident.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ident.cpp' object='dansguardian-ident.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ident.o `test -f 'authplugins/ident.cpp' || echo '$(srcdir)/'`authplugins/ident.cpp dansguardian-ident.obj: authplugins/ident.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ident.obj -MD -MP -MF $(DEPDIR)/dansguardian-ident.Tpo -c -o dansguardian-ident.obj `if test -f 'authplugins/ident.cpp'; then $(CYGPATH_W) 'authplugins/ident.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ident.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ident.Tpo $(DEPDIR)/dansguardian-ident.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ident.cpp' object='dansguardian-ident.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ident.obj `if test -f 'authplugins/ident.cpp'; then $(CYGPATH_W) 'authplugins/ident.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ident.cpp'; fi` dansguardian-ip.o: authplugins/ip.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ip.o -MD -MP -MF $(DEPDIR)/dansguardian-ip.Tpo -c -o dansguardian-ip.o `test -f 'authplugins/ip.cpp' || echo '$(srcdir)/'`authplugins/ip.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ip.Tpo $(DEPDIR)/dansguardian-ip.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ip.cpp' object='dansguardian-ip.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ip.o `test -f 'authplugins/ip.cpp' || echo '$(srcdir)/'`authplugins/ip.cpp dansguardian-ip.obj: authplugins/ip.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ip.obj -MD -MP -MF $(DEPDIR)/dansguardian-ip.Tpo -c -o dansguardian-ip.obj `if test -f 'authplugins/ip.cpp'; then $(CYGPATH_W) 'authplugins/ip.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ip.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ip.Tpo $(DEPDIR)/dansguardian-ip.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ip.cpp' object='dansguardian-ip.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ip.obj `if test -f 'authplugins/ip.cpp'; then $(CYGPATH_W) 'authplugins/ip.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ip.cpp'; fi` dansguardian-ntlm.o: authplugins/ntlm.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ntlm.o -MD -MP -MF $(DEPDIR)/dansguardian-ntlm.Tpo -c -o dansguardian-ntlm.o `test -f 'authplugins/ntlm.cpp' || echo '$(srcdir)/'`authplugins/ntlm.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ntlm.Tpo $(DEPDIR)/dansguardian-ntlm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ntlm.cpp' object='dansguardian-ntlm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ntlm.o `test -f 'authplugins/ntlm.cpp' || echo '$(srcdir)/'`authplugins/ntlm.cpp dansguardian-ntlm.obj: authplugins/ntlm.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-ntlm.obj -MD -MP -MF $(DEPDIR)/dansguardian-ntlm.Tpo -c -o dansguardian-ntlm.obj `if test -f 'authplugins/ntlm.cpp'; then $(CYGPATH_W) 'authplugins/ntlm.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ntlm.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-ntlm.Tpo $(DEPDIR)/dansguardian-ntlm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/ntlm.cpp' object='dansguardian-ntlm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-ntlm.obj `if test -f 'authplugins/ntlm.cpp'; then $(CYGPATH_W) 'authplugins/ntlm.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/ntlm.cpp'; fi` dansguardian-digest.o: authplugins/digest.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-digest.o -MD -MP -MF $(DEPDIR)/dansguardian-digest.Tpo -c -o dansguardian-digest.o `test -f 'authplugins/digest.cpp' || echo '$(srcdir)/'`authplugins/digest.cpp @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-digest.Tpo $(DEPDIR)/dansguardian-digest.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/digest.cpp' object='dansguardian-digest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-digest.o `test -f 'authplugins/digest.cpp' || echo '$(srcdir)/'`authplugins/digest.cpp dansguardian-digest.obj: authplugins/digest.cpp @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -MT dansguardian-digest.obj -MD -MP -MF $(DEPDIR)/dansguardian-digest.Tpo -c -o dansguardian-digest.obj `if test -f 'authplugins/digest.cpp'; then $(CYGPATH_W) 'authplugins/digest.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/digest.cpp'; fi` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dansguardian-digest.Tpo $(DEPDIR)/dansguardian-digest.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='authplugins/digest.cpp' object='dansguardian-digest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dansguardian_CPPFLAGS) $(CPPFLAGS) $(dansguardian_CXXFLAGS) $(CXXFLAGS) -c -o dansguardian-digest.obj `if test -f 'authplugins/digest.cpp'; then $(CYGPATH_W) 'authplugins/digest.cpp'; else $(CYGPATH_W) '$(srcdir)/authplugins/digest.cpp'; fi` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-sbinPROGRAMS ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-sbinPROGRAMS install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-sbinPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/src/SysV.hpp0000644001165000116500000000343711110523210013510 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@?? jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_SYSV #define __HPP_SYSV // INCLUDES #include "OptionContainer.hpp" #include #include // DECLARATIONS // Kill the process specified in the given pidfile, optionally deleting the pidfile while we're at it, // along with the UNIX domain sockets for the old logger & url cache int sysv_kill(std::string pidfile, bool dounlink = true); // show PID of running DG process int sysv_showpid(std::string pidfile); // check that the process in the pidfile is running bool sysv_amirunning(std::string pidfile); // delete any existing file with this name, and create a new one with relevant mode flags int sysv_openpidfile(std::string pidfile); // write our pid to the given file & close it int sysv_writepidfile(int pidfilefd); // send HUP or USR1 to the process in the pidfile int sysv_hup(std::string pidfile); int sysv_usr1(std::string pidfile); #endif dansguardian-2.10.1.1/src/ConfigVar.hpp0000644001165000116500000000332311110523210014454 00000000000000//Defines the ConfigVar class, which implements reading options from a file //into a map //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_CONFIGVAR #define __HPP_CONFIGVAR // INCLUDES #include #include #include "String.hpp" // DECLARATIONS class ConfigVar { public: ConfigVar(); // read the given file, splitting option/value at the given delimiter ConfigVar(const char *filename, const char *delimiter = "="); int readVar(const char *filename, const char *delimiter = "="); // return the value for the named option String entry(const char *reference); String operator[] (const char *reference); private: // comparison operator (maps are sorted) - true if s1 comes before s2 struct ltstr { bool operator() (String s1, String s2) const { return strcmp(s1.toCharArray(), s2.toCharArray()) < 0; } }; // the map itself - key type, value type, key comparison operator std::map < String, String, ltstr > params; }; #endif dansguardian-2.10.1.1/src/Makefile.am0000644001165000116500000000743611135357414014154 00000000000000clean_SUBDIRS= . downloadmanagers contentscanners authplugins # A MASSIVE thank you to Lawrence Manning for pointing out the # -export-dynamic option was needed to solve a long problem # which stopped DG2.9 from actually running ever. # Daniel Barron Fri 18th March 2005 # Unfortunately, since it was never made to work on anything # other than Linux, libtool support has been removed in favour # of configure-time options (at DB's request). if HAVE_CLAMAV CLAMAV_SOURCE = contentscanners/clamav.cpp else CLAMAV_SOURCE = endif #if HAVE_KAVCLIENT #KAVAV_SOURCES = contentscanners/kavav.cpp #else #KAVAV_SOURCES = #endif if ENABLE_CLAMD CLAMDSCAN_SOURCE = contentscanners/clamdscan.cpp else CLAMDSCAN_SOURCE = endif if ENABLE_ICAP ICAPSCAN_SOURCE = contentscanners/icapscan.cpp else ICAPSCAN_SOURCE = endif if ENABLE_KAVD KAVDSCAN_SOURCE = contentscanners/kavdscan.cpp else KAVDSCAN_SOURCE = endif if ENABLE_COMMANDLINE COMMANDLINE_SOURCE = contentscanners/commandlinescan.cpp else COMMANDLINE_SOURCE = endif DEFAULTDM_SOURCE = downloadmanagers/default.cpp if ENABLE_FANCYDM FANCYDM_SOURCE = downloadmanagers/fancy.cpp else FANCYDM_SOURCE = endif if ENABLE_TRICKLEDM TRICKLEDM_SOURCE = downloadmanagers/trickle.cpp else TRICKLEDM_SOURCE = endif PROXYAUTH_SOURCE = authplugins/proxy.cpp IDENTAUTH_SOURCE = authplugins/ident.cpp IPAUTH_SOURCE = authplugins/ip.cpp DIGESTAUTH_SOURCE = authplugins/digest.cpp if ENABLE_NTLM NTLMAUTH_SOURCE = authplugins/ntlm.cpp else NTLMAUTH_SOURCE = endif sbin_PROGRAMS = dansguardian dansguardian_CXXFLAGS = $(PCRE_CFLAGS) $(CLAMAV_CFLAGS) $(AM_CXXFLAGS) dansguardian_LDADD = $(PCRE_LIBS) $(CLAMAV_LIBS) $(AM_LIBS) dansguardian_CPPFLAGS = -D__CONFFILE='"$(DGCONFFILE)"' \ -D__LOGLOCATION='"$(DGLOGLOCATION)/"' \ -D__PIDDIR='"$(DGPIDDIR)"' \ -D__PROXYUSER='"$(DGPROXYUSER)"' \ -D__PROXYGROUP='"$(DGPROXYGROUP)"' \ -D__CONFDIR='"$(DGCONFDIR)"' \ $(AM_CPPFLAGS) dansguardian_SOURCES = String.cpp String.hpp \ FDTunnel.cpp FDTunnel.hpp \ ConnectionHandler.cpp ConnectionHandler.hpp \ DataBuffer.cpp DataBuffer.hpp \ HTTPHeader.cpp HTTPHeader.hpp \ NaughtyFilter.cpp NaughtyFilter.hpp \ RegExp.cpp RegExp.hpp \ FDFuncs.cpp FDFuncs.hpp \ BaseSocket.cpp BaseSocket.hpp \ Socket.cpp Socket.hpp \ FatController.cpp FatController.hpp \ UDSocket.cpp UDSocket.hpp \ SysV.cpp SysV.hpp \ ListContainer.cpp ListContainer.hpp \ Auth.cpp Auth.hpp \ HTMLTemplate.cpp HTMLTemplate.hpp \ LanguageContainer.cpp LanguageContainer.hpp \ DynamicURLList.cpp DynamicURLList.hpp \ DynamicIPList.cpp DynamicIPList.hpp \ ImageContainer.cpp ImageContainer.hpp \ IPList.cpp IPList.hpp \ OptionContainer.cpp OptionContainer.hpp \ FOptionContainer.cpp FOptionContainer.hpp \ ListManager.cpp ListManager.hpp \ md5.cpp md5.hpp \ DownloadManager.cpp DownloadManager.hpp \ ConfigVar.cpp ConfigVar.hpp \ ContentScanner.cpp ContentScanner.hpp \ SocketArray.cpp SocketArray.hpp \ dansguardian.cpp \ Plugin.hpp \ $(CLAMAV_SOURCE) $(ICAPSCAN_SOURCE) \ $(KAVDSCAN_SOURCE) $(CLAMDSCAN_SOURCE) \ $(COMMANDLINE_SOURCE) \ $(DEFAULTDM_SOURCE) $(FANCYDM_SOURCE) \ $(TRICKLEDM_SOURCE) $(PROXYAUTH_SOURCE) \ $(IDENTAUTH_SOURCE) $(IPAUTH_SOURCE) \ $(NTLMAUTH_SOURCE) $(DIGESTAUTH_SOURCE) dansguardian-2.10.1.1/src/FDFuncs.cpp0000644001165000116500000000351311110523210014062 00000000000000// File descriptor functions - generic functions for reading, writing, // and (in future) creating files // Please use *only* for files, not sockets! //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "FDFuncs.hpp" // IMPLEMENTATION // wrapper around FD read that restarts on EINTR int readEINTR(int fd, char *buf, unsigned int count) { int rc; errno = 0; while (true) { // using the while as a restart point with continue rc = read(fd, buf, count); if (rc < 0) { if (errno == EINTR) { continue; // was interupted by a signal so restart } } break; // end the while } return rc; // return status } // wrapper around FD write that restarts on EINTR int writeEINTR(int fd, char *buf, unsigned int count) { int rc; errno = 0; while (true) { // using the while as a restart point with continue rc = write(fd, buf, count); if (rc < 0) { if (errno == EINTR) { continue; // was interupted by a signal so restart } } break; // end the while } return rc; // return status } dansguardian-2.10.1.1/src/Auth.cpp0000644001165000116500000001043611110523210013475 00000000000000// AuthPlugin class - interface for plugins for retrieving client usernames // and filter group membership //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "Auth.hpp" #include "OptionContainer.hpp" #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; extern authcreate_t proxycreate; extern authcreate_t digestcreate; extern authcreate_t identcreate; extern authcreate_t ipcreate; #ifdef ENABLE_NTLM extern authcreate_t ntlmcreate; #endif // IMPLEMENTATION AuthPlugin::AuthPlugin(ConfigVar &definition):is_connection_based(false), needs_proxy_query(false) { cv = definition; } int AuthPlugin::init(void *args) { return 0; } int AuthPlugin::quit() { return 0; } // determine what filter group the given username is in // return -1 when user not found int AuthPlugin::determineGroup(std::string &user, int &fg) { if (user.length() < 1 || user == "-") { return DGAUTH_NOMATCH; } String u(user); u.toLower(); // since the filtergroupslist is read in in lowercase, we should do this. user = u.toCharArray(); // also pass back to ConnectionHandler, so appears lowercase in logs String ue(u); ue += "="; char *i = o.filter_groups_list.findStartsWithPartial(ue.toCharArray()); if (i == NULL) { #ifdef DGDEBUG std::cout << "User not in filter groups list: " << ue << std::endl; #endif return DGAUTH_NOUSER; } #ifdef DGDEBUG std::cout << "User found: " << i << std::endl; #endif ue = i; if (ue.before("=") == u) { ue = ue.after("=filter"); int l = ue.length(); if (l < 1 || l > 2) { return DGAUTH_NOUSER; } fg = ue.toInteger(); if (fg > o.numfg) { return DGAUTH_NOUSER; } if (fg > 0) { fg--; } return DGAUTH_OK; } return DGAUTH_NOUSER; } // take in a configuration file, find the AuthPlugin class associated with the plugname variable, and return an instance AuthPlugin* auth_plugin_load(const char *pluginConfigPath) { ConfigVar cv; if (cv.readVar(pluginConfigPath, "=") > 0) { if (!is_daemonised) { std::cerr << "Unable to load plugin config: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable to load plugin config %s", pluginConfigPath); return NULL; } String plugname(cv["plugname"]); if (plugname.length() < 1) { if (!is_daemonised) { std::cerr << "Unable read plugin config plugname variable: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable read plugin config plugname variable %s", pluginConfigPath); return NULL; } if (plugname == "proxy-basic") { #ifdef DGDEBUG std::cout << "Enabling proxy-basic auth plugin" << std::endl; #endif return proxycreate(cv); } if (plugname == "proxy-digest") { #ifdef DGDEBUG std::cout << "Enabling proxy-digest auth plugin" << std::endl; #endif return digestcreate(cv); } if (plugname == "ident") { #ifdef DGDEBUG std::cout << "Enabling ident server auth plugin" << std::endl; #endif return identcreate(cv); } if (plugname == "ip") { #ifdef DGDEBUG std::cout << "Enabling IP-based auth plugin" << std::endl; #endif return ipcreate(cv); } #ifdef ENABLE_NTLM if (plugname == "proxy-ntlm") { #ifdef DGDEBUG std::cout << "Enabling proxy-NTLM auth plugin" << std::endl; #endif return ntlmcreate(cv); } #endif if (!is_daemonised) { std::cerr << "Unable to load plugin: " << pluginConfigPath << std::endl; } syslog(LOG_ERR, "Unable to load plugin %s", pluginConfigPath); return NULL; } dansguardian-2.10.1.1/src/NaughtyFilter.cpp0000644001165000116500000012615111157441533015405 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "NaughtyFilter.hpp" #include "RegExp.hpp" #include "ListContainer.hpp" #include #include #include // GLOBALS extern OptionContainer o; #ifdef HAVE_PCRE extern RegExp absurl_re, relurl_re; #endif // DECLARATIONS // category list entry class - stores category index & weight of all phrases // found so far that fall under this category. also includes a less-than // operator so that the STL sort algorithm can be applied to lists of these. class listent { public: listent() {}; listent(const int& w, String& s) { weight = w; string = s; }; int weight; String string; int operator < (const listent &a) const { // sort in descending order of score return weight > a.weight ? 1 : 0; }; }; // IMPLEMENTATION // constructor - set up defaults NaughtyFilter::NaughtyFilter() : isItNaughty(false), isException(false), usedisplaycats(false), filtergroup(0), naughtiness(0) { } void NaughtyFilter::reset() { isItNaughty = false; isException = false; filtergroup = 0; whatIsNaughty = ""; whatIsNaughtyLog = ""; whatIsNaughtyCategories = ""; usedisplaycats = false; naughtiness = 0; } // check the given document body for banned, weighted, and exception phrases (and PICS, and regexes, &c.) void NaughtyFilter::checkme(DataBuffer *body, String &url, String &domain) { // original data off_t rawbodylen = (*body).buffer_length; char *rawbody = (*body).data; // check PICS now - not dependent on case, hex decoding, etc. // as only sites which play by the rules will self-rate if ((*o.fg[filtergroup]).enable_PICS) { #ifdef DGDEBUG std::cout << "PICS is enabled" << std::endl; #endif checkPICS(rawbody); if (isItNaughty) return; // Well there is no point in continuing is there? } if (o.weighted_phrase_mode == 0) return; // hex-decoded data (not case converted) off_t hexdecodedlen = rawbodylen; char *hexdecoded = rawbody; unsigned char c; // Hex decode content if desired // Do this now, as it's not especially case-sensitive, // and the case alteration should modify case post-decoding if (o.hex_decode_content) { // Mod suggested by AFN Tue 8th April 2003 #ifdef DGDEBUG std::cout << "Hex decoding is enabled" << std::endl; #endif hexdecoded = new char[rawbodylen + 128 + 1]; memset(hexdecoded, 0, rawbodylen + 128 + 1); unsigned char c1; unsigned char c2; unsigned char c3; char hexval[5] = "0x"; // Initializes a "hexadecimal string" hexval[4] = '\0'; char *ptr; // pointer required by strtol // make a copy of the escaped document char by char off_t i = 0; off_t j = 0; while (i < rawbodylen - 3) { // we lose 3 bytes but what the hell.. c1 = rawbody[i]; c2 = rawbody[i + 1]; c3 = rawbody[i + 2]; if (c1 == '%' && (((c2 >= '0') && (c2 <= '9')) || ((c2 >= 'a') && (c2 <= 'f')) || ((c2 >= 'A') && (c2 <= 'F'))) && (((c3 >= '0') && (c3 <= '9')) || ((c3 >= 'a') && (c3 <= 'f')) || ((c3 >= 'A') && (c3 <= 'F')))) { hexval[2] = c2; hexval[3] = c3; c = (unsigned char) strtol(hexval, &ptr, 0); i += 3; } else { c = c1; i++; } hexdecoded[j] = c; j++; } // copy any remaining bytes while (i < rawbodylen) { hexdecoded[j++] = rawbody[i++]; } hexdecoded[j] = '\0'; hexdecodedlen = j; } // scan twice, with & without case conversion (if desired) - aids support for exotic char encodings // TODO: move META/title sentinel location outside this loop, as they are not case sensitive operations bool preserve_case = o.preserve_case; if (o.preserve_case == 2) { // scanning twice *is* desired // first time round the loop, don't preserve case (non-exotic encodings) #ifdef DGDEBUG std::cout << "Filtering with/without case preservation is enabled" << std::endl; #endif preserve_case = false; } // Store for the lowercase (maybe) data // The extra 128 is used for various speed tricks to // squeeze as much speed as possible. char* bodylc = new char[hexdecodedlen + 128 + 1]; memset(bodylc, 0, hexdecodedlen + 128 + 1); // Store for the tag-stripped data char* bodynohtml = NULL; if (o.phrase_filter_mode == 1 || o.phrase_filter_mode == 2) { bodynohtml = new char[hexdecodedlen + 128 + 1]; memset(bodynohtml, 0, hexdecodedlen + 128 + 1); } for (int loop = 0; loop < (o.preserve_case == 2 ? 2 : 1); loop++) { #ifdef DGDEBUG std::cout << "Preserve case: " << preserve_case << std::endl; #endif off_t i, j; #ifdef DGDEBUG if (o.phrase_filter_mode == 0 || o.phrase_filter_mode == 2 || o.phrase_filter_mode == 3) std::cout << "Raw content needed" << std::endl; #endif // use the one that's been hex decoded, but not stripped // make a copy of the document lowercase char by char if (preserve_case) { for (i = 0; i < hexdecodedlen; i++) { c = hexdecoded[i]; if (c == 13 || c == 9 || c == 10) { c = 32; // convert all whitespace to a space } bodylc[i] = c; } } else { #ifdef DGDEBUG std::cout << "Not preserving case of raw content" << std::endl; #endif for (i = 0; i < hexdecodedlen; i++) { c = hexdecoded[i]; if (c >= 'A' && c <= 'Z') { c = 'a' + c - 'A'; } else if (c >= 192 && c <= 221) { // for accented chars c += 32; // 224 + c - 192 } else { if (c == 13 || c == 9 || c == 10) { c = 32; // convert all whitespace to a space } } bodylc[i] = c; } } // filter meta tags & title only // based on idea from Nicolas Peyrussie if(o.phrase_filter_mode == 3) { #ifdef DGDEBUG std::cout << "Filtering META/title" << std::endl; #endif bool addit = false; // flag if we should copy this char to filtered version bool needcheck = false; // flag if we actually find anything worth filtering off_t bodymetalen; // find or as end of search range char* endhead = strstr(bodylc, "' i += 7; c = bodylc[i]; } } // meta tags end at a > // title tags end at the next < (opening of ) if (addit && ((c == '>') || (c == '<'))) { // stop ading data addit = false; // add a space before the next word in the check buffer bodymeta[j++] = 32; } if (addit) { // if we're in "record" mode (i.e. inside a title/metatag), strip certain characters out // of the data (to sanitise metatags & aid filtering of titles) if ( c== ',' || c == '=' || c == '"' || c == '\'' || c == '(' || c == ')' || c == '.') { // replace with a space c = 32; } // don't bother duplicating spaces if ((c != 32) || (c == 32 && (bodymeta[j-1] != 32))) { bodymeta[j++] = c; // copy it to the filtered copy } } } if (needcheck) { bodymeta[j++] = '\0'; #ifdef DGDEBUG std::cout << bodymeta << std::endl; #endif bodymetalen = j; checkphrase(bodymeta, bodymetalen); } #ifdef DGDEBUG else std::cout<<"Nothing to filter"< bool addit; // flag if we should copy this char to filtered version j = 1; bodynohtml[0] = 32; // * for this for (off_t i = 0; i < hexdecodedlen; i++) { addit = true; c = bodylc[i]; if (c == '<') { inhtml = true; // flag we are inside a html <> } if (c == '>') { // flag we have just left a html <> inhtml = false; c = 32; } if (inhtml) { addit = false; } if (c == 32) { if (bodynohtml[j - 1] == 32) { // * and this addit = false; } } if (addit) { // if it passed the filters bodynohtml[j++] = c; // copy it to the filtered copy } } #ifdef DGDEBUG std::cout << "Checking smart content" << std::endl; #endif checkphrase(bodynohtml, j - 1); // second time round the case loop (if there is a second time), // do preserve case (exotic encodings) preserve_case = true; } delete[]bodylc; delete[]bodynohtml; if (hexdecoded != rawbody) delete[]hexdecoded; } // check the phrase lists void NaughtyFilter::checkphrase(char *file, off_t l, String *url, String *domain) { int weighting = 0; int cat; std::string weightedphrase; // checkme: translate this? String currcat("Embedded URLs"); // found categories list & reusable iterators std::map listcategories; // check for embedded references to banned sites/URLs. // have regexes that check for URLs in pages (look for attributes (src, href, javascript location) // or look for protocol strings (in which case, incl. ftp)?) and extract them. // then check the extracted list against the banned site/URL lists. // ADs category lists do not want to add to the possibility of a site being banned. // Exception lists are not checked. // Do not do full-blown category retrieval/duplicate checking; simply add the // "Embedded URLs" category. // Put a warning next to the option in the config file that this will take lots of CPU. // Support phrase mode 1/2 distinction (duplicate sites/URLs). // Have weight configurable per filter group, not globally or with a list directive - // a weight of 0 will disable the option, effectively making this functionality per-FG itself. // todo: if checkphrase is passed the domain & existing URL, it can create full URLs from relative ones. // if a src/href URL starts with a /, append it to the domain; otherwise, append it to the existing URL. // chop off anything after a ?, run through realPath, then put through the URL lists. #ifdef HAVE_PCRE // if weighted phrases are enabled, and we have been passed a URL and domain, and embedded URL checking is enabled... // then check for embedded URLs! if (url != NULL && o.fg[filtergroup]->embedded_url_weight > 0) { std::map::iterator ourcat; bool catinited = false; std::map found; std::map::iterator founditem; String u; char* j; // check for absolute URLs if (absurl_re.match(file)) { // each match generates 2 results (because of the brackets in the regex), we're only interested in the first #ifdef DGDEBUG std::cout << "Found " << absurl_re.numberOfMatches()/2 << " absolute URLs:" << std::endl; #endif for (int i = 0; i < absurl_re.numberOfMatches(); i+=2) { // chop off quotes u = absurl_re.result(i); u = u.subString(1,u.length()-2); #ifdef DGDEBUG std::cout << u << std::endl; #endif if ((((j = o.fg[filtergroup]->inBannedSiteList(u)) != NULL) && !(o.lm.l[o.fg[filtergroup]->banned_site_list]->lastcategory.contains("ADs"))) || (((j = o.fg[filtergroup]->inBannedURLList(u)) != NULL) && !(o.lm.l[o.fg[filtergroup]->banned_url_list]->lastcategory.contains("ADs")))) { // duplicate checking // checkme: this should really be being done *before* we search the lists. // but because inBanned* methods do some cleaning up of their own, we don't know the form to check against. // we actually want these cleanups do be done before passing to inBanned*/inException* - this would // speed up ConnectionHandler a bit too. founditem = found.find(j); if ((o.weighted_phrase_mode == 2) && (founditem != found.end())) { founditem->second++; } else { // add the site to the found phrases list found[j] = 1; if (weightedphrase.length() == 0) weightedphrase = "["; else weightedphrase += " "; weightedphrase += j; if (!catinited) { listcategories[-1] = listent(o.fg[filtergroup]->embedded_url_weight,currcat); ourcat = listcategories.find(-1); catinited = true; } else ourcat->second.weight += o.fg[filtergroup]->embedded_url_weight; } } } } found.clear(); // check for relative URLs if (relurl_re.match(file)) { // we don't want any parameters on the end of the current URL, since we append to it directly // when forming absolute URLs from relative ones. we do want a / on the end, too. String currurl(*url); if (currurl.contains("?")) currurl = currurl.before("?"); if (currurl[currurl.length()-1] != '/') currurl += "/"; // each match generates 2 results (because of the brackets in the regex), we're only interested in the first #ifdef DGDEBUG std::cout << "Found " << relurl_re.numberOfMatches()/2 << " relative URLs:" << std::endl; #endif for (int i = 0; i < relurl_re.numberOfMatches(); i+=2) { u = relurl_re.result(i); // can't find a way to negate submatches in PCRE, so it is entirely possible // that some absolute URLs have made their way into this list. we don't want them. if (u.contains("://")) continue; #ifdef DGDEBUG std::cout << u << std::endl; #endif // remove src/href & quotes u = u.after("="); u.removeWhiteSpace(); u = u.subString(1,u.length()-2); // create absolute URL if (u[0] == '/') u = (*domain) + u; else u = currurl + u; #ifdef DGDEBUG std::cout << "absolute form: " << u << std::endl; #endif if ((((j = o.fg[filtergroup]->inBannedSiteList(u)) != NULL) && !(o.lm.l[o.fg[filtergroup]->banned_site_list]->lastcategory.contains("ADs"))) || (((j = o.fg[filtergroup]->inBannedURLList(u)) != NULL) && !(o.lm.l[o.fg[filtergroup]->banned_url_list]->lastcategory.contains("ADs")))) { // duplicate checking // checkme: this should really be being done *before* we search the lists. // but because inBanned* methods do some cleaning up of their own, we don't know the form to check against. // we actually want these cleanups do be done before passing to inBanned*/inException* - this would // speed up ConnectionHandler a bit too. founditem = found.find(j); if ((o.weighted_phrase_mode == 2) && (founditem != found.end())) { founditem->second++; } else { // add the site to the found phrases list found[j] = 1; if (weightedphrase.length() == 0) weightedphrase = "["; else weightedphrase += " "; weightedphrase += j; if (!catinited) { listcategories[-1] = listent(o.fg[filtergroup]->embedded_url_weight,currcat); ourcat = listcategories.find(-1); catinited = true; } else ourcat->second.weight += o.fg[filtergroup]->embedded_url_weight; } } } } if (catinited) { weighting = ourcat->second.weight; weightedphrase += "]"; #ifdef DGDEBUG std::cout << weightedphrase << std::endl; std::cout << "score from embedded URLs: " << ourcat->second.weight << std::endl; #endif } } #endif std::string bannedphrase; std::string exceptionphrase; String bannedcategory; int type, index, weight, time; bool allcmatched = true, bannedcombi = false; std::string s1; // this line here searches for phrases contained in the list - the rest of the code is all sorting // through it to find the categories, weightings, types etc. of what has actually been found. std::map > found; (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).graphSearch(found, file, l); // cache reusable iterators std::map >::iterator foundend = found.end(); std::map >::iterator foundcurrent; // look for combinations first //if banned must wait for exception later std::string combifound; std::string combisofar; std::vector::iterator combicurrent = o.lm.l[o.fg[filtergroup]->banned_phrase_list]->combilist.begin(); std::map::iterator catcurrent; int lowest_occurrences = 0; while (combicurrent != o.lm.l[o.fg[filtergroup]->banned_phrase_list]->combilist.end()) { // Grab the current combination phrase part index = *combicurrent; // Do stuff if what we have is an end marker (end of one list of parts) if (index == -2) { // Were all the parts in this combination matched? if (allcmatched) { type = *(++combicurrent); // check this time limit against the list of time limits time = *(++combicurrent); if (not (o.lm.l[o.fg[filtergroup]->banned_phrase_list]->checkTimeAtD(time))) { // nope - so don't take any notice of it #ifdef DGDEBUG combicurrent++; cat = (*++combicurrent); std::cout << "Ignoring combi phrase based on time limits: " << combisofar << "; " << o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getListCategoryAtD(cat) << std::endl; #else combicurrent += 2; #endif combisofar = ""; } else if (type == -1) { // combination exception isItNaughty = false; isException = true; whatIsNaughtyLog = o.language_list.getTranslation(605); // Combination exception phrase found: whatIsNaughtyLog += combisofar; whatIsNaughty = ""; ++combicurrent; cat = *(++combicurrent); whatIsNaughtyCategories = o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getListCategoryAtD(cat); return; } else if (type == 1) { // combination weighting weight = *(++combicurrent); weighting += weight * (o.weighted_phrase_mode == 2 ? 1 : lowest_occurrences); if (weight > 0) { cat = *(++combicurrent); //category index -1 indicates an uncategorised list if (cat >= 0) { //don't output duplicate categories catcurrent = listcategories.find(cat); if (catcurrent != listcategories.end()) { catcurrent->second.weight += weight * (o.weighted_phrase_mode == 2 ? 1 : lowest_occurrences); } else { currcat = o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getListCategoryAtD(cat); listcategories[cat] = listent(weight,currcat); } } } else { // skip past category for negatively weighted phrases combicurrent++; } if (weightedphrase.length() > 0) { weightedphrase += "+"; } weightedphrase += "("; if (weight < 0) { weightedphrase += "-" + combisofar; } else { weightedphrase += combisofar; } #ifdef DGDEBUG std::cout << "found combi weighted phrase ("<< o.weighted_phrase_mode << "): " << combisofar << " x" << lowest_occurrences << " (per phrase: " << weight << ", calculated: " << (weight * (o.weighted_phrase_mode == 2 ? 1 : lowest_occurrences)) << ")" << std::endl; #endif weightedphrase += ")"; combisofar = ""; } else if (type == 0) { // combination banned bannedcombi = true; combifound += "(" + combisofar + ")"; combisofar = ""; combicurrent += 2; cat = *(combicurrent); bannedcategory = o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getListCategoryAtD(cat); } } else { // We had an end marker, but not all the parts so far were matched. // Reset the match flag ready for the next chain, and advance to its first part. allcmatched = true; combicurrent += 4; lowest_occurrences = 0; } } else { // We didn't get an end marker - just an individual part. // If all parts in the current chain have been matched so far, look for this one as well. if (allcmatched) { s1 =(*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getItemAtInt(index); if ((foundcurrent = found.find(s1)) == foundend) { allcmatched = false; combisofar = ""; } else { if (combisofar.length() > 0) { combisofar += ", "; } combisofar += s1; // also track lowest number of times any one part occurs in the text // as this will correspond to the number of times the whole chain occurs if ((lowest_occurrences == 0) || (lowest_occurrences > foundcurrent->second.second)) { lowest_occurrences = foundcurrent->second.second; } } } } // Advance to the next part in the current chain combicurrent++; } // even if we already found a combi ban, we must still wait; there may be non-combi exceptions to follow // now check non-combi phrases foundcurrent = found.begin(); while (foundcurrent != foundend) { // check time for current phrase if (not o.lm.l[o.fg[filtergroup]->banned_phrase_list]->checkTimeAt(foundcurrent->second.first)) { #ifdef DGDEBUG std::cout << "Ignoring phrase based on time limits: " << foundcurrent->first << ", " << (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getListCategoryAt(foundcurrent->second.first) << std::endl; #endif foundcurrent++; continue; } // 0=banned, 1=weighted, -1=exception, 2=combi, 3=weightedcombi type = (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getTypeAt(foundcurrent->second.first); if (type == 0) { // if we already found a combi ban, we don't need to know this stuff if (!bannedcombi) { isItNaughty = true; bannedphrase = foundcurrent->first; bannedcategory = (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getListCategoryAt(foundcurrent->second.first, &cat); } } else if (type == 1) { // found a weighted phrase - either add one lot of its score, or one lot for every occurrence, depending on phrase filtering mode weight = (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getWeightAt(foundcurrent->second.first) * (o.weighted_phrase_mode == 2 ? 1 : foundcurrent->second.second); weighting += weight; if (weight > 0) { currcat = (*o.lm.l[(*o.fg[filtergroup]).banned_phrase_list]).getListCategoryAt(foundcurrent->second.first, &cat); if (cat >= 0) { //don't output duplicate categories catcurrent = listcategories.find(cat); if (catcurrent != listcategories.end()) { // add one or N times the weight to this category's score catcurrent->second.weight += weight * (o.weighted_phrase_mode == 2 ? 1 : foundcurrent->second.second); } else { listcategories[cat] = listent(weight,currcat); } } } if (o.show_weighted_found) { if (weightedphrase.length() > 0) { weightedphrase += "+"; } if (weight < 0) { weightedphrase += "-"; } weightedphrase += foundcurrent->first; } #ifdef DGDEBUG std::cout << "found weighted phrase ("<< o.weighted_phrase_mode << "): " << foundcurrent->first << " x" << foundcurrent->second.second << " (per phrase: " << o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getWeightAt(foundcurrent->second.first) << ", calculated: " << weight << ")" << std::endl; #endif } else if (type == -1) { isException = true; isItNaughty = false; whatIsNaughtyLog = o.language_list.getTranslation(604); // Exception phrase found: whatIsNaughtyLog += foundcurrent->first; whatIsNaughty = ""; whatIsNaughtyCategories = o.lm.l[o.fg[filtergroup]->banned_phrase_list]->getListCategoryAt(foundcurrent->second.first, NULL); return; // no point in going further } foundcurrent++; } #ifdef DGDEBUG std::cout << "WEIGHTING: " << weighting << std::endl; #endif // store the lowest negative weighting or highest positive weighting out of all filtering runs, preferring to store positive weightings. if ((weighting < 0 && naughtiness <= 0 && weighting < naughtiness) || (naughtiness >= 0 && weighting > naughtiness) || (naughtiness < 0 && weighting > 0) ) { naughtiness = weighting; } #ifdef DGDEBUG std::cout << "NAUGHTINESS: " << naughtiness << std::endl; #endif // *now* we can safely get down to the whole banning business! if (bannedcombi) { isItNaughty = true; whatIsNaughtyLog = o.language_list.getTranslation(400); // Banned combination phrase found: whatIsNaughtyLog += combifound; whatIsNaughty = o.language_list.getTranslation(401); // Banned combination phrase found. whatIsNaughtyCategories = bannedcategory.toCharArray(); return; } if (isItNaughty) { whatIsNaughtyLog = o.language_list.getTranslation(300); // Banned Phrase found: whatIsNaughtyLog += bannedphrase; whatIsNaughty = o.language_list.getTranslation(301); // Banned phrase found. whatIsNaughtyCategories = bannedcategory.toCharArray(); return; } if (weighting > (*o.fg[filtergroup]).naughtyness_limit) { isItNaughty = true; whatIsNaughtyLog = o.language_list.getTranslation(402); // Weighted phrase limit of whatIsNaughtyLog += String((*o.fg[filtergroup]).naughtyness_limit).toCharArray(); whatIsNaughtyLog += " : "; whatIsNaughtyLog += String(weighting).toCharArray(); if (o.show_weighted_found) { whatIsNaughtyLog += " ("; whatIsNaughtyLog += weightedphrase; whatIsNaughtyLog += ")"; } whatIsNaughty = o.language_list.getTranslation(403); // Weighted phrase limit exceeded. // Generate category list, sorted with highest scoring first. bool nonempty = false; bool belowthreshold = false; String categories; std::deque sortable_listcategories; catcurrent = listcategories.begin(); while (catcurrent != listcategories.end()) { sortable_listcategories.push_back(catcurrent->second); catcurrent++; } std::sort(sortable_listcategories.begin(), sortable_listcategories.end()); std::deque::iterator k = sortable_listcategories.begin(); while (k != sortable_listcategories.end()) { // if category display threshold is in use, apply it if (!belowthreshold && (o.fg[filtergroup]->category_threshold > 0) && (k->weight < o.fg[filtergroup]->category_threshold)) { whatIsNaughtyDisplayCategories = categories.toCharArray(); belowthreshold = true; usedisplaycats = true; } if (k->string.length() > 0) { if (nonempty) categories += ", "; // put brackets around the string to indicate cats that are logged but not displayed if (belowthreshold) categories += "("; categories += k->string; if (belowthreshold) categories += ")"; nonempty = true; } k++; // if category threshold is set to show only the top category, // everything after the first loop is below the threshold if (!belowthreshold && o.fg[filtergroup]->category_threshold < 0) { whatIsNaughtyDisplayCategories = categories.toCharArray(); belowthreshold = true; usedisplaycats = true; } } whatIsNaughtyCategories = categories.toCharArray(); return; } // whatIsNaughty is what is displayed in the browser // whatIsNaughtyLog is what is logged in the log file if at all } // * // * // * PICS code // * // * // check the document's PICS rating // when checkPICS is called we assume checkphrase has made the document lower case. // data must also have been NULL terminated. void NaughtyFilter::checkPICS(char *file) { (*o.fg[filtergroup]).pics1.match(file); if (!(*o.fg[filtergroup]).pics1.matched()) { return; } // exit if not found for (int i = 0; i < (*o.fg[filtergroup]).pics1.numberOfMatches(); i++) { checkPICSrating((*o.fg[filtergroup]).pics1.result(i)); // pass on result for further // tests } } // the meat of the process void NaughtyFilter::checkPICSrating(std::string label) { (*o.fg[filtergroup]).pics2.match(label.c_str()); if (!(*o.fg[filtergroup]).pics2.matched()) { return; } // exit if not found String lab(label.c_str()); // convert to a String for easy manip String r; String service; for (int i = 0; i < (*o.fg[filtergroup]).pics2.numberOfMatches(); i++) { r = (*o.fg[filtergroup]).pics2.result(i).c_str(); // ditto r = r.after("("); r = r.before(")"); // remove the brackets // Only check the substring of lab that is between // the start of lab (or the end of the previous match) // and the start of this rating. // It is possible to have multiple ratings in one pics-label. // This is done on e.g. http://www.jesusfilm.org/ if (i == 0) { service = lab.subString(0, (*o.fg[filtergroup]).pics2.offset(i)); } else { service = lab.subString((*o.fg[filtergroup]).pics2.offset(i - 1) + (*o.fg[filtergroup]).pics2.length(i - 1), (*o.fg[filtergroup]).pics2.offset(i)); } if (service.contains("safesurf")) { checkPICSratingSafeSurf(r); if (isItNaughty) { return; } } if (service.contains("evaluweb")) { checkPICSratingevaluWEB(r); if (isItNaughty) { return; } } if (service.contains("microsys")) { checkPICSratingCyberNOT(r); if (isItNaughty) { return; } } if (service.contains("icra")) { checkPICSratingICRA(r); if (isItNaughty) { return; } } if (service.contains("rsac")) { checkPICSratingRSAC(r); if (isItNaughty) { return; } } if (service.contains("weburbia")) { checkPICSratingWeburbia(r); if (isItNaughty) { return; } } if (service.contains("vancouver")) { checkPICSratingVancouver(r); if (isItNaughty) { return; } } if (service.contains("icec")) { checkPICSratingICEC(r); if (isItNaughty) { return; } } if (service.contains("safenet")) { checkPICSratingSafeNet(r); if (isItNaughty) { return; } } // check label for word denoting rating system then pass on to the // appropriate function the rating String. } } void NaughtyFilter::checkPICSagainstoption(String s, const char *l, int opt, std::string m) { if (s.indexOf(l) != -1) { // if the rating contains the label then: int i = 0; // get the rating label value s = s.after(l); if (s.indexOf(" ") != -1) { //remove anything after it s = s.before(" "); } // sanity checking if (s.length() > 0) { i = s.toInteger(); // convert the value in a String to an integer if (opt < i) { // check its value against the option in config file isItNaughty = true; // must be over limit whatIsNaughty = m + " "; whatIsNaughty += o.language_list.getTranslation(1000); // PICS labeling level exceeded on the above site. whatIsNaughtyCategories = "PICS"; whatIsNaughtyLog = whatIsNaughty; } } } } // The next few functions are flippin' obvious so no explanation... void NaughtyFilter::checkPICSratingevaluWEB(String r) { checkPICSagainstoption(r, "rating ", (*o.fg[filtergroup]).pics_evaluweb_rating, "evaluWEB age range"); } void NaughtyFilter::checkPICSratingWeburbia(String r) { checkPICSagainstoption(r, "s ", (*o.fg[filtergroup]).pics_weburbia_rating, "Weburbia rating"); } void NaughtyFilter::checkPICSratingCyberNOT(String r) { checkPICSagainstoption(r, "sex ", (*o.fg[filtergroup]).pics_cybernot_sex, "CyberNOT sex rating"); if (isItNaughty) { return; } checkPICSagainstoption(r, "other ", (*o.fg[filtergroup]).pics_cybernot_sex, "CyberNOT other rating"); } // Korean PICS void NaughtyFilter::checkPICSratingICEC(String r) { checkPICSagainstoption(r, "y ", (*o.fg[filtergroup]).pics_icec_rating, "ICEC rating"); } // Korean PICS void NaughtyFilter::checkPICSratingSafeNet(String r) { checkPICSagainstoption(r, "n ", (*o.fg[filtergroup]).pics_safenet_nudity, "SafeNet nudity"); if (isItNaughty) {return;} checkPICSagainstoption(r, "s ", (*o.fg[filtergroup]).pics_safenet_sex, "SafeNet sex"); if (isItNaughty) {return;} checkPICSagainstoption(r, "v ", (*o.fg[filtergroup]).pics_safenet_violence, "SafeNet violence"); if (isItNaughty) {return;} checkPICSagainstoption(r, "l ", (*o.fg[filtergroup]).pics_safenet_language, "SafeNet language"); if (isItNaughty) {return;} checkPICSagainstoption(r, "i ", (*o.fg[filtergroup]).pics_safenet_gambling, "SafeNet gambling"); if (isItNaughty) {return;} checkPICSagainstoption(r, "h ", (*o.fg[filtergroup]).pics_safenet_alcoholtobacco, "SafeNet alcohol tobacco"); } void NaughtyFilter::checkPICSratingRSAC(String r) { checkPICSagainstoption(r, "v ", (*o.fg[filtergroup]).pics_rsac_violence, "RSAC violence"); if (isItNaughty) { return; } checkPICSagainstoption(r, "s ", (*o.fg[filtergroup]).pics_rsac_sex, "RSAC sex"); if (isItNaughty) { return; } checkPICSagainstoption(r, "n ", (*o.fg[filtergroup]).pics_rsac_nudity, "RSAC nudity"); if (isItNaughty) { return; } checkPICSagainstoption(r, "l ", (*o.fg[filtergroup]).pics_rsac_language, "RSAC language"); } void NaughtyFilter::checkPICSratingVancouver(String r) { checkPICSagainstoption(r, "MC ", (*o.fg[filtergroup]).pics_vancouver_multiculturalism, "Vancouvermulticulturalism"); checkPICSagainstoption(r, "Edu ", (*o.fg[filtergroup]).pics_vancouver_educationalcontent, "Vancouvereducationalcontent"); checkPICSagainstoption(r, "Env ", (*o.fg[filtergroup]).pics_vancouver_environmentalawareness, "Vancouverenvironmentalawareness"); checkPICSagainstoption(r, "Tol ", (*o.fg[filtergroup]).pics_vancouver_tolerance, "Vancouvertolerance"); checkPICSagainstoption(r, "V ", (*o.fg[filtergroup]).pics_vancouver_violence, "Vancouverviolence"); checkPICSagainstoption(r, "S ", (*o.fg[filtergroup]).pics_vancouver_sex, "Vancouversex"); checkPICSagainstoption(r, "P ", (*o.fg[filtergroup]).pics_vancouver_profanity, "Vancouverprofanity"); checkPICSagainstoption(r, "SF ", (*o.fg[filtergroup]).pics_vancouver_safety, "Vancouversafety"); checkPICSagainstoption(r, "Can ", (*o.fg[filtergroup]).pics_vancouver_canadiancontent, "Vancouvercanadiancontent"); checkPICSagainstoption(r, "Com ", (*o.fg[filtergroup]).pics_vancouver_commercialcontent, "Vancouvercommercialcontent"); checkPICSagainstoption(r, "Gam ", (*o.fg[filtergroup]).pics_vancouver_gambling, "Vancouvergambling"); } void NaughtyFilter::checkPICSratingSafeSurf(String r) { checkPICSagainstoption(r, "000 ", (*o.fg[filtergroup]).pics_safesurf_agerange, "Safesurf age range"); if (isItNaughty) { return; } checkPICSagainstoption(r, "001 ", (*o.fg[filtergroup]).pics_safesurf_profanity, "Safesurf profanity"); if (isItNaughty) { return; } checkPICSagainstoption(r, "002 ", (*o.fg[filtergroup]).pics_safesurf_heterosexualthemes, "Safesurf heterosexualthemes"); if (isItNaughty) { return; } checkPICSagainstoption(r, "003 ", (*o.fg[filtergroup]).pics_safesurf_homosexualthemes, "Safesurf "); if (isItNaughty) { return; } checkPICSagainstoption(r, "004 ", (*o.fg[filtergroup]).pics_safesurf_nudity, "Safesurf nudity"); if (isItNaughty) { return; } checkPICSagainstoption(r, "005 ", (*o.fg[filtergroup]).pics_safesurf_violence, "Safesurf violence"); if (isItNaughty) { return; } checkPICSagainstoption(r, "006 ", (*o.fg[filtergroup]).pics_safesurf_sexviolenceandprofanity, "Safesurf sexviolenceandprofanity"); if (isItNaughty) { return; } checkPICSagainstoption(r, "007 ", (*o.fg[filtergroup]).pics_safesurf_intolerance, "Safesurf intolerance"); if (isItNaughty) { return; } checkPICSagainstoption(r, "008 ", (*o.fg[filtergroup]).pics_safesurf_druguse, "Safesurf druguse"); if (isItNaughty) { return; } checkPICSagainstoption(r, "009 ", (*o.fg[filtergroup]).pics_safesurf_otheradultthemes, "Safesurf otheradultthemes"); if (isItNaughty) { return; } checkPICSagainstoption(r, "00A ", (*o.fg[filtergroup]).pics_safesurf_gambling, "Safesurf gambling"); if (isItNaughty) { return; } } void NaughtyFilter::checkPICSratingICRA(String r) { checkPICSagainstoption(r, "la ", (*o.fg[filtergroup]).pics_icra_languagesexual, "ICRA languagesexual"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ca ", (*o.fg[filtergroup]).pics_icra_chat, "ICRA chat"); if (isItNaughty) { return; } checkPICSagainstoption(r, "cb ", (*o.fg[filtergroup]).pics_icra_moderatedchat, "ICRA moderatedchat"); if (isItNaughty) { return; } checkPICSagainstoption(r, "lb ", (*o.fg[filtergroup]).pics_icra_languageprofanity, "ICRA languageprofanity"); if (isItNaughty) { return; } checkPICSagainstoption(r, "lc ", (*o.fg[filtergroup]).pics_icra_languagemildexpletives, "ICRA languagemildexpletives"); if (isItNaughty) { return; } checkPICSagainstoption(r, "na ", (*o.fg[filtergroup]).pics_icra_nuditygraphic, "ICRA nuditygraphic"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nb ", (*o.fg[filtergroup]).pics_icra_nuditymalegraphic, "ICRA nuditymalegraphic"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nc ", (*o.fg[filtergroup]).pics_icra_nudityfemalegraphic, "ICRA nudityfemalegraphic"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nd ", (*o.fg[filtergroup]).pics_icra_nuditytopless, "ICRA nuditytopless"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ne ", (*o.fg[filtergroup]).pics_icra_nuditybottoms, "ICRA nuditybottoms"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nf ", (*o.fg[filtergroup]).pics_icra_nuditysexualacts, "ICRA nuditysexualacts"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ng ", (*o.fg[filtergroup]).pics_icra_nudityobscuredsexualacts, "ICRA nudityobscuredsexualacts"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nh ", (*o.fg[filtergroup]).pics_icra_nuditysexualtouching, "ICRA nuditysexualtouching"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ni ", (*o.fg[filtergroup]).pics_icra_nuditykissing, "ICRA nuditykissing"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nr ", (*o.fg[filtergroup]).pics_icra_nudityartistic, "ICRA nudityartistic"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ns ", (*o.fg[filtergroup]).pics_icra_nudityeducational, "ICRA nudityeducational"); if (isItNaughty) { return; } checkPICSagainstoption(r, "nt ", (*o.fg[filtergroup]).pics_icra_nuditymedical, "ICRA nuditymedical"); if (isItNaughty) { return; } checkPICSagainstoption(r, "oa ", (*o.fg[filtergroup]).pics_icra_drugstobacco, "ICRA drugstobacco"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ob ", (*o.fg[filtergroup]).pics_icra_drugsalcohol, "ICRA drugsalcohol"); if (isItNaughty) { return; } checkPICSagainstoption(r, "oc ", (*o.fg[filtergroup]).pics_icra_drugsuse, "ICRA drugsuse"); if (isItNaughty) { return; } checkPICSagainstoption(r, "od ", (*o.fg[filtergroup]).pics_icra_gambling, "ICRA gambling"); if (isItNaughty) { return; } checkPICSagainstoption(r, "oe ", (*o.fg[filtergroup]).pics_icra_weaponuse, "ICRA weaponuse"); if (isItNaughty) { return; } checkPICSagainstoption(r, "of ", (*o.fg[filtergroup]).pics_icra_intolerance, "ICRA intolerance"); if (isItNaughty) { return; } checkPICSagainstoption(r, "og ", (*o.fg[filtergroup]).pics_icra_badexample, "ICRA badexample"); if (isItNaughty) { return; } checkPICSagainstoption(r, "oh ", (*o.fg[filtergroup]).pics_icra_pgmaterial, "ICRA pgmaterial"); if (isItNaughty) { return; } checkPICSagainstoption(r, "va ", (*o.fg[filtergroup]).pics_icra_violencerape, "ICRA violencerape"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vb ", (*o.fg[filtergroup]).pics_icra_violencetohumans, "ICRA violencetohumans"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vc ", (*o.fg[filtergroup]).pics_icra_violencetoanimals, "ICRA violencetoanimals"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vd ", (*o.fg[filtergroup]).pics_icra_violencetofantasy, "ICRA violencetofantasy"); if (isItNaughty) { return; } checkPICSagainstoption(r, "ve ", (*o.fg[filtergroup]).pics_icra_violencekillinghumans, "ICRA violencekillinghumans"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vf ", (*o.fg[filtergroup]).pics_icra_violencekillinganimals, "ICRA violencekillinganimals"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vg ", (*o.fg[filtergroup]).pics_icra_violencekillingfantasy, "ICRA violencekillingfantasy"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vh ", (*o.fg[filtergroup]).pics_icra_violenceinjuryhumans, "ICRA violenceinjuryhumans"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vi ", (*o.fg[filtergroup]).pics_icra_violenceinjuryanimals, "ICRA violenceinjuryanimals"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vj ", (*o.fg[filtergroup]).pics_icra_violenceinjuryfantasy, "ICRA violenceinjuryfantasy"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vr ", (*o.fg[filtergroup]).pics_icra_violenceartisitic, "ICRA violenceartisitic"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vs ", (*o.fg[filtergroup]).pics_icra_violenceeducational, "ICRA violenceeducational"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vt ", (*o.fg[filtergroup]).pics_icra_violencemedical, "ICRA violencemedical"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vu ", (*o.fg[filtergroup]).pics_icra_violencesports, "ICRA violencesports"); if (isItNaughty) { return; } checkPICSagainstoption(r, "vk ", (*o.fg[filtergroup]).pics_icra_violenceobjects, "ICRA violenceobjects"); } dansguardian-2.10.1.1/src/SocketArray.cpp0000644001165000116500000000541511110523210015024 00000000000000// SocketArray - wrapper for clean handling of an array of Sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "SocketArray.hpp" #include #include // GLOBALS extern bool is_daemonised; // IMPLEMENTATION SocketArray::~SocketArray() { delete[] drawer; } void SocketArray::deleteAll() { delete[] drawer; drawer = NULL; socknum = 0; } // close all sockets & create new ones void SocketArray::reset(int sockcount) { delete[] drawer; drawer = new Socket[sockcount]; socknum = sockcount; } // bind our first socket to any IP int SocketArray::bindSingle(int port) { if (socknum < 1) { return -1; } return drawer[0].bind(port); } // return an array of our socket FDs int* SocketArray::getFDAll() { int *fds = new int[socknum]; for (unsigned int i = 0; i < socknum; i++) { #ifdef DGDEBUG std::cerr << "Socket " << i << " fd:" << drawer[i].getFD() << std::endl; #endif fds[i] = drawer[i].getFD(); } return fds; } // listen on all IPs with given kernel queue size int SocketArray::listenAll(int queue) { for (unsigned int i = 0; i < socknum; i++) { if (drawer[i].listen(queue)) { if (!is_daemonised) { std::cerr << "Error listening to socket" << std::endl; } syslog(LOG_ERR, "%s","Error listening to socket"); return -1; } } return 0; } // bind all sockets to given IP list int SocketArray::bindAll(std::deque &ips, int port) { if (ips.size() > socknum) { return -1; } for (unsigned int i = 0; i < socknum; i++) { #ifdef DGDEBUG std::cerr << "Binding server socket[" << port << " " << ips[i] << " " << i << "])" << std::endl; #endif if (drawer[i].bind(ips[i].toCharArray(), port)) { if (!is_daemonised) { std::cerr << "Error binding server socket: [" << port << " " << ips[i] << " " << i << "] (" << strerror(errno) << ")" << std::endl; } syslog(LOG_ERR, "Error binding socket: [%d %s %d] (%s)", port, ips[i].toCharArray(), i, strerror(errno)); return -1; } } return 0; } dansguardian-2.10.1.1/src/LanguageContainer.cpp0000644001165000116500000000530711110523210016163 00000000000000//Please refer to http://dansguardian.org/?page=copyright //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "LanguageContainer.hpp" #include "RegExp.hpp" #include "String.hpp" #include #include #include #include #include #include #include #include #include // GLOBALS extern bool is_daemonised; // IMPLEMENTATION // wipe loaded language file void LanguageContainer::reset() { keys.clear(); values.clear(); } // look for the translated string corresponding to the given key const char *LanguageContainer::getTranslation(const unsigned int index) { int i; int s = keys.size(); for (i = 0; i < s; i++) { if (keys[i] == index) { return values[i].toCharArray(); } } return "MISSING TRANSLATION KEY"; } // open a language file, containing message names (keys) and translated messages (values) bool LanguageContainer::readLanguageList(const char *filename) { std::string linebuffer; // a string line buffer ;) String v; String line; unsigned int k; std::ifstream languagefile(filename, std::ios::in); // open the file for reading if (!languagefile.good()) { if (!is_daemonised) { std::cerr << "Error opening messages file (does it exist?): " << filename << std::endl; } syslog(LOG_ERR, "%s", "Error opening messages file (does it exist?): "); syslog(LOG_ERR, "%s", filename); return false; } while (!languagefile.eof()) { // keep going until end of file getline(languagefile, linebuffer); // grab a line if (linebuffer.length() == 0) { continue; } line = linebuffer.c_str(); k = line.after("\"").before("\",\"").toInteger(); v = line.after("\",\"").before("\""); if (k > 0 && v.length() > 0) { keys.push_back(k); values.push_back(v); } } languagefile.close(); return true; // successful read } dansguardian-2.10.1.1/src/ListContainer.cpp0000644001165000116500000015137611173344376015412 00000000000000// ListContainer - class for both item and phrase lists //Please refer to http://dansguardian.org/?page=copyright //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include #include #include "ListContainer.hpp" #include "OptionContainer.hpp" #include "RegExp.hpp" #include #include #include #include #include #include #include #include #include // GLOBALS extern bool is_daemonised; extern OptionContainer o; // DEFINES #define ROOTNODESIZE 260 #define MAXROOTLINKS ROOTNODESIZE-4 #define GRAPHENTRYSIZE 64 #define MAXLINKS GRAPHENTRYSIZE-4 #define ROOTOFFSET ROOTNODESIZE - GRAPHENTRYSIZE // IMPLEMENTATION // Constructor - set default values ListContainer::ListContainer():refcount(0), parent(false), filedate(0), used(false), bannedpfiledate(0), exceptionpfiledate(0), weightedpfiledate(0), blanketblock(false), blanket_ip_block(false), blanketsslblock(false), blanketssl_ip_block(false), sourceisexception(false), sourcestartswith(false), sourcefilters(0), data(NULL), realgraphdata(NULL), maxchildnodes(0), graphitems(0), data_length(0), data_memory(0), items(0), isSW(false), issorted(false), graphused(false), force_quick_search(false), /*sthour(0), stmin(0), endhour(0), endmin(0),*/ istimelimited(false) { } // delete the memory block when the class is destryed ListContainer::~ListContainer() { reset(); } // for both types of list - clear & reset all values void ListContainer::reset() { free(data); if (graphused) free(realgraphdata); // dereference this and included lists // - but not if the reason we're being // deleted is due to deletion (this will // only happen due to list garbage // collection, at which point the list // ref should already be zero) if (refcount > 0) { --refcount; #if DGDEBUG std::cout << "de-reffing " << sourcefile << " due to manual list reset, refcount: " << refcount << std::endl; #endif for (size_t i = 0; i < morelists.size(); ++i) o.lm.deRefList(morelists[i]); } data = NULL; realgraphdata = NULL; maxchildnodes = 0; graphitems = 0; data_length = 0; data_memory = 0; items = 0; isSW = false; issorted = false; graphused = false; force_quick_search = 0; /*sthour = 0; stmin = 0; endhour = 0; endmin = 0; days = ""; timetag = "";*/ category = ""; istimelimited = false; combilist.clear(); slowgraph.clear(); list.clear(); lengthlist.clear(); weight.clear(); itemtype.clear(); timelimitindex.clear(); morelists.clear(); timelimits.clear(); listcategory.clear(); categoryindex.clear(); used = false; parent = false; bannedpfile = ""; exceptionpfile = ""; weightedpfile = ""; bannedpfiledate = 0; exceptionpfiledate = 0; weightedpfiledate = 0; } // for item lists - during a config reload, can we simply retain the already loaded list? bool ListContainer::previousUseItem(const char *filename, bool startswith, int filters) { String f(filename); if (f == sourcefile && startswith == sourcestartswith && filters == sourcefilters) { return true; } return false; } // for phrase lists - read in the given file, which may be an exception list // inherit category and time limits from parent bool ListContainer::readPhraseList(const char *filename, bool isexception, int catindex, int timeindex, bool incref) { // only increment refcount on first read, not read of included files // (includes get amalgamated, unlike item lists) if (incref) ++refcount; sourcefile = filename; sourceisexception = isexception; std::string linebuffer; // a string line buffer ;) String temp; // a String for temporary manipulation String line; String lcat; size_t len = 0; try { len = getFileLength(filename); } catch (std::runtime_error &e) { if (!is_daemonised) { std::cerr << "Error reading file (does it exist?) " << filename << ": " << e.what() << std::endl; } syslog(LOG_ERR, "Error reading file (does it exist?) %s: %s", filename, e.what()); return false; } if (len < 2) { return true; // its blank - perhaps due to webmin editing // just return } filedate = getFileDate(filename); increaseMemoryBy(len + 2); // Allocate some memory to hold file std::ifstream listfile(filename, std::ios::in); // open the file for reading if (!listfile.good()) { if (!is_daemonised) { std::cerr << "Error opening file (does it exist?): " << filename << std::endl; } syslog(LOG_ERR, "Error opening file (does it exist?): %s", filename); return false; } lcat = ""; bool caseinsensitive = true; while (!listfile.eof()) { // keep going until end of file getline(listfile, linebuffer); // grab a line if (linebuffer.length() != 0) { // sanity checking line = linebuffer.c_str(); line.removeWhiteSpace(); // convert to lowercase - unless this is, for example, // a phraselist in an odd character encoding which has // been marked as not to be converted if (caseinsensitive) line.toLower(); if (line.startsWith("<")) readPhraseListHelper(line, isexception, catindex, timeindex); // handle included list files else if (line.startsWith(".")) { temp = line.after(".include<").before(">"); if (temp.length() > 0) { if (!readPhraseList(temp.toCharArray(), isexception, catindex, timeindex, false)) { listfile.close(); return false; } } } // phrase lists can be categorised (but not time limited) else if (line.startsWith("#listcategory:")) { //use the original line so as to preserve case in category names temp = linebuffer.c_str(); lcat = temp.after("\"").before("\""); // this serves two purposes: returning the index of the category string // if it is already in our category list, and adding it to the list (also // returning index) if it is not. catindex = getCategoryIndex(&lcat); #ifdef DGDEBUG std::cout << "List category: " << lcat << std::endl; std::cout << "Category list index: " << catindex << std::endl; #endif } // phrase lists can also be marked as not to be case-converted, // to aid support for exotic character encodings else if (line.startsWith("#noconvert")) { #ifdef DGDEBUG std::cout << "List flagged as not to be case-converted" << std::endl; #endif caseinsensitive = false; } // Read in time tags; set timeindex to the ID of the new tag else if (line.startsWith("#time: ")) { // see if we have a time tag TimeLimit tl; if (!readTimeTag(&line, tl)) { return false; } timelimits.push_back(tl); timeindex = timelimits.size() - 1; #ifdef DGDEBUG std::cout << "Found time limit on phrase list. Now have " << timelimits.size() << " limits on this list (including parents)." << std::endl; #endif continue; } } } listfile.close(); return true; // sucessful read } // for phrase lists - helper function for readPhraseList void ListContainer::readPhraseListHelper(String line, bool isexception, int catindex, int timeindex) { // read in weighting value, if there int weighting = line.after("><").before(">").toInteger(); // defaults to 0 int type; if (weighting != 0) { // this is a weighted phrase type = 1; line = line.before("><") + ">"; } else { if (isexception) { // this is an exception phrase type = -1; } else { type = 0; } } if (line.after(">,").length() > 2) { // push type & weighting for all phrases on this line onto the combi list while (line.length() > 2) { line = line.after("<"); // combination banned, weighted, or exception readPhraseListHelper2(line.before(">"), type + 11, weighting, catindex, timeindex); line = line.after(">,"); } // end of combi marker readPhraseListHelper2("", type + 21, weighting, catindex, timeindex); } else { line = line.after("<").before(">"); // push type & weighting for this individual phrase onto combi list (not combination phrase) readPhraseListHelper2(line, type, weighting, catindex, timeindex); } } // for phrase lists - push phrase, type, weighting & category onto combi list void ListContainer::readPhraseListHelper2(String phrase, int type, int weighting, int catindex, int timeindex) { // -1=exception // 0=banned // 1=weighted // 10 = combination exception // 11 = combination banned // 12 = combination weighted // 20,21,22 = end of combi marker if (type > 19) { combilist.push_back(-2); // mark an end of a combi combilist.push_back(type - 21); // store the combi type combilist.push_back(timeindex); // store the combi timtime limitt combilist.push_back(weighting); // store the combi weight combilist.push_back(catindex); // store the combi category return; } if (phrase.length() > 127) { if (!is_daemonised) { std::cerr << "Phrase length too long, truncating: " << phrase << std::endl; } syslog(LOG_ERR, "Phrase length too long, truncating: %s", phrase.toCharArray()); phrase = phrase.subString(0, 127); } if (phrase.length() < 1) { // its too small to use return; } if (type < 10) { if (!addToItemListPhrase(phrase.toCharArray(), phrase.length(), type, weighting, false, catindex, timeindex)) { if (!is_daemonised) { std::cerr << "Duplicate phrase, dropping: " << phrase << std::endl; } syslog(LOG_ERR, "Duplicate phrase, dropping: %s", phrase.toCharArray()); } return; } // must be a combi or end marker if got here // must be a combi if got here addToItemListPhrase(phrase.toCharArray(), phrase.length(), type, weighting, true, catindex, timeindex); } // for item lists - add phrases to list proper bool ListContainer::addToItemListPhrase(const char *s, size_t len, int type, int weighting, bool combi, int catindex, int timeindex) { list.push_back(data_length); lengthlist.push_back(len); for (size_t i = 0; i < len; i++) { data[data_length + i] = s[i]; } data[data_length + len] = 0; data_length += len + 1; if (combi) { // if this is a combination item, store the ID of the current item on the combi list combilist.push_back(items); } items++; weight.push_back(weighting); itemtype.push_back(type); categoryindex.push_back(catindex); timelimitindex.push_back(timeindex); return true; } // for item lists - read item list from file. checkme - what is startswith? is it used? what is filters? bool ListContainer::readItemList(const char *filename, bool startswith, int filters) { ++refcount; #ifdef DGDEBUG if (filters != 32) std::cout << "Converting to lowercase" << std::endl; #endif sourcefile = filename; sourcestartswith = startswith; sourcefilters = filters; std::string linebuffer; RegExp re; re.comp("^.*\\:[0-9]+\\/.*"); #ifdef DGDEBUG std::cout << filename << std::endl; #endif if (isCacheFileNewer(filename)) { // see if cached .process file linebuffer = filename; // is available and up to date linebuffer += ".processed"; if (getFileLength(linebuffer.c_str()) >= 4000) { // don't bother with small files if (!readProcessedItemList(linebuffer.c_str(), startswith, filters)) { // read cached return false; } filedate = getFileDate(linebuffer.c_str()); issorted = true; // don't bother sorting cached file return true; } } filedate = getFileDate(filename); size_t len = 0; try { len = getFileLength(filename); } catch (std::runtime_error &e) { if (!is_daemonised) { std::cerr << "Error reading file " << filename << ": " << e.what() << std::endl; } syslog(LOG_ERR, "Error reading file %s: %s", filename, e.what()); return false; } if (len < 2) { return true; // its blank - perhaps due to webmin editing // just return } increaseMemoryBy(len + 2); // Allocate some memory to hold file // The plus one is to cope with files not ending in a new line std::ifstream listfile(filename, std::ios::in); if (!listfile.good()) { if (!is_daemonised) { std::cerr << "Error opening: " << filename << std::endl; } syslog(LOG_ERR, "Error opening file: %s", filename); return false; } String temp, inc, hostname, url; while (!listfile.eof()) { getline(listfile, linebuffer); if (linebuffer.length() < 2) continue; // its jibberish temp = linebuffer.c_str(); //item lists (URLs, domains) can be both categorised and time-limited if (linebuffer[0] == '#') { if (temp.startsWith("#time: ")) { // see if we have a time tag if (!readTimeTag(&temp, listtimelimit)) { return false; } continue; } else if (temp.startsWith("#listcategory:")) { category = temp.after("\"").before("\""); #ifdef DGDEBUG std::cout << "found item list category: " << category << std::endl; #endif continue; } continue; // it's a comment } // blanket block flags if (linebuffer == "**") { blanketblock = true; continue; } else if (linebuffer == "*ip") { blanket_ip_block = true; continue; } else if (linebuffer == "**s") { blanketsslblock = true; continue; } else if (linebuffer == "*ips") { blanketssl_ip_block = true; continue; } // Strip off comments that don't necessarily start at the beginning of a line // - but not regular expression comments std::string::size_type commentstart = 1; while ((commentstart = temp.find_first_of('#', commentstart)) != std::string::npos) { // Don't treat "(?#...)" as a DG comment - it's a regex comment if (temp[commentstart - 1] != '?') { temp = temp.substr(0, commentstart); break; } ++commentstart; } temp.removeWhiteSpace(); // tidy up and make it handle CRLF files if (temp.startsWith(".Include<")) { // see if we have another list inc = temp.after(".Include<"); // to include inc = inc.before(">"); if (!readAnotherItemList(inc.toCharArray(), startswith, filters)) { // read it listfile.close(); return false; } continue; } if (temp.endsWith("/")) { temp.chop(); // tidy up } if (temp.startsWith("ftp://")) { temp = temp.after("ftp://"); // tidy up } if (filters == 1) { // remove port addresses if (temp.before("/").contains(":")) { // quicker than full regexp if (re.match(temp.toCharArray())) { hostname = temp.before(":"); url = temp.after("/"); temp = hostname + "/" + url; } } } if (filters != 32) { temp.toLower(); // tidy up - but don't make regex lists lowercase! } if (temp.length() > 0) addToItemList(temp.toCharArray(), temp.length()); // add to unsorted list } listfile.close(); return true; // sucessful read } // for item lists - read nested item lists bool ListContainer::readAnotherItemList(const char *filename, bool startswith, int filters) { int result = o.lm.newItemList(filename, startswith, filters, false); if (result < 0) { if (!is_daemonised) { std::cerr << "Error opening file: " << filename << std::endl; } syslog(LOG_ERR, "Error opening file: %s", filename); return false; } morelists.push_back((unsigned) result); return true; } // for item lists - is this item in the list? bool ListContainer::inList(const char *string) { if (findInList(string) != NULL) { return true; } return false; } // for item lists - is an item in the list that ends with this string? bool ListContainer::inListEndsWith(const char *string) { if (isNow()) { if (items > 0) { if (search(&ListContainer::greaterThanEW,0, items - 1, string) >= 0) { lastcategory = category; return true; } } bool rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).inListEndsWith(string); if (rc) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return true; } } } return false; } // for item lists - is an item in the list that starts with this string? bool ListContainer::inListStartsWith(const char *string) { if (isNow()) { if (items > 0) { if (search(&ListContainer::greaterThanSW,0, items - 1, string) >= 0) { lastcategory = category; return true; } } bool rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).inListStartsWith(string); if (rc) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return true; } } } return false; } // find pointer to the part of the data array containing this string char *ListContainer::findInList(const char *string) { if (isNow()) { if (items > 0) { int r; if (isSW) { r = search(&ListContainer::greaterThanSWF,0, items - 1, string); } else { r = search(&ListContainer::greaterThanEWF,0, items - 1, string); } if (r >= 0) { lastcategory = category; return (data + list[r]); } } char *rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).findInList(string); if (rc != NULL) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return rc; } } } return NULL; } // find an item in the list which starts with this char *ListContainer::findStartsWith(const char *string) { if (isNow()) { if (items > 0) { int r = search(&ListContainer::greaterThanSW,0, items - 1, string); if (r >= 0) { lastcategory = category; return (data + list[r]); } } char *rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).findStartsWith(string); if (rc != NULL) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return rc; } } } return NULL; } char *ListContainer::findStartsWithPartial(const char *string) { if (isNow()) { if (items > 0) { int r = search(&ListContainer::greaterThanSW,0, items - 1, string); if (r >= 0) { lastcategory = category; return (data + list[r]); } if (r < -1) { r = 0 - r - 2; lastcategory = category; return (data + list[r]); // nearest match } } char *rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).findStartsWithPartial(string); if (rc != NULL) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return rc; } } } return NULL; } char *ListContainer::findEndsWith(const char *string) { if (isNow()) { if (items > 0) { int r = search(&ListContainer::greaterThanEW,0, items - 1, string); if (r >= 0) { lastcategory = category; return (data + list[r]); } } char *rc; for (unsigned int i = 0; i < morelists.size(); i++) { rc = (*o.lm.l[morelists[i]]).findEndsWith(string); if (rc != NULL) { lastcategory = (*o.lm.l[morelists[i]]).lastcategory; return rc; } } } return NULL; } // For phrase lists - grab the text, score and type of a given phrase, based on item number within list std::string ListContainer::getItemAtInt(int index) { std::string s(data + list[index], lengthlist[index]); return s; } int ListContainer::getWeightAt(unsigned int index) { return weight[index]; } int ListContainer::getTypeAt(unsigned int index) { return itemtype[index]; } // Phrase lists - check whether the current time is within the limit imposed upon the given phrase bool ListContainer::checkTimeAt(unsigned int index) { if (timelimitindex[index] == -1) { return true; } return isNow(timelimitindex[index]); } bool ListContainer::checkTimeAtD(int index) { if (index == -1) { return true; } return isNow(index); } struct lessThanEWF: public std::binary_function { bool operator()(const size_t& aoff, const size_t& boff) { const char* a = data + aoff; const char* b = data + boff; size_t alen = strlen(a); size_t blen = strlen(b); size_t apos = alen - 1; size_t bpos = blen - 1; for (size_t maxlen = ((alen < blen) ? alen : blen); maxlen > 0; apos--, bpos--, maxlen--) if (a[apos] > b[bpos]) return true; else if (a[apos] < b[bpos]) return false; if (alen > blen) return true; else //if (alen < blen) return false; //return true; // both equal }; char *data; }; struct lessThanSWF: public std::binary_function { bool operator()(const size_t& aoff, const size_t& boff) { const char* a = data + aoff; const char* b = data + boff; size_t alen = strlen(a); size_t blen = strlen(b); size_t maxlen = (alen < blen) ? alen : blen; for (size_t i = 0; i < maxlen; i++) if (a[i] > b[i]) return true; else if (a[i] < b[i]) return false; if (alen > blen) return true; else //if (alen < blen) return false; //return true; // both equal }; char *data; }; void ListContainer::doSort(const bool startsWith) { // sort by ending of line for (size_t i = 0; i < morelists.size(); i++) (*o.lm.l[morelists[i]]).doSort(startsWith); if (items < 2 || issorted) return; if (startsWith) { lessThanSWF lts; lts.data = data; std::sort(list.begin(), list.end(), lts); } else { lessThanEWF lte; lte.data = data; std::sort(list.begin(), list.end(), lte); } isSW = startsWith; issorted = true; return; } bool ListContainer::createCacheFile() { unsigned int i; for (i = 0; i < morelists.size(); i++) { (*o.lm.l[morelists[i]]).createCacheFile(); } if (isCacheFileNewer(sourcefile.toCharArray())) { // only do if it needs updating return true; } if (items < 1000) { // There is little to gain when there are so few return true; } String f(sourcefile); f += ".processed"; #ifdef DGDEBUG std::cout << "creating processed file:" << f << std::endl; #endif std::ofstream listfile(f.toCharArray(), std::ios::out); if (listfile.fail()) { if (!is_daemonised) { std::cerr << "Error creating cache file. Do you have write access to this area: \"" << f << "\"?" << std::endl; } syslog(LOG_ERR, "Error creating cache file. Do you have write access to this area: \"%s\"?", f.toCharArray()); return false; } for (i = 0; i < morelists.size(); i++) { f = ".Include<"; f += (*o.lm.l[morelists[i]]).sourcefile; f += ">\n"; listfile.write(f.toCharArray(), f.length()); } if (listtimelimit.timetag.length() > 10) { // no point in writing corrupt short one f = listtimelimit.timetag; f += "\n"; listfile.write(f.toCharArray(), f.length()); } if (category.length() > 2) { // no point in writing corrupt short one // lengthened from 4 to allow "ADs" category to be preserved in processed files f = "#listcategory:\""; f += category; f += "\"\n"; listfile.write(f.toCharArray(), f.length()); } char *offset; for (i = 0; i < (unsigned) items; i++) { // write the entries in order offset = data + list[i]; listfile.write(offset, strlen(offset)); listfile.put('\n'); // newline per entry } listfile.close(); return true; } bool ListContainer::makeGraph(bool fqs) { force_quick_search = fqs; if (data_length == 0) return true; long int i; // Quick search has been forced on - put all items on the "slow" list and be done with it if (force_quick_search) { for (i = 0; i < items; i++) { // Check to see if the item is a duplicate std::string thisphrase = getItemAtInt(i); bool found = false; unsigned int foundindex = 0; for (std::vector::iterator j = slowgraph.begin(); j != slowgraph.end(); j++) { if (getItemAtInt(*j) == thisphrase) { found = true; foundindex = *j; break; } } if (!found) { // Not a duplicate - store it slowgraph.push_back(i); } else { // Duplicate - resolve the collision // // Existing entry must be a combi AND // new entry is not a combi so we overwrite the // existing values as combi values and types are // stored in the combilist // OR // both are weighted phrases and the new phrase is higher weighted // OR // the existing phrase is weighted and the new phrase is banned // OR // new phrase is an exception; exception phrases take precedence if ((itemtype[foundindex] > 9 && itemtype[i] < 10) || (itemtype[foundindex] == 1 && itemtype[i] == 1 && (weight[i] > weight[foundindex])) || (itemtype[foundindex] == 1 && itemtype[i] == 0) || itemtype[i] == -1) { itemtype[foundindex] = itemtype[i]; weight[foundindex] = weight[i]; categoryindex[foundindex] = categoryindex[i]; timelimitindex[foundindex] = timelimitindex[i]; } } } return true; } std::string s; std::string lasts; graphused = true; #ifdef DGDEBUG std::cout << "Bytes needed for phrase tree in worst-case scenario: " << (sizeof(int) * ((GRAPHENTRYSIZE * data_length) + ROOTOFFSET)) << ", starting off with allocation of " << (sizeof(int) * ((GRAPHENTRYSIZE * ((data_length / 3) + 1)) + ROOTOFFSET)) << std::endl; prolificroot = false; secondmaxchildnodes = 0; #endif // Make a conservative guess at how much memory will be needed - call realloc() as necessary to change what is actually taken current_graphdata_size = (GRAPHENTRYSIZE * ((data_length / 3) + 1)) + ROOTOFFSET; realgraphdata = (int*) calloc(current_graphdata_size, sizeof(int)); if (realgraphdata == NULL) { syslog(LOG_ERR, "Cannot allocate memory for phrase tree: %s", strerror(errno)); return false; } graphitems++; std::deque sizelist; for (i = 0; i < items; i++) { sizelist.push_back(i); } graphSizeSort(0, items - 1, &sizelist); for (i = 0; i < items; i++) { graphAdd(String(data + list[sizelist[i]], lengthlist[sizelist[i]]), 0, sizelist[i]); } #ifdef DGDEBUG std::cout << "Bytes actually needed for phrase tree: " << (sizeof(int) * ((GRAPHENTRYSIZE * graphitems) + ROOTOFFSET)) << std::endl; std::cout << "Most prolific node has " << maxchildnodes << " children" << std::endl; std::cout << "It " << (prolificroot ? "is" : "is not") << " the root node" << std::endl; std::cout << "Second most prolific node has " << secondmaxchildnodes << " children" << std::endl; #endif realgraphdata = (int*) realloc(realgraphdata, sizeof(int) * ((GRAPHENTRYSIZE * graphitems) + ROOTOFFSET)); if (realgraphdata == NULL) { syslog(LOG_ERR, "Cannot reallocate memory for phrase tree: %s", strerror(errno)); return false; } int ml = realgraphdata[2]; int branches; for (i = ml - 1; i >= 0; i--) { branches = graphFindBranches(realgraphdata[4 + i]); if (branches < 12) { // quicker to use B-M on node with few branches graphCopyNodePhrases(realgraphdata[4 + i]); // remove link to this node and so effectively remove all nodes // it links to but don't recover the memory as its not worth it for (int j = i; j < ml; j++) { realgraphdata[4 + j] = realgraphdata[4 + j + 1]; } realgraphdata[2]--; } } return true; } void ListContainer::graphSizeSort(int l, int r, std::deque *sizelist) { if (r <= l) return; size_t e; int k; size_t v = getItemAtInt((*sizelist)[r]).length(); int i = l - 1, j = r, p = i, q = r; for (;;) { while (getItemAtInt((*sizelist)[++i]).length() < v); while (v < getItemAtInt((*sizelist)[--j]).length()) { if (j == l) break; } if (i >= j) break; e = (*sizelist)[i]; (*sizelist)[i] = (*sizelist)[j]; (*sizelist)[j] = e; if (v == getItemAtInt((*sizelist)[i]).length()) { p++; e = (*sizelist)[p]; (*sizelist)[p] = (*sizelist)[i]; (*sizelist)[i] = e; } if (v == getItemAtInt((*sizelist)[j]).length()) { q--; e = (*sizelist)[q]; (*sizelist)[q] = (*sizelist)[j]; (*sizelist)[j] = e; } } e = (*sizelist)[i]; (*sizelist)[i] = (*sizelist)[r]; (*sizelist)[r] = e; j = i - 1; i++; for (k = l; k <= p; k++, j--) { e = (*sizelist)[k]; (*sizelist)[k] = (*sizelist)[j]; (*sizelist)[j] = e; } for (k = r - 1; k >= q; k--, i++) { e = (*sizelist)[k]; (*sizelist)[k] = (*sizelist)[i]; (*sizelist)[i] = e; } graphSizeSort(l, j, sizelist); graphSizeSort(i, r, sizelist); } // find the total number of children a node has, along all branches int ListContainer::graphFindBranches(unsigned int pos) { int branches = 0; int * graphdata; if (pos == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; int links = graphdata[pos * GRAPHENTRYSIZE + 2]; for (int i = 0; i < links; i++) { branches += graphFindBranches(graphdata[pos * GRAPHENTRYSIZE + 4 + i]); } if (links > 1) { branches += links - 1; } return branches; } // copy all phrases starting from a given root link into the slowgraph void ListContainer::graphCopyNodePhrases(unsigned int pos) { int * graphdata; if (pos == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; int links = graphdata[pos * GRAPHENTRYSIZE + 2]; int i; for (i = 0; i < links; i++) { graphCopyNodePhrases(graphdata[pos * GRAPHENTRYSIZE + 4 + i]); } bool found = false; unsigned int foundindex = 0; unsigned int phrasenumber = graphdata[pos * GRAPHENTRYSIZE + 3]; std::string thisphrase = getItemAtInt(phrasenumber); for (std::vector::iterator i = slowgraph.begin(); i != slowgraph.end(); i++) { if (getItemAtInt(*i) == thisphrase) { found = true; foundindex = *i; break; } } if (!found) { slowgraph.push_back(phrasenumber); } else { // Duplicate - resolve the collision // // Existing entry must be a combi AND // new entry is not a combi so we overwrite the // existing values as combi values and types are // stored in the combilist // OR // both are weighted phrases and the new phrase is higher weighted // OR // the existing phrase is weighted and the new phrase is banned // OR // new phrase is an exception; exception phrases take precedence if ((itemtype[foundindex] > 9 && itemtype[phrasenumber] < 10) || (itemtype[foundindex] == 1 && itemtype[phrasenumber] == 1 && (weight[phrasenumber] > weight[foundindex])) || (itemtype[foundindex] == 1 && itemtype[phrasenumber] == 0) || itemtype[phrasenumber] == -1) { itemtype[foundindex] = itemtype[phrasenumber]; weight[foundindex] = weight[phrasenumber]; categoryindex[foundindex] = categoryindex[phrasenumber]; timelimitindex[foundindex] = timelimitindex[phrasenumber]; } } } int ListContainer::bmsearch(char *file, off_t fl, const std::string& s) { off_t pl = s.length(); if (fl < pl) return 0; // reality checking if (pl > 126) return 0; // reality checking // must match all off_t j, l; // counters int p; // to hold precalcuated value for speed bool match; // flag int qsBc[256]; // Quick Search Boyer Moore shift table (256 alphabet) char *k; // pointer used in matching int count = 0; char *phrase = new char[pl + 1]; for (j = 0; j < pl; j++) { phrase[j] = s[j]; } phrase[pl] = 0; // For speed we append the phrase to the end of the memory block so it // is always found, thus eliminating some checking. This is possible as // we know an extra 127 bytes have been provided by NaughtyFilter.cpp // and also the OptionContainer does not allow phrase lengths greater // than 126 chars k = file + fl; for (j = 0; j < pl; j++) { k[j] = s[j]; } // Next we need to make the Quick Search Boyer Moore shift table p = pl + 1; for (j = 0; j < 256; j++) { // Preprocessing qsBc[j] = p; } for (j = 0; j < pl; j++) { // Preprocessing qsBc[(unsigned char) phrase[j]] = pl - j; } // Now do the searching! for (j = 0;;) { k = file + j; match = true; for (l = 0; l < pl; l++) { // quiv, but faster, memcmp() if (k[l] != phrase[l]) { match = false; break; } } if (match) { if (j >= fl) { break; // is the end of file marker } count++; } j += qsBc[(unsigned char) file[j + pl]]; // shift } delete[]phrase; return count; } // Format of the data is each entry has GRAPHENTRYSIZE int values with format of: // [letter][last letter flag][num links][from phrase][link0][link1]... void ListContainer::graphSearch(std::map >& result, char *doc, off_t len) { off_t i, j, k; std::map >::iterator existingitem; //do standard quick search on short branches (or everything, if force_quick_search is on) for (std::vector::iterator i = slowgraph.begin(); i != slowgraph.end(); i++) { std::string phrase = getItemAtInt(*i); j = bmsearch(doc, len, phrase); for (k = 0; k < j; k++) { existingitem = result.find(phrase); if (existingitem == result.end()) { result[phrase] = std::pair(*i, 1); } else { existingitem->second.second++; } } } if (force_quick_search || graphitems == 0) { #ifdef DGDEBUG std::cout << "Map (quicksearch) start" << std::endl; for (std::map >::iterator i = result.begin(); i != result.end(); i++) { std::cout << "Map: " << i->first << " " << i->second.second << std::endl; } std::cout << "Map (quicksearch) end" << std::endl; #endif return; } off_t sl; off_t ppos; off_t currnode; int * graphdata = realgraphdata; off_t ml; char p; off_t pos; off_t depth; // number of links from root node to first letter of phrase ml = graphdata[2] + 4; // iterate over entire document for (i = 0; i < len; i++) { // iterate over all children of the root node for (j = 4; j < ml; j++) { // grab the endpoint of this link pos = realgraphdata[j]; sl = 0; // now comes the main graph search! // this is basically a depth-first tree search depth = 0; while (true) { // get the address of the link endpoint and the data actually stored at it // note that this only works for GRAPHENTRYSIZE == 64 ppos = pos << 6; if (ppos == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; p = graphdata[ppos]; // does the character at this string depth match the relevant character in the node we're currently looking at? if (p == doc[i + depth]) { // it does! // is this graph node marked as being the end of a phrase? if (graphdata[ppos + 1] == 1) { // it is, so store the pointer to the matched phrase. std::string phrase = getItemAtInt(graphdata[ppos + 3]); existingitem = result.find(phrase); if (existingitem == result.end()) { result[phrase] = std::pair(graphdata[ppos + 3], 1); } else { existingitem->second.second++; } #ifdef DGDEBUG std::cout << "Found this phrase: " << phrase << std::endl; #endif } // grab this node's number of children sl = graphdata[ppos + 2]; if (sl > 0) { // this is now the node we're interested in looking at the children of currnode = ppos; // zip straight to the first child of the matched node // (this is the magic that makes it depth first) pos = graphdata[ppos + 4]; depth++; continue; } // if we just matched a node that has no children, // we can stop searching. there should be no case in // which the node was not also marked as end of phrase. else break; } if ((--sl) > 0) { // if we get here, we have discounted one child, but // we still have more children to examine from the last matched node. // we don't keep more than one current interesting node - no backtracking // is necessary, as there is only ever one occurrence of a given character as // a branch of a given node. backtracking would therefore never // trigger a match down a different route than has been taken thus far, so // don't bother. pos = graphdata[currnode + 4 + (graphdata[currnode + 2] - sl)]; continue; } // if we get here, we've discounted all branches at this depth, and the search is over. break; } } } #ifdef DGDEBUG std::cout << "Map start" << std::endl; for (std::map >::iterator i = result.begin(); i != result.end(); i++) { std::cout << "Map: " << i->first << " " << i->second.second << std::endl; } std::cout << "Map end" << std::endl; #endif } void ListContainer::graphAdd(String s, const int inx, int item) { unsigned char p = s.charAt(0); unsigned char c; bool found = false; String t; int i, px; int numlinks; int *graphdata; int *graphdata2 = realgraphdata + ROOTOFFSET; if (inx == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; //iterate over the input node's immediate children for (i = 0; i < graphdata[inx * GRAPHENTRYSIZE + 2]; i++) { //grab the character from this child c = (unsigned char) graphdata2[(graphdata[inx * GRAPHENTRYSIZE + 4 + i]) * GRAPHENTRYSIZE]; if (p == c) { //it matches the first char of our string! //keep searching, starting from here, to see if the entire phrase is already in the graph t = s; t.lop(); if (t.length() > 0) { graphAdd(t, graphdata[inx * GRAPHENTRYSIZE + 4 + i], item); return; } found = true; // this means the phrase is already there // as part of an existing phrase //check the end of word flag on the child px = graphdata2[(graphdata[inx * GRAPHENTRYSIZE + 4 + i]) * GRAPHENTRYSIZE + 1]; if (px == 1) { // the exact phrase is already there px = graphdata2[(graphdata[inx * GRAPHENTRYSIZE + 4 + i]) * GRAPHENTRYSIZE + 3]; // -1=exception // 0=banned // 1=weighted // 10 = combination exception // 11 = combination banned // 12 = combination weighted // 20,21,22 = end of combi marker if ((itemtype[px] > 9 && itemtype[item] < 10) || (itemtype[px] == 1 && itemtype[item] == 1 && (weight[item] > weight[px])) || (itemtype[px] == 1 && itemtype[item] == 0) || itemtype[item] == -1) { // exists as a combi entry already // if got here existing entry must be a combi AND // new entry is not a combi so we overwrite the // existing values as combi values and types are // stored in the combilist // OR // both are weighted phrases and the new phrase is higher weighted // OR // the existing phrase is weighted and the new phrase is banned // OR // new phrase is an exception; exception phrases take precedence itemtype[px] = itemtype[item]; weight[px] = weight[item]; categoryindex[px] = categoryindex[item]; timelimitindex[px] = timelimitindex[item]; } } } } // the phrase wasn't already in the list, so add it if (!found) { i = graphitems; graphitems++; // Reallocate memory if we're running out if (current_graphdata_size < ((GRAPHENTRYSIZE * graphitems) + ROOTOFFSET)) { int new_current_graphdata_size = (GRAPHENTRYSIZE * (graphitems + 256)) + ROOTOFFSET; realgraphdata = (int*) realloc(realgraphdata, sizeof(int) * new_current_graphdata_size); if (realgraphdata == NULL) { syslog(LOG_ERR, "Cannot reallocate memory for phrase tree: %s", strerror(errno)); exit(1); } memset(realgraphdata + current_graphdata_size, 0, sizeof(int) * (new_current_graphdata_size - current_graphdata_size)); current_graphdata_size = new_current_graphdata_size; graphdata2 = realgraphdata + ROOTOFFSET; if (inx == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; } numlinks = graphdata[inx * GRAPHENTRYSIZE + 2]; if ((inx == 0) ? ((numlinks + 1) > MAXROOTLINKS) : ((numlinks +1) > MAXLINKS)) { syslog(LOG_ERR, "Cannot load phraselists from this many languages/encodings simultaneously. (more than %d links from this node! [1])", (inx == 0) ? MAXROOTLINKS : MAXLINKS); if (!is_daemonised) std::cout << "Cannot load phraselists from this many languages/encodings simultaneously. (more than " << ((inx == 0) ? MAXROOTLINKS : MAXLINKS) << " links from this node! [1])" << std::endl; exit(1); } if ((numlinks + 1) > maxchildnodes) { maxchildnodes = numlinks + 1; #ifdef DGDEBUG prolificroot = (inx == 0); #endif } #ifdef DGDEBUG else if ((numlinks + 1) > secondmaxchildnodes) secondmaxchildnodes = numlinks + 1; #endif graphdata[inx * GRAPHENTRYSIZE + 2]++; graphdata[inx * GRAPHENTRYSIZE + 4 + numlinks] = i; graphdata2[i * GRAPHENTRYSIZE] = p; graphdata2[i * GRAPHENTRYSIZE + 3] = item; s.lop(); // iterate over remaining characters and add child nodes while (s.length() > 0) { numlinks = graphdata2[i * GRAPHENTRYSIZE + 2]; if ((inx == 0) ? ((numlinks + 1) > MAXROOTLINKS) : ((numlinks +1) > MAXLINKS)) { syslog(LOG_ERR, "Cannot load phraselists from this many languages/encodings simultaneously. (more than %d links from this node! [2])", (inx == 0) ? MAXROOTLINKS : MAXLINKS); if (!is_daemonised) std::cout << "Cannot load phraselists from this many languages/encodings simultaneously. (more than " << ((inx == 0) ? MAXROOTLINKS : MAXLINKS) << " links from this node! [2])" << std::endl; exit(1); } if ((numlinks + 1) > maxchildnodes) { maxchildnodes = numlinks + 1; #ifdef DGDEBUG prolificroot = (inx == 0); #endif } #ifdef DGDEBUG else if ((numlinks + 1) > secondmaxchildnodes) secondmaxchildnodes = numlinks + 1; #endif graphdata2[i * GRAPHENTRYSIZE + 2]++; graphdata2[i * GRAPHENTRYSIZE + 4 + numlinks] = i + 1; i++; graphitems++; // Reallocate memory if we're running out if (current_graphdata_size < ((GRAPHENTRYSIZE * graphitems) + ROOTOFFSET)) { int new_current_graphdata_size = (GRAPHENTRYSIZE * (graphitems + 256)) + ROOTOFFSET; realgraphdata = (int*) realloc(realgraphdata, sizeof(int) * new_current_graphdata_size); if (realgraphdata == NULL) { syslog(LOG_ERR, "Cannot reallocate memory for phrase tree: %s", strerror(errno)); exit(1); } memset(realgraphdata + current_graphdata_size, 0, sizeof(int) * (new_current_graphdata_size - current_graphdata_size)); current_graphdata_size = new_current_graphdata_size; graphdata2 = realgraphdata + ROOTOFFSET; if (inx == 0) graphdata = realgraphdata; else graphdata = realgraphdata + ROOTOFFSET; } p = s.charAt(0); graphdata2[i * GRAPHENTRYSIZE] = p; graphdata2[i * GRAPHENTRYSIZE + 3] = item; s.lop(); } graphdata2[i * GRAPHENTRYSIZE + 1] = 1; } } bool ListContainer::readProcessedItemList(const char *filename, bool startswith, int filters) { #ifdef DGDEBUG std::cout << "reading processed file:" << filename << std::endl; #endif size_t len = 0; size_t slen; try { len = getFileLength(filename); } catch (std::runtime_error &e) { if (!is_daemonised) { std::cerr << "Error reading file " << filename << ": " << e.what() << std::endl; } syslog(LOG_ERR, "Error reading file %s: %s", filename, e.what()); return false; } if (len < 5) { if (!is_daemonised) { std::cerr << "File too small (less than 5 bytes - is it corrupt?): " << filename << std::endl; } syslog(LOG_ERR, "%s", "File too small (less than 5 bytes - is it corrupt?):"); syslog(LOG_ERR, "%s", filename); return false; } increaseMemoryBy(len + 2); std::ifstream listfile(filename, std::ios::in); if (!listfile.good()) { if (!is_daemonised) { std::cerr << "Error opening: " << filename << std::endl; } syslog(LOG_ERR, "Error opening: %s", filename); return false; } std::string linebuffer; String temp, inc; while (!listfile.eof()) { getline(listfile, linebuffer); if (linebuffer[0] == '.') { temp = linebuffer.c_str(); if (temp.startsWith(".Include<")) { // see if we have another list inc = temp.after(".Include<").before(">"); // to include if (!readAnotherItemList(inc.toCharArray(), startswith, filters)) { // read it listfile.close(); return false; } continue; } } else if (linebuffer[0] == '#') { temp = linebuffer.c_str(); if (temp.startsWith("#time: ")) { // see if we have a time tag if (!readTimeTag(&temp, listtimelimit)) { return false; } continue; } else if (temp.startsWith("#listcategory:")) { // see if we have a category category = temp.after("\"").before("\""); #ifdef DGDEBUG std::cout << "found item processed list category: " << category << std::endl; #endif continue; } continue; // it's a comment man } // blanket block flags if (linebuffer == "**") { blanketblock = true; continue; } else if (linebuffer == "*ip") { blanket_ip_block = true; continue; } else if (linebuffer == "**s") { blanketsslblock = true; continue; } else if (linebuffer == "*ips") { blanketssl_ip_block = true; continue; } slen = linebuffer.length(); if (slen < 3) continue; list.push_back(data_length); lengthlist.push_back(slen); for (size_t i = 0; i < slen; i++) { data[data_length + i] = linebuffer[i]; } data[data_length + slen] = 0; data_length += slen + 1; items++; } listfile.close(); return true; } void ListContainer::addToItemList(const char *s, size_t len) { list.push_back(data_length); lengthlist.push_back(len); for (size_t i = 0; i < len; i++) { data[data_length + i] = s[i]; } data[data_length + len] = 0; data_length += len + 1; items++; } int ListContainer::search(int (ListContainer::*comparitor)(const char* a, const char* b), int a, int s, const char *p) { if (a > s) return (-1 - a); int m = (a + s) / 2; int r = (this->*comparitor)(p, data + list[m]); if (r == 0) return m; if (r == -1) return search(comparitor, m + 1, s, p); if (a == s) return (-1 - a); return search(comparitor, a, m - 1, p); } int ListContainer::greaterThanEWF(const char *a, const char *b) { int alen = strlen(a); int blen = strlen(b); int apos = alen - 1; int bpos = blen - 1; for (int maxlen = (alen < blen ? alen : blen); maxlen > 0; apos--, bpos--, maxlen--) if (a[apos] > b[bpos]) return 1; else if (a[apos] < b[bpos]) return -1; if (alen > blen) return 1; else if (alen < blen) return -1; return 0; // both equal } int ListContainer::greaterThanSWF(const char *a, const char *b) { int alen = strlen(a); int blen = strlen(b); int maxlen = alen < blen ? alen : blen; for (int i = 0; i < maxlen; i++) if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1; if (alen > blen) return 1; else if (alen < blen) return -1; return 0; // both equal } int ListContainer::greaterThanSW(const char *a, const char *b) { int alen = strlen(a); int blen = strlen(b); int maxlen = alen < blen ? alen : blen; for (int i = 0; i < maxlen; i++) if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1; // if the URLs didn't match and the one the user is browsing to is longer // than what we just compared against, we need to compare against longer URLs, // but only if the next character is actually part of a folder name rather than a separator. // ('cos if it *is* a separator, it doesn't matter that the overall URL is longer, the // beginning of it matches a banned URL.) if ((alen > blen) && !(a[blen] == '/' || a[blen]=='?' || a[blen]=='&' || a[blen]=='=')) return 1; // if the banned URL is longer than the URL we're checking, the two // can't possibly match. else if (blen > alen) return -1; return 0; // both equal } int ListContainer::greaterThanEW(const char *a, const char *b) { int alen = strlen(a); int blen = strlen(b); int apos = alen - 1; int bpos = blen - 1; for (int maxlen = (alen < blen ? alen : blen); maxlen > 0; apos--, bpos--, maxlen--) if (a[apos] > b[bpos]) return 1; else if (a[apos] < b[bpos]) return -1; if (blen > alen) return -1; return 0; // both equal } bool ListContainer::isCacheFileNewer(const char *filename) { size_t len = 0; try { len = getFileLength(filename); } catch (std::runtime_error &e) { if (!is_daemonised) { std::cerr << "Error reading file " << filename << ": " << e.what() << std::endl; } syslog(LOG_ERR, "Error reading file %s: %s", filename, e.what()); return false; } int bannedlistdate = getFileDate(filename); std::string linebuffer(filename); linebuffer += ".processed"; int cachedate = getFileDate(linebuffer.c_str()); if (cachedate < bannedlistdate) { return false; // cache file is older than list file } return true; } void ListContainer::increaseMemoryBy(size_t bytes) { if (data_memory > 0) { data = (char*) realloc(data, (data_memory + bytes) * sizeof(char)); memset(data + data_memory, 0, bytes * sizeof(char)); data_memory += bytes; } else { free(data); data = (char*) calloc(bytes, sizeof(char)); data_memory = bytes; } } size_t getFileLength(const char *filename) { struct stat status; int rc = stat(filename, &status); if (rc < 0) throw std::runtime_error(strerror(errno)); return status.st_size; } time_t getFileDate(const char *filename) { struct stat status; int rc = stat(filename, &status); if (rc != 0) { if (errno == ENOENT) return 0; else throw std::runtime_error(strerror(errno)); } return status.st_mtime; } bool ListContainer::upToDate() { if (getFileDate(sourcefile.toCharArray()) > filedate) { return false; } String cachefile(sourcefile); cachefile += ".processed"; if (getFileDate(cachefile.toCharArray()) > filedate) { return false; } for (unsigned int i = 0; i < morelists.size(); i++) { if (!(*o.lm.l[morelists[i]]).upToDate()) { return false; } } return true; } bool ListContainer::readTimeTag(String * tag, TimeLimit& tl) { #ifdef DGDEBUG std::cout << "Found a time tag" << std::endl; #endif unsigned int tsthour, tstmin, tendhour, tendmin; String temp((*tag).after("#time: ")); tsthour = temp.before(" ").toInteger(); temp = temp.after(" "); tstmin = temp.before(" ").toInteger(); temp = temp.after(" "); tendhour = temp.before(" ").toInteger(); temp = temp.after(" "); tendmin = temp.before(" ").toInteger(); String tdays(temp.after(" ")); tdays.removeWhiteSpace(); if (tsthour > 23) { if (!is_daemonised) { std::cerr << "Time Tag Start Hour over bounds." << std::endl; } syslog(LOG_ERR, "%s", "Time Tag Start Hour over bounds."); return false; } if (tendhour > 23) { if (!is_daemonised) { std::cerr << "Time Tag End Hour over bounds." << std::endl; } syslog(LOG_ERR, "%s", "Time Tag End Hour over bounds."); return false; } if (tstmin > 59) { if (!is_daemonised) { std::cerr << "Time Tag Start Min over bounds." << std::endl; } syslog(LOG_ERR, "%s", "Time Tag Start Min over bounds."); return false; } if (tendmin > 59) { if (!is_daemonised) { std::cerr << "Time Tag End Min over bounds." << std::endl; } syslog(LOG_ERR, "%s", "Time Tag End Min over bounds."); return false; } if (tdays.length() > 7) { if (!is_daemonised) { std::cerr << "Time Tag Days over bounds." << std::endl; } syslog(LOG_ERR, "%s", "Time Tag Days over bounds."); return false; } istimelimited = true; tl.sthour = tsthour; tl.stmin = tstmin; tl.endhour = tendhour; tl.endmin = tendmin; tl.days = tdays; tl.timetag = (*tag); return true; } // Returns true if the current time is within the limits specified on this list. // For phrases, the time limit list index must be passed in - // included lists don't have their own ListContainer, so time limits are stored differently. bool ListContainer::isNow(int index) { if (!istimelimited) { return true; } TimeLimit& tl = listtimelimit; if (index > -1) { tl = timelimits[index]; } time_t tnow; // to hold the result from time() struct tm *tmnow; // to hold the result from localtime() unsigned int hour, min, wday; time(&tnow); // get the time after the lock so all entries in order tmnow = localtime(&tnow); // convert to local time (BST, etc) hour = tmnow->tm_hour; min = tmnow->tm_min; wday = tmnow->tm_wday; // wrap week to start on Monday if (wday == 0) { wday = 7; } wday--; unsigned char cday = '0' + wday; bool matchday = false; for (unsigned int i = 0; i < tl.days.length(); i++) { if (tl.days[i] == cday) { matchday = true; break; } } if (!matchday) { return false; } if (hour < tl.sthour) { return false; } if (hour > tl.endhour) { return false; } if (hour == tl.sthour) { if (min < tl.stmin) { return false; } } if (hour == tl.endhour) { if (min > tl.endmin) { return false; } } #ifdef DGDEBUG std::cout << "time match " << tl.sthour << ":" << tl.stmin << "-" << tl.endhour << ":" << tl.endmin << " " << hour << ":" << min << " " << sourcefile << std::endl; #endif return true; } int ListContainer::getCategoryIndex(String * lcat) { // where in the category list is our category? if nowhere, add it. if ((*lcat).length() < 2) { #ifdef DGDEBUG std::cout << "blank entry index" << std::endl; #endif return 0; // blank entry index } int l = (signed) listcategory.size(); int i; for (i = 0; i < l; i++) { if ((*lcat) == listcategory[i]) { return i; } } listcategory.push_back((*lcat)); return l; } String ListContainer::getListCategoryAt(int index, int *catindex) { //category index of -1 indicates uncategorised list if ((index >= categoryindex.size()) || (categoryindex[index] < 0)) { return ""; } //return category index (allows naughtyfilter to do numeric comparison between categories //when doing duplicate search; much faster than string comparison) if (catindex != NULL) { (*catindex) = categoryindex[index]; } return listcategory[categoryindex[index]]; } String ListContainer::getListCategoryAtD(int index) { //category index of -1 indicates uncategorised list if ((index < 0) || (index >= listcategory.size())) { return ""; } return listcategory[index]; } dansguardian-2.10.1.1/src/ContentScanner.hpp0000644001165000116500000000664411110523210015533 00000000000000// Defines the class interface to be implemented by ContentScanner plugins //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_CONTENTSCANNER #define __HPP_CONTENTSCANNER // INCLUDES #include "String.hpp" #include "ConfigVar.hpp" #include "DataBuffer.hpp" #include "Socket.hpp" #include "HTTPHeader.hpp" #include "ListContainer.hpp" #include "FDFuncs.hpp" #include "Plugin.hpp" #include // DEFINES #define DGCS_OK 0 #define DGCS_ERROR -1 #define DGCS_WARNING 3 #define DGCS_NOSCAN 0 #define DGCS_NEEDSCAN 1 #define DGCS_TESTERROR -1 #define DGCS_CLEAN 0 #define DGCS_SCANERROR -1 #define DGCS_INFECTED 1 //#define DGCS_CURED 2 // not used #define DGCS_MAX 4 // use values above this for custom return codes // DECLARATIONS class CSPlugin; // class factory functions for CS plugins typedef CSPlugin* cscreate_t(ConfigVar &); // CS plugin interface proper - to be implemented by plugins themselves class CSPlugin: public Plugin { public: ConfigVar cv; String lastmessage; String lastvirusname; //constructor with CS plugin configuration passed in CSPlugin(ConfigVar &definition); virtual ~CSPlugin() {}; // test whether a given request should be scanned or not, based on sent & received headers virtual int scanTest(HTTPHeader *requestheader, HTTPHeader *docheader, const char* user, int filtergroup, const char* ip); // scanning functions themselves virtual int scanMemory(HTTPHeader *requestheader, HTTPHeader *docheader, const char *user, int filtergroup, const char *ip, const char *object, unsigned int objectsize); virtual int scanFile(HTTPHeader *requestheader, HTTPHeader *docheader, const char *user, int filtergroup, const char *ip, const char* filename) = 0; virtual String getLastMessage() {return lastmessage;}; virtual String getLastVirusName() {return lastvirusname;}; // start, restart and stop the plugin virtual int init(void* args); virtual int quit() {return DGCS_OK;}; private: // lists of all the various things we may not want to scan ListContainer exceptionvirusmimetypelist; ListContainer exceptionvirusextensionlist; ListContainer exceptionvirussitelist; ListContainer exceptionvirusurllist; protected: // the following are unlikely to need to be overridden // read in scan exception lists virtual bool readStandardLists(); // make & write to temp files, primarily for plugins with no direct memory scanning capability (e.g. clamdscan) virtual int makeTempFile(String *filename); virtual int writeMemoryTempFile(const char *object, unsigned int objectsize, String *filename); }; // Return an instance of the plugin defined in the given configuration file CSPlugin* cs_plugin_load( const char *pluginConfigPath ); #endif dansguardian-2.10.1.1/src/downloadmanagers/0000777001165000116500000000000011212164550015510 500000000000000dansguardian-2.10.1.1/src/downloadmanagers/default.cpp0000644001165000116500000002121211110523210017537 00000000000000// Default download manager, used when no other plugin matches the user agent //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../DownloadManager.hpp" #include "../OptionContainer.hpp" #include #include #include #include // GLOBALS extern OptionContainer o; // DECLARATIONS class dminstance:public DMPlugin { public: dminstance(ConfigVar & definition):DMPlugin(definition) {}; int in(DataBuffer * d, Socket * sock, Socket * peersock, HTTPHeader * requestheader, HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig); // default plugin is as basic as you can get - no initialisation, and uses the default // set of matching mechanisms. uncomment and implement these to override default behaviour. //int init(void* args); //bool willHandle(HTTPHeader *requestheader, HTTPHeader *docheader); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin DMPlugin *defaultdmcreate(ConfigVar & definition) { #ifdef DGDEBUG std::cout << "Creating default DM" << std::endl; #endif return new dminstance(definition); } // end of Class factory // uncomment these if you wish to replace the default inherited functions // < 0 = error // = 0 = ok // > 0 = warning //int dminstance::init(void* args) { // return 0; //} //int dminstance::quit(void) { // return 0; //} // download body for this request int dminstance::in(DataBuffer * d, Socket * sock, Socket * peersock, class HTTPHeader * requestheader, class HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig) { //DataBuffer *d = where to stick the data back into //Socket *sock = where to read from //Socket *peersock = browser to send stuff to for keeping it alive //HTTPHeader *requestheader = header client used to request //HTTPHeader *docheader = header used for sending first line of reply //bool wantall = to determine if just content filter or a full scan //int *headersent = to use to send the first line of header if needed // or to mark the header has already been sent //bool *toobig = flag to modify to say if it could not all be downloaded #ifdef DGDEBUG std::cout << "Inside default download manager plugin" << std::endl; #endif // To access settings for the plugin use the following example: // std::cout << "cvtest:" << cv["dummy"] << std::endl; int rc; off_t newsize; off_t bytesremaining = docheader->contentLength(); // if using non-persistent connections, some servers will not report // a content-length. in these situations, just download everything. bool geteverything = false; if ((bytesremaining < 0) && !(docheader->isPersistent())) geteverything = true; char *block = NULL; // buffer for storing a grabbed block from the // imput stream char *temp = NULL; bool swappedtodisk = false; bool doneinitialdelay = false; struct timeval themdays; struct timeval nowadays; gettimeofday(&themdays, NULL); // buffer size for streaming downloads off_t blocksize = 32768; // set to a sensible minimum if (!wantall && (blocksize > o.max_content_filter_size)) blocksize = o.max_content_filter_size; else if (wantall && (blocksize > o.max_content_ramcache_scan_size)) blocksize = o.max_content_ramcache_scan_size; #ifdef DGDEBUG std::cout << "blocksize: " << blocksize << std::endl; #endif while ((bytesremaining > 0) || geteverything) { // send x-header keep-alive here if (o.trickle_delay > 0) { gettimeofday(&nowadays, NULL); if (doneinitialdelay ? nowadays.tv_sec - themdays.tv_sec > o.trickle_delay : nowadays.tv_sec - themdays.tv_sec > o.initial_trickle_delay) { themdays.tv_sec = nowadays.tv_sec; doneinitialdelay = true; if ((*headersent) < 1) { #ifdef DGDEBUG std::cout << "sending first line of header first" << std::endl; #endif docheader->out(NULL,peersock, __DGHEADER_SENDFIRSTLINE); (*headersent) = 1; } #ifdef DGDEBUG std::cout << "trickle delay - sending X-DGKeepAlive: on" << std::endl; #endif peersock->writeString("X-DGKeepAlive: on\r\n"); } } if (wantall) { if (!swappedtodisk) { // if not swapped to disk and file is too large for RAM, then swap to disk if (d->buffer_length > o.max_content_ramcache_scan_size) { #ifdef DGDEBUG std::cout << "swapping to disk" << std::endl; #endif d->tempfilefd = d->getTempFileFD(); if (d->tempfilefd < 0) { #ifdef DGDEBUG std::cerr << "error buffering to disk so skipping disk buffering" << std::endl; #endif syslog(LOG_ERR, "%s", "error buffering to disk so skipping disk buffering"); (*toobig) = true; break; } writeEINTR(d->tempfilefd, d->data, d->buffer_length); swappedtodisk = true; d->tempfilesize = d->buffer_length; } } else if (d->tempfilesize > o.max_content_filecache_scan_size) { // if swapped to disk and file too large for that too, then give up #ifdef DGDEBUG std::cout << "defaultdm: file too big to be scanned, halting download" << std::endl; #endif (*toobig) = true; break; } } else { if (d->buffer_length > o.max_content_filter_size) { // if we aren't downloading for virus scanning, and file too large for filtering, give up #ifdef DGDEBUG std::cout << "defaultdm: file too big to be filtered, halting download" << std::endl; #endif (*toobig) = true; break; } } if (!swappedtodisk) { if (d->buffer_length >= blocksize) { newsize = d->buffer_length; } else { newsize = blocksize; } #ifdef DGDEBUG std::cout << "newsize: " << newsize << std::endl; #endif // if not getting everything until connection close, grab only what is left if (!geteverything && (newsize > bytesremaining)) newsize = bytesremaining; delete[] block; block = new char[newsize]; try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } // improved more efficient socket read which uses the buffer better rc = d->bufferReadFromSocket(sock, block, newsize, d->timeout); // grab a block of input, doubled each time if (rc <= 0) { break; // an error occured so end the while() // or none received so pipe is closed } else { bytesremaining -= rc; /*if (d->data != temp) delete[] temp;*/ temp = new char[d->buffer_length + rc + 1]; // replacement store temp[d->buffer_length + rc] = '\0'; memcpy(temp, d->data, d->buffer_length); // copy the current data memcpy(temp + d->buffer_length, block, rc); // copy the new data delete[]d->data; // delete the current data block d->data = temp; temp = NULL; d->buffer_length += rc; // update data size counter } } else { try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } rc = d->bufferReadFromSocket(sock, d->data, // if not getting everything until connection close, grab only what is left (!geteverything && (bytesremaining < d->buffer_length) ? bytesremaining : d->buffer_length), d->timeout); if (rc <= 0) { break; } else { bytesremaining -= rc; lseek(d->tempfilefd, 0, SEEK_END); // not really needed writeEINTR(d->tempfilefd, d->data, rc); d->tempfilesize += rc; #ifdef DGDEBUG std::cout << "written to disk:" << rc << " total:" << d->tempfilesize << std::endl; #endif } } } if (!(*toobig) && !swappedtodisk) { // won't deflate stuff swapped to disk if (d->decompress.contains("deflate")) { #ifdef DGDEBUG std::cout << "zlib format" << std::endl; #endif d->zlibinflate(false); // incoming stream was zlib compressed } else if (d->decompress.contains("gzip")) { #ifdef DGDEBUG std::cout << "gzip format" << std::endl; #endif d->zlibinflate(true); // incoming stream was gzip compressed } } d->bytesalreadysent = 0; #ifdef DGDEBUG std::cout << "Leaving default download manager plugin" << std::endl; #endif delete[] block; /*if (d->data != temp) delete[] temp;*/ return 0; } dansguardian-2.10.1.1/src/downloadmanagers/trickle.cpp0000644001165000116500000002352511110523210017561 00000000000000// Trickle download manager - sends parts of a file being downloaded, a byte // at a time. // WARNING: Files which are/can be processed before they are complete - such // as certain image formats, shell scripts, and multimedia files - MAY have a // working, malicious portion sent to the browser before scanning has // completed! //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../DownloadManager.hpp" #include "../OptionContainer.hpp" #include #include #include #include // GLOBALS extern OptionContainer o; // DECLARATIONS class trickledm:public DMPlugin { public: trickledm(ConfigVar & definition):DMPlugin(definition) {}; int in(DataBuffer * d, Socket * sock, Socket * peersock, HTTPHeader * requestheader, HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig); // default plugin is as basic as you can get - no initialisation, and uses the default // set of matching mechanisms. uncomment and implement these to override default behaviour. //int init(void* args); //bool willHandle(HTTPHeader *requestheader, HTTPHeader *docheader); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin DMPlugin *trickledmcreate(ConfigVar & definition) { #ifdef DGDEBUG std::cout << "Creating trickle DM" << std::endl; #endif return new trickledm(definition); } // end of Class factory // uncomment these if you wish to replace the default inherited functions // < 0 = error // = 0 = ok // > 0 = warning //int dminstance::init(void* args) { // return 0; //} //int dminstance::quit(void) { // return 0; //} // download body for this request int trickledm::in(DataBuffer * d, Socket * sock, Socket * peersock, class HTTPHeader * requestheader, class HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig) { //DataBuffer *d = where to stick the data back into //Socket *sock = where to read from //Socket *peersock = browser to send stuff to for keeping it alive //HTTPHeader *requestheader = header client used to request //HTTPHeader *docheader = header used for sending first line of reply //bool wantall = to determine if just content filter or a full scan //int *headersent = to use to send the first line of header if needed // or to mark the header has already been sent //bool *toobig = flag to modify to say if it could not all be downloaded #ifdef DGDEBUG std::cout << "Inside trickle download manager plugin" << std::endl; #endif // To access settings for the plugin use the following example: // std::cout << "cvtest:" << cv["dummy"] << std::endl; int rc = 0; d->bytesalreadysent = 0; off_t newsize; off_t bytesremaining = docheader->contentLength(); // if using non-persistent connections, some servers will not report // a content-length. in these situations, just download everything. bool geteverything = false; if ((bytesremaining < 0) && !(docheader->isPersistent())) geteverything = true; char *block = NULL; // buffer for storing a grabbed block from the // imput stream char *temp = NULL; bool swappedtodisk = false; bool doneinitialdelay = false; struct timeval themdays; struct timeval nowadays; gettimeofday(&themdays, NULL); // buffer size for streaming downloads off_t blocksize = 32768; // set to a sensible minimum if (!wantall && (blocksize > o.max_content_filter_size)) blocksize = o.max_content_filter_size; else if (wantall && (blocksize > o.max_content_ramcache_scan_size)) blocksize = o.max_content_ramcache_scan_size; #ifdef DGDEBUG std::cout << "blocksize: " << blocksize << std::endl; #endif while ((bytesremaining > 0) || geteverything) { // send keep-alive bytes here if (o.trickle_delay > 0) { gettimeofday(&nowadays, NULL); if (doneinitialdelay ? nowadays.tv_sec - themdays.tv_sec > o.trickle_delay : nowadays.tv_sec > o.initial_trickle_delay) { themdays.tv_sec = nowadays.tv_sec; doneinitialdelay = true; if ((*headersent) < 1) { #ifdef DGDEBUG std::cout << "sending header first" << std::endl; #endif docheader->out(NULL,peersock, __DGHEADER_SENDALL); (*headersent) = 2; } if (!swappedtodisk) { // leave a kilobyte "barrier" so the whole file does not get sent before scanning if ((d->buffer_length > 1024) && (d->bytesalreadysent < (d->buffer_length - 1024))) { #ifdef DGDEBUG std::cout << "trickle delay - sending a byte from the memory buffer" << std::endl; #endif peersock->writeToSocket(d->data + (d->bytesalreadysent++), 1, 0, d->timeout); } #ifdef DGDEBUG else std::cout << "trickle delay - no unsent bytes remaining! (memory)" << std::endl; #endif } else { // check the file is at least one kilobyte ahead of our send pointer, so // the whole file does not get sent before scanning if (lseek(d->tempfilefd, d->bytesalreadysent + 1024, SEEK_SET) != (off_t)-1) { lseek(d->tempfilefd, d->bytesalreadysent, SEEK_SET); #ifdef DGDEBUG std::cout << "trickle delay - sending a byte from the file" << std::endl; #endif char byte; read(d->tempfilefd, &byte, 1); peersock->writeToSocket(&byte, 1, 0, d->timeout); d->bytesalreadysent++; } #ifdef DGDEBUG else std::cout << "trickle delay - no unsent bytes remaining! (file)" << std::endl; #endif } } } if (wantall) { if (!swappedtodisk) { // if not swapped to disk and file is too large for RAM, then swap to disk if (d->buffer_length > o.max_content_ramcache_scan_size) { #ifdef DGDEBUG std::cout << "swapping to disk" << std::endl; #endif d->tempfilefd = d->getTempFileFD(); if (d->tempfilefd < 0) { #ifdef DGDEBUG std::cerr << "error buffering to disk so skipping disk buffering" << std::endl; #endif syslog(LOG_ERR, "%s", "error buffering to disk so skipping disk buffering"); (*toobig) = true; break; } writeEINTR(d->tempfilefd, d->data, d->buffer_length); swappedtodisk = true; d->tempfilesize = d->buffer_length; } } else if (d->tempfilesize > o.max_content_filecache_scan_size) { // if swapped to disk and file too large for that too, then give up #ifdef DGDEBUG std::cout << "defaultdm: file too big to be scanned, halting download" << std::endl; #endif (*toobig) = true; break; } } else { if (d->buffer_length > o.max_content_filter_size) { // if we aren't downloading for virus scanning, and file too large for filtering, give up #ifdef DGDEBUG std::cout << "defaultdm: file too big to be filtered, halting download" << std::endl; #endif (*toobig) = true; break; } } if (!swappedtodisk) { if (d->buffer_length >= blocksize) { newsize = d->buffer_length; } else { newsize = blocksize; } #ifdef DGDEBUG std::cout << "newsize: " << newsize << std::endl; #endif // if not getting everything until connection close, grab only what is left if (!geteverything && (newsize > bytesremaining)) newsize = bytesremaining; delete[] block; block = new char[newsize]; try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } // improved more efficient socket read which uses the buffer better rc = d->bufferReadFromSocket(sock, block, newsize, d->timeout); // grab a block of input, doubled each time if (rc <= 0) { break; // an error occured so end the while() // or none received so pipe is closed } else { bytesremaining -= rc; /*if (d->data != temp) delete[] temp;*/ temp = new char[d->buffer_length + rc + 1]; // replacement store temp[d->buffer_length + rc] = '\0'; memcpy(temp, d->data, d->buffer_length); // copy the current data memcpy(temp + d->buffer_length, block, rc); // copy the new data delete[]d->data; // delete the current data block d->data = temp; temp = NULL; d->buffer_length += rc; // update data size counter } } else { try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } rc = d->bufferReadFromSocket(sock, d->data, // if not getting everything until connection close, grab only what is left (!geteverything && (bytesremaining < d->buffer_length) ? bytesremaining : d->buffer_length), d->timeout); if (rc <= 0) { break; } else { bytesremaining -= rc; lseek(d->tempfilefd, 0, SEEK_END); writeEINTR(d->tempfilefd, d->data, rc); d->tempfilesize += rc; #ifdef DGDEBUG std::cout << "written to disk:" << rc << " total:" << d->tempfilesize << std::endl; #endif } } } if (!(*toobig) && !swappedtodisk) { // won't deflate stuff swapped to disk if (d->decompress.contains("deflate")) { #ifdef DGDEBUG std::cout << "zlib format" << std::endl; #endif d->zlibinflate(false); // incoming stream was zlib compressed } else if (d->decompress.contains("gzip")) { #ifdef DGDEBUG std::cout << "gzip format" << std::endl; #endif d->zlibinflate(true); // incoming stream was gzip compressed } } #ifdef DGDEBUG std::cout << "Leaving trickle download manager plugin" << std::endl; #endif delete[] block; /*if (d->data != temp) delete[] temp;*/ return 0; } dansguardian-2.10.1.1/src/downloadmanagers/fancy.cpp0000644001165000116500000004257311110523210017230 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../DownloadManager.hpp" #include "../OptionContainer.hpp" #include "../HTMLTemplate.hpp" #include "../ConnectionHandler.hpp" #include #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // DECLARATIONS class fancydm:public DMPlugin { public: fancydm(ConfigVar & definition):DMPlugin(definition), toobig_unscanned(false), toobig_notdownloaded(false) {}; int in(DataBuffer * d, Socket * sock, Socket * peersock, HTTPHeader * requestheader, HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig); int init(void* args); void sendLink(Socket &peersock, String &linkurl, String &prettyurl); private: // customisable fancy DM template HTMLTemplate progresspage; // upper (non-scanned) file download size limit // part of "multi-stage" downloads for when content length is unknown: // - start downloading & hope for the best // - if too large, warn the user, but keep downloading (won't be scanned) // - if larger than upper limit also, kill download. off_t upperlimit; // was file too large to be scanned? bool toobig_unscanned; // was file so large as to not even be downloaded? bool toobig_notdownloaded; // format an integer in seconds as hours:minutes:seconds std::string timestring(const int seconds); // format a number of bytes as a number of Gb/Mb/Kb String bytestring(const off_t bytes); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin DMPlugin *fancydmcreate(ConfigVar & definition) { #ifdef DGDEBUG std::cout << "Creating fancy DM" << std::endl; #endif return new fancydm(definition); } // end of Class factory // initialisation - load the template file int fancydm::init(void* args) { // call inherited init DMPlugin::init(args); // read in absolute max download limit upperlimit = cv["maxdownloadsize"].toOffset() * 1024; if (upperlimit <= o.max_content_filecache_scan_size) upperlimit = 0; #ifdef DGDEBUG std::cout << "Upper download limit: " << upperlimit << std::endl; #endif String fname(cv["template"]); if (fname.length() > 0) { // read the template file, and return OK on success, error on failure. fname = o.languagepath + fname; return progresspage.readTemplateFile(fname.toCharArray(), "-FILENAME-|-FILESIZE-|-SERVERIP-") ? 0 : -1; } else { // eek! there's no template option in our config. if (!is_daemonised) std::cerr << "Template not specified for fancy download manager" << std::endl; syslog(LOG_ERR, "Template not specified for fancy download manager"); return -2; } } // call template's downloadlink JavaScript function void fancydm::sendLink(Socket &peersock, String &linkurl, String &prettyurl) { String mess("\n"); peersock.writeString(mess.toCharArray()); // send text-only version for non-JS-enabled browsers // 1220 "Scan complete.

Click here to download: " // 1221 "Download complete; file not scanned.

Click here to download: " // 1222 "File too large to cache.

Click here to re-download, bypassing virus scanning: " mess = "

"; mess += o.language_list.getTranslation(toobig_notdownloaded ? 1222 : (toobig_unscanned ? 1221 : 1220)); mess += "" + prettyurl + "

"; peersock.writeString(mess.toCharArray()); peersock.writeString("\r\n"); peersock.writeString("\n"); if (toobig_notdownloaded) { // add URL to clean cache (for all groups) addToClean(prettyurl, o.filter_groups + 1); } } // download body for this request int fancydm::in(DataBuffer * d, Socket * sock, Socket * peersock, class HTTPHeader * requestheader, class HTTPHeader * docheader, bool wantall, int *headersent, bool * toobig) { //DataBuffer *d = where to stick the data back into //Socket *sock = where to read from //Socket *peersock = browser to send stuff to for keeping it alive //HTTPHeader *docheader = header used for sending first line of reply //HTTPHeader *requestheader = header client used to request //bool wantall = to determine if just content filter or a full scan //int *headersent = to use to send the first line of header if needed // or to mark the header has already been sent //bool *toobig = flag to modify to say if it could not all be downloaded #ifdef DGDEBUG std::cout << "Inside fancy download manager plugin" << std::endl; #endif int rc; off_t newsize; off_t expectedsize = docheader->contentLength(); off_t bytessec = 0; off_t bytesgot = 0; int percentcomplete = 0; unsigned int eta = 0; int timeelapsed = 0; // if using non-persistent connections, some servers will not report // a content-length. in these situations, just download everything. bool geteverything = false; if ((expectedsize < 0) && !(docheader->isPersistent())) geteverything = true; if (expectedsize < 0) expectedsize = 0; bool initialsent = false; String message, jsmessage; char *block = NULL; // buffer for storing a grabbed block from the input stream char *temp = NULL; bool swappedtodisk = false; struct timeval starttime; struct timeval themdays; struct timeval nowadays; gettimeofday(&themdays, NULL); gettimeofday(&starttime, NULL); toobig_unscanned = false; toobig_notdownloaded = false; bool secondstage = false; // buffer size for streaming downloads off_t blocksize = 32768; // set to a sensible minimum if (!wantall && (blocksize > o.max_content_filter_size)) blocksize = o.max_content_filter_size; else if (wantall && (blocksize > o.max_content_ramcache_scan_size)) blocksize = o.max_content_ramcache_scan_size; #ifdef DGDEBUG std::cout << "blocksize: " << blocksize << std::endl; #endif // determine downloaded filename String filename(requestheader->disposition()); if (filename.length() == 0) { filename = requestheader->url(); filename = requestheader->decode(filename); if (filename.contains("?")) filename = filename.before("?"); while (filename.contains("/")) filename = filename.after("/"); } while ((bytesgot < expectedsize) || geteverything) { // send text header to show status if (o.trickle_delay > 0) { gettimeofday(&nowadays, NULL); timeelapsed = nowadays.tv_sec - starttime.tv_sec; if ((!initialsent && timeelapsed > o.initial_trickle_delay) || (initialsent && nowadays.tv_sec - themdays.tv_sec > o.trickle_delay)) { initialsent = true; bytessec = bytesgot / timeelapsed; themdays.tv_sec = nowadays.tv_sec; if ((*headersent) < 1) { #ifdef DGDEBUG std::cout << "sending header for text status" << std::endl; #endif message = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n"; // Output initial template std::deque::iterator i = progresspage.html.begin(); std::deque::iterator penultimate = progresspage.html.end()-1; bool newline; while (i != progresspage.html.end()) { newline = false; message = *i; if (message == "-FILENAME-") { message = filename; } else if (message == "-FILESIZE-") { message = String(expectedsize); } else if (message == "-SERVERIP-") { message = peersock->getLocalIP(); } else if ((i == penultimate) || ((*(i+1))[0] != '-')) { newline = true; } peersock->writeString(message.toCharArray()); // preserve line breaks from the original template file if (newline) peersock->writeString("\n"); i++; } // send please wait message for non-JS-enabled browsers // 1200 "Please wait - downloading to be scanned..." message = "\n"; peersock->writeString(message.toCharArray()); (*headersent) = 2; } #ifdef DGDEBUG std::cout << "trickle delay - sending progress..." << std::endl; #endif message = "Downloading status: "; // Output a call to template's JavaScript progressupdate function jsmessage = ""; peersock->writeString(jsmessage.toCharArray()); // send text only version for non-JS-enabled browsers. // checkme: translation? if (geteverything) { message = "\n"; } else { percentcomplete = bytesgot/(expectedsize/100); eta = (expectedsize-bytesgot)/bytessec; message = "\n"; } peersock->writeString(message.toCharArray()); peersock->writeString("\r\n"); } } if (wantall) { if (!swappedtodisk) { // if not swapped to disk and file is too large for RAM, then swap to disk if (bytesgot > o.max_content_ramcache_scan_size) { #ifdef DGDEBUG std::cout << "swapping to disk" << std::endl; #endif d->tempfilefd = d->getTempFileFD(); if (d->tempfilefd < 0) { #ifdef DGDEBUG std::cerr << "error buffering to disk so skipping disk buffering" << std::endl; #endif syslog(LOG_ERR, "%s", "error buffering to disk so skipping disk buffering"); (*toobig) = true; break; } writeEINTR(d->tempfilefd, d->data, d->buffer_length); swappedtodisk = true; d->tempfilesize = d->buffer_length; } } else if (bytesgot > o.max_content_filecache_scan_size) { (*toobig) = true; toobig_unscanned = true; if (geteverything && (upperlimit > 0)) { // multi-stage download enabled, and we don't know content length if ((!secondstage) && initialsent) { secondstage = true; // send download size warning message jsmessage = ""; peersock->writeString(jsmessage.toCharArray()); // text-only version message = "\n"; peersock->writeString(message.toCharArray()); peersock->writeString("\r\n"); // add URL to clean cache (for all groups) String url(requestheader->url()); addToClean(url, o.filter_groups + 1); #ifdef DGDEBUG std::cout << "fancydm: file too big to be scanned, entering second stage of download" << std::endl; #endif } // too large to even download, let alone scan if (bytesgot > upperlimit) { #ifdef DGDEBUG std::cout << "fancydm: file too big to be downloaded, halting second stage of download" << std::endl; #endif toobig_unscanned = false; toobig_notdownloaded = true; break; } } else { // multi-stage download disabled, or we know content length // if swapped to disk and file too large for that too, then give up #ifdef DGDEBUG std::cout << "fancydm: file too big to be scanned, halting download" << std::endl; #endif toobig_unscanned = false; toobig_notdownloaded = true; break; } } } else { if (bytesgot > o.max_content_filter_size) { // if we aren't downloading for virus scanning, and file too large for filtering, give up #ifdef DGDEBUG std::cout << "fancydm: file too big to be filtered, halting download" << std::endl; #endif (*toobig) = true; break; } } if (!swappedtodisk) { if (d->buffer_length >= blocksize) { newsize = d->buffer_length; } else { newsize = blocksize; } #ifdef DGDEBUG std::cout << "newsize: " << newsize << std::endl; #endif // if not getting everything until connection close, grab only what is left if (!geteverything && (newsize > (expectedsize - bytesgot))) newsize = expectedsize - bytesgot; delete[] block; block = new char[newsize]; try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } // improved more efficient socket read which uses the buffer better rc = d->bufferReadFromSocket(sock, block, newsize, d->timeout, o.trickle_delay); // grab a block of input, doubled each time if (rc <= 0) { break; // an error occured so end the while() // or none received so pipe is closed } else { /*if (d->data != temp) delete[] temp;*/ temp = new char[d->buffer_length + rc + 1]; // replacement store temp[d->buffer_length + rc] = '\0'; memcpy(temp, d->data, d->buffer_length); // copy the current data memcpy(temp + d->buffer_length, block, rc); // copy the new data delete[]d->data; // delete the current data block d->data = temp; temp = NULL; d->buffer_length += rc; // update data size counter } } else { try { sock->checkForInput(d->timeout); } catch(std::exception & e) { break; } rc = d->bufferReadFromSocket(sock, d->data, // if not getting everything until connection close, grab only what is left (!geteverything && ((expectedsize - bytesgot) < d->buffer_length) ? (expectedsize - bytesgot) : d->buffer_length), d->timeout); if (rc <= 0) { break; } else { lseek(d->tempfilefd, 0, SEEK_END); // not really needed writeEINTR(d->tempfilefd, d->data, rc); d->tempfilesize += rc; #ifdef DGDEBUG std::cout << "written to disk: " << rc << " total: " << d->tempfilesize << std::endl; #endif } } if (d->tempfilesize > 0) { bytesgot = d->tempfilesize; } else { bytesgot = d->buffer_length; } } if (initialsent) { if (!swappedtodisk) { // if we sent textual content then we can't // stream the file to the user so we must save to disk for them // to download by clicking on the magic link // You can get to this point by having a large ram cache, or // slow internet connection with small initial trickle delay. // This should be rare. #ifdef DGDEBUG std::cout << "swapping to disk" << std::endl; #endif d->tempfilefd = d->getTempFileFD(); if (d->tempfilefd < 0) { #ifdef DGDEBUG std::cerr << "error buffering complete to disk so skipping disk buffering" << std::endl; #endif syslog(LOG_ERR, "error buffering complete to disk so skipping disk buffering"); } else { writeEINTR(d->tempfilefd, d->data, d->buffer_length); swappedtodisk = true; d->tempfilesize = d->buffer_length; } } // Output a call to template's JavaScript nowscanning function peersock->writeString("\n"); // send text-only version // 1210 "Download Complete. Starting scan..." if (!(toobig_unscanned || toobig_notdownloaded)) { message = "\n"; peersock->writeString(message.toCharArray()); } // only keep full downloads if (!toobig_notdownloaded) (*d).preservetemp = true; (*d).dontsendbody = true; } if (!(*toobig) && !swappedtodisk) { // won't deflate stuff swapped to disk if (d->decompress.contains("deflate")) { #ifdef DGDEBUG std::cout << "zlib format" << std::endl; #endif d->zlibinflate(false); // incoming stream was zlib compressed } else if (d->decompress.contains("gzip")) { #ifdef DGDEBUG std::cout << "gzip format" << std::endl; #endif d->zlibinflate(true); // incoming stream was gzip compressed } } d->bytesalreadysent = 0; /*if (d->data != temp) delete[] temp;*/ delete[] block; return 0; } // format an integer in seconds as hours:minutes:seconds std::string fancydm::timestring(const int seconds) { int hours = (int)floor((double)seconds/3600); int minutes = (int)floor(((double)seconds/60)-(hours*3600)); int remainingseconds = seconds-(minutes*60)-(hours*3600); char result[9]; snprintf(result, 9, "%02i:%02i:%02i", hours, minutes, remainingseconds); return result; } // format a number of bytes as a number of Gb/Mb/Kb String fancydm::bytestring(const off_t bytes) { int b = (int)floor((double)bytes/(1024*1024*1024)); if (b > 0) return String(b)+" Gb"; b = (int)floor((double)bytes/(1024*1024)); if (b > 0) return String(b)+" Mb"; b = (int)floor((double)bytes/1024); if (b > 0) return String(b)+" Kb"; return String(b)+" bytes"; } dansguardian-2.10.1.1/src/String.cpp0000644001165000116500000002675011134062414014062 00000000000000// String - guess what: it's a string class! //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "String.hpp" #include "md5.hpp" #if defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96 #warning "Using strstream instead of sstream" #include #else #include #endif #include #include // construct string representations of ints/longs #if defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96 String::String(const int num) { std::ostrstream buf; buf << num << std::ends; *this = buf.str(); // with side effect: it calls buf.freeze() } String::String(const long num) { std::ostrstream buf; buf << num << std::ends; *this = buf.str(); } String::String(const unsigned int num) { std::ostrstream buf; buf << num << std::ends; *this = buf.str(); } String::String(const long unsigned int num) { std::ostrstream buf; buf << num << std::ends; *this = buf.str(); } # ifndef OFFT_COLLISION // If large file support is not enabled (and possibly even if it is), // the type of off_t may be a typedef of a type for which we already // have a constructor. In that case, don't define one which takes an // off_t, or we get compiler errors. String::String(const off_t num) { std::ostrstream buf; buf << num << std::ends; *this = buf.str(); } # endif #else String::String(const int num) { std::stringstream buf; buf << num << std::ends; // std::string can contain a NULL byte within the counted length // - this happens here. Add a byte to the length when allocating // the buffer it's going to go into (to account for the appended // NULL), but subtract one when updating our idea of what the string // length is, since it counts the NULL byte in the stringstream's // own buffer. int l = buf.str().length(); char* data = new char[l+1]; buf >> data; *this = data; delete[] data; } String::String(const long num) { std::stringstream buf; buf << num << std::ends; int l = buf.str().length(); char* data = new char[l+1]; buf >> data; *this = data; delete[] data; } String::String(const unsigned int num) { std::stringstream buf; buf << num << std::ends; int l = buf.str().length(); char* data = new char[l+1]; buf >> data; *this = data; delete[] data; } String::String(const long unsigned num) { std::stringstream buf; buf << num << std::ends; int l = buf.str().length(); char* data = new char[l+1]; buf >> data; *this = data; delete[] data; } # ifndef OFFT_COLLISION // If large file support is not enabled (and possibly even if it is), // the type of off_t may be a typedef of a type for which we already // have a constructor. In that case, don't define one which takes an // off_t, or we get compiler errors. String::String(const off_t num) { std::stringstream buf; buf << num << std::ends; int l = buf.str().length(); char* data = new char[l+1]; buf >> data; *this = data; delete[] data; } # endif #endif void String::replaceall(const char *what, const char *with) { std::string::size_type pos = 0; size_t whatlen = strlen(what); size_t withlen = strlen(with); while ((pos = this->find(what, pos)) != std::string::npos) { // replace charactrs in original string this->replace(pos, whatlen, with); // increment search position pos += withlen; } } // string-to-off_t conversion // This is horrible, horrible code, but the best I can come up with // which will work in both 32 and 64-bit file offset modes. :( off_t String::toOffset() { if (this->length() == 0) return 0; off_t t = 0; if (sizeof(off_t) == 4) sscanf(this->c_str(), "%d", &t); else if (sizeof(off_t) == 8) sscanf(this->c_str(), "%lld", &t); return t; } // string-to-integer conversion int String::toInteger() { if (this->length() == 0) { return 0; } return (atoi(this->c_str())); } // string-to-long-int conversion long int String::toLong() { if (this->length() == 0) { return 0; } return (atol(this->c_str())); } // return integer from hex string int String::hexToInteger() { int n = 0; // position in string int m = 0; // position in digit[] to shift int count; // loop index int intValue = 0; // integer value of hex string int digit[5]; // hold values to convert while (n < 4) { if ((*this)[n]=='\0') break; if ((*this)[n] > '0' && (*this)[n] < '9' ) digit[n] = (*this)[n] & 0x0f; else if (((*this)[n] >='a' && (*this)[n] <= 'f') || ((*this)[n] >='A' && (*this)[n] <= 'F')) digit[n] = ((*this)[n] & 0x0f) + 9; else break; n++; } count = n; m = n - 1; n = 0; while(n < count) { // digit[n] is value of hex digit at position n // (m << 2) is the number of positions to shift // OR the bits into return value intValue = intValue | (digit[n] << (m << 2)); m--; n++; } return (intValue); } // case conversions void String::toLower() { unsigned int l = this->length(); char* c = new char[l + 1]; const char* d = this->c_str(); for (unsigned int i = 0; i < l; i++) { c[i] = tolower(d[i]); } *this = String(c, l); delete[] c; } void String::toUpper() { unsigned int l = this->length(); char* c = new char[l + 1]; const char* d = this->c_str(); for (unsigned int i = 0; i < l; i++) { c[i] = toupper(d[i]); } *this = String(c, l); delete[] c; } // decode %xx to individual characters (checkme: i'm sure this is duplicated elsewhere...) void String::hexDecode() { if (this->length() < 3) return; char *temp = new char[this->length() + 1]; const char *t = this->c_str(); unsigned char c; unsigned char c1; unsigned char c2; unsigned char c3; char hexval[5] = "0x"; // Initializes a "hexadecimal string" hexval[4] = '\0'; char *ptr; // pointer required by strtol unsigned int j = 0; unsigned int end = this->length() - 2; unsigned int i, k; for (i = 0; i < end;) { c1 = t[i]; c2 = t[i + 1]; c3 = t[i + 2]; if (c1 == '%' && (((c2 >= '0') && (c2 <= '9')) || ((c2 >= 'a') && (c2 <= 'f')) || ((c2 >= 'A') && (c2 <= 'F'))) && (((c3 >= '0') && (c3 <= '9')) || ((c3 >= 'a') && (c3 <= 'f')) || ((c3 >= 'A') && (c3 <= 'F')))) { hexval[2] = c2; hexval[3] = c3; c = (unsigned char) strtol(hexval, &ptr, 0); i += 3; } else { c = c1; i++; } temp[j++] = c; } k = this->length(); for (; i < k; i++) { temp[j++] = t[i]; // copy last 2 bytes if any// } temp[j] = '\0'; (*this) = String(temp, j); delete[]temp; } // does this string start with the given text? bool String::startsWith(const String& s) { if (!strncmp(this->c_str(), s.c_str(), s.length())) { return true; } return false; } // does this string end with the given text? bool String::endsWith(const String& s) { if (s.length() > this->length()) { return false; } if (!strncmp((this->c_str() + this->length() - s.length()), s.c_str(), s.length())) { return true; } return false; } // does this string start with the given text after conversion to lowercase? // (pass the search string in in lowercase; only the text being searched // is converted) bool String::startsWithLower(const String& s) { for (unsigned int i = 0; i < s.length(); i++) { if (tolower((*this)[i]) != s[i]) return false; } return true; } // find the position of the given substring within the string int String::indexOf(const char *s) { size_type i = this->find(s); if (i != std::string::npos) return i; return -1; } // does this string contain given substring? bool String::contains(const char *s) { if (indexOf(s) != -1) { return true; } return false; } // grab the part of the string that follows the first occurrence of given text String String::after(const char *bs) const { size_type i = this->find(bs); if (i == std::string::npos) return ""; return this->substr(i + strlen(bs)); } // grab the part of the string that precedes the first occurrence of given text String String::before(const char *bs) const { size_type i = this->find(bs); if (i == std::string::npos) return ""; return this->substr(0, i); } // remove characters from end/beginning void String::chop() { *this = this->substr(0, this->length() - 1); } void String::lop() { *this = this->substr(1); } // remove leading & trailing whitespace void String::removeWhiteSpace() { size_type start = this->find_first_not_of(" \t\r\n"); if (start == std::string::npos) start = 0; size_type end = this->find_last_not_of(" \t\r\n"); if (end == std::string::npos) end = this->length() - 1; *this = this->substr(start, (end - start)+1); } // remove protocol specifier void String::removePTP() { if (this->startsWith("http://") || this->startsWith("https://") || this->startsWith("ftp://")) { *this = this->after("://"); } } // limit string to given length int String::limitLength(unsigned int l) { *this = this->substr(0, l); return this->length(); } // remove repeated occurrences of given character void String::removeMultiChar(unsigned char c) { std::string temp; unsigned char t; bool wasslash = false; unsigned int l = this->length(); for (unsigned int i = 0; i < l; i++) { t = (*this)[i]; if (t != c) { // we didn't find the character - copy what we did find, // and clear repetition flag temp += t; wasslash = false; continue; } // we found the character if (wasslash) { // we found it repeated - don't copy it again continue; } // we found the character, without repetition flag set // - copy only first occurrence & set repetition flag wasslash = true; temp += t; } *this = temp; } // tidy up slashes, trailing dots, etc. in file paths void String::realPath() { if (this->length() < 3) { return; } char *temp = new char[this->length() + 1]; unsigned char b, c, d; unsigned int offset = 0, l = this->length(); for (unsigned int i = 0; i < l; i++) { b = (*this)[i]; if (b == '/') { if ((*this)[i + 1] == '/') { // ignore multiple slashes continue; } } if (b == '.') { c = (*this)[i + 1]; if (c == '\0' || c == '/') { continue; // ignore just dot } if (c == '.') { d = (*this)[i + 2]; if (d == '\0' || d == '/' || d == '\\') { if (offset > 0) { offset--; } while (offset > 0) { if (temp[--offset] == '/') { break; } if (temp[offset] == '\\') { break; } } i++; continue; } } } temp[offset++] = b; } temp[offset] = '\0'; *this = temp; delete[] temp; } // * // * // * Hashing functions // * // * String String::md5(const char *salt) { String newValue(*this); newValue += salt; return newValue.md5(); } String String::md5() { char *md5array = new char[16]; char *buf = new char[16]; int i; String ret; md5_buffer(this->c_str(), (size_t) this->length(), md5array); for (i = 0; i < 16; i++) { sprintf(buf, "%02X", (unsigned char) (md5array[i])); ret += buf; } delete[]md5array; delete[]buf; return ret; } dansguardian-2.10.1.1/src/Socket.hpp0000644001165000116500000000373011110523210014030 00000000000000// Socket class - implements BaseSocket for INET domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_SOCKET #define __HPP_SOCKET // INCLUDES #include "BaseSocket.hpp" // DECLARATIONS class Socket : public BaseSocket { friend class FDTunnel; public: // create INET socket & clear address structs Socket(); // create socket using pre-existing FD (address structs will be empty!) Socket(int fd); // create socket from pre-existing FD, storing given local & remote IPs Socket(int newfd, struct sockaddr_in myip, struct sockaddr_in peerip); // connect to given IP & port (following default constructor) int connect(const std::string& ip, int port); // bind to given port int bind(int port); // bind to given IP & port, for machines with multiple NICs int bind(const std::string& ip, int port); // accept incoming connections & return new Socket Socket* accept(); // close socket & clear address structs void reset(); // get remote IP/port std::string getPeerIP(); int getPeerSourcePort(); unsigned long int getPeerSourceAddr(); // get local IP std::string getLocalIP(); private: // local & remote addresses struct sockaddr_in my_adr; struct sockaddr_in peer_adr; }; #endif dansguardian-2.10.1.1/src/FatController.hpp0000644001165000116500000000222011111546173015365 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_FATCONTROLLER #define __HPP_FATCONTROLLER // INCLUDES #include "OptionContainer.hpp" #include "UDSocket.hpp" #include // DECLARATIONS // program main loop - pass in FD of pidfile int fc_controlit(); #endif dansguardian-2.10.1.1/src/HTTPHeader.cpp0000644001165000116500000013003711151231075014476 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 //This file contains modifications suggested and mostly provided by //Daniel Robbins 13/4/01 drobbins@gento.org //Modifications include, but not limited to, getcontenttype(), << , >> // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "HTTPHeader.hpp" #include "Socket.hpp" #include "OptionContainer.hpp" #include "FDTunnel.hpp" #include #include #include #include #include #include #include // GLOBALS extern OptionContainer o; // regexp for decoding %xx in URLs extern RegExp urldecode_re; // IMPLEMENTATION // set timeout for socket operations void HTTPHeader::setTimeout(int t) { timeout = t; } // reset header object for future use void HTTPHeader::reset() { if (dirty) { header.clear(); //postdata.reset(); postdata[0] = '\0'; postdatalen = 0; postdatachopped = false; ispostupload = false; waspersistent = false; ispersistent = false; cachedurl = ""; phost = NULL; pport = NULL; pcontentlength = NULL; pcontenttype = NULL; pproxyauthorization = NULL; pcontentdisposition = NULL; puseragent = NULL; pxforwardedfor = NULL; pcontentencoding = NULL; pproxyconnection = NULL; dirty = false; } } // * // * // * header value and type checks // * // * // grab request type (GET, HEAD etc.) String HTTPHeader::requestType() { return header.front().before(" "); } // grab return code int HTTPHeader::returnCode() { return header.front().after(" ").before(" ").toInteger(); } // grab content length off_t HTTPHeader::contentLength() { // code 304 - not modified - no content String temp(header.front().after(" ")); if (temp.startsWith("304")) return 0; if (pcontentlength != NULL) { temp = pcontentlength->after(" "); return temp.toOffset(); } // no content-length header - we don't know return -1; } // grab the auth type String HTTPHeader::getAuthType() { if (pproxyauthorization != NULL) { return pproxyauthorization->after(" ").before(" "); } return ""; } // check the request's return code to see if it's an auth required message bool HTTPHeader::authRequired() { String temp(header.front().after(" ")); if (temp.startsWith("407")) { return true; } return false; } // grab content disposition String HTTPHeader::disposition() { if (pcontentdisposition != NULL) { String filename(pcontentdisposition->after("filename").after("=")); if (filename.contains(";")) filename = filename.before(";"); filename.removeWhiteSpace(); // incase of trailing space if (filename.contains("\"")) { return filename.after("\"").before("\""); } return filename; // example format: // Content-Disposition: attachment; filename="filename.ext" // Content-Disposition: attachment; filename=filename.ext // Content-Disposition: filename="filename.ext" // 3rd format encountered from download script on realVNC's // website. notice it does not contain any semicolons! PRA 4-11-2005 } return ""; // it finds the header proposed filename } // grab the user agent String HTTPHeader::userAgent() { if (puseragent != NULL) { // chop off '/r' String result(puseragent->after(" ")); result.resize(result.length() - 1); return result; } return ""; } // grab the content type header String HTTPHeader::getContentType() { if (pcontenttype != NULL) { String mimetype(pcontenttype->after(" ")); if (mimetype.length() < 1) return "-"; unsigned char c; size_t j = 0; while (j < mimetype.length()) { c = mimetype[j]; if (c == ' ' || c == ';' || c < 32) { // remove the mimetype = mimetype.subString(0, j); // extra info not needed j = 0; } ++j; } mimetype.toLower(); return mimetype; } return "-"; } // does the given content type string match our headers? bool HTTPHeader::isContentType(const String& t) { return getContentType().startsWith(t); } // grab contents of X-Forwarded-For header // Modification based on a submitted patch by // Jimmy Myrick (jmyrick@tiger1.tiger.org) std::string HTTPHeader::getXForwardedForIP() { if (pxforwardedfor != NULL) { String line(pxforwardedfor->after(": ")); line.chop(); return std::string(line.toCharArray()); } return ""; } // check the return code to see if it's a redirection request bool HTTPHeader::isRedirection() { // The 1st line of the header for a redirection is thus: // HTTP/1.(0|1) 3xx if (header.size() < 1) { return false; } // sometimes get called b 4 read String answer(header.front().after(" ").before(" ")); if (answer[0] == '3' && answer.length() == 3) { return true; } return false; } // grab the contents of Proxy-Authorization header // returns base64-decoding of the chunk of data after the auth type string std::string HTTPHeader::getAuthData() { if (pproxyauthorization != NULL) { String line(pproxyauthorization->after(" ").after(" ")); return decodeb64(line); // it's base64 MIME encoded } return ""; } // grab raw contents of Proxy-Authorization header without decoding std::string HTTPHeader::getRawAuthData() { if (pproxyauthorization != NULL) { return pproxyauthorization->after(" ").after(" "); } return ""; } // do we have a non-identity content encoding? this means body is compressed bool HTTPHeader::isCompressed() { if (pcontentencoding != NULL) { if (pcontentencoding->indexOf("identity") != -1) { // http1.1 says this // should not be here, but not must not return false; } #ifdef DGDEBUG std::cout << "is compressed" << std::endl; #endif return true; // i.e. encoded with something other than clear } return false; } // grab content encoding header String HTTPHeader::contentEncoding() { if (pcontentencoding != NULL) { String ce(pcontentencoding->after(": ")); ce.toLower(); return ce; } return ""; // we need a default don't we? } // * // * // * header modifications // * // * // squid adds this so if more support it it may be useful one day void HTTPHeader::addXForwardedFor(const std::string &clientip) { std::string line("X-Forwarded-For: " + clientip + "\r"); header.push_back(String(line.c_str())); } // set content length header to report given lenth void HTTPHeader::setContentLength(int newlen) { if (pcontentlength != NULL) { (*pcontentlength) = "Content-Length: " + String(newlen) + "\r"; } } // set the proxy-connection header to allow persistence (or not) void HTTPHeader::makePersistent(bool persist) { if (persist) { // Only make persistent if it originally was, but now isn't. // The intention isn't to change browser behaviour, just to // un-do any connection downgrading which DG may have performed // earlier. if (waspersistent && !ispersistent) { if (pproxyconnection != NULL) { (*pproxyconnection) = pproxyconnection->before(":") + ": Keep-Alive\r"; } else { header.push_back(String("Proxy-Connection: Keep-Alive\r")); pproxyconnection = &(header.back()); } ispersistent = true; } } else { // Only downgrade to non-persistent if it isn't currently persistent. if (ispersistent) { if (pproxyconnection != NULL) { (*pproxyconnection) = pproxyconnection->before(":") + ": Close\r"; } else { header.push_back(String("Proxy-Connection: Close\r")); pproxyconnection = &(header.back()); } ispersistent = false; } } } // return a modified accept-encoding header, based on the one supplied, // but with "identity" added and only supported encodings allowed. String HTTPHeader::modifyEncodings(String e) { // There are 4 types of encoding: gzip, deflate, compress and identity // deflate is in zlib format // compress is in unix compress format // identity is uncompressed and supported by all browsers (obviously) // we do not support compress e.toLower(); String o("Accept-Encoding: identity"); #if ZLIB_VERNUM < 0x1210 #warning 'Accept-Encoding: gzip' is disabled #else if (e.contains("gzip")) { o += ",gzip"; } #endif if (e.contains("deflate")) { o += ",deflate"; } return o; } // set content length to report the given length, and strip content encoding void HTTPHeader::removeEncoding(int newlen) { if (pcontentlength != NULL) { (*pcontentlength) = "Content-Length: " + String(newlen) + "\r"; } // this may all be overkill. since we strip everything out of the outgoing // accept-encoding header that we don't support, we won't be getting anything // back again that we don't support, in theory. leave new code commented // unless it proves to be necessary further down the line. PRA 20-10-2005 if (pcontentencoding != NULL) { /*#ifdef DGDEBUG std::cout << std::endl << "Stripping Content-Encoding header" < 65535) { port = (https ? 443 : 80); } hostname = hostname.before(":"); // chop off the port bit } #ifdef DGDEBUG std::cout << "setURL: header.front() changed from: " << header.front() << std::endl; #endif if (!https) header.front() = header.front().before(" ") + " " + url + " " + header.front().after(" ").after(" "); else // Should take form of "CONNECT example.com:443 HTTP/1.0" for SSL header.front() = header.front().before(" ") + " " + hostname + ":" + String(port) + " " + header.front().after(" ").after(" "); #ifdef DGDEBUG std::cout << " to: " << header.front() << std::endl; #endif if (phost != NULL) { #ifdef DGDEBUG std::cout << "setURL: header[] line changed from: " << (*phost) << std::endl; #endif (*phost) = String("Host: ") + hostname; if (port != (https ? 443 : 80)) { (*phost) += ":"; (*phost) += String(port); } (*phost) += "\r"; #ifdef DGDEBUG std::cout << " to " << (*phost) << std::endl; #endif } if (pport != NULL) { #ifdef DGDEBUG std::cout << "setURL: header[] line changed from: " << (*pport) << std::endl; #endif (*pport) = String("Port: ") + String(port) + "\r"; #ifdef DGDEBUG std::cout << " to " << (*pport) << std::endl; #endif } // Don't just cache the URL we're sent - url() performs some other // processing, notably stripping the port part. Caching here will // bypass all that. //cachedurl = url.toCharArray(); } // Does a regexp search and replace. // urlRegExp Code originally from from Ton Gorter 2004 bool HTTPHeader::regExp(String& line, std::deque& regexp_list, std::deque& replacement_list) { RegExp *re; String replacement; String repstr; String newLine; bool linemodified = false; unsigned int i; unsigned int j, k; unsigned int s = regexp_list.size(); unsigned int matches, submatches; unsigned int match; unsigned int srcoff; unsigned int nextoffset; unsigned int matchlen; unsigned int oldlinelen; // iterate over our list of precompiled regexes for (i = 0; i < s; i++) { newLine = ""; re = &(regexp_list[i]); if (re->match(line.toCharArray())) { repstr = replacement_list[i]; matches = re->numberOfMatches(); srcoff = 0; for (j = 0; j < matches; j++) { nextoffset = re->offset(j); matchlen = re->length(j); // copy next chunk of unmodified data if (nextoffset > srcoff) { newLine += line.subString(srcoff, nextoffset - srcoff); srcoff = nextoffset; } // Count number of submatches (brackets) in replacement string for (submatches = 0; j+submatches+1 < matches; submatches++) if (re->offset(j+submatches+1) + re->length(j+submatches+1) > srcoff + matchlen) break; // \1 and $1 replacement replacement = ""; for (k = 0; k < repstr.length(); k++) { // find \1..\9 and $1..$9 and fill them in with submatched strings if ((repstr[k] == '\\' || repstr[k] == '$') && repstr[k+1] >= '1' && repstr[k+1] <= '9') { match = repstr[++k] - '0'; if (match <= submatches) { replacement += re->result(j + match).c_str(); } } else { // unescape \\ and \$, and add non-backreference characters to string if (repstr[k] == '\\' && (repstr[k+1] == '\\' || repstr[k+1] == '$')) k++; replacement += repstr.subString(k, 1); } } // copy filled in replacement string newLine += replacement; srcoff += matchlen; j += submatches; } oldlinelen = line.length(); if (srcoff < oldlinelen) { newLine += line.subString(srcoff, oldlinelen - srcoff); } #ifdef DGDEBUG std::cout << "Line modified! (" << line << " -> " << newLine << ")" << std::endl; #endif // copy newLine into line and continue with other regexes line = newLine; linemodified = true; } } return linemodified; } // Perform searches and replacements on URL bool HTTPHeader::urlRegExp(int filtergroup) { // exit immediately if list is empty if (not o.fg[filtergroup]->url_regexp_list_comp.size()) return false; #ifdef DGDEBUG std::cout << "Starting URL reg exp replace" << std::endl; #endif String newUrl(url()); if (regExp(newUrl, o.fg[filtergroup]->url_regexp_list_comp, o.fg[filtergroup]->url_regexp_list_rep)) { setURL(newUrl); return true; } return false; } // Perform searches and replacements on header lines bool HTTPHeader::headerRegExp(int filtergroup) { // exit immediately if list is empty if (not o.fg[filtergroup]->header_regexp_list_comp.size()) return false; bool result = false; for (std::deque::iterator i = header.begin(); i != header.end(); i++) { #ifdef DGDEBUG std::cout << "Starting header reg exp replace: " << *i << std::endl; #endif bool chop = false; if (i->endsWith("\r")) { i->chop(); chop = true; } result |= regExp(*i, o.fg[filtergroup]->header_regexp_list_comp, o.fg[filtergroup]->header_regexp_list_rep); if (chop) i->append("\r"); } return result; } // * // * // * detailed header checks & fixes // * // * // is a URL malformed? bool HTTPHeader::malformedURL(const String& url) { String host(url.after("://")); if (host.contains("/")) host = host.before("/"); if (host.length() < 2) { #ifdef DGDEBUG std::cout << "host len too small" << std::endl; #endif return true; } if (host.contains(":")) host = host.before(":"); if (host.contains("..") || host.endsWith(".")) { #ifdef DGDEBUG std::cout << "double dots in domain name" << std::endl; #endif return true; } int i, len; unsigned char c; len = host.length(); bool containsletter = false; for (i = 0; i < len; i++) { c = (unsigned char) host[i]; // If it contains something other than numbers, dots, or [a-fx] (hex encoded IPs), // IP obfuscation can be ruled out. if (!containsletter && (((c < '0') || (c > '9')) && (c != '.') && (c != 'x') && (c != 'X') && ((c < 'a') || (c > 'f')) && ((c < 'A') || (c > 'F')))) containsletter = true; if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != '.' && c != '-' && c != '_') { #ifdef DGDEBUG std::cout << "bad char in hostname" << std::endl; #endif return true; // only allowed letters, digits, hiphen, dots } } // no IP obfuscation going on if (containsletter) return false; #ifdef DGDEBUG else std::cout << "Checking for IP obfuscation in " << host << std::endl; #endif // Check no IP obfuscation is going on // This includes IPs encoded as a single decimal number, // fully or partly hex encoded, and octal encoded bool first = true; bool obfuscation = false; if (host.endsWith(".")) host.chop(); do { if (!first) host = host.after("."); first = false; String hostpart(host); if (host.contains(".")) hostpart = hostpart.before("."); // If any part of the host starts with a letter, any letter, // then we must have a hostname rather than an IP (obscured // or otherwise). TLDs never start with a number. if ((hostpart[0] >= 'a' && hostpart[0] <= 'z') || (hostpart[0] >= 'A' && hostpart[0] <= 'Z')) return false; // If any part of the host begins with 0, it may be hex or octal if ((hostpart[0] == '0') && (hostpart.length() > 1)) { obfuscation = true; continue; } // Also check range, for decimal obfuscation. int part = hostpart.toInteger(); if ((part < 0) || (part > 255)) obfuscation = true; } while (host.contains(".")); // If we have any obfuscated parts, and haven't proven it's a hostname, it's invalid. return obfuscation; } // is this a POST request encapsulating a file upload? bool HTTPHeader::isPostUpload(Socket &peersock) { if (header.front().toCharArray()[0] != 'P') { return false; } /*bool answer = false; int postlen = postdata.buffer_length; int i; if (postlen < 14) { // min length for there to be a match return false; } char *postdatablock = new char[postlen + 64]; // extra 64 for search try { postdata.copyToMemory(postdatablock); for (i = 0; i < postlen; i++) { // make lowercase char by char if (isupper(postdatablock[i])) { postdatablock[i] = tolower(postdatablock[i]); } } RegExp mysearch; std::string dis("content-type: "); // signifies file upload char *p = new char[32]; try { for (i = 0; i < (signed) dis.length(); i++) { p[i] = dis[i]; // copy it to the block of memory } char *pend = p + dis.length(); // pointer for search char *postdatablockend = postdatablock + postlen; // search the post data for the content type header char *res = mysearch.search(postdatablock, postdatablockend, p, pend); // if we searched all the way to the end without finding it, // there is no post upload going on; otherwise, there is if (res != postdatablockend) { answer = true; } } catch(exception & e) { }; delete[]p; } catch(exception & e) { }; delete[]postdatablock; return answer;*/ off_t cl = contentLength(); if (((cl > 0) && (cl < 14)) || (getContentType() == "application/x-www-form-urlencoded")) { #ifdef DGDEBUG std::cout << "Based on content length/type, is not POST upload!" << std::endl; #endif ispostupload = false; return false; } if (getContentType().length() > 0) { #ifdef DGDEBUG std::cout << "Based on content length/type, is POST upload!" << std::endl; #endif ispostupload = true; return true; } #ifdef DGDEBUG std::cout << "Reading a line of POST data to determine content type: "; #endif postdatalen = peersock.getLine(postdata, 14, 60, &postdatachopped); #ifdef DGDEBUG std::cout << postdata << std::endl; #endif if (postdatalen != 14) { #ifdef DGDEBUG std::cout << "Is not POST upload!" << std::endl; #endif ispostupload = false; return false; } String conttype(postdata); if (conttype.startsWithLower("content-type: ")) { #ifdef DGDEBUG std::cout << "Is POST upload!" << std::endl; #endif ispostupload = true; return true; } else { #ifdef DGDEBUG std::cout << "Is not POST upload!" << std::endl; #endif ispostupload = false; return false; } } // fix bugs in certain web servers that don't obey standards. // actually, it's us that don't obey standards - HTTP RFC says header names // are case-insensitive. - Anonymous SF Poster, 2006-02-23 void HTTPHeader::checkheader(bool allowpersistent) { // are these headers outgoing, or incoming? bool outgoing = true; if (header.front().startsWith("HT")) outgoing = false; bool first = true; for (std::deque::iterator i = header.begin(); i != header.end(); i++) { // check each line in the headers // HTTP 1.1 is persistent by default if (first) { if (i->after("HTTP/").startsWith("1.1")) { #ifdef DGDEBUG std::cout << "CheckHeader: HTTP/1.1, so assuming persistency" << std::endl; #endif waspersistent = true; ispersistent = true; } // Do not allow persistent connections on CONNECT requests - the browser thinks it has a tunnel // directly to the external server, not a connection to the proxy, so it won't be re-used in the // manner expected by DG and will result in waiting for time-outs. Bug identified by Jason Deasi. if ((*i)[0] == 'C') { #ifdef DGDEBUG std::cout << "CheckHeader: CONNECT request; disallowing persistency" << std::endl; #endif allowpersistent = false; } first = false; // force HTTP/1.0 - we don't support chunked transfer encoding, possibly amongst other things if (outgoing) (*i) = i->before(" HTTP/") + " HTTP/1.0\r"; } // index headers - try to perform the checks in the order the average browser sends the headers. // also only do the necessary checks for the header type (sent/received). else if (outgoing && (phost == NULL) && i->startsWithLower("host:")) { phost = &(*i); } // don't allow through multiple host headers else if (outgoing && (phost != NULL) && i->startsWithLower("host:")) { i->assign("X-DG-IgnoreMe: removed multiple host headers\r"); } else if (outgoing && (puseragent == NULL) && i->startsWithLower("user-agent:")) { puseragent = &(*i); } else if (outgoing && i->startsWithLower("accept-encoding:")) { (*i) = "Accept-Encoding:" + i->after(":"); (*i) = modifyEncodings(*i) + "\r"; } else if ((pcontenttype == NULL) && i->startsWithLower("content-type:")) { pcontenttype = &(*i); } else if ((pcontentlength == NULL) && i->startsWithLower("content-length:")) { pcontentlength = &(*i); } // is this ever sent outgoing? else if ((pcontentdisposition == NULL) && i->startsWithLower("content-disposition:")) { pcontentdisposition = &(*i); } else if ((!outgoing) && (pcontentencoding == NULL) && i->startsWithLower("content-encoding:")) { pcontentencoding = &(*i); } else if ((pproxyauthorization == NULL) && i->startsWithLower("proxy-authorization:")) { pproxyauthorization = &(*i); } else if ((pproxyconnection == NULL) && (i->startsWithLower("proxy-connection:") || i->startsWithLower("connection:"))) { #ifdef DGDEBUG std::cout << "CheckHeader: Found Proxy-Connection" << std::endl; #endif if (i->contains("live")) { #ifdef DGDEBUG std::cout << "CheckHeader: P-C says keep-alive" << std::endl; #endif waspersistent = true; if (!allowpersistent) { #ifdef DGDEBUG std::cout << "CheckHeader: ... but we aren't allowed to" << std::endl; #endif ispersistent = false; (*i) = i->before(":") + ": Close\r"; } else { ispersistent = true; } } else { #ifdef DGDEBUG std::cout << "CheckHeader: P-C says close" << std::endl; #endif ispersistent = false; waspersistent = false; } pproxyconnection = &(*i); } else if (outgoing && (pxforwardedfor == NULL) && i->startsWithLower("x-forwarded-for:")) { pxforwardedfor = &(*i); } // this one's non-standard, so check for it last else if (outgoing && (pport = NULL) && i->startsWithLower("port:")) { pport = &(*i); } #ifdef DGDEBUG std::cout << (*i) << std::endl; #endif } #ifdef DGDEBUG std::cout << "CheckHeader flags: AP=" << allowpersistent << " IP=" << ispersistent << " PPC=" << !(pproxyconnection == NULL) << std::endl; #endif // if a request was HTTP 1.1 and there was no proxy-connection header, we may need to add one if ((!allowpersistent) && ispersistent) { // we should only be in this state if pproxyconnection == NULL (otherwise ispersistent will have been falsified earlier) #ifdef DGDEBUG std::cout << "CheckHeader: Adding our own Proxy-Connection: Close" << std::endl; #endif header.push_back("Proxy-Connection: Close\r"); pproxyconnection = &(header.back()); ispersistent = false; } else if (allowpersistent && ispersistent && (pproxyconnection == NULL)) { #ifdef DGDEBUG std::cout << "CheckHeader: Adding our own Proxy-Connection: Keep-Alive" << std::endl; #endif // we should only be in this state if HTTP 1.1, persistency allowed, but persistency not explicitly asked for header.push_back("Proxy-Connection: Keep-Alive\r"); pproxyconnection = &(header.back()); } // Normalise request headers (fix host, port, first line of header, etc. to all be consistent) if (outgoing) { String newurl(url(true)); setURL(newurl); } } // A request may be in the form: // GET http://foo.bar:80/ HTML/1.0 (if :80 is omitted 80 is assumed) // or: // GET / HTML/1.0 // Host: foo.bar (optional header in HTTP/1.0, but like HTTP/1.1, we require it!) // Port: 80 (not a standard header; do any clients send it?) // or: // CONNECT foo.bar:443 HTTP/1.1 // So we need to handle all 3 String HTTPHeader::url(bool withport) { // Version of URL *with* port is not cached, // as vast majority of our code doesn't like // port numbers in URLs. if (cachedurl.length() > 0 && !withport) return cachedurl; port = 80; bool https = false; String hostname; String answer(header.front().after(" ")); answer.removeMultiChar(' '); if (answer.after(" ").startsWith("HTTP/")) { answer = answer.before(" HTTP/"); } else { answer = answer.before(" http/"); // just in case! } if (requestType() == "CONNECT") { https = true; port = 443; if (!answer.startsWith("https://")) { answer = "https://" + answer; } } if (pport != NULL) { port = pport->after(" ").toInteger(); if (port == 0 || port > 65535) port = (https ? 443 : 80); } if (answer.length()) { if (answer[0] == '/') { // must be the latter above if (phost != NULL) { hostname = phost->after(" "); hostname.removeWhiteSpace(); if (hostname.contains(":")) { port = hostname.after(":").toInteger(); if (port == 0 || port > 65535) { port = (https ? 443 : 80); } hostname = hostname.before(":"); } while (hostname.endsWith(".")) hostname.chop(); if (withport && (port != (https ? 443 : 80))) hostname += ":" + String(port); hostname = "http://" + hostname; answer = hostname + answer; } // Squid doesn't like requests in this format. Work around the fact. header.front() = requestType() + " " + answer + " HTTP/" + header.front().after(" HTTP/"); } else { // must be in the form GET http://foo.bar:80/ HTML/1.0 if (!answer.after("://").contains("/")) { answer += "/"; // needed later on so correct host is extracted } String protocol(answer.before("://")); hostname = answer.after("://"); String url(hostname.after("/")); url.removeWhiteSpace(); // remove rubbish like ^M and blanks if (url.length() > 0) { url = "/" + url; } hostname = hostname.before("/"); // extra / was added 4 here if (hostname.contains("@")) { // Contains a username:password combo hostname = hostname.after("@"); } if (hostname.contains(":")) { port = hostname.after(":").toInteger(); if (port == 0 || port > 65535) { port = (https ? 443 : 80); } hostname = hostname.before(":"); // chop off the port bit } while (hostname.endsWith(".")) hostname.chop(); if (withport && (port != (https ? 443 : 80))) hostname += ":" + String(port); answer = protocol + "://" + hostname + url; } } if (answer.endsWith("//")) { answer.chop(); } #ifdef DGDEBUG std::cout << "from header url:" << answer << std::endl; #endif // Don't include port numbers in the URL in the cached version. // Most of the code only copes with URLs *without* port specifiers. if (!withport) cachedurl = answer.toCharArray(); return answer; } // * // * // * Bypass URL/Cookie funcs // * // * // chop the GBYPASS or GIBYPASS variable out of a bypass URL // This function ASSUMES that you really know what you are doing // Do NOT run this function unless you know that the URL contains a valid bypass code // Ernest W Lessenger void HTTPHeader::chopBypass(String url, bool infectionbypass) { if (url.contains(infectionbypass ? "GIBYPASS=" : "GBYPASS=")) { if (url.contains(infectionbypass ? "?GIBYPASS=" : "?GBYPASS=")) { String bypass(url.after(infectionbypass ? "?GIBYPASS=" : "?GBYPASS=")); header.front() = header.front().before(infectionbypass ? "?GIBYPASS=" : "?GBYPASS=") + header.front().after(bypass.toCharArray()); } else { String bypass(url.after(infectionbypass ? "&GIBYPASS=" : "&GBYPASS=")); header.front() = header.front().before(infectionbypass ? "&GIBYPASS=" : "&GBYPASS=") + header.front().after(bypass.toCharArray()); } } cachedurl = ""; } // same for scan bypass void HTTPHeader::chopScanBypass(String url) { if (url.contains("GSBYPASS=")) { if (url.contains("?GSBYPASS=")) { String bypass(url.after("?GSBYPASS=")); header.front() = header.front().before("?GSBYPASS=") + header.front().after(bypass.toCharArray()); } else { String bypass(url.after("&GSBYPASS=")); header.front() = header.front().before("&GSBYPASS=") + header.front().after(bypass.toCharArray()); } } cachedurl = ""; } // I'm not proud of this... --Ernest String HTTPHeader::getCookie(const char *cookie) { String line; // TODO - do away with loop here somehow, or otherwise speed it up? for (std::deque::iterator i = header.begin(); i != header.end(); i++) { if (i->startsWithLower("cookie:")) { line = i->after(": "); if (line.contains(cookie)) { // We know we have the cookie line = line.after(cookie); line.lop(); // Get rid of the '=' if (line.contains(";")) { line = line.before(";"); } } // break; // Technically there should be only one Cookie: header, but... } } line.removeWhiteSpace(); #ifdef DGDEBUG std::cout << "Found GBYPASS cookie:" << line << std::endl; #endif return line; } // add cookie with given name & value to outgoing headers void HTTPHeader::setCookie(const char *cookie, const char *domain, const char *value) { String line("Set-Cookie: "); line += cookie; line += "="; line += value; line += "; path=/; domain=."; line += domain; line += "\r"; header.push_back(line); #ifdef DGDEBUG std::cout << "Setting cookie:" << line << std::endl; #endif // no expiry specified so ends with the browser session } // is this a temporary filter bypass cookie? bool HTTPHeader::isBypassCookie(String url, const char *magic, const char *clientip) { String cookie(getCookie("GBYPASS")); if (!cookie.length()) { #ifdef DGDEBUG std::cout << "No bypass cookie" << std::endl; #endif return false; } String cookiehash(cookie.subString(0, 32)); String cookietime(cookie.after(cookiehash.toCharArray())); String mymagic(magic); mymagic += clientip; mymagic += cookietime; bool matched = false; while(url.contains(".")) { String hashed(url.md5(mymagic.toCharArray())); if (hashed == cookiehash) { matched = true; break; } url = url.after("."); } if (not matched) { #ifdef DGDEBUG std::cout << "Cookie GBYPASS not match" << std::endl; #endif return false; } time_t timen = time(NULL); time_t timeu = cookietime.toLong(); if (timeu < timen) { #ifdef DGDEBUG std::cout << "Cookie GBYPASS expired: " << timeu << " " << timen << std::endl; #endif return false; } return true; } // is this a temporary filter bypass URL? int HTTPHeader::isBypassURL(String * url, const char *magic, const char *clientip, bool *isvirusbypass) { if ((*url).length() <= 45) return false; // Too short, can't be a bypass // check to see if this is a bypass URL, and which type it is bool filterbypass = false; bool virusbypass = false; if ((isvirusbypass == NULL) && ((*url).contains("GBYPASS="))) { filterbypass = true; } else if ((isvirusbypass != NULL) && (*url).contains("GIBYPASS=")) { virusbypass = true; } if (!(filterbypass || virusbypass)) return 0; #ifdef DGDEBUG std::cout << "URL " << (filterbypass ? "GBYPASS" : "GIBYPASS") << " found checking..." << std::endl; #endif String url_left((*url).before(filterbypass ? "GBYPASS=" : "GIBYPASS=")); url_left.chop(); // remove the ? or & String url_right((*url).after(filterbypass ? "GBYPASS=" : "GIBYPASS=")); String url_hash(url_right.subString(0, 32)); String url_time(url_right.after(url_hash.toCharArray())); #ifdef DGDEBUG std::cout << "URL: " << url_left << ", HASH: " << url_hash << ", TIME: " << url_time << std::endl; #endif String mymagic(magic); mymagic += clientip; mymagic += url_time; String hashed(url_left.md5(mymagic.toCharArray())); if (hashed != url_hash) { #ifdef DGDEBUG std::cout << "URL " << (filterbypass ? "GBYPASS" : "GIBYPASS") << " hash mismatch" << std::endl; #endif return 0; } time_t timen = time(NULL); time_t timeu = url_time.toLong(); if (timeu < 1) { #ifdef DGDEBUG std::cout << "URL " << (filterbypass ? "GBYPASS" : "GIBYPASS") << " bad time value" << std::endl; #endif return 1; // bad time value } if (timeu < timen) { // expired key #ifdef DGDEBUG std::cout << "URL " << (filterbypass ? "GBYPASS" : "GIBYPASS") << " expired" << std::endl; #endif return 1; // denotes expired but there } #ifdef DGDEBUG std::cout << "URL " << (filterbypass ? "GBYPASS" : "GIBYPASS") << " not expired" << std::endl; #endif if (virusbypass) (*isvirusbypass) = true; return (int) timeu; } // is this a scan bypass URL? i.e. a "magic" URL for retrieving a previously scanned file bool HTTPHeader::isScanBypassURL(String * url, const char *magic, const char *clientip) { if ((*url).length() <= 45) return false; // Too short, can't be a bypass if (!(*url).contains("GSBYPASS=")) { // If this is not a bypass url return false; } #ifdef DGDEBUG std::cout << "URL GSBYPASS found checking..." << std::endl; #endif String url_left((*url).before("GSBYPASS=")); url_left.chop(); // remove the ? or & String url_right((*url).after("GSBYPASS=")); String url_hash(url_right.subString(0, 32)); #ifdef DGDEBUG std::cout << "URL: " << url_left << ", HASH: " << url_hash << std::endl; #endif // format is: // GSBYPASS=hash(ip+url+tempfilename+mime+disposition+secret) // &N=tempfilename&M=mimetype&D=dispos String tempfilename(url_right.after("&N=")); String tempfilemime(tempfilename.after("&M=")); String tempfiledis(tempfilemime.after("&D=")); tempfilemime = tempfilemime.before("&D="); tempfilename = tempfilename.before("&M="); String tohash(clientip + url_left + tempfilename + tempfilemime + tempfiledis + magic); String hashed(tohash.md5()); #ifdef DGDEBUG std::cout << "checking hash: " << clientip << " " << url_left << " " << tempfilename << " " << " " << tempfilemime << " " << tempfiledis << " " << magic << " " << hashed << std::endl; #endif if (hashed == url_hash) { return true; } #ifdef DGDEBUG std::cout << "URL GSBYPASS HASH mismatch" << std::endl; #endif return false; } // * // * // * URL and Base64 decoding funcs // * // * // URL decoding (%xx) // uses regex pre-compiled on startup String HTTPHeader::decode(const String &s, bool decodeAll) { if (s.length() < 3) { return s; } #ifdef DGDEBUG std::cout << "decoding url" << std::endl; #endif if (!urldecode_re.match(s.c_str())) { return s; } // exit if not found #ifdef DGDEBUG std::cout << "matches:" << urldecode_re.numberOfMatches() << std::endl; std::cout << "removing %XX" << std::endl; #endif int match; int offset; int pos = 0; int size = s.length(); String result; String n; for (match = 0; match < urldecode_re.numberOfMatches(); match++) { offset = urldecode_re.offset(match); if (offset > pos) { result += s.subString(pos, offset - pos); } n = urldecode_re.result(match).c_str(); n.lop(); // remove % result += hexToChar(n, decodeAll); #ifdef DGDEBUG std::cout << "encoded: " << urldecode_re.result(match) << " decoded: " << hexToChar(n) << " string so far: " << result << std::endl; #endif pos = offset + 3; } if (size > pos) { result += s.subString(pos, size - pos); } else { n = "%" + n; } return result; } // turn %xx back into original character String HTTPHeader::hexToChar(const String &n, bool all) { if (n.length() < 2) { return String(n); } static char buf[2]; unsigned int a, b; unsigned char c; a = n[0]; b = n[1]; if (a >= 'a' && a <= 'f') { a -= 87; } else if (a >= 'A' && a <= 'F') { a -= 55; } else if (a >= '0' && a <= '9') { a -= 48; } else { return String("%") + n; } if (b >= 'a' && b <= 'f') { b -= 87; } else if (b >= 'A' && b <= 'F') { b -= 55; } else if (b >= '0' && b <= '9') { b -= 48; } else { return String("%") + n; } c = a * 16 + b; if (all || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-')) { buf[0] = c; buf[1] = '\0'; return String(buf); } else { return String("%") + n; } } // decode a line of base64 std::string HTTPHeader::decodeb64(const String& line) { // decode a block of b64 MIME long four = 0; int d; std::string result; int len = line.length() - 4; for (int i = 0; i < len; i += 4) { four = 0; d = decode1b64(line[i + 0]); four = four | d; d = decode1b64(line[i + 1]); four = (four << 6) | d; d = decode1b64(line[i + 2]); four = (four << 6) | d; d = decode1b64(line[i + 3]); four = (four << 6) | d; d = (four & 0xFF0000) >> 16; result += (char) d; d = (four & 0xFF00) >> 8; result += (char) d; d = four & 0xFF; result += (char) d; } return result; } // decode an individual base64 character int HTTPHeader::decode1b64(char c) { unsigned char i = '\0'; switch (c) { case '+': i = 62; break; case '/': i = 63; break; case '=': i = 0; break; default: // must be A-Z, a-z or 0-9 i = '9' - c; if (i > 0x3F) { // under 9 i = 'Z' - c; if (i > 0x3F) { // over Z i = 'z' - c; if (i > 0x3F) { // over z so invalid i = 0x80; // so set the high bit } else { // a-z i = c - 71; } } else { // A-Z i = c - 65; } } else { // 0-9 i = c + 4; } break; } return (int) i; } // * // * // * network send/receive funcs // * // * // send headers out over the given socket // "reconnect" flag gives permission to reconnect to the socket on write error // - this allows us to re-open the proxy connection on pconns if squid's end has // timed out but the client's end hasn't. not much use with NTLM, since squid // will throw a 407 and restart negotiation, but works well with basic & others. void HTTPHeader::out(Socket * peersock, Socket * sock, int sendflag, bool reconnect) throw(std::exception) { String l; // for amalgamating to avoid conflict with the Nagel algorithm if (sendflag == __DGHEADER_SENDALL || sendflag == __DGHEADER_SENDFIRSTLINE) { if (header.size() > 0) { l = header.front() + "\n"; #ifdef DGDEBUG std::cout << "headertoclient:" << l << std::endl; #endif // first reconnect loop - send first line while (true) { if (!(*sock).writeToSocket(l.toCharArray(), l.length(), 0, timeout)) { // reconnect & try again if we've been told to if (reconnect) { // don't try more than once #ifdef DGDEBUG std::cout << "Proxy connection broken (1); trying to re-establish..." << std::endl; syslog(LOG_ERR,"Proxy connection broken (1); trying to re-establish..."); #endif reconnect = false; sock->reset(); int rc = sock->connect(o.proxy_ip, o.proxy_port); if (rc) throw std::exception(); continue; } throw std::exception(); } // if we got here, we succeeded, so break the reconnect loop break; } } if (sendflag == __DGHEADER_SENDFIRSTLINE) { return; } } l = ""; for (std::deque::iterator i = header.begin() + 1; i != header.end(); i++) { l += (*i) + "\n"; } l += "\r\n"; #ifdef DGDEBUG std::cout << "headertoclient:" << l << std::endl; #endif // second reconnect loop while (true) { // send header to the output stream // need exception for bad write if (!(*sock).writeToSocket(l.toCharArray(), l.length(), 0, timeout)) { // reconnect & try again if we've been told to if (reconnect) { // don't try more than once #ifdef DGDEBUG std::cout << "Proxy connection broken (2); trying to re-establish..." << std::endl; syslog(LOG_ERR,"Proxy connection broken (2); trying to re-establish..."); #endif reconnect = false; sock->reset(); int rc = sock->connect(o.proxy_ip, o.proxy_port); if (rc) throw std::exception(); // include the first line on the retry l = header.front() + "\n" + l; continue; } throw std::exception(); } // if we got here, we succeeded, so break the reconnect loop break; } if ((!requestType().startsWith("HTTP")) && (pcontentlength != NULL)) { if (postdatalen > 0) { #ifdef DGDEBUG std::cout << "Sending initial POST data chunk" << std::endl; #endif // Re-add the chopped off \n, if necessary if (postdatachopped) { #ifdef DGDEBUG std::cout << "Re-adding newline to POST data (postdatalen " << postdatalen << ")" << std::endl; #endif postdata[postdatalen-1] = '\n'; postdata[postdatalen] = '\0'; } sock->writeToSockete(postdata, postdatalen, 0, timeout); } #ifdef DGDEBUG std::cout << "Opening tunnel for remainder of POST data" << std::endl; #endif FDTunnel fdt; off_t remaining = contentLength() - postdatalen; if (remaining < 0) throw std::runtime_error("No POST data left to send!?"); fdt.tunnel(*peersock, *sock, false, remaining, true); } } // discard remainder of POST data void HTTPHeader::discard(Socket *sock) { static char fred[4096]; off_t cl = contentLength() - postdatalen; int rc; while (cl > 0) { rc = sock->readFromSocket(fred, ((cl > 4096) ? 4096 : cl), 0, timeout, false); if (rc > 0) cl -= rc; else break; } } void HTTPHeader::in(Socket * sock, bool allowpersistent, bool honour_reloadconfig) { if (dirty) reset(); dirty = true; // the RFCs don't specify a max header line length so this should be // dynamic really. Pointed out (well reminded actually) by Daniel Robbins char buff[8192]; // setup a buffer to hold the incomming HTTP line String line; // temp store to hold the line after processing line = "----"; // so we get past the first while bool firsttime = true; bool discard = false; while (line.length() > 3 || discard) { // loop until the stream is // failed or we get to the end of the header (a line by itself) // get a line of header from the stream // on the first time round the loop, honour the reloadconfig flag if desired // - this lets us break when waiting for the next request on a pconn, but not // during receipt of a request in progress. (*sock).getLine(buff, 8192, timeout, firsttime ? honour_reloadconfig : false); // getline will throw an exception if there is an error which will // only be caught by HandleConnection() line = buff; // convert the line to a String // ignore crap left in buffer from old pconns (in particular, the IE "extra CRLF after POST" bug) discard = false; if (not (firsttime && line.length() <= 3)) header.push_back(line); // stick the line in the deque that holds the header else { discard = true; #ifdef DGDEBUG std::cout << "Discarding unwanted bytes at head of request (pconn closed or IE multipart POST bug)" << std::endl; #endif } firsttime = false; } header.pop_back(); // remove the final blank line of a header if (header.size() == 0) throw std::exception(); checkheader(allowpersistent); // sort out a few bits in the header } dansguardian-2.10.1.1/src/ListContainer.hpp0000644001165000116500000001266111173344201015373 00000000000000// ListContainer class - for item and phrase lists //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@/ jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_LISTCONTAINER #define __HPP_LISTCONTAINER // INLCUDES #include #include #include #include #include "String.hpp" // DECLARATIONS // time limit information struct TimeLimit { unsigned int sthour, stmin, endhour, endmin; String days, timetag; }; time_t getFileDate(const char *filename); size_t getFileLength(const char *filename); class ListContainer { public: std::vector combilist; int refcount; bool parent; time_t filedate; bool used; String bannedpfile; String exceptionpfile; String weightedpfile; time_t bannedpfiledate; time_t exceptionpfiledate; time_t weightedpfiledate; String sourcefile; // used for non-phrase lists only String category; String lastcategory; std::vector morelists; // has to be non private as reg exp compiler needs to access these ListContainer(); ~ListContainer(); void reset(); bool readPhraseList(const char *filename, bool isexception, int catindex = -1, int timeindex = -1, bool incref = true); bool readItemList(const char *filename, bool startswith, int filters); bool inList(const char *string); bool inListEndsWith(const char *string); bool inListStartsWith(const char *string); char *findInList(const char *string); char *findEndsWith(const char *string); char *findStartsWith(const char *string); char *findStartsWithPartial(const char *string); int getListLength() { return items; } std::string getItemAtInt(int index); int getWeightAt(unsigned int index); int getTypeAt(unsigned int index); void doSort(const bool startsWith); bool createCacheFile(); bool makeGraph(bool fqs); bool previousUseItem(const char *filename, bool startswith, int filters); bool upToDate(); String getListCategoryAt(int index, int *catindex = NULL); String getListCategoryAtD(int index); void graphSearch(std::map >& result, char *doc, off_t len); bool isNow(int index = -1); bool checkTimeAt(unsigned int index); bool checkTimeAtD(int index); bool blanketblock; bool blanket_ip_block; bool blanketsslblock; bool blanketssl_ip_block; private: bool sourceisexception; bool sourcestartswith; int sourcefilters; char *data; // Format of the data is each entry has 64 int values with format of: // [letter][last letter flag][num links][from phrase][link0][link1]... int *realgraphdata; int current_graphdata_size; #ifdef DGDEBUG bool prolificroot; int secondmaxchildnodes; #endif int maxchildnodes; int graphitems; std::vector slowgraph; size_t data_length; size_t data_memory; long int items; bool isSW; bool issorted; bool graphused; std::vector list; std::vector lengthlist; std::vector weight; std::vector itemtype; // 0=banned, 1=weighted, -1=exception bool force_quick_search; //time-limited lists - only items (sites, URLs), not phrases TimeLimit listtimelimit; bool istimelimited; //categorised lists - both phrases & items std::vector listcategory; std::vector categoryindex; // set of time limits for phrase lists std::vector timelimitindex; std::vector timelimits; bool readAnotherItemList(const char *filename, bool startswith, int filters); void readPhraseListHelper(String line, bool isexception, int catindex, int timeindex); void readPhraseListHelper2(String phrase, int type, int weighting, int catindex, int timeindex); bool addToItemListPhrase(const char *s, size_t len, int type, int weighting, bool combi, int catindex, int timeindex); void graphSizeSort(int l, int r, std::deque *sizelist); void graphAdd(String s, const int inx, int item); int graphFindBranches(unsigned int pos); void graphCopyNodePhrases(unsigned int pos); int bmsearch(char *file, off_t fl, const std::string& s); bool readProcessedItemList(const char *filename, bool startswith, int filters); void addToItemList(const char *s, size_t len); int greaterThanEWF(const char *a, const char *b); // full match int greaterThanEW(const char *a, const char *b); // partial ends with int greaterThanSWF(const char *a, const char *b); // full match int greaterThanSW(const char *a, const char *b); // partial starts with int search(int (ListContainer::*comparitor)(const char* a, const char* b), int a, int s, const char *p); bool isCacheFileNewer(const char *string); void increaseMemoryBy(size_t bytes); //categorised & time-limited lists support bool readTimeTag(String * tag, TimeLimit& tl); int getCategoryIndex(String * lcat); }; #endif dansguardian-2.10.1.1/src/RegExp.cpp0000644001165000116500000001542111110523210013765 00000000000000// RegExp class - search text using regular expressions //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@// jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "RegExp.hpp" #include #include // constructor - set defaults RegExp::RegExp():imatched(false), wascompiled(false) { } // copy constructor RegExp::RegExp(const RegExp & r) { results.clear(); offsets.clear(); lengths.clear(); unsigned int i; for (i = 0; i < r.results.size(); i++) { results.push_back(r.results[i]); } for (i = 0; i < r.offsets.size(); i++) { offsets.push_back(r.offsets[i]); } for (i = 0; i < r.lengths.size(); i++) { lengths.push_back(r.lengths[i]); } imatched = r.imatched; wascompiled = r.wascompiled; searchstring = r.searchstring; if (wascompiled == true) { #ifdef HAVE_PCRE if (regcomp(®, searchstring.c_str(), REG_ICASE | REG_EXTENDED | REG_DOTALL) != 0 ) { #else if (regcomp(®, searchstring.c_str(), REG_ICASE | REG_EXTENDED) != 0 ) { #endif regfree(®); imatched = false; wascompiled = false; } } } // destructor - free regex if compiled RegExp::~RegExp() { if (wascompiled) { regfree(®); } } // return the i'th match result std::string RegExp::result(int i) { if (i >= (signed) results.size() || i < 0) { // reality check return ""; // maybe exception? } return results[i]; } // get the position of the i'th match result in the overall text unsigned int RegExp::offset(int i) { if (i >= (signed) offsets.size() || i < 0) { // reality check return 0; // maybe exception? } return offsets[i]; } // get the length of the i'th match unsigned int RegExp::length(int i) { if (i >= (signed) lengths.size() || i < 0) { // reality check return 0; // maybe exception? } return lengths[i]; } // how many matches did the last run generate? int RegExp::numberOfMatches() { int i = (signed) results.size(); return i; } // did it, in fact, generate any? bool RegExp::matched() { return imatched; // regexp matches only - not search/replace } // compile the given regular expression bool RegExp::comp(const char *exp) { if (wascompiled) { regfree(®); wascompiled = false; } results.clear(); offsets.clear(); lengths.clear(); imatched = false; #ifdef DGDEBUG std::cout << "Compiling " << exp << std::endl; #endif #ifdef HAVE_PCRE #ifdef DGDEBUG std::cout << "...with PCRE " << std::endl; #endif if (regcomp(®, exp, REG_ICASE | REG_EXTENDED | REG_DOTALL) != 0) { // compile regex #else #ifdef DGDEBUG std::cout << "...without PCRE " << std::endl; #endif if (regcomp(®, exp, REG_ICASE | REG_EXTENDED) != 0) { #endif regfree(®); return false; // need exception? } wascompiled = true; searchstring = exp; return true; } // match the given text against the pre-compiled expression bool RegExp::match(const char *text) { if (!wascompiled) { return false; // need exception? } char *pos = (char *) text; int i; results.clear(); offsets.clear(); lengths.clear(); imatched = false; regmatch_t *pmatch = new regmatch_t[reg.re_nsub + 1]; // to hold result if (!pmatch) { // if it failed delete[]pmatch; imatched = false; return false; // exception? } if (regexec(®, pos, reg.re_nsub + 1, pmatch, 0)) { // run regex delete[]pmatch; imatched = false; // #ifdef DGDEBUG // std::cout << "no match for:" << searchstring << std::endl; // #endif return false; // if no match } size_t matchlen; char *submatch; unsigned int largestoffset; int error = 0; while (error == 0) { largestoffset = 0; for (i = 0; i <= (signed) reg.re_nsub; i++) { if (pmatch[i].rm_so != -1) { matchlen = pmatch[i].rm_eo - pmatch[i].rm_so; submatch = new char[matchlen + 1]; strncpy(submatch, pos + pmatch[i].rm_so, matchlen); submatch[matchlen] = '\0'; results.push_back(std::string(submatch)); offsets.push_back(pmatch[i].rm_so + (pos - text)); lengths.push_back(matchlen); delete[]submatch; if ((pmatch[i].rm_so + matchlen) > largestoffset) { largestoffset = pmatch[i].rm_so + matchlen; } } } if (largestoffset > 0) { pos += largestoffset; error = regexec(®, pos, reg.re_nsub + 1, pmatch, REG_NOTBOL); } else { error = -1; } } imatched = true; delete[]pmatch; #ifdef DGDEBUG std::cout << "match(s) for:" << searchstring << std::endl; #endif return true; // match(s) found } // My own version of STL::search() which seems to be 5-6 times faster char *RegExp::search(char *file, char *fileend, char *phrase, char *phraseend) { int j, l; // counters int p; // to hold precalcuated value for speed bool match; // flag int qsBc[256]; // Quick Search Boyer Moore shift table (256 alphabet) char *k; // pointer used in matching int pl = phraseend - phrase; // phrase length int fl = (int) (fileend - file) - pl; // file length that could match if (fl < pl) return fileend; // reality checking if (pl > 126) return fileend; // reality checking // For speed we append the phrase to the end of the memory block so it // is always found, thus eliminating some checking. This is possible as // we know an extra 127 bytes have been provided by NaughtyFilter.cpp // and also the OptionContainer does not allow phrase lengths greater // than 126 chars for (j = 0; j < pl; j++) { fileend[j] = phrase[j]; } // Next we need to make the Quick Search Boyer Moore shift table p = pl + 1; for (j = 0; j < 256; j++) { // Preprocessing qsBc[j] = p; } for (j = 0; j < pl; j++) { // Preprocessing qsBc[(unsigned char) phrase[j]] = pl - j; } // Now do the searching! for (j = 0;;) { k = file + j; match = true; for (l = 0; l < pl; l++) { // quiv, but faster, memcmp() if (k[l] != phrase[l]) { match = false; break; } } if (match) { return (j + file); // match found at offset j (but could be the // copy put at fileend) } j += qsBc[(unsigned char) file[j + pl]]; // shift } return fileend; // should never get here as it should always match } dansguardian-2.10.1.1/src/authplugins/0000777001165000116500000000000011212164550014526 500000000000000dansguardian-2.10.1.1/src/authplugins/proxy.cpp0000644001165000116500000000350211110523210016314 00000000000000// Proxy auth plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../Auth.hpp" #include // DECLARATIONS // class name is relevant! class proxyinstance:public AuthPlugin { public: proxyinstance(ConfigVar &definition):AuthPlugin(definition) { needs_proxy_query = true; }; int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin AuthPlugin *proxycreate(ConfigVar & definition) { return new proxyinstance(definition); } // end of Class factory // proxy auth header username extraction int proxyinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) { // don't match for non-basic auth types String t(h.getAuthType()); t.toLower(); if (t != "basic") return DGAUTH_NOMATCH; // extract username string = h.getAuthData(); if (string.length() > 0) { string.resize(string.find_first_of(':')); return DGAUTH_OK; } return DGAUTH_NOMATCH; } dansguardian-2.10.1.1/src/authplugins/ip.cpp0000644001165000116500000002572311110523210015554 00000000000000// IP (range, subnet) auth plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../Auth.hpp" #include "../RegExp.hpp" #include "../OptionContainer.hpp" #include #include #include #include #include // GLOBALS extern bool is_daemonised; extern OptionContainer o; // DECLARATIONS // structs linking subnets and IP ranges to filter groups struct subnetstruct { uint32_t maskedaddr; uint32_t mask; int group; }; struct rangestruct { uint32_t startaddr; uint32_t endaddr; int group; }; // class for linking IPs to filter groups, complete with comparison operators // allowing standard C++ sort to work class ip { public: ip(uint32_t a, int g) { addr = a; group = g; }; uint32_t addr; int group; int operator < (const ip &a) const { return addr < a.addr; }; int operator < (const uint32_t &a) const { return addr < a; }; int operator == (const uint32_t &a) const { return a == addr; }; }; // class name is relevant! class ipinstance:public AuthPlugin { public: // keep credentials for the whole of a connection - IP isn't going to change. // not quite true - what about downstream proxy with x-forwarded-for? ipinstance(ConfigVar &definition):AuthPlugin(definition) { if (!o.use_xforwardedfor) is_connection_based = true; }; int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); int determineGroup(std::string &user, int &fg); int init(void* args); int quit(); private: std::vector iplist; std::list ipsubnetlist; std::list iprangelist; int readIPMelangeList(const char *filename); int searchList(int a, int s, const uint32_t &ip); int inList(const uint32_t &ip); int inSubnet(const uint32_t &ip); int inRange(const uint32_t &ip); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin AuthPlugin *ipcreate(ConfigVar & definition) { return new ipinstance(definition); } // end of Class factory // // // Standard plugin funcs // // // plugin quit - clear IP, subnet & range lists int ipinstance::quit() { iplist.clear(); ipsubnetlist.clear(); iprangelist.clear(); return 0; } // plugin init - read in ip melange list int ipinstance::init(void* args) { String fname(cv["ipgroups"]); if (fname.length() > 0) { return readIPMelangeList(fname.toCharArray()); } else { if (!is_daemonised) std::cerr << "No ipgroups file defined in IP auth plugin config" << std::endl; syslog(LOG_ERR, "No ipgroups file defined in IP auth plugin config"); return -1; } } // IP-based filter group determination // never actually return NOUSER from this, because we don't actually look in the filtergroupslist. // NOUSER stops ConnectionHandler from querying subsequent plugins. int ipinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) { // we don't get usernames out of this plugin, just a filter group // for now, use the IP as the username if (o.use_xforwardedfor) { // grab the X-Forwarded-For IP if available string = h.getXForwardedForIP(); // otherwise, grab the IP directly from the client connection if (string.length() == 0) string = peercon.getPeerIP(); } else { string = peercon.getPeerIP(); } return DGAUTH_OK; } int ipinstance::determineGroup(std::string &user, int &fg) { struct in_addr sin; inet_aton(user.c_str(), &sin); uint32_t addr = ntohl(sin.s_addr); // check straight IPs, subnets, and ranges fg = inList(addr); if (fg >= 0) { #ifdef DGDEBUG std::cout << "Matched IP " << user << " to straight IP list" << std::endl; #endif return DGAUTH_OK; } fg = inSubnet(addr); if (fg >= 0) { #ifdef DGDEBUG std::cout << "Matched IP " << user << " to subnet" << std::endl; #endif return DGAUTH_OK; } fg = inRange(addr); if (fg >= 0) { #ifdef DGDEBUG std::cout << "Matched IP " << user << " to range" << std::endl; #endif return DGAUTH_OK; } #ifdef DGDEBUG std::cout << "Matched IP " << user << " to nothing" << std::endl; #endif return DGAUTH_NOMATCH; } // // // IP list functions (straight match, range match, subnet match) // // // search for IP in list & return filter group on success, -1 on failure int ipinstance::inList(const uint32_t &ip) { if (iplist.size() > 0) { return searchList(0, iplist.size(), ip); } return -1; } // binary search list for given IP & return filter group, or -1 on failure int ipinstance::searchList(int a, int s, const uint32_t &ip) { if (a > s) return -1; int m = (a + s) / 2; if (iplist[m] == ip) return iplist[m].group; if (iplist[m] < ip) return searchList(m + 1, s, ip); if (a == s) return -1; return searchList(a, m - 1, ip); } // search subnet list for given IP & return filter group or -1 int ipinstance::inSubnet(const uint32_t &ip) { for(std::list::const_iterator i = ipsubnetlist.begin(); i != ipsubnetlist.end(); ++i) { if (i->maskedaddr == (ip & i->mask)) { return i->group; } } return -1; } // search range list for a range containing given IP & return filter group or -1 int ipinstance::inRange(const uint32_t &ip) { for(std::list::const_iterator i = iprangelist.begin(); i != iprangelist.end(); ++i) { if ((ip >= i->startaddr) && (ip <= i->endaddr)) { return i->group; } } return -1; } // read in a list linking IPs, subnets & IP ranges to filter groups // return 0 for success, -1 for failure, 1 for warning int ipinstance::readIPMelangeList(const char *filename) { // load in the list file std::ifstream input ( filename ); if (!input) { if (!is_daemonised) { std::cerr << "Error reading file (does it exist?): " << filename << std::endl; } syslog(LOG_ERR, "%s%s","Error reading file (does it exist?): ",filename); return -1; } // compile regexps for determining whether a list entry is an IP, a subnet (IP + mask), or a range RegExp matchIP, matchSubnet, matchRange; #ifdef HAVE_PCRE matchIP.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); matchSubnet.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); matchRange.comp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}-\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); #else matchIP.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); matchSubnet.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); matchRange.comp("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}-[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"); #endif // read in the file String line; String key, value; char buffer[ 2048 ]; bool warn = false; while (input) { if (!input.getline(buffer, sizeof( buffer ))) { break; } // ignore comments if (buffer[0] == '#') continue; // ignore blank lines if (strlen(buffer) < 10) continue; line = buffer; // split into key & value if (line.contains("=")) { key = line.before("="); key.removeWhiteSpace(); value = line.after("filter"); } else { if (!is_daemonised) std::cerr << "No filter group given; entry " << line << " in " << filename << std::endl; syslog(LOG_ERR, "No filter group given; entry %s in %s", line.toCharArray(), filename); warn = true; continue; } #ifdef DGDEBUG std::cout << "key: " << key << std::endl; std::cout << "value: " << value.toInteger() << std::endl; #endif if ((value.toInteger() < 1) || (value.toInteger() > o.filter_groups)) { if (!is_daemonised) std::cerr << "Filter group out of range; entry " << line << " in " << filename << std::endl; syslog(LOG_ERR, "Filter group out of range; entry %s in %s", line.toCharArray(), filename); warn = true; continue; } // store the IP address (numerically, not as a string) and filter group in either the IP list, subnet list or range list if (matchIP.match(key.toCharArray())) { struct in_addr address; if (inet_aton(key.toCharArray(), &address)) { iplist.push_back(ip(ntohl(address.s_addr),value.toInteger()-1)); } } else if (matchSubnet.match(key.toCharArray())) { struct in_addr address; struct in_addr addressmask; String subnet(key.before("/")); String mask(key.after("/")); if (inet_aton(subnet.toCharArray(), &address) && inet_aton(mask.toCharArray(), &addressmask)) { subnetstruct s; int addr = ntohl(address.s_addr); s.mask = ntohl(addressmask.s_addr); // pre-mask the address for quick comparison s.maskedaddr = addr & s.mask; s.group = value.toInteger()-1; ipsubnetlist.push_back(s); } } else if (matchRange.match(key.toCharArray())) { struct in_addr addressstart; struct in_addr addressend; String start(key.before("-")); String end(key.after("-")); if (inet_aton(start.toCharArray(), &addressstart) && inet_aton(end.toCharArray(), &addressend)) { rangestruct r; r.startaddr = ntohl(addressstart.s_addr); r.endaddr = ntohl(addressend.s_addr); r.group = value.toInteger()-1; iprangelist.push_back(r); } } // hmmm. the key didn't match any of our regular expressions. output message & return a warning value. else { if (!is_daemonised) std::cerr << "Entry " << line << " in " << filename << " was not recognised as an IP address, subnet or range" << std::endl; syslog(LOG_ERR, "Entry %s in %s was not recognised as an IP address, subnet or range", line.toCharArray(), filename); warn = true; } } input.close(); #ifdef DGDEBUG std::cout << "starting sort" << std::endl; #endif std::sort(iplist.begin(), iplist.end()); #ifdef DGDEBUG std::cout << "sort complete" << std::endl; std::cout << "ip list dump:" << std::endl; std::vector::const_iterator i = iplist.begin(); while (i != iplist.end()) { std::cout << "IP: " << i->addr << " Group: " << i->group << std::endl; ++i; } std::cout << "subnet list dump:" << std::endl; std::list::const_iterator j = ipsubnetlist.begin(); while (j != ipsubnetlist.end()) { std::cout << "Masked IP: " << j->maskedaddr << " Mask: " << j->mask << " Group: " << j->group << std::endl; ++j; } std::cout << "range list dump:" << std::endl; std::list::const_iterator k = iprangelist.begin(); while (k != iprangelist.end()) { std::cout << "Start IP: " << k->startaddr << " End IP: " << k->endaddr << " Group: " << k->group << std::endl; ++k; } #endif // return either warning or success return warn ? 1 : 0; } dansguardian-2.10.1.1/src/authplugins/ident.cpp0000644001165000116500000000700211110523210016235 00000000000000// Ident server auth plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../Auth.hpp" #include "../OptionContainer.hpp" #include // GLOBALS extern OptionContainer o; // DECLARATIONS // class name is relevant! class identinstance:public AuthPlugin { public: identinstance(ConfigVar &definition):AuthPlugin(definition) {}; int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin AuthPlugin *identcreate(ConfigVar & definition) { return new identinstance(definition); } // end of Class factory // ident server username extraction // checkme: needs better error reporting int identinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) { std::string clientip; if (o.use_xforwardedfor) { // grab the X-Forwarded-For IP if available clientip = h.getXForwardedForIP(); // otherwise, grab the IP directly from the client connection if (clientip.length() == 0) clientip = peercon.getPeerIP(); } else { clientip = peercon.getPeerIP(); } int clientport = peercon.getPeerSourcePort(); #ifdef DGDEBUG std::cout << "Connecting to: " << clientip << std::endl; std::cout << "to ask about: " << clientport << std::endl; #endif Socket iq; iq.setTimeout(5); int rc = iq.connect(clientip.c_str(), 113); // ident port if (rc) { #ifdef DGDEBUG std::cerr << "Error connecting to obtain ident from: " << clientip << std::endl; #endif return DGAUTH_NOMATCH; } #ifdef DGDEBUG std::cout << "Connected to:" << clientip << std::endl; #endif std::string request; request = String(clientport).toCharArray(); request += ", "; request += String(o.filter_port).toCharArray(); request += "\r\n"; #ifdef DGDEBUG std::cout << "About to send:" << request << std::endl; #endif if (!iq.writeToSocket((char *) request.c_str(), request.length(), 0, 5)) { #ifdef DGDEBUG std::cerr << "Error writing to ident connection to: " << clientip << std::endl; #endif iq.close(); // close conection to client return -1; } #ifdef DGDEBUG std::cout << "wrote ident request to:" << clientip << std::endl; #endif char buff[8192]; try { iq.getLine(buff, 8192, 5); } catch(std::exception & e) { return -2; } String temp; temp = buff; // convert to String #ifdef DGDEBUG std::cout << "got ident reply: " << temp << " from: " << clientip << std::endl; #endif iq.close(); // close conection to client temp = temp.after(":"); if (!temp.before(":").contains("USERID")) { return -3; } temp = temp.after(":"); temp = temp.after(":"); temp.removeWhiteSpace(); if (temp.length() > 0) { string = temp.toCharArray(); return DGAUTH_OK; } return DGAUTH_NOMATCH; } dansguardian-2.10.1.1/src/authplugins/digest.cpp0000644001165000116500000000366511110523210016424 00000000000000// Digest auth plugin // Based on contribution by Darryl Sutherland //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../Auth.hpp" #include // DECLARATIONS // class name is relevant! class digestinstance:public AuthPlugin { public: digestinstance(ConfigVar &definition):AuthPlugin(definition) {}; int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); }; // IMPLEMENTATION // class factory code *MUST* be included in every plugin AuthPlugin *digestcreate(ConfigVar & definition) { return new digestinstance(definition); } // end of Class factory // proxy auth header username extraction int digestinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) { // don't match for non-digest auth types String t = h.getAuthType(); t.toLower(); if (t != "digest") return DGAUTH_NOMATCH; // extract username string = h.getRawAuthData(); if (string.length() > 0) { String temp(string); temp = temp.after("username=\""); temp = temp.before("\""); string = temp; return DGAUTH_OK; } return DGAUTH_NOMATCH; } dansguardian-2.10.1.1/src/authplugins/ntlm.cpp0000644001165000116500000002013611110523210016107 00000000000000// NTLM auth plugin //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "../Auth.hpp" #include "../FDTunnel.hpp" #include "../OptionContainer.hpp" #include #include // DEFINES extern OptionContainer o; // NTLM username grabbing needs to be independent of endianness #ifdef HAVE_BYTESWAP_H # include # define bswap16(x) bswap_16(x) # define bswap32(x) bswap_32(x) #else # ifndef bswap16 # define bswap16(x) (((((u_int16_t)x) >> 8) & 0xff) | ((((u_int16_t)x) & 0xff) << 8)) # endif # ifndef bswap32 # define bswap32(x) (((((u_int32_t)x) & 0xff000000) >> 24) | ((((u_int32_t)x) & 0x00ff0000) >> 8) | \ ((((u_int32_t)x) & 0x0000ff00) << 8) | ((((u_int32_t)x) & 0x000000ff) << 24)) # endif #endif #ifdef WORDS_BIGENDIAN # define SSWAP(x) (bswap16((x))) # define WSWAP(x) (bswap32((x))) #else # define SSWAP(x) (x) # define WSWAP(x) (x) #endif // DECLARATIONS // class name is relevant! class ntlminstance:public AuthPlugin { public: // keep credentials for all requests on a given persistent connection; // NTLM proxy auth is designed to be used in this manner and won't re-send credentials. ntlminstance(ConfigVar &definition):AuthPlugin(definition) { is_connection_based = true; needs_proxy_query = true; }; int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); }; // things need to be on byte boundaries here #pragma pack(1) struct strhdr { int16_t len; int16_t maxlen; int32_t offset; }; struct ntlmhdr { char signature[8]; // literally NTLMSSP\0 int32_t type; // 1, 2 or 3, auth resposes are type 3. }; // this struct is only valid if h.type == 3 // as we only evesdrop to get userid dont care about type 1 and 2 messages struct ntlm_auth { ntlmhdr h; strhdr lmresponse; // LANMAN challenge response strhdr ntresponse; // NT challenge response strhdr domain; // Domain to authenticate against strhdr user; // Username (only thing we care about atm.) strhdr workstation; // Workstation name strhdr sessionkey; // Session key for server's use int32_t flags; // Request flags char payload[256 * 6]; // String data - enough for everything at 255 chars // but packet does not need to be that big }; // union so load data into buffer and the byte aligned struct gets // filled in. union ntlm_authenticate { ntlm_auth a; char buf[sizeof(ntlm_auth)]; }; #pragma pack() // "template adaptor" for iconv - basically, let G++ do the hard work of // figuring out whether or not the second parameter is const for us ;) template inline size_t local_iconv_adaptor (size_t (*iconv_func)(iconv_t, T, size_t *, char**,size_t*), iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { return iconv_func (cd, (T)inbuf, inbytesleft, outbuf, outbytesleft); } // IMPLEMENTATION // class factory code *MUST* be included in every plugin AuthPlugin *ntlmcreate(ConfigVar & definition) { return new ntlminstance(definition); } // end of Class factory // ntlm auth header username extraction - also lets connection persist long enough to complete NTLM negotiation int ntlminstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) { FDTunnel fdt; String at(h.getAuthType()); if (at != "NTLM") { // if no auth currently underway, then... if (at.length() == 0) { // allow the initial request through so the client will get the proxy's initial auth required response. // advertise persistent connections so that parent proxy will agree to advertise NTLM support. #ifdef DGDEBUG std::cout << "No auth negotiation currently in progress - making initial request persistent so that proxy will advertise NTLM" << std::endl; #endif h.makePersistent(); } return DGAUTH_NOMATCH; } #ifdef DGDEBUG std::cout << "NTLM - sending step 1" << std::endl; #endif if (o.forwarded_for) { std::string clientip; if (o.use_xforwardedfor) { // grab the X-Forwarded-For IP if available clientip = h.getXForwardedForIP(); // otherwise, grab the IP directly from the client connection if (clientip.length() == 0) clientip = peercon.getPeerIP(); } else { clientip = peercon.getPeerIP(); } h.addXForwardedFor(clientip); // add squid-like entry } h.makePersistent(); h.out(&peercon, &proxycon, __DGHEADER_SENDALL); #ifdef DGDEBUG std::cout << "NTLM - receiving step 2" << std::endl; #endif h.in(&proxycon, true); if (h.authRequired()) { #ifdef DGDEBUG std::cout << "NTLM - sending step 2" << std::endl; #endif h.out(NULL, &peercon, __DGHEADER_SENDALL); if (h.contentLength() != -1) fdt.tunnel(proxycon, peercon, false, h.contentLength(), true); #ifdef DGDEBUG std::cout << "NTLM - receiving step 3" << std::endl; #endif h.in(&peercon, true); #ifdef DGDEBUG std::cout << "NTLM - decoding type 3 message" << std::endl; #endif std::string message(h.getAuthData()); ntlm_authenticate auth; ntlm_auth *a = &(auth.a); static char username[256]; // fixed size static char username2[256]; char* inptr = username; char* outptr = username2; size_t l,o; // copy the NTLM message into the union's buffer, simultaneously filling in the struct if ((message.length() > sizeof(ntlm_auth)) || (message.length() < offsetof(ntlm_auth, payload))) { syslog(LOG_ERR, "NTLM - Invalid message of length %zd, message was: %s", message.length(), message.c_str()); #ifdef DGDEBUG std::cerr << "NTLM - Invalid message of length " << message.length() << ", message was: " << message << std::endl; #endif return -3; } memcpy((void *)auth.buf, (const void *)message.c_str(), message.length()); // verify that the message is indeed a type 3 if (strcmp("NTLMSSP",a->h.signature) == 0 && WSWAP(a->h.type) == 3) { // grab the length & offset of the username within the message // cope with the possibility we are a different byte order to Windows l = SSWAP(a->user.len); o = WSWAP(a->user.offset); if ((l > 0) && (o >= 0) && (o + l) <= sizeof(a->payload) && (l <= 254)) { // everything is in range // note offsets are from start of packet - not the start of the payload area memcpy((void *)username, (const void *)&(auth.buf[o]),l); username[l] = '\0'; // check flags - we may need to convert from UTF-16 to something more sensible int f = WSWAP(a->flags); if (f & WSWAP(0x0001)) { iconv_t ic = iconv_open("UTF-8", "UTF-16LE"); if (ic == (iconv_t)-1) { syslog(LOG_ERR, "NTLM - Cannot initialise conversion from UTF-16LE to UTF-8: %s", strerror(errno)); #ifdef DGDEBUG std::cerr << "NTLM - Cannot initialise conversion from UTF-16LE to UTF-8: " << strerror(errno) << std::endl; #endif iconv_close(ic); return -2; } size_t l2 = 256; local_iconv_adaptor(iconv, ic, &inptr, &l, &outptr, &l2); iconv_close(ic); username2[256 - l2] = '\0'; #ifdef DGDEBUG std::cout << "NTLM - got username (converted from UTF-16LE) " << username2 << std::endl; #endif string = username2; } else { #ifdef DGDEBUG std::cout << "NTLM - got username " << username << std::endl; #endif string = username; } return DGAUTH_OK; } } return DGAUTH_NOMATCH; } else { #ifdef DGDEBUG for (unsigned int i = 0; i < h.header.size(); i++) std::cout << h.header[i] << std::endl; #endif return -1; } } dansguardian-2.10.1.1/src/NaughtyFilter.hpp0000644001165000116500000000543611134076164015413 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_NAUGHTYFILTER #define __HPP_NAUGHTYFILTER // INCLUDES #include "String.hpp" #include "OptionContainer.hpp" #include "DataBuffer.hpp" // DECLARATIONS class NaughtyFilter { public: // should the content be blocked? bool isItNaughty; // should the content bypass any further filtering? bool isException; // should the browser use the categories string or the displaycategories string? // (related to category list thresholding) bool usedisplaycats; int filtergroup; // the reason for banning, what to say about it in the logs, and the // categories under which banning has taken place std::string whatIsNaughty; std::string whatIsNaughtyLog; std::string whatIsNaughtyCategories; std::string whatIsNaughtyDisplayCategories; NaughtyFilter(); void reset(); void checkme(DataBuffer * body, String &url, String &domain); // highest positive (or lowest negative) weighting out of // both phrase filtering passes (smart/raw) int naughtiness; private: // check the banned, weighted & exception lists // pass in both URL & domain to activate embedded URL checking // (this is made optional in this manner because it's pointless // trying to look for links etc. in "smart" filtering mode, i.e. // after HTML has been removed.) void checkphrase(char *file, off_t l, String *url = NULL, String *domain = NULL); // check PICS ratings void checkPICS(char *file); void checkPICSrating(std::string label); void checkPICSratingSafeSurf(String r); void checkPICSratingevaluWEB(String r); void checkPICSratingCyberNOT(String r); void checkPICSratingRSAC(String r); void checkPICSratingICRA(String r); void checkPICSratingWeburbia(String r); void checkPICSratingVancouver(String r); // new Korean stuff void checkPICSratingICEC(String r); void checkPICSratingSafeNet(String r); void checkPICSagainstoption(String s, const char *l, int opt, std::string m); }; #endif dansguardian-2.10.1.1/src/DynamicIPList.cpp0000644001165000116500000000732311110523210015246 00000000000000// DynamicIPList - maintains a sorted list of IP addresses, for checking & // limiting the number of concurrent proxy users. //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "DynamicIPList.hpp" #include #include #include #include #include #ifdef DGDEBUG #include #endif // IMPLEMENTATION // constructor - store our options & allocate our lists DynamicIPList::DynamicIPList(int maxitems, int maxitemage): data(new unsigned long int[maxitems]), datatime(new unsigned long int[maxitems]), size(maxitems), items(0), maxage(maxitemage) { } // delete the memory block when the class is destryed DynamicIPList::~DynamicIPList() { delete[] data; delete[] datatime; } // store the timestamp for the given entry, used to determine age during purge void DynamicIPList::stamp(unsigned int pos) { datatime[pos] = time(NULL); } // binary search for the given item int DynamicIPList::search(int a, int s, unsigned long int ip) { if (a > s) return (-1 - a); int m = (a + s) / 2; unsigned long int i = data[m]; if (ip == i) return m; if (ip < i) return search(m + 1, s, ip); if (a == s) return (-1 - a); return search(a, m - 1, ip); } // remove entries older then maxage void DynamicIPList::purgeOldEntries() { if (items < 1) return; unsigned long int timenow = time(NULL); for(int i = 0; i < items; i++) { if ((timenow - datatime[i]) > (unsigned)maxage) { data[i] = 0; } } empties(); } // search for given item in list // -ve if not found 0-(pos + 1) is where it would go // 0 to size if found int DynamicIPList::posInList(unsigned long int ip) { #ifdef DGDEBUG std::cout << "****** ip cache table ******" << std::endl; std::cout << "items: " << items << std::endl; int d; for(d = 0; d < items; d++) { std::cout << data[d] << std::endl; } std::cout << "****** ip cache table ******" << std::endl; #endif if (items == 0) { return -1; } return search(0, items - 1, ip); } // return whether or not given IP is in/could be added to list // (i.e. returns false if list already full & this IP's not in it) bool DynamicIPList::inList(unsigned long int ip) { // is item already in list? int pos = posInList(ip); if (pos > -1) { stamp(pos); return true; } // is list full? if (items >= size) { return false; } // list isn't full, and IP not already there, so add it pos = 0 - pos - 1; int i; for (i = items; i > pos; i--) { data[i] = data[i - 1]; datatime[i] = datatime[i - 1]; } data[pos] = ip; stamp(pos); items++; return true; } // shuffle the list to remove gaps left by a purge void DynamicIPList::empties() { int decrement = 0; unsigned long int t; int i; if (data[0] == 0) { decrement = 1; } for (i = 1; i < items; i++) { t = data[i]; if (t == 0) { decrement++; } else { if (decrement > 0) { data[i - decrement] = t; datatime[i - decrement] = datatime[i]; } } } items -= decrement; } dansguardian-2.10.1.1/src/ConnectionHandler.hpp0000644001165000116500000001023411110523210016172 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_CONNECTIONHANDLER #define __HPP_CONNECTIONHANDLER // INCLUDES #include #include #include "OptionContainer.hpp" #include "Socket.hpp" #include "HTTPHeader.hpp" #include "NaughtyFilter.hpp" // DECLARATIONS // check the URL cache to see if we've already flagged an address as clean bool wasClean(String &url, const int fg); // add a known clean URL to the cache void addToClean(String &url, const int fg); // the ConnectionHandler class - handles filtering, scanning, and blocking of // data passed between a client and the external proxy. class ConnectionHandler { public: ConnectionHandler():clienthost(NULL) {}; ~ConnectionHandler() { delete clienthost; }; // pass data between proxy and client, filtering as we go. void handleConnection(Socket &peerconn, String &ip); private: std::string *clienthost; bool matchedip; // write a log entry containing the given data (if required) void doLog(std::string &who, std::string &from, String &where, unsigned int &port, std::string &what, String &how, off_t &size, std::string *cat, bool isnaughty, bool isexception, bool istext, struct timeval *thestart, bool cachehit, int code, std::string &mimetype, bool wasinfected, bool wasscanned, int naughtiness, int filtergroup, HTTPHeader* reqheader, bool contentmodified = false, bool urlmodified = false, bool headermodified = false); // perform URL encoding on a string std::string miniURLEncode(const char *s); // when using IP address counting - have we got any remaining free IPs? bool gotIPs(std::string ipstr); // check the request header is OK (client host/user/IP allowed to browse, site not banned, upload not too big) void requestChecks(HTTPHeader *header, NaughtyFilter *checkme, String *urld, std::string *clientip, std::string *clientuser, int filtergroup, bool &isbanneduser, bool &isbannedip); // strip the URL down to just the IP/hostname, then do an isIPHostname on the result bool isIPHostnameStrip(String url); // show the relevant banned page depending upon the report level settings, request type, etc. bool denyAccess(Socket *peerconn, Socket *proxysock, HTTPHeader *header, HTTPHeader *docheader, String *url, NaughtyFilter *checkme, std::string *clientuser, std::string *clientip, int filtergroup, bool ispostblock, int headersent, bool wasinfected, bool scanerror); // create temporary ban bypass URLs/cookies String hashedURL(String *url, int filtergroup, std::string *clientip, bool infectionbypass); String hashedCookie(String *url, int filtergroup, std::string *clientip, int bypasstimestamp); // do content scanning (AV filtering) and naughty filtering void contentFilter(HTTPHeader *docheader, HTTPHeader *header, DataBuffer *docbody, Socket *proxysock, Socket *peerconn, int *headersent, bool *pausedtoobig, off_t *docsize, NaughtyFilter *checkme, bool runav, bool wasclean, int filtergroup, std::deque *sendtoscanner, std::string *clientuser, std::string *clientip, bool *wasinfected, bool *wasscanned, bool isbypass, String &url, String &domain, bool *scanerror, bool &contentmodified, String *csmessage); // send a file to the client - used during bypass of blocked downloads off_t sendFile(Socket *peerconn, String & filename, String & filemime, String & filedis, String &url); }; #endif dansguardian-2.10.1.1/src/ListManager.cpp0000644001165000116500000001273511173344174015031 00000000000000// ListManager - contains the ListContainers for all item and phrase lists, and can create new ones //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@/ jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "ListManager.hpp" #include #include #include // GLOBALS extern bool is_daemonised; // IMPLEMENTATION ListManager::~ListManager() { for (unsigned int i = 0; i < l.size(); i++) { if (l[i] != NULL) { delete l[i]; l[i] = NULL; } } } // find an unused list in our collection of lists int ListManager::findNULL() { for (unsigned int i = 0; i < l.size(); i++) { if (l[i] == NULL) { #ifdef DGDEBUG std::cout << "found free list:" << i << std::endl; #endif return (signed) i; } } return -1; } // delete all lists with zero reference count void ListManager::garbageCollect() { for (unsigned int i = 0; i < l.size(); i++) { if (l[i] != NULL) { if ((*l[i]).refcount < 1) { #ifdef DGDEBUG std::cout << "deleting zero ref list: " << i << " " << l[i]->refcount << std::endl; #endif delete l[i]; l[i] = NULL; } } } } void ListManager::deRefList(size_t i) { l[i]->refcount--; #ifdef DGDEBUG std::cout << "de-referencing list ref: " << i << ", refcount: " << l[i]->refcount << " (" << l[i]->sourcefile << ")" << std::endl; #endif for (size_t j = 0; j < l[i]->morelists.size(); ++j) deRefList(l[i]->morelists[j]); } void ListManager::refList(size_t i) { l[i]->refcount++; #ifdef DGDEBUG std::cout << "referencing list ref: " << i << ", refcount: " << l[i]->refcount << " (" << l[i]->sourcefile << ")" << std::endl; #endif for (size_t j = 0; j < l[i]->morelists.size(); ++j) refList(l[i]->morelists[j]); } // load the given list, or increase refcount on list if it's already been loaded. int ListManager::newItemList(const char *filename, bool startswith, int filters, bool parent) { for (size_t i = 0; i < l.size(); i++) { if (l[i] == NULL) { continue; } if ((*l[i]).previousUseItem(filename, startswith, filters)) { // this upToDate check also checks all .Included files if ((*l[i]).upToDate()) { #ifdef DGDEBUG std::cout << "Using previous item: " << i << " " << filename << std::endl; #endif refList(i); return i; } } } // find an empty list slot, create a new listcontainer, and load the list int free = findNULL(); if (free > -1) { l[free] = new ListContainer; } else { #ifdef DGDEBUG std::cout << "pushing back for new list" << std::endl; #endif l.push_back(new ListContainer); free = l.size() - 1; } (*l[free]).parent = parent; if (!(*l[free]).readItemList(filename, startswith, filters)) { delete l[free]; l[free] = NULL; return -1; } return free; } // create a new phrase list. check dates on top-level list files to see if a reload is necessary. // note: unlike above, doesn't automatically call readPhraseList. // pass in exception, banned, and weighted phrase lists all at once. int ListManager::newPhraseList(const char *exception, const char *banned, const char *weighted) { time_t bannedpfiledate = getFileDate(banned); time_t exceptionpfiledate = getFileDate(exception); time_t weightedpfiledate = getFileDate(weighted); for (size_t i = 0; i < l.size(); i++) { if (l[i] == NULL) { continue; } if ((*l[i]).exceptionpfile == String(exception) && (*l[i]).bannedpfile == String(banned) && (*l[i]).weightedpfile == String(weighted)) { if (bannedpfiledate <= (*l[i]).bannedpfiledate && exceptionpfiledate <= (*l[i]).exceptionpfiledate && weightedpfiledate <= (*l[i]).weightedpfiledate) { // Known limitation - only weighted, exception, banned phrase // list checked for changes - not the included files. // //need to check all files that were included for phrase list //so when phrases read in in list container it needs to store //all the file names and if a single one has changed needs a //complete regenerate #ifdef DGDEBUG std::cout << "Using previous phrase: " << exception << " - " << banned << " - " << weighted << std::endl; #endif refList(i); return i; } } } int free = findNULL(); if (free > -1) { l[(unsigned) free] = new ListContainer; } else { l.push_back(new ListContainer); free = l.size() - 1; } (*l[(unsigned) free]).parent = true; // all phrase lists are parent as // there are no sub lists (*l[(unsigned) free]).bannedpfiledate = bannedpfiledate; (*l[(unsigned) free]).exceptionpfiledate = exceptionpfiledate; (*l[(unsigned) free]).weightedpfiledate = weightedpfiledate; (*l[(unsigned) free]).exceptionpfile = exception; (*l[(unsigned) free]).bannedpfile = banned; (*l[(unsigned) free]).weightedpfile = weighted; return (unsigned) free; } dansguardian-2.10.1.1/src/DataBuffer.cpp0000644001165000116500000003736611110523210014612 00000000000000//Please refer to http://dansguardian.org/?page=copyright //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "HTTPHeader.hpp" #include "OptionContainer.hpp" #include #include #include #include #include #include #include #include #include #include // DEFINES #define __DGHEADER_SENDALL 0 #define __DGHEADER_SENDFIRSTLINE 1 #define __DGHEADER_SENDREST 2 // GLOBALS extern OptionContainer o; // IMPLEMENTATION DataBuffer::DataBuffer():data(new char[1]), buffer_length(0), compresseddata(NULL), compressed_buffer_length(0), tempfilesize(0), dontsendbody(false), tempfilefd(-1), timeout(20), bytesalreadysent(0), preservetemp(false) { data[0] = '\0'; } DataBuffer::DataBuffer(const void* indata, off_t length):data(new char[length]), buffer_length(length), compresseddata(NULL), compressed_buffer_length(0), tempfilesize(0), dontsendbody(false), tempfilefd(-1), timeout(20), bytesalreadysent(0), preservetemp(false) { memcpy(data, indata, length); } void DataBuffer::reset() { delete[]data; data = new char[1]; data[0] = '\0'; delete[]compresseddata; compresseddata = NULL; buffer_length = 0; compressed_buffer_length = 0; if (tempfilefd > -1) { close(tempfilefd); if (!preservetemp) { unlink(tempfilepath.toCharArray()); } tempfilefd = -1; tempfilesize = 0; } bytesalreadysent = 0; dontsendbody = false; preservetemp = false; decompress = ""; } // delete the memory block when the class is destroyed DataBuffer::~DataBuffer() { delete[]data; if (compresseddata != NULL) { delete[]compresseddata; compresseddata = NULL; } if (tempfilefd > -1) { close(tempfilefd); if (!preservetemp) { unlink(tempfilepath.toCharArray()); } tempfilefd = -1; tempfilesize = 0; } } // swap back to a compressed version of the data, if one exits // also delete uncompressed version // if body was decompressed but not modified, this can save bandwidth void DataBuffer::swapbacktocompressed() { if (compresseddata != NULL && compressed_buffer_length > 0) { delete[]data; buffer_length = compressed_buffer_length; data = compresseddata; compresseddata = NULL; compressed_buffer_length = 0; } } // a much more efficient reader that does not assume the contents of // the buffer gets filled thus reducing memcpy()ing and new()ing int DataBuffer::bufferReadFromSocket(Socket * sock, char *buffer, int size, int sockettimeout) { int pos = 0; int rc; while (pos < size) { rc = sock->readFromSocket(&buffer[pos], size - pos, 0, sockettimeout); if (rc < 1) { // none recieved or an error if (pos > 0) { return pos; // some was recieved previous into buffer } return rc; // just return with the return code } pos += rc; } return size; // full buffer } // a much more efficient reader that does not assume the contents of // the buffer gets filled thus reducing memcpy()ing and new()ing. // in addition to the actual socket timeout, used for each individual read, this version // incorporates a "global" timeout within which all reads must complete. int DataBuffer::bufferReadFromSocket(Socket * sock, char *buffer, int size, int sockettimeout, int timeout) { int pos = 0; int rc; struct timeval starttime; struct timeval nowadays; gettimeofday(&starttime, NULL); while (pos < size) { rc = sock->readFromSocket(&buffer[pos], size - pos, 0, sockettimeout, false); if (rc < 1) { // none recieved or an error if (pos > 0) { return pos; // some was recieved previous into buffer } return rc; // just return with the return code } pos += rc; gettimeofday(&nowadays, NULL); if (nowadays.tv_sec - starttime.tv_sec > timeout) { #ifdef DGDEBUG std::cout << "buffered socket read more than timeout" << std::endl; #endif return pos; // just return how much got so far then } } return size; // full buffer } // make a temp file and return its FD. only currently used in DM plugins. int DataBuffer::getTempFileFD() { if (tempfilefd > -1) { return tempfilefd; } tempfilepath = o.download_dir.c_str(); tempfilepath += "/tfXXXXXX"; char *tempfilepatharray = new char[tempfilepath.length() + 1]; strcpy(tempfilepatharray, tempfilepath.toCharArray()); if ((tempfilefd = mkstemp(tempfilepatharray)) < 0) { #ifdef DGDEBUG std::cerr << "error creating temp " << tempfilepath << ": " << strerror(errno) << std::endl; #endif syslog(LOG_ERR, "Could not create temp file to store download for scanning: %s", strerror(errno)); tempfilefd = -1; tempfilepath = ""; } else { tempfilepath = tempfilepatharray; } delete[]tempfilepatharray; return tempfilefd; } // check the client's user agent, see if we have a DM plugin compatible with it, and use it to download the body of the given request bool DataBuffer::in(Socket * sock, Socket * peersock, HTTPHeader * requestheader, HTTPHeader * docheader, bool runav, int *headersent) { //Socket *sock = where to read from //Socket *peersock = browser to send stuff to for keeping it alive //HTTPHeader *requestheader = header client used to request //HTTPHeader *docheader = header used for sending first line of reply //bool runav = to determine if limit is av or not //int *headersent = to use to send the first line of header if needed // or to mark that the header has already been sent // so we know if we only partially downloaded from // squid so later, if allowed, we can send the rest bool toobig = false; // match request to download manager so browsers potentially can have a prettier version // and software updates, stream clients, etc. can have a compatible version. int rc = 0; # ifdef DGDEBUG int j = 0; #endif for (std::deque::iterator i = o.dmplugins_begin; i != o.dmplugins_end; i++) { if ((i + 1) == o.dmplugins_end) { #ifdef DGDEBUG std::cerr << "Got to final download manager so defaulting to always match." << std::endl; #endif dm_plugin = (DMPlugin*)(*i); rc = dm_plugin->in(this, sock, peersock, requestheader, docheader, runav, headersent, &toobig); break; } else { if (((DMPlugin*)(*i))->willHandle(requestheader, docheader)) { #ifdef DGDEBUG std::cerr << "Matching download manager number: " << j << std::endl; #endif dm_plugin = (DMPlugin*)(*i); rc = dm_plugin->in(this, sock, peersock, requestheader, docheader, runav, headersent, &toobig); break; } } #ifdef DGDEBUG j++; #endif } // we should check rc and log on error/warn // note for later - Tue 16th November 2004 return toobig; } // send the request body to the client after having been handled by a DM plugin void DataBuffer::out(Socket * sock) throw(std::exception) { if (dontsendbody) { #ifdef DGDEBUG std::cout << "dontsendbody true; not sending" << std::endl; #endif return; } (*sock).readyForOutput(timeout); // exceptions on timeout or error if (tempfilefd > -1) { // must have been too big for ram so stream from disk in blocks #ifdef DGDEBUG std::cout << "Sending " << tempfilesize - bytesalreadysent << " bytes from temp file (" << bytesalreadysent << " already sent)" << std::endl; #endif off_t sent = bytesalreadysent; int rc; lseek(tempfilefd, bytesalreadysent, SEEK_SET); while (sent < tempfilesize) { rc = readEINTR(tempfilefd, data, buffer_length); #ifdef DGDEBUG std::cout << "reading temp file rc:" << rc << std::endl; #endif if (rc < 0) { #ifdef DGDEBUG std::cout << "error reading temp file so throwing exception" << std::endl; #endif throw std::exception(); } if (rc == 0) { #ifdef DGDEBUG std::cout << "got zero bytes reading temp file" << std::endl; #endif break; // should never happen } // as it's cached to disk the buffer must be reasonably big if (!(*sock).writeToSocket(data, rc, 0, timeout)) { throw std::exception(); } sent += rc; #ifdef DGDEBUG std::cout << "total sent from temp:" << sent << std::endl; #endif } close(tempfilefd); tempfilefd = -1; tempfilesize = 0; unlink(tempfilepath.toCharArray()); } else { #ifdef DGDEBUG std::cout << "Sending " << buffer_length - bytesalreadysent << " bytes from RAM (" << buffer_length << " in buffer; " << bytesalreadysent << " already sent)" << std::endl; #endif // it's in RAM, so just send it, no streaming from disk if (buffer_length != 0) { if (!(*sock).writeToSocket(data + bytesalreadysent, buffer_length - bytesalreadysent, 0, timeout)) throw std::exception(); } else { if (!sock->writeToSocket("\r\n\r\n", 4, 0, timeout)) throw std::exception(); } } } // zlib decompression void DataBuffer::zlibinflate(bool header) { if (buffer_length < 12) { return; // it can't possibly be zlib'd } #ifdef DGDEBUG std::cout << "compressed size:" << buffer_length << std::endl; #endif #if ZLIB_VERNUM < 0x1210 #warning ************************************ #warning For gzip support you need zlib 1.2.1 #warning or later to be installed. #warning You can ignore this warning but #warning internet bandwidth may be wasted. #warning ************************************ if (header) { return; } #endif int newsize = buffer_length * 5; // good estimate of deflated HTML char *block = new char[newsize]; char *temp = NULL; int err; off_t bytesgot = 0; z_stream d_stream; d_stream.zalloc = (alloc_func) 0; d_stream.zfree = (free_func) 0; d_stream.opaque = (voidpf) 0; d_stream.next_in = (Bytef *) data; d_stream.avail_in = buffer_length; d_stream.next_out = (Bytef *) block; d_stream.avail_out = newsize; // inflate either raw zlib, or possibly gzip with a header if (header) { err = inflateInit2(&d_stream, 15 + 32); } else { err = inflateInit2(&d_stream, -15); } if (err != Z_OK) { // was a problem so just return delete[]block; // don't forget to free claimed memory #ifdef DGDEBUG std::cerr << "bad init inflate: " << err << std::endl; #endif return; } while (true) { #ifdef DGDEBUG std::cerr << "inflate loop" << std::endl; #endif err = inflate(&d_stream, Z_SYNC_FLUSH); bytesgot = d_stream.total_out; if (err == Z_STREAM_END) { err = inflateEnd(&d_stream); if (err != Z_OK) { delete[] block; #ifdef DGDEBUG std::cerr << "bad inflateEnd: " << d_stream.msg << std::endl; #endif return; } break; } if (err != Z_OK) { // was a problem so just return delete[]block; // don't forget to free claimed memory #ifdef DGDEBUG std::cerr << "bad inflate: " << d_stream.msg << std::endl; #endif err = inflateEnd(&d_stream); if (err != Z_OK) { #ifdef DGDEBUG std::cerr << "bad inflateEnd: " << d_stream.msg << std::endl; #endif } return; } if (bytesgot > o.max_content_filter_size) { delete[]block; // don't forget to free claimed memory #ifdef DGDEBUG std::cerr << "inflated file larger than maxcontentfiltersize, not inflating further" << std::endl; #endif err = inflateEnd(&d_stream); if (err != Z_OK) { #ifdef DGDEBUG std::cerr << "bad inflateEnd: " << d_stream.msg << std::endl; #endif } return; } // inflation is going ok, but we don't have enough room in the output buffer newsize = bytesgot * 2; temp = new char[newsize]; memcpy(temp, block, bytesgot); delete[]block; block = temp; temp = NULL; d_stream.next_out = (Bytef *) (block + bytesgot); d_stream.avail_out = newsize - bytesgot; } compresseddata = data; compressed_buffer_length = buffer_length; buffer_length = bytesgot; #ifdef DGDEBUG std::cout << "decompressed size: " << buffer_length << std::endl; #endif data = new char[bytesgot+1]; data[bytesgot] = '\0'; memcpy(data, block, bytesgot); delete[] block; } // Does a regexp search and replace. struct newreplacement { int match; String replacement; }; bool DataBuffer::contentRegExp(int filtergroup) { #ifdef DGDEBUG std::cout << "Starting content reg exp replace" << std::endl; #endif bool contentmodified = false; unsigned int i; unsigned int j, k, m; unsigned int s = (*o.fg[filtergroup]).content_regexp_list_comp.size(); unsigned int matches; unsigned int submatch, submatches; RegExp *re; String *replacement; unsigned int replen; int sizediff; char *newblock; char *dstpos; unsigned int srcoff; unsigned int nextoffset; unsigned int matchlen; std::queue matchqueue; for (i = 0; i < s; i++) { re = &((*o.fg[filtergroup]).content_regexp_list_comp[i]); if (re->match(data)) { replacement = &((*o.fg[filtergroup]).content_regexp_list_rep[i]); //replen = replacement->length(); matches = re->numberOfMatches(); sizediff = 0; m = 0; for (j = 0; j < matches; j++) { srcoff = re->offset(j); matchlen = re->length(j); // Count matches for ()'s for (submatches = 0; j+submatches+1 < matches; submatches++) if (re->offset(j+submatches+1) + re->length(j+submatches+1) > srcoff + matchlen) break; // \1 and $1 replacement // store match no. and default (empty) replacement string newreplacement* newrep = new newreplacement; newrep->match = j; newrep->replacement = ""; // iterate over regex's replacement string for (k = 0; k < replacement->length(); k++) { // look for \1..\9 and $1..$9 if (((*replacement)[k] == '\\' || (*replacement)[k] == '$') && (*replacement)[k+1] >= '1' && (*replacement)[k+1] <= '9') { // determine match number submatch = (*replacement)[++k] - '0'; // add submatch contents to replacement string if (submatch <= submatches) { newrep->replacement += re->result(j + submatch).c_str(); } } else { // unescape \\ and \$, and add other non-backreference characters if ((*replacement)[k] == '\\' && ((*replacement)[k+1] == '\\' || (*replacement)[k+1] == '$')) k++; newrep->replacement += replacement->subString(k, 1); } } matchqueue.push(newrep); // update size difference between original and modified content sizediff -= re->length(j); sizediff += newrep->replacement.length(); // skip submatches to next top level match j += submatches; m++; } // now we know eventual size of content-replaced block, allocate memory for it newblock = new char[buffer_length + sizediff + 1]; newblock[buffer_length + sizediff] = '\0'; srcoff = 0; dstpos = newblock; matches = m; #ifdef DGDEBUG std::cout << "content matches:" << matches << std::endl; #endif // replace top-level matches using filled-out replacement strings newreplacement* newrep; for (j = 0; j < matches; j++) { newrep = matchqueue.front(); nextoffset = re->offset(newrep->match); if (nextoffset > srcoff) { memcpy(dstpos, data + srcoff, nextoffset - srcoff); dstpos += nextoffset - srcoff; srcoff = nextoffset; } replen = newrep->replacement.length(); memcpy(dstpos, newrep->replacement.toCharArray(), replen); dstpos += replen; srcoff += re->length(newrep->match); delete newrep; matchqueue.pop(); } if (srcoff < buffer_length) { memcpy(dstpos, data + srcoff, buffer_length - srcoff); } delete[]data; data = newblock; buffer_length = buffer_length + sizediff; contentmodified = true; } } return contentmodified; } dansguardian-2.10.1.1/src/md5.cpp0000644001165000116500000003034711110523210013264 00000000000000/* Functions to compute MD5 message digest of files or memory blocks. according to the definition of MD5 in RFC 1321 from April 1992. Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Ulrich Drepper , 1995. */ // Updated by Daniel Barron Tue 24th February 2004 to work with DansGuardian // on mulitple platforms. Then again on Sat 29th January 2005 to work with // autotools. #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include #if STDC_HEADERS || defined _LIBC # include # include #else # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif #endif #include "md5.hpp" #ifndef WORDS_BIGENDIAN # ifdef __BYTE_ORDER # if __BYTE_ORDER == __BIG_ENDIAN # define WORDS_BIGENDIAN 1 # endif # else # if _BYTE_ORDER == _BIG_ENDIAN # define WORDS_BIGENDIAN 1 # endif # endif #endif #ifdef WORDS_BIGENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else # define SWAP(n) (n) #endif /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ void md5_init_ctx(struct md5_ctx *ctx) { ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->total[0] = ctx->total[1] = 0; ctx->buflen = 0; } /* Put result from CTX in first 16 bytes following RESBUF. The result must be in little endian byte order. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) { ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A); ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B); ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C); ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D); return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ md5_uint32 bytes = ctx->buflen; size_t pad; /* Now count remaining bytes. */ ctx->total[0] += bytes; if (ctx->total[0] < bytes) ++ctx->total[1]; pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; memcpy(&ctx->buffer[bytes], fillbuf, pad); /* Put the 64-bit file length in *bits* at the end of the buffer. */ *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3); *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] = SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29)); /* Process last bytes. */ md5_process_block(ctx->buffer, bytes + pad + 8, ctx); return md5_read_ctx(ctx, resbuf); } /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ int md5_stream(FILE * stream, void *resblock) { /* Important: BLOCKSIZE must be a multiple of 64. */ #define BLOCKSIZE 4096 struct md5_ctx ctx; char buffer[BLOCKSIZE + 72]; size_t sum; /* Initialize the computation context. */ md5_init_ctx(&ctx); /* Iterate over full file contents. */ while (1) { /* We read the file in blocks of BLOCKSIZE bytes. One call of the computation function processes the whole buffer so that with the next round of the loop another block can be read. */ size_t n; sum = 0; /* Read block. Take care for partial reads. */ do { n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream); sum += n; } while (sum < BLOCKSIZE && n != 0); if (n == 0 && ferror(stream)) return 1; /* If end of file is reached, end the loop. */ if (n == 0) break; /* Process buffer with BLOCKSIZE bytes. Note that BLOCKSIZE % 64 == 0 */ md5_process_block(buffer, BLOCKSIZE, &ctx); } /* Add the last bytes if necessary. */ if (sum > 0) md5_process_bytes(buffer, sum, &ctx); /* Construct result in desired memory. */ md5_finish_ctx(&ctx, resblock); return 0; } /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ void *md5_buffer(const char *buffer, size_t len, void *resblock) { struct md5_ctx ctx; /* Initialize the computation context. */ md5_init_ctx(&ctx); /* Process whole buffer but last len % 64 bytes. */ md5_process_bytes(buffer, len, &ctx); /* Put result in desired memory area. */ return md5_finish_ctx(&ctx, resblock); } void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ if (ctx->buflen != 0) { size_t left_over = ctx->buflen; size_t add = 128 - left_over > len ? len : 128 - left_over; /* Only put full words in the buffer. */ add -= add % __alignof__(md5_uint32); memcpy(&ctx->buffer[left_over], buffer, add); ctx->buflen += add; if (ctx->buflen > 64) { md5_process_block(ctx->buffer, ctx->buflen & ~63, ctx); ctx->buflen &= 63; /* The regions in the following copy operation cannot overlap. */ memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ctx->buflen); } buffer = (const char *) buffer + add; len -= add; } /* Process available complete blocks. */ if (len > 64) { md5_process_block(buffer, len & ~63, ctx); buffer = (const char *) buffer + (len & ~63); len &= 63; } /* Move remaining bytes in internal buffer. */ if (len > 0) { size_t left_over = ctx->buflen; memcpy(&ctx->buffer[left_over], buffer, len); left_over += len; if (left_over >= 64) { md5_process_block(ctx->buffer, 64, ctx); left_over -= 64; memcpy(ctx->buffer, &ctx->buffer[64], left_over); } ctx->buflen = left_over; } } /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ /* #define FF(b, c, d) ((b & c) | (~b & d)) */ #define FF(b, c, d) (d ^ (b & (c ^ d))) #define FG(b, c, d) FF (d, b, c) #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. */ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx) { md5_uint32 correct_words[16]; const md5_uint32 *words = (md5_uint32 *) buffer; size_t nwords = len / sizeof(md5_uint32); const md5_uint32 *endp = words + nwords; md5_uint32 A = ctx->A; md5_uint32 B = ctx->B; md5_uint32 C = ctx->C; md5_uint32 D = ctx->D; /* First increment the byte count. RFC 1321 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ ctx->total[0] += len; if (ctx->total[0] < len) ++ctx->total[1]; /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ while (words < endp) { md5_uint32 *cwp = correct_words; md5_uint32 A_save = A; md5_uint32 B_save = B; md5_uint32 C_save = C; md5_uint32 D_save = D; /* First round: using the given function, the context and a constant the next context is computed. Because the algorithms processing unit is a 32-bit word and it is determined to work on words in little endian byte order we perhaps have to change the byte order before the computation. To reduce the work for the next steps we store the swapped words in the array CORRECT_WORDS. */ #define OP(a, b, c, d, s, T) \ do \ { \ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ ++words; \ CYCLIC (a, s); \ a += b; \ } \ while (0) /* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) /* Before we start, one word to the strange constants. They are defined in RFC 1321 as T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 */ /* Round 1. */ OP(A, B, C, D, 7, 0xd76aa478); OP(D, A, B, C, 12, 0xe8c7b756); OP(C, D, A, B, 17, 0x242070db); OP(B, C, D, A, 22, 0xc1bdceee); OP(A, B, C, D, 7, 0xf57c0faf); OP(D, A, B, C, 12, 0x4787c62a); OP(C, D, A, B, 17, 0xa8304613); OP(B, C, D, A, 22, 0xfd469501); OP(A, B, C, D, 7, 0x698098d8); OP(D, A, B, C, 12, 0x8b44f7af); OP(C, D, A, B, 17, 0xffff5bb1); OP(B, C, D, A, 22, 0x895cd7be); OP(A, B, C, D, 7, 0x6b901122); OP(D, A, B, C, 12, 0xfd987193); OP(C, D, A, B, 17, 0xa679438e); OP(B, C, D, A, 22, 0x49b40821); /* For the second to fourth round we have the possibly swapped words in CORRECT_WORDS. Redefine the macro to take an additional first argument specifying the function to use. */ #undef OP #define OP(f, a, b, c, d, k, s, T) \ do \ { \ a += f (b, c, d) + correct_words[k] + T; \ CYCLIC (a, s); \ a += b; \ } \ while (0) /* Round 2. */ OP(FG, A, B, C, D, 1, 5, 0xf61e2562); OP(FG, D, A, B, C, 6, 9, 0xc040b340); OP(FG, C, D, A, B, 11, 14, 0x265e5a51); OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); OP(FG, A, B, C, D, 5, 5, 0xd62f105d); OP(FG, D, A, B, C, 10, 9, 0x02441453); OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); OP(FG, D, A, B, C, 14, 9, 0xc33707d6); OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); OP(FG, B, C, D, A, 8, 20, 0x455a14ed); OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); OP(FG, C, D, A, B, 7, 14, 0x676f02d9); OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP(FH, A, B, C, D, 5, 4, 0xfffa3942); OP(FH, D, A, B, C, 8, 11, 0x8771f681); OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); OP(FH, B, C, D, A, 14, 23, 0xfde5380c); OP(FH, A, B, C, D, 1, 4, 0xa4beea44); OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); OP(FH, B, C, D, A, 6, 23, 0x04881d05); OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); /* Round 4. */ OP(FI, A, B, C, D, 0, 6, 0xf4292244); OP(FI, D, A, B, C, 7, 10, 0x432aff97); OP(FI, C, D, A, B, 14, 15, 0xab9423a7); OP(FI, B, C, D, A, 5, 21, 0xfc93a039); OP(FI, A, B, C, D, 12, 6, 0x655b59c3); OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); OP(FI, C, D, A, B, 10, 15, 0xffeff47d); OP(FI, B, C, D, A, 1, 21, 0x85845dd1); OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); OP(FI, C, D, A, B, 6, 15, 0xa3014314); OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); OP(FI, A, B, C, D, 4, 6, 0xf7537e82); OP(FI, D, A, B, C, 11, 10, 0xbd3af235); OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); OP(FI, B, C, D, A, 9, 21, 0xeb86d391); /* Add the starting values of the context. */ A += A_save; B += B_save; C += C_save; D += D_save; } /* Put checksum in context given as argument. */ ctx->A = A; ctx->B = B; ctx->C = C; ctx->D = D; } dansguardian-2.10.1.1/src/Plugin.hpp0000644001165000116500000000221711110523210014035 00000000000000// the Plugin interface - inherit this to define new plugin types //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_PLUGIN #define __HPP_PLUGIN // INCLUDES // DECLARATIONS class Plugin { public: virtual ~Plugin(){}; // plugin initialise/quit routines. // return 0 for OK, < 0 for error, > 0 for warning virtual int init(void* args) = 0; virtual int quit() = 0; }; #endif dansguardian-2.10.1.1/src/HTTPHeader.hpp0000644001165000116500000001374711151226452014516 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_HTTPHeader #define __HPP_HTTPHeader // DEFINES #define __DGHEADER_SENDALL 0 #define __DGHEADER_SENDFIRSTLINE 1 #define __DGHEADER_SENDREST 2 // INCLUDES #include #include "String.hpp" //#include "DataBuffer.hpp" #include "Socket.hpp" #include "RegExp.hpp" // DECLARATIONS class HTTPHeader { public: std::deque header; //DataBuffer postdata; unsigned int port; // reset header object for future use void reset(); // network communication funcs void setTimeout(int t); void in(Socket *sock, bool allowpersistent = false, bool honour_reloadconfig = false); // send headers out over the given socket // "reconnect" flag gives permission to reconnect to the socket on write error // - this allows us to re-open the proxy connection on pconns if squid's end has // timed out but the client's end hasn't. not much use with NTLM, since squid // will throw a 407 and restart negotiation, but works well with basic & others. void out(Socket *peersock, Socket *sock, int sendflag, bool reconnect = false) throw(std::exception); // discard remainder of POST data void discard(Socket *sock); // header value and type checks // request type: GET, HEAD, POST etc. String requestType(); int returnCode(); // get content length - returns -1 if undetermined off_t contentLength(); String getContentType(); // check received content type against given content type bool isContentType(const String& t); // check HTTP message code to see if it's an auth required message bool authRequired(); // Content-Disposition String disposition(); String userAgent(); // grab contents of X-Forwarded-For std::string getXForwardedForIP(); // check HTTP message code to see if it's a redirect bool isRedirection(); // see if content-type is something other than "identity" bool isCompressed(); String contentEncoding(); // grab the contents of Proxy-Authorization header // returns base64-decoding of the chunk of data after the auth type string std::string getAuthData(); // grab raw contents of Proxy-Authorization header, without b64 decode std::string getRawAuthData(); // check whether a connection is persistent bool isPersistent() { return ispersistent; }; // detailed value/type checks bool malformedURL(const String& url); bool isPostUpload(Socket &peersock); String getAuthType(); String url(bool withport = false); // header modifications void addXForwardedFor(const std::string &clientip); // strip content-encoding, and simultaneously set content-length to newlen void removeEncoding(int newlen); void setContentLength(int newlen); // regexp search and replace bool urlRegExp(int filtergroup); bool headerRegExp(int filtergroup); // make a connection persistent - or not void makePersistent(bool persist = true); // do URL decoding (%xx) on string // decode everything, or just numbers, letters and - String decode(const String &s, bool decodeAll = false); // Bypass URL & Cookie funcs // is this a temporary filter bypass URL? int isBypassURL(String *url, const char *magic, const char *clientip, bool *isvirusbypass); // is this a scan bypass URL? (download previously scanned file) bool isScanBypassURL(String *url, const char *magic, const char *clientip); // is this a temporary filter bypass cookie? bool isBypassCookie(String url, const char *magic, const char *clientip); // chop GBYPASS/GSPYBASS off URLs (must know it's there to begin with) void chopBypass(String url, bool infectionbypass); void chopScanBypass(String url); // add cookie to outgoing headers with given name & value void setCookie(const char *cookie, const char *domain, const char *value); HTTPHeader():dirty(true) { reset(); }; private: // timeout for socket operations int timeout; // header index pointers String *phost; String *pport; String *pcontentlength; String *pcontenttype; String *pproxyauthorization; String *pcontentdisposition; String *puseragent; String *pxforwardedfor; String *pcontentencoding; String *pproxyconnection; // cached result of url() std::string cachedurl; char postdata[15]; off_t postdatalen; bool postdatachopped; bool ispostupload; bool ispersistent, waspersistent; bool dirty; // check & fix headers from servers that don't obey standards void checkheader(bool allowpersistent); // convert %xx back to original character String hexToChar(const String &n, bool all = false); // base64 decode an individual char int decode1b64(char c); // base64 decode a complete string std::string decodeb64(const String& line); // modify supplied accept-encoding header, adding "identity" and stripping unsupported compression types String modifyEncodings(String e); // modifies the URL in all relevant header lines after a regexp search and replace // setURL Code originally from from Ton Gorter 2004 void setURL(String &url); // Generic search & replace code, called by urlRegExp and headerRegExp // urlRegExp Code originally from from Ton Gorter 2004 bool regExp(String &line, std::deque ®exp_list, std::deque &replacement_list); // grab cookies from headers String getCookie(const char *cookie); }; #endif dansguardian-2.10.1.1/src/Socket.cpp0000644001165000116500000001050211110523210014016 00000000000000// Socket class - implements BaseSocket for INET domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "Socket.hpp" #include #include #include #include #include #include #include #include #include // IMPLEMENTATION // constructor - create an INET socket & clear address structs Socket::Socket() { sck = socket(AF_INET, SOCK_STREAM, 0); memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sin_family = AF_INET; peer_adr.sin_family = AF_INET; peer_adr_length = sizeof(struct sockaddr_in); int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } // create socket from pre-existing FD (address structs will be invalid!) Socket::Socket(int fd):BaseSocket(fd) { memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sin_family = AF_INET; peer_adr.sin_family = AF_INET; peer_adr_length = sizeof(struct sockaddr_in); int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } // create socket from pre-existing FD, storing local & remote IPs Socket::Socket(int newfd, struct sockaddr_in myip, struct sockaddr_in peerip):BaseSocket(newfd) { memset(&my_adr, 0, sizeof my_adr); // *** memset(&peer_adr, 0, sizeof peer_adr); // *** my_adr.sin_family = AF_INET; // *** Fix suggested by peer_adr.sin_family = AF_INET; // *** Christopher Weimann my_adr = myip; peer_adr = peerip; peer_adr_length = sizeof(struct sockaddr_in); int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } // find the ip to which the client has connected std::string Socket::getLocalIP() { return inet_ntoa(my_adr.sin_addr); } // find the ip of the client connecting to us std::string Socket::getPeerIP() { return inet_ntoa(peer_adr.sin_addr); } // find the port of the client connecting to us int Socket::getPeerSourcePort() { return ntohs(peer_adr.sin_port); } // return the address of the client connecting to us unsigned long int Socket::getPeerSourceAddr() { return (unsigned long int)ntohl(peer_adr.sin_addr.s_addr); } // close connection & wipe address structs void Socket::reset() { this->baseReset(); sck = socket(AF_INET, SOCK_STREAM, 0); memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); my_adr.sin_family = AF_INET; peer_adr.sin_family = AF_INET; peer_adr_length = sizeof(struct sockaddr_in); } // connect to given IP & port (following default constructor) int Socket::connect(const std::string &ip, int port) { int len = sizeof my_adr; peer_adr.sin_port = htons(port); inet_aton(ip.c_str(), &peer_adr.sin_addr); return ::connect(sck, (struct sockaddr *) &peer_adr, len); } // bind socket to given port int Socket::bind(int port) { int len = sizeof my_adr; int i = 1; setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); my_adr.sin_port = htons(port); return ::bind(sck, (struct sockaddr *) &my_adr, len); } // bind socket to given port & IP int Socket::bind(const std::string &ip, int port) { int len = sizeof my_adr; int i = 1; setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); my_adr.sin_port = htons(port); my_adr.sin_addr.s_addr = inet_addr(ip.c_str()); return ::bind(sck, (struct sockaddr *) &my_adr, len); } // accept incoming connections & return new Socket Socket* Socket::accept() { peer_adr_length = sizeof(struct sockaddr_in); int newfd = this->baseAccept((struct sockaddr*) &peer_adr, &peer_adr_length); Socket* s = new Socket(newfd, my_adr, peer_adr); return s; } dansguardian-2.10.1.1/src/ConnectionHandler.cpp0000644001165000116500000026052211151226466016216 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "ConnectionHandler.hpp" #include "DataBuffer.hpp" #include "UDSocket.hpp" #include "Auth.hpp" #include "FDTunnel.hpp" #include "ImageContainer.hpp" #include "FDFuncs.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_ORIG_IP #include #include #endif // GLOBALS extern OptionContainer o; extern bool is_daemonised; extern bool reloadconfig; // IMPLEMENTATION // // URL cache funcs // // check the URL cache to see if we've already flagged an address as clean bool wasClean(String &url, const int fg) { if (reloadconfig) return false; UDSocket ipcsock; if (ipcsock.getFD() < 0) { syslog(LOG_ERR, "Error creating ipc socket to url cache"); return false; } if (ipcsock.connect(o.urlipc_filename.c_str()) < 0) { // conn to dedicated url cach proc syslog(LOG_ERR, "Error connecting via ipc to url cache: %s", strerror(errno)); ipcsock.close(); return false; } std::string myurl(" "); myurl += url.after("://").toCharArray(); myurl[0] = fg+1; myurl += "\n"; #ifdef DGDEBUG std::cout << "sending cache search request: " << myurl; #endif try { ipcsock.writeString(myurl.c_str()); // throws on err } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception writing to url cache" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "Exception writing to url cache"); syslog(LOG_ERR, "%s", e.what()); } char reply; try { ipcsock.readFromSocket(&reply, 1, 0, 6); // throws on err } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception reading from url cache" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "Exception reading from url cache"); syslog(LOG_ERR, "%s", e.what()); } ipcsock.close(); return reply == 'Y'; } // add a known clean URL to the cache void addToClean(String &url, const int fg) { if (reloadconfig) return; UDSocket ipcsock; if (ipcsock.getFD() < 0) { syslog(LOG_ERR, "Error creating ipc socket to url cache"); return; } if (ipcsock.connect(o.urlipc_filename.c_str()) < 0) { // conn to dedicated url cach proc syslog(LOG_ERR, "Error connecting via ipc to url cache: %s", strerror(errno)); #ifdef DGDEBUG std::cout << "Error connecting via ipc to url cache: " << strerror(errno) << std::endl; #endif return; } std::string myurl("g "); myurl += url.after("://").toCharArray(); myurl[1] = fg+1; myurl += "\n"; try { ipcsock.writeString(myurl.c_str()); // throws on err } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception adding to url cache" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "Exception adding to url cache"); syslog(LOG_ERR, "%s", e.what()); } ipcsock.close(); } // // ConnectionHandler class // // strip the URL down to just the IP/hostname, then do an isIPHostname on the result bool ConnectionHandler::isIPHostnameStrip(String url) { url.removePTP(); // chop off the ht(f)tp(s):// if (url.contains("/")) { url = url.before("/"); // chop off any path after the domain } return (*o.fg[0]).isIPHostname(url); } // perform URL encoding on a string std::string ConnectionHandler::miniURLEncode(const char *s) { std::string encoded; //char *buf = new char[16]; // way longer than needed char *buf = new char[3]; unsigned char c; for (int i = 0; i < (signed) strlen(s); i++) { c = s[i]; // allowed characters in a url that have non special meaning if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { encoded += c; continue; } // all other characters get encoded sprintf(buf, "%02x", c); encoded += "%"; encoded += buf; } delete[]buf; return encoded; } // create a temporary bypass URL for the banned page String ConnectionHandler::hashedURL(String *url, int filtergroup, std::string *clientip, bool infectionbypass) { // filter/virus bypass hashes last for a certain time only String timecode(time(NULL) + (infectionbypass ? (*o.fg[filtergroup]).infection_bypass_mode : (*o.fg[filtergroup]).bypass_mode)); // use the standard key in normal bypass mode, and the infection key in infection bypass mode String magic(infectionbypass ? (*o.fg[filtergroup]).imagic.c_str() : (*o.fg[filtergroup]).magic.c_str()); magic += (*clientip).c_str(); magic += timecode; String res(infectionbypass ? "GIBYPASS=" : "GBYPASS="); if (!(*url).after("://").contains("/")) { String newurl((*url)); newurl += "/"; res += newurl.md5(magic.toCharArray()); } else { res += (*url).md5(magic.toCharArray()); } res += timecode; return res; } // create temporary bypass cookie String ConnectionHandler::hashedCookie(String * url, int filtergroup, std::string * clientip, int bypasstimestamp) { String timecode(bypasstimestamp); String magic((*o.fg[filtergroup]).cookie_magic.c_str()); magic += (*clientip).c_str(); magic += timecode; String res((*url).md5(magic.toCharArray())); res += timecode; #ifdef DGDEBUG std::cout << "hashedCookie=" << res << std::endl; #endif return res; } // when using IP address counting - have we got any remaining free IPs? bool ConnectionHandler::gotIPs(std::string ipstr) { if (reloadconfig) return false; UDSocket ipcsock; if (ipcsock.getFD() < 0) { syslog(LOG_ERR, "Error creating ipc socket to IP cache"); return false; } // TODO: put in proper file name check if (ipcsock.connect(o.ipipc_filename.c_str()) < 0) { // connect to dedicated ip list proc syslog(LOG_ERR, "Error connecting via ipc to IP cache: %s", strerror(errno)); return false; } char reply; ipstr += '\n'; try { ipcsock.writeToSockete(ipstr.c_str(), ipstr.length(), 0, 6); ipcsock.readFromSocket(&reply, 1, 0, 6); // throws on err } catch (std::exception& e) { #ifdef DGDEBUG std::cerr << "Exception with IP cache" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "Exception with IP cache"); syslog(LOG_ERR, "%s", e.what()); } ipcsock.close(); return reply == 'Y'; } // send a file to the client - used during bypass of blocked downloads off_t ConnectionHandler::sendFile(Socket * peerconn, String & filename, String & filemime, String & filedis, String &url) { int fd = open(filename.toCharArray(), O_RDONLY); if (fd < 0) { // file access error syslog(LOG_ERR, "Error reading file to send"); #ifdef DGDEBUG std::cout << "Error reading file to send:" << filename << std::endl; #endif String fnf(o.language_list.getTranslation(1230)); String message("HTTP/1.0 404 " + fnf + "\nContent-Type: text/html\n\n" + fnf + "

" + fnf + "

\n"); peerconn->writeString(message.toCharArray()); return 0; } off_t filesize = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); String message("HTTP/1.0 200 OK\nContent-Type: " + filemime + "\nContent-Length: " + String(filesize)); if (filedis.length() == 0) { filedis = url.before("?"); while (filedis.contains("/")) filedis = filedis.after("/"); } message += "\nContent-disposition: attachment; filename=" + filedis; message += "\n\n"; try { peerconn->writeString(message.toCharArray()); } catch(std::exception & e) { close(fd); return 0; } // perform the actual sending off_t sent = 0; int rc; char *buffer = new char[250000]; while (sent < filesize) { rc = readEINTR(fd, buffer, 250000); #ifdef DGDEBUG std::cout << "reading send file rc:" << rc << std::endl; #endif if (rc < 0) { #ifdef DGDEBUG std::cout << "error reading send file so throwing exception" << std::endl; #endif delete[]buffer; throw std::exception(); } if (rc == 0) { #ifdef DGDEBUG std::cout << "got zero bytes reading send file" << std::endl; #endif break; // should never happen } // as it's cached to disk the buffer must be reasonably big if (!peerconn->writeToSocket(buffer, rc, 0, 100)) { delete[]buffer; throw std::exception(); } sent += rc; #ifdef DGDEBUG std::cout << "total sent from temp:" << sent << std::endl; #endif } delete[]buffer; close(fd); return sent; } // pass data between proxy and client, filtering as we go. // this is the only public function of ConnectionHandler - all content blocking/filtering is triggered from calls that live here. void ConnectionHandler::handleConnection(Socket &peerconn, String &ip) { struct timeval thestart; gettimeofday(&thestart, NULL); peerconn.setTimeout(10); HTTPHeader header; // to hold the incoming client request header header.setTimeout(14); // set a timeout as we don't want blocking 4 eva // this also sets how long a pconn will wait for other requests // squid apparently defaults to 1 minute (persistent_request_timeout), // so wait slightly less than this to avoid duff pconns. // checkme: have this value configurable, and/or reconnect to proxy // when the onward connection has timed out instead of failing? HTTPHeader docheader; // to hold the returned page header from proxy docheader.setTimeout(20); DataBuffer docbody; // to hold the returned page docbody.setTimeout(120); bool waschecked = false; // flags bool wasrequested = false; bool isexception = false; bool isourwebserver = false; bool wasclean = false; bool cachehit = false; bool isbypass = false; bool iscookiebypass = false; bool isvirusbypass = false; int bypasstimestamp = 0; bool isscanbypass = false; bool ispostblock = false; bool pausedtoobig = false; bool wasinfected = false; bool wasscanned = false; bool contentmodified = false; bool urlmodified = false; bool headermodified = false; bool isconnect; bool ishead; bool scanerror; bool runav = false; // not just AV but any content scanner int headersent = 0; // 0=none,1=first line,2=all std::deque sendtoscanner; std::string mimetype("-"); String url; String urld; String urldomain; std::string exceptionreason; // to hold the reason for not blocking std::string exceptioncat; off_t docsize = 0; // to store the size of the returned document for logging std::string clientip(ip.toCharArray()); // hold the clients ip delete clienthost; clienthost = NULL; // and the hostname, if available matchedip = false; #ifdef DGDEBUG // debug stuff surprisingly enough std::cout << "got connection" << std::endl; std::cout << clientip << std::endl; #endif Socket proxysock; // to hold connection to proxy try { // connect to proxy int rc = proxysock.connect(o.proxy_ip, o.proxy_port); if (rc) { #ifdef DGDEBUG std::cerr << "Error connecting to proxy" << std::endl; #endif syslog(LOG_ERR, "Error connecting to proxy"); return; // if we can't connect to the proxy, there is no point // in continuing } header.in(&peerconn, true, true); // get header from client, allowing persistency and breaking on reloadconfig bool persist = header.isPersistent(); bool firsttime = true; #ifdef DGDEBUG int pcount = 0; #endif // assume all requests over the one persistent connection are from // the same user. means we only need to query the auth plugin until // we get credentials, then assume they are valid for all reqs. on // the persistent connection. std::string clientuser; std::string oldclientuser; int filtergroup, oldfg = 0, gmode; bool authed = false; bool isbanneduser = false; bool persistent_authed = false; FDTunnel fdt; NaughtyFilter checkme; AuthPlugin* auth_plugin = NULL; // maintain a persistent connection while ((firsttime || persist) && !reloadconfig) { if (!firsttime) { #ifdef DGDEBUG std::cout << "persisting (count " << ++pcount << ")" << std::endl; syslog(LOG_ERR, "Served %d requests on this connection so far", pcount); std::cout << clientip << std::endl; #endif header.reset(); try { header.in(&peerconn, true, true); // get header from client, allowing persistency and breaking on reloadconfig } catch (std::exception &e) { #ifdef DGDEBUG std::cout << "Persistent connection closed" << std::endl; #endif break; } // don't let the connection persist if the client doesn't want it to. persist = header.isPersistent(); // we will actually need to do *lots* of resetting of flags etc. here for pconns to work gettimeofday(&thestart, NULL); waschecked = false; // flags wasrequested = false; isexception = false; isourwebserver = false; wasclean = false; cachehit = false; isbypass = false; iscookiebypass = false; isvirusbypass = false; bypasstimestamp = 0; isscanbypass = false; ispostblock = false; pausedtoobig = false; wasinfected = false; wasscanned = false; contentmodified = false; urlmodified = false; headermodified = false; authed = false; isbanneduser = false; //bool runav = false; // not just AV but any content scanner headersent = 0; // 0=none,1=first line,2=all delete clienthost; clienthost = NULL; // and the hostname, if available matchedip = false; docsize = 0; // to store the size of the returned document for logging mimetype = "-"; exceptionreason = ""; exceptioncat = ""; sendtoscanner.clear(); // reset header, docheader & docbody // headers *should* take care of themselves on the next in() // actually not entirely true for docheader - we may read // certain properties of it (in denyAccess) before we've // actually performed the next in(), so make sure we do a full // reset now. docheader.reset(); docbody.reset(); checkme.reset(); // our filter object // more? } else { // reset flags & objects next time round the loop firsttime = false; } // don't have credentials for this connection yet? get some! if (!persistent_authed) { #ifdef DGDEBUG std::cout << "Not got persistent credentials for this connection - querying auth plugins" << std::endl; #endif bool dobreak = false; if (o.authplugins.size() != 0) { // We have some auth plugins loaded for (std::deque::iterator i = o.authplugins_begin; i != o.authplugins_end; i++) { #ifdef DGDEBUG std::cout << "Querying next auth plugin..." << std::endl; #endif // try to get the username & parse the return value auth_plugin = (AuthPlugin*)(*i); rc = auth_plugin->identify(peerconn, proxysock, header, /*filtergroup,*/ clientuser); if (rc == DGAUTH_NOMATCH) { #ifdef DGDEBUG std::cout<<"Auth plugin did not find a match; querying remaining plugins"<determineGroup(clientuser, filtergroup); if (rc == DGAUTH_OK) { #ifdef DGDEBUG std::cout<<"Auth plugin found username & group; not querying remaining plugins"<= o.numfg)) { #ifdef DGDEBUG if (!authed) std::cout << "No identity found; using defaults" << std::endl; else std::cout << "Plugin returned out-of-range filter group number; using defaults" << std::endl; #endif // If none of the auth plugins currently loaded rely on querying the proxy, // such as 'ident' or 'ip', then pretend we're authed. What this flag // actually controls is whether or not the query should be forwarded to the // proxy (without pre-emptive blocking); we don't want this for 'ident' or // 'ip', because Squid isn't necessarily going to return 'auth required'. authed = !o.auth_needs_proxy_query; #ifdef DGDEBUG if (!o.auth_needs_proxy_query) std::cout << "No loaded auth plugins require parent proxy queries; enabling pre-emptive blocking despite lack of authentication" << std::endl; #endif clientuser = "-"; filtergroup = 0; //default group - one day configurable? } else { #ifdef DGDEBUG std::cout << "Identity found; caching username & group" << std::endl; #endif if (auth_plugin->is_connection_based) { #ifdef DGDEBUG std::cout<<"Auth plugin is for a connection-based auth method - keeping credentials for entire connection"<group_mode; #ifdef DGDEBUG std::cout << "username: " << clientuser << std::endl; std::cout << "filtergroup: " << filtergroup << std::endl; std::cout << "groupmode: " << gmode << std::endl; #endif // filter group modes are: 0 = banned, 1 = filtered, 2 = exception. // is this user banned? isbanneduser = (gmode == 0); url = header.url(); urld = header.decode(url); if (url.after("://").contains("/")) { urldomain = url.after("//").before("/"); } else { urldomain = url.after("//"); } // checks for bad URLs to prevent security holes/domain obfuscation. if (header.malformedURL(url)) { try { // writestring throws exception on error/timeout peerconn.writeString("HTTP/1.0 400 Bad Request\nContent-Type: text/html\n\nDansGuardian - 400 Bad Request

DansGuardian - 400 Bad Request

"); peerconn.writeString(o.language_list.getTranslation(200)); // The requested URL is malformed. peerconn.writeString("\n"); } catch(std::exception & e) { } proxysock.close(); // close connection to proxy break; } if (o.use_xforwardedfor) { std::string xforwardip(header.getXForwardedForIP()); if (xforwardip.length() > 6) { clientip = xforwardip; } #ifdef DGDEBUG std::cout << "using x-forwardedfor:" << clientip << std::endl; #endif } // is this machine banned? bool isbannedip = o.inBannedIPList(&clientip, clienthost); if (isbannedip) matchedip = clienthost == NULL; if (o.forwarded_for) { header.addXForwardedFor(clientip); // add squid-like entry } #ifdef ENABLE_ORIG_IP // if working in transparent mode and grabbing of original IP addresses is // enabled, does the original IP address match one of those that the host // we are going to resolves to? // Resolves http://www.kb.cert.org/vuls/id/435052 if (o.get_orig_ip) { // XXX This will currently only work on Linux/Netfilter. sockaddr_in origaddr; socklen_t origaddrlen(sizeof(sockaddr_in)); // Note: we assume that for non-redirected connections, this getsockopt call will // return the proxy server's IP, and not -1. Hence, comparing the result with // the return value of Socket::getLocalIP() should tell us that the client didn't // connect transparently, and we can assume they aren't vulnerable. if (getsockopt(peerconn.getFD(), SOL_IP, SO_ORIGINAL_DST, &origaddr, &origaddrlen) < 0) { syslog(LOG_ERR, "Failed to get client's original destination IP: %s", strerror(errno)); proxysock.close(); break; } std::string orig_dest_ip(inet_ntoa(origaddr.sin_addr)); if (orig_dest_ip == peerconn.getLocalIP()) { // The destination IP before redirection is the same as the IP the // client has actually been connected to - they aren't connecting transparently. #ifdef DGDEBUG std::cout << "SO_ORIGINAL_DST and getLocalIP are equal; client not connected transparently" << std::endl; #endif } else { // Look up domain from request URL, and check orig IP against resolved IPs addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; addrinfo *results; int result = getaddrinfo(urldomain.c_str(), NULL, &hints, &results); if (result) { freeaddrinfo(results); syslog(LOG_ERR, "Cannot resolve hostname for host header checks: %s", gai_strerror(errno)); proxysock.close(); break; } addrinfo *current = results; bool matched = false; while (current != NULL) { if (orig_dest_ip == inet_ntoa(((sockaddr_in*)(current->ai_addr))->sin_addr)) { #ifdef DGDEBUG std::cout << urldomain << " matched to original destination of " << orig_dest_ip << std::endl; #endif matched = true; break; } current = current->ai_next; } freeaddrinfo(results); if (!matched) { // Host header/URL said one thing, but the original destination IP said another. // This is exactly the vulnerability we want to prevent. #ifdef DGDEBUG std::cout << urldomain << " DID NOT MATCH original destination of " << orig_dest_ip << std::endl; #endif syslog(LOG_ERR, "Destination host of %s did not match the original destination IP of %s", urldomain.c_str(), orig_dest_ip.c_str()); try { // writestring throws exception on error/timeout peerconn.writeString("HTTP/1.0 400 Bad Request\nContent-Type: text/html\n\nDansGuardian - 400 Bad Request

DansGuardian - 400 Bad Request

"); peerconn.writeString(o.language_list.getTranslation(200)); // The requested URL is malformed. peerconn.writeString("\n"); } catch(std::exception & e) { } // close connection to proxy proxysock.close(); break; } } } #endif if (header.isScanBypassURL(&url, (*o.fg[filtergroup]).magic.c_str(), clientip.c_str())) { #ifdef DGDEBUG std::cout << "Scan Bypass URL match" << std::endl; #endif isscanbypass = true; isbypass = true; exceptionreason = o.language_list.getTranslation(608); } else if (((*o.fg[filtergroup]).bypass_mode != 0) || ((*o.fg[filtergroup]).infection_bypass_mode != 0)) { #ifdef DGDEBUG std::cout << "About to check for bypass..." << std::endl; #endif if ((*o.fg[filtergroup]).bypass_mode != 0) bypasstimestamp = header.isBypassURL(&url, (*o.fg[filtergroup]).magic.c_str(), clientip.c_str(), NULL); if ((bypasstimestamp == 0) && ((*o.fg[filtergroup]).infection_bypass_mode != 0)) bypasstimestamp = header.isBypassURL(&url, (*o.fg[filtergroup]).imagic.c_str(), clientip.c_str(), &isvirusbypass); if (bypasstimestamp > 0) { #ifdef DGDEBUG if (isvirusbypass) std::cout << "Infection bypass URL match" << std::endl; else std::cout << "Filter bypass URL match" << std::endl; #endif header.chopBypass(url, isvirusbypass); if (bypasstimestamp > 1) { // not expired isbypass = true; // checkme: need a TR string for virus bypass exceptionreason = o.language_list.getTranslation(606); } } else if ((*o.fg[filtergroup]).bypass_mode != 0) { if (header.isBypassCookie(urldomain, (*o.fg[filtergroup]).cookie_magic.c_str(), clientip.c_str())) { #ifdef DGDEBUG std::cout << "Bypass cookie match" << std::endl; #endif iscookiebypass = true; isbypass = true; exceptionreason = o.language_list.getTranslation(607); } } #ifdef DGDEBUG std::cout << "Finished bypass checks." << std::endl; #endif } #ifdef DGDEBUG if (isbypass) { std::cout << "Bypass activated!" << std::endl; } #endif if (isscanbypass) { //we need to decode the URL and send the temp file with the //correct header to the client then delete the temp file String tempfilename(url.after("GSBYPASS=").after("&N=")); String tempfilemime(tempfilename.after("&M=")); String tempfiledis(header.decode(tempfilemime.after("&D="), true)); #ifdef DGDEBUG std::cout << "Original filename: " << tempfiledis << std::endl; #endif String rtype(header.requestType()); tempfilemime = tempfilemime.before("&D="); tempfilename = o.download_dir + "/tf" + tempfilename.before("&M="); try { docsize = sendFile(&peerconn, tempfilename, tempfilemime, tempfiledis, url); header.chopScanBypass(url); url = header.url(); //urld = header.decode(url); // unneeded really doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, NULL, false, isexception, false, &thestart, cachehit, 200, mimetype, wasinfected, wasscanned, 0, filtergroup, &header); if (o.delete_downloaded_temp_files) { unlink(tempfilename.toCharArray()); } } catch(std::exception & e) { } proxysock.close(); // close connection to proxy break; } // being a banned user/IP overrides the fact that a site may be in the exception lists // needn't check these lists in bypass modes if (!(isbanneduser || isbannedip || isbypass)) { bool is_ssl = header.requestType() == "CONNECT"; bool is_ip = isIPHostnameStrip(urld); if ((gmode == 2)) { // admin user isexception = true; exceptionreason = o.language_list.getTranslation(601); // Exception client user match. } else if (o.inExceptionIPList(&clientip, clienthost)) { // admin pc matchedip = clienthost == NULL; isexception = true; exceptionreason = o.language_list.getTranslation(600); // Exception client IP match. } else if ((*o.fg[filtergroup]).inExceptionSiteList(urld, true, is_ip, is_ssl)) { // allowed site if ((*o.fg[0]).isOurWebserver(url)) { isourwebserver = true; } else { isexception = true; exceptionreason = o.language_list.getTranslation(602); // Exception site match. exceptioncat = (*o.lm.l[(*o.fg[filtergroup]).exception_site_list]).lastcategory.toCharArray(); } } else if ((*o.fg[filtergroup]).inExceptionURLList(urld, true, is_ip, is_ssl)) { // allowed url isexception = true; exceptionreason = o.language_list.getTranslation(603); // Exception url match. exceptioncat = (*o.lm.l[(*o.fg[filtergroup]).exception_url_list]).lastcategory.toCharArray(); } else if ((rc = (*o.fg[filtergroup]).inExceptionRegExpURLList(urld)) > -1) { isexception = true; // exception regular expression url match: exceptionreason = o.language_list.getTranslation(609); exceptionreason += (*o.fg[filtergroup]).exception_regexpurl_list_source[rc].toCharArray(); exceptioncat = o.lm.l[o.fg[filtergroup]->exception_regexpurl_list_ref[rc]]->category.toCharArray(); } } #ifdef DGDEBUG std::cout << "extracted url:" << urld << std::endl; #endif // don't run scanTest if content scanning is disabled, or on exceptions if contentscanexceptions is off, // or on SSL (CONNECT) requests, or on HEAD requests, or if in AV bypass mode String reqtype(header.requestType()); isconnect = reqtype[0] == 'C'; ishead = reqtype[0] == 'H'; runav = ((*o.fg[filtergroup]).disable_content_scan != 1) && !(isexception && !o.content_scan_exceptions) && !isconnect && !ishead && !isvirusbypass; #ifdef DGDEBUG std::cerr << "runav = " << runav << std::endl; #endif if (((isexception || iscookiebypass || isvirusbypass) // don't filter exception and local web server // Cookie bypass so don't need to add cookie so just CONNECT (unless should virus scan) && !isbannedip // bad users pc && !isbanneduser // bad user && !runav) // needs virus scanning // bad people still need to be able to access the banned page || isourwebserver) { proxysock.readyForOutput(10); // exception on timeout or error header.out(&peerconn, &proxysock, __DGHEADER_SENDALL, true); // send proxy the request docheader.in(&proxysock, persist); persist = docheader.isPersistent(); docheader.out(NULL, &peerconn, __DGHEADER_SENDALL); // only open a two-way tunnel on CONNECT if the return code indicates success if (!(docheader.returnCode() == 200)) { isconnect = false; } try { fdt.reset(); // make a tunnel object // tunnel from client to proxy and back // two-way if SSL fdt.tunnel(proxysock, peerconn, isconnect, docheader.contentLength(), true); // not expected to exception docsize = fdt.throughput; if (!isourwebserver) { // don't log requests to the web server String rtype(header.requestType()); doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, (exceptioncat.length() ? &exceptioncat : NULL), false, isexception, false, &thestart, cachehit, ((!isconnect && persist) ? docheader.returnCode() : 200), mimetype, wasinfected, wasscanned, 0, filtergroup, &header); } } catch(std::exception & e) { } if (persist) continue; proxysock.close(); // close connection to proxy break; } checkme.filtergroup = filtergroup; if ((o.max_ips > 0) && (!gotIPs(clientip))) { #ifdef DGDEBUG std::cout << "no client IP slots left" << std::endl; #endif checkme.isItNaughty = true; checkme.whatIsNaughty = "IP limit exceeded. There is a "; checkme.whatIsNaughty += String(o.max_ips).toCharArray(); checkme.whatIsNaughty += " IP limit set."; checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.whatIsNaughtyCategories = "IP Limit"; } // URL regexp search and replace urlmodified = header.urlRegExp(filtergroup); if (urlmodified) { url = header.url(); urld = header.decode(url); if (url.after("://").contains("/")) { urldomain = url.after("//").before("/"); } else { urldomain = url.after("//"); } // if the user wants, re-check the exception site, URL and regex lists after modification. // this allows you to, for example, force safe search on Google URLs, then flag the // request as an exception, to prevent questionable language in returned site summaries // from blocking the entire request. // this could be achieved with exception phrases (which are, of course, always checked // after the URL) too, but there are cases for both, and flexibility is good. if (o.recheck_replaced_urls && !(isbanneduser || isbannedip)) { bool is_ssl = header.requestType() == "CONNECT"; bool is_ip = isIPHostnameStrip(urld); if ((*o.fg[filtergroup]).inExceptionSiteList(urld, true, is_ip, is_ssl)) { // allowed site if ((*o.fg[0]).isOurWebserver(url)) { isourwebserver = true; } else { isexception = true; exceptionreason = o.language_list.getTranslation(602); // Exception site match. exceptioncat = (*o.lm.l[(*o.fg[filtergroup]).exception_site_list]).lastcategory.toCharArray(); } } else if ((*o.fg[filtergroup]).inExceptionURLList(urld, true, is_ip, is_ssl)) { // allowed url isexception = true; exceptionreason = o.language_list.getTranslation(603); // Exception url match. exceptioncat = (*o.lm.l[(*o.fg[filtergroup]).exception_url_list]).lastcategory.toCharArray(); } else if ((rc = (*o.fg[filtergroup]).inExceptionRegExpURLList(urld)) > -1) { isexception = true; // exception regular expression url match: exceptionreason = o.language_list.getTranslation(609); exceptionreason += (*o.fg[filtergroup]).exception_regexpurl_list_source[rc].toCharArray(); exceptioncat = o.lm.l[o.fg[filtergroup]->exception_regexpurl_list_ref[rc]]->category.toCharArray(); } // don't filter exception and local web server if ((isexception // even after regex URL replacement, we still don't want banned IPs/users viewing exception sites && !isbannedip // bad users pc && !isbanneduser // bad user && !runav) || isourwebserver) { proxysock.readyForOutput(10); // exception on timeout or error header.out(&peerconn, &proxysock, __DGHEADER_SENDALL, true); // send proxy the request docheader.in(&proxysock, persist); persist = docheader.isPersistent(); docheader.out(NULL, &peerconn, __DGHEADER_SENDALL); // only open a two-way tunnel on CONNECT if the return code indicates success if (!(docheader.returnCode() == 200)) { isconnect = false; } try { fdt.reset(); // make a tunnel object // tunnel from client to proxy and back // two-way if SSL fdt.tunnel(proxysock, peerconn, isconnect, docheader.contentLength(), true); // not expected to exception docsize = fdt.throughput; if (!isourwebserver) { // don't log requests to the web server String rtype(header.requestType()); doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, (exceptioncat.length() ? &exceptioncat : NULL), false, isexception, false, &thestart, cachehit, ((!isconnect && persist) ? docheader.returnCode() : 200), mimetype, wasinfected, wasscanned, checkme.naughtiness, filtergroup, &header, // content wasn't modified, but URL was false, true); } } catch(std::exception & e) { } if (persist) continue; proxysock.close(); // close connection to proxy break; } } } // Outgoing header modifications headermodified = header.headerRegExp(filtergroup); // if o.content_scan_exceptions is on then exceptions have to // pass on until later for AV scanning too. // Bloody annoying feature that adds mess and complexity to the code if (isexception) { checkme.isException = true; checkme.whatIsNaughtyLog = exceptionreason; checkme.whatIsNaughtyCategories = exceptioncat; } if (isconnect && !isbypass && !isexception) { if (!authed) { #ifdef DGDEBUG std::cout << "CONNECT: user not authed - getting response to see if it's auth required" << std::endl; #endif // send header to proxy proxysock.readyForOutput(10); header.out(NULL, &proxysock, __DGHEADER_SENDALL, true); // get header from proxy proxysock.checkForInput(120); docheader.in(&proxysock, persist); persist = docheader.isPersistent(); wasrequested = true; if (docheader.returnCode() != 200) { #ifdef DGDEBUG std::cout << "CONNECT: user not authed - doing standard filtering on auth required response" << std::endl; #endif isconnect = false; } } if (isconnect) { #ifdef DGDEBUG std::cout << "CONNECT: user is authed/auth not required - attempting pre-emptive ban" << std::endl; #endif // if its a connect and we don't do filtering on it now then // it will get tunneled and not filtered. We can't tunnel later // as its ssl so we can't see the return header etc // So preemptive banning is forced on with ssl unfortunately. // It is unlikely to cause many problems though. requestChecks(&header, &checkme, &urld, &clientip, &clientuser, filtergroup, isbanneduser, isbannedip); #ifdef DGDEBUG std::cout << "done checking" << std::endl; #endif } } if (!checkme.isItNaughty && isconnect) { // can't filter content of CONNECT if (!wasrequested) { proxysock.readyForOutput(10); // exception on timeout or error header.out(NULL, &proxysock, __DGHEADER_SENDALL, true); // send proxy the request } else { docheader.out(NULL, &peerconn, __DGHEADER_SENDALL); } try { #ifdef DGDEBUG std::cout << "Opening tunnel for CONNECT" << std::endl; #endif fdt.reset(); // make a tunnel object // tunnel from client to proxy and back - *true* two-way tunnel fdt.tunnel(proxysock, peerconn, true); // not expected to exception docsize = fdt.throughput; String rtype(header.requestType()); doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, &checkme.whatIsNaughtyCategories, false, isexception, false, &thestart, cachehit, (wasrequested ? docheader.returnCode() : 200), mimetype, wasinfected, wasscanned, checkme.naughtiness, filtergroup, &header, false, urlmodified); } catch(std::exception & e) { } if (persist) continue; proxysock.close(); // close connection to proxy break; } if (authed && !isexception && !isbypass && (o.max_upload_size > -1) && header.isPostUpload(peerconn)) { if ((o.max_upload_size == 0) || (header.contentLength() > o.max_upload_size)) { #ifdef DGDEBUG std::cout << "Detected POST upload violation by Content-Length header - discarding rest of POST data..." << std::endl; #endif header.discard(&peerconn); checkme.whatIsNaughty = o.max_upload_size == 0 ? o.language_list.getTranslation(700) : o.language_list.getTranslation(701); // Web upload is banned. checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.whatIsNaughtyCategories = "Web upload"; checkme.isItNaughty = true; ispostblock = true; } } #ifdef DGDEBUG // Banning POST requests for unauthed users (when auth is enabled) could potentially prevent users from authenticating. else if (!authed) std::cout << "Skipping POST upload blocking because user is unauthed." << std::endl; #endif // check header sent to proxy - this is done before the send, so that pre-emptive banning // can be used for authenticated users. this gets around the problem of Squid fetching content // from sites when they're just going to get banned: not too big an issue in most cases, but // not good if blocking sites it would be illegal to retrieve, and allows web bugs/tracking // links not to be requested. if (authed && !isbypass && !isexception && !checkme.isItNaughty) { requestChecks(&header, &checkme, &urld, &clientip, &clientuser, filtergroup, isbanneduser, isbannedip); } if (!checkme.isItNaughty) { // the request is ok, so we can now pass it to the proxy, and check the returned header // temp char used in various places here char *i; // send header to proxy if (!wasrequested) { proxysock.readyForOutput(10); header.out(&peerconn, &proxysock, __DGHEADER_SENDALL, true); // get header from proxy proxysock.checkForInput(120); docheader.in(&proxysock, persist); persist = docheader.isPersistent(); wasrequested = true; // so we know where we are later } #ifdef DGDEBUG std::cout << "got header from proxy" << std::endl; if (!persist) std::cout << "header says close, so not persisting" << std::endl; #endif // if we're not careful, we can end up accidentally setting the bypass cookie twice. // because of the code flow, this second cookie ends up with timestamp 0, and is always disallowed. if (isbypass && !isvirusbypass && !iscookiebypass) { #ifdef DGDEBUG std::cout<<"Setting GBYPASS cookie; bypasstimestamp = "< 0) && (cl > o.max_content_filecache_scan_size)) runav = false; } // now that we have the proxy's header too, we can make a better informed decision on whether or not to scan. // this used to be done before we'd grabbed the proxy's header, rendering exceptionvirusmimetypelist useless, // and exceptionvirusextensionlist less effective, because we didn't have a Content-Disposition header. // checkme: split scanTest into two parts? we can check the site & URL lists long before we get here, then // do the rest of the checks later. if (runav) { runav = false; #ifdef DGDEBUG std::cerr << "cs plugins:" << o.csplugins.size() << std::endl; #endif //send header to plugin here needed //also send user and group int csrc = 0; #ifdef DGDEBUG int j = 0; #endif for (std::deque::iterator i = o.csplugins_begin; i != o.csplugins_end; i++) { #ifdef DGDEBUG std::cerr << "running scanTest " << j << std::endl; #endif csrc = ((CSPlugin*)(*i))->scanTest(&header, &docheader, clientuser.c_str(), filtergroup, clientip.c_str()); #ifdef DGDEBUG std::cerr << "scanTest " << j << " returned: " << csrc << std::endl; #endif if (csrc > 0) { sendtoscanner.push_back(true); runav = true; } else { if (csrc < 0) syslog(LOG_ERR, "scanTest returned error: %d", csrc); sendtoscanner.push_back(false); } #ifdef DGDEBUG j++; #endif } } #ifdef DGDEBUG std::cerr << "runav = " << runav << std::endl; #endif // no need to check bypass mode, exception mode, auth required headers, redirections, or banned ip/user (the latter get caught by requestChecks later) if (!isexception && !isbypass && !(isbannedip || isbanneduser) && !docheader.isRedirection() && !docheader.authRequired()) { bool download_exception = false; // Check the exception file site and MIME type lists. mimetype = docheader.getContentType().toCharArray(); if (o.fg[filtergroup]->inExceptionFileSiteList(urld)) download_exception = true; else { if (o.lm.l[o.fg[filtergroup]->exception_mimetype_list]->findInList(mimetype.c_str())) download_exception = true; } // Perform banned MIME type matching if (!download_exception) { // If downloads are blanket blocked, block outright. if (o.fg[filtergroup]->block_downloads) { // did not match the exception list checkme.whatIsNaughty = o.language_list.getTranslation(750); // Blanket file download is active checkme.whatIsNaughty += mimetype; checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.isItNaughty = true; checkme.whatIsNaughtyCategories = "Blanket download block"; } else if ((i = o.lm.l[o.fg[filtergroup]->banned_mimetype_list]->findInList(mimetype.c_str())) != NULL) { // matched the banned list checkme.whatIsNaughty = o.language_list.getTranslation(800); // Banned MIME Type: checkme.whatIsNaughty += i; checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.isItNaughty = true; checkme.whatIsNaughtyCategories = "Banned MIME Type"; } #ifdef DGDEBUG std::cout << mimetype.length() << std::endl; std::cout << ":" << mimetype; std::cout << ":" << std::endl; #endif } // Perform extension matching - if not already matched the exception MIME or site lists if (!download_exception) { // Can't ban file extensions of URLs that just redirect String tempurl(urld); String tempdispos(docheader.disposition()); unsigned int elist, blist; elist = o.fg[filtergroup]->exception_extension_list; blist = o.fg[filtergroup]->banned_extension_list; char* e = NULL; char* b = NULL; if (tempdispos.length() > 1) { // dispos filename must take presidense #ifdef DGDEBUG std::cout << "Disposition filename:" << tempdispos << ":" << std::endl; #endif // The function expects a url so we have to // generate a pseudo one. tempdispos = "http://foo.bar/" + tempdispos; e = o.fg[filtergroup]->inExtensionList(elist, tempdispos); // Only need to check banned list if not blanket blocking if ((e == NULL) && !(o.fg[filtergroup]->block_downloads)) b = o.fg[filtergroup]->inExtensionList(blist, tempdispos); } else { if (!tempurl.contains("?")) { e = o.fg[filtergroup]->inExtensionList(elist, tempurl); if ((e == NULL) && !(o.fg[filtergroup]->block_downloads)) b = o.fg[filtergroup]->inExtensionList(blist, tempurl); } else if (String(mimetype.c_str()).contains("application/")) { while (tempurl.endsWith("?")) { tempurl.chop(); } while (tempurl.contains("/")) { // no slash no url e = o.fg[filtergroup]->inExtensionList(elist, tempurl); if (e != NULL) break; if (!(o.fg[filtergroup]->block_downloads)) b = o.fg[filtergroup]->inExtensionList(blist, tempurl); while (tempurl.contains("/") && !tempurl.endsWith("?")) { tempurl.chop(); } tempurl.chop(); // get rid of the ? } } } // If downloads are blanket blocked, block unless matched the exception list. // If downloads are not blanket blocked, block if matched the banned list and not the exception list. if (o.fg[filtergroup]->block_downloads && (e == NULL)) { // did not match the exception list checkme.whatIsNaughty = o.language_list.getTranslation(751); // Blanket file download is active checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.isItNaughty = true; checkme.whatIsNaughtyCategories = "Blanket download block"; } else if (!(o.fg[filtergroup]->block_downloads) && (e == NULL) && (b != NULL)) { // matched the banned list checkme.whatIsNaughty = o.language_list.getTranslation(900); // Banned extension: checkme.whatIsNaughty += b; checkme.whatIsNaughtyLog = checkme.whatIsNaughty; checkme.isItNaughty = true; checkme.whatIsNaughtyCategories = "Banned extension"; } else if (e != NULL) { // intention is to match either/or of the MIME & extension lists // so if it gets this far, un-naughty it (may have been naughtied by the MIME type list) checkme.isItNaughty = false; } } } // check header sent to proxy - this could be done before the send, but we // want to wait until after the MIME type & extension checks, because they may // act as a quicker rejection. also so as not to pre-emptively ban currently // un-authed users. if (!authed && !isbypass && !isexception && !checkme.isItNaughty && !docheader.authRequired()) { requestChecks(&header, &checkme, &urld, &clientip, &clientuser, filtergroup, isbanneduser, isbannedip); } // check body from proxy // can't do content filtering on HEAD or redirections (no content) // actually, redirections CAN have content if (!checkme.isItNaughty && (cl != 0) && !ishead) { if (((docheader.isContentType("text") || docheader.isContentType("-")) && !isexception) || runav) { // don't search the cache if scan_clean_cache disabled & runav true (won't have been cached) // also don't search cache for auth required headers (same reason) // checkme: does not searching the cache if scan_clean_cache is disabled break the fancy DM's bypass stuff? // probably, since it uses a "magic" status code in the cache; easier than coding yet another hash type. if (o.url_cache_number > 0 && !(!o.scan_clean_cache && runav) && !docheader.authRequired()) { if (wasClean(urld, filtergroup)) { wasclean = true; cachehit = true; runav = false; #ifdef DGDEBUG std::cout << "url was clean skipping content and AV checking" << std::endl; #endif } } // despite the debug note above, we do still go through contentFilter for cached non-exception HTML, // as content replacement rules need to be applied. waschecked = true; if (runav) { #ifdef DGDEBUG std::cout << "Filtering with expectation of a possible csmessage" << std::endl; #endif String csmessage; contentFilter(&docheader, &header, &docbody, &proxysock, &peerconn, &headersent, &pausedtoobig, &docsize, &checkme, runav, wasclean, filtergroup, &sendtoscanner, &clientuser, &clientip, &wasinfected, &wasscanned, isbypass, urld, urldomain, &scanerror, contentmodified, &csmessage); if (csmessage.length() > 0) { #ifdef DGDEBUG std::cout << "csmessage found: " << csmessage << std::endl; #endif exceptionreason = csmessage.toCharArray(); } } else { contentFilter(&docheader, &header, &docbody, &proxysock, &peerconn, &headersent, &pausedtoobig, &docsize, &checkme, runav, wasclean, filtergroup, &sendtoscanner, &clientuser, &clientip, &wasinfected, &wasscanned, isbypass, urld, urldomain, &scanerror, contentmodified, NULL); } } } } if (!isexception && checkme.isException) { isexception = true; exceptionreason = checkme.whatIsNaughtyLog; } if (o.url_cache_number > 0) { // add to cache if: wasn't already there, wasn't naughty, wasn't allowed by bypass/soft block, was text, // was virus scanned and scan_clean_cache is enabled, was a GET request, // and response was not a set of auth required headers (we haven't checked // the actual content, just the proxy's auth error page!). // also don't add "not modified" responses to the cache - if someone adds // an entry and does a soft restart, we don't want the site to end up in // the clean cache because someone who's already been to it hits refresh. if (!wasclean && !checkme.isItNaughty && !isbypass && (docheader.isContentType("text") || (runav && o.scan_clean_cache)) && (header.requestType() == "GET") && (docheader.returnCode() == 200)) { addToClean(urld, filtergroup); } } // then we deny. previously, this checked the isbypass flag too; now, since bypass requests only undergo the same checking // as exceptions, it needn't. and in fact it mustn't, if bypass requests are to be virus scanned/blocked in the same manner as exceptions. // make sure we keep track of whether or not logging has been performed, as we may be in stealth mode and don't want to double log. bool logged = false; if (checkme.isItNaughty) { String rtype(header.requestType()); #ifdef DGDEBUG std::cout<<"Category: "< -1) { // must have been a 'fancy' // download manager so we need to send a special link which // will get recognised and cause DG to send the temp file to // the browser. The link will be the original URL with some // magic appended to it like the bypass system. // format is: // GSBYPASS=hash(ip+url+tempfilename+mime+disposition+secret) // &N=tempfilename&M=mimetype&D=dispos String ip(clientip); String tempfilename(docbody.tempfilepath.after("/tf")); String tempfilemime(docheader.getContentType()); String tempfiledis(miniURLEncode(docheader.disposition().toCharArray()).c_str()); String secret((*o.fg[filtergroup]).magic.c_str()); String magic(ip + url + tempfilename + tempfilemime + tempfiledis + secret); String hashed(magic.md5()); #ifdef DGDEBUG std::cout << "sending magic link to client: " << ip << " " << url << " " << tempfilename << " " << tempfilemime << " " << tempfiledis << " " << secret << " " << hashed << std::endl; #endif String sendurl(url); if (!sendurl.after("://").contains("/")) { sendurl += "/"; } if (sendurl.contains("?")) { sendurl = sendurl + "&GSBYPASS=" + hashed + "&N="; } else { sendurl = sendurl + "?GSBYPASS=" + hashed + "&N="; } sendurl += tempfilename + "&M=" + tempfilemime + "&D=" + tempfiledis; docbody.dm_plugin->sendLink(peerconn, sendurl, url); // can't persist after this - DM plugins don't generally send a Content-Length. persist = false; } else { #ifdef DGDEBUG std::cout << "sending body to client" << std::endl; #endif docbody.out(&peerconn); // send doc body to client } #ifdef DGDEBUG if (pausedtoobig) { std::cout << "sent PARTIAL body to client" << std::endl; } else { std::cout << "sent body to client" << std::endl; } #endif if (pausedtoobig && !docbody.dontsendbody) { #ifdef DGDEBUG std::cout << "about to start tunnel to send the rest" << std::endl; #endif fdt.reset(); #ifdef DGDEBUG std::cout << "tunnel activated" << std::endl; #endif fdt.tunnel(proxysock, peerconn, false, docheader.contentLength() - docsize, true); docsize += fdt.throughput; String rtype(header.requestType()); if (!logged) doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, &checkme.whatIsNaughtyCategories, false, isexception, docheader.isContentType("text"), &thestart, cachehit, docheader.returnCode(), mimetype, wasinfected, wasscanned, checkme.naughtiness, filtergroup, &header, contentmodified, urlmodified, headermodified); } } else if (!ishead /*&& !docheader.isRedirection()*/) { // was not supposed to be checked fdt.reset(); #ifdef DGDEBUG std::cout << "tunnel activated" << std::endl; #endif fdt.tunnel(proxysock, peerconn, isconnect, docheader.contentLength(), true); docsize = fdt.throughput; String rtype(header.requestType()); if (!logged) doLog(clientuser, clientip, url, header.port, exceptionreason, rtype, docsize, &checkme.whatIsNaughtyCategories, false, isexception, docheader.isContentType("text"), &thestart, cachehit, docheader.returnCode(), mimetype, wasinfected, wasscanned, checkme.naughtiness, filtergroup, &header, contentmodified, urlmodified, headermodified); } } // while persist } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "connection handler caught an exception: " << e.what() << std::endl; #endif proxysock.close(); // close connection to proxy return; } proxysock.close(); // close conection to squid try { #ifdef DGDEBUG std::cerr << "Attempting graceful connection close" << std::endl; #endif int fd = peerconn.getFD(); shutdown(fd, SHUT_WR); char buff[2]; peerconn.readFromSocket(buff, 2, 0, 5); } catch(std::exception & e) { return; } return; } // decide whether or not to perform logging, categorise the log entry, and write it. void ConnectionHandler::doLog(std::string &who, std::string &from, String &where, unsigned int &port, std::string &what, String &how, off_t &size, std::string *cat, bool isnaughty, bool isexception, bool istext, struct timeval *thestart, bool cachehit, int code, std::string &mimetype, bool wasinfected, bool wasscanned, int naughtiness, int filtergroup, HTTPHeader* reqheader, bool contentmodified, bool urlmodified, bool headermodified) { // don't log if logging disabled entirely, or if it's an ad block and ad logging is disabled, // or if it's an exception and exception logging is disabled if ( (o.ll == 0) || ((cat != NULL) && !o.log_ad_blocks && (strstr(cat->c_str(),"ADs") != NULL)) || ((o.log_exception_hits == 0) && isexception)) { #ifdef DGDEBUG if (o.ll != 0) if (isexception) std::cout << "Not logging exceptions" << std::endl; else std::cout << "Not logging 'ADs' blocks" << std::endl; #endif return; } std::string data, cr("\n"); if ((isexception && (o.log_exception_hits == 2)) || isnaughty || o.ll == 3 || (o.ll == 2 && istext)) { // put client hostname in log if enabled. // for banned & exception IP/hostname matches, we want to output exactly what was matched against, // be it hostname or IP - therefore only do lookups here when we don't already have a cached hostname, // and we don't have a straight IP match agaisnt the banned or exception IP lists. if (o.log_client_hostnames && (clienthost == NULL) && !matchedip && !o.anonymise_logs) { #ifdef DGDEBUG std::cout<<"logclienthostnames enabled but reverseclientiplookups disabled; lookup forced."< *names = ipToHostname(from.c_str()); if (names->size() > 0) clienthost = new std::string(names->front().toCharArray()); delete names; } // Search 'log-only' domain, url and regexp url lists std::string *newcat = NULL; if (!cat || cat->length() == 0) { #ifdef DGDEBUG std::cout << "Checking for log-only categories" << std::endl; #endif const char* c = o.fg[filtergroup]->inLogSiteList(where); #ifdef DGDEBUG if (c) std::cout << "Found log-only domain category: " << c << std::endl; #endif if (!c) { c = o.fg[filtergroup]->inLogURLList(where); #ifdef DGDEBUG if (c) std::cout << "Found log-only URL category: " << c << std::endl; #endif } if (!c) { c = o.fg[filtergroup]->inLogRegExpURLList(where); #ifdef DGDEBUG if (c) std::cout << "Found log-only regexp URL category: " << c << std::endl; #endif } if (c) { newcat = new std::string(c); cat = newcat; } } #ifdef DGDEBUG else std::cout << "Not looking for log-only category; current cat string is: " << *cat << " (" << cat->length() << ")" << std::endl; #endif // Formatting code moved into log_listener in FatController.cpp // Original patch by J. Gauthier #ifdef DGDEBUG std::cout << "Building raw log data string... "; #endif data = String(isexception)+cr; data += ( cat ? (*cat) + cr : cr); data += String(isnaughty)+cr; data += String(naughtiness)+cr; data += where+cr; data += what+cr; data += how+cr; data += who+cr; data += from+cr; data += String(port)+cr; data += String(wasscanned)+cr; data += String(wasinfected)+cr; data += String(contentmodified)+cr; data += String(urlmodified)+cr; data += String(headermodified)+cr; data += String(size)+cr; data += String(filtergroup)+cr; data += String(code)+cr; data += String(cachehit)+cr; data += String(mimetype)+cr; data += String((*thestart).tv_sec)+cr; data += String((*thestart).tv_usec)+cr; data += (clienthost ? (*clienthost) + cr : cr); if (o.log_user_agent) data += (reqheader ? reqheader->userAgent() + cr : cr); #ifdef DGDEBUG std::cout << "...built" << std::endl; #endif delete newcat; // connect to dedicated logging proc UDSocket ipcsock; if (ipcsock.getFD() < 0) { if (!is_daemonised) std::cout << "Error creating IPC socket to log" << std::endl; syslog(LOG_ERR, "Error creating IPC socket to log"); return; } if (ipcsock.connect(o.ipc_filename.c_str()) < 0) { if (!is_daemonised) std::cout << "Error connecting via IPC socket to log: " << strerror(errno) << std::endl; syslog(LOG_ERR, "Error connecting via IPC socket to log: %s", strerror(errno)); ipcsock.close(); return; } // send data try { ipcsock.setTimeout(10); ipcsock.writeString(data.c_str()); ipcsock.close(); } catch (std::exception &e) { syslog(LOG_INFO, "Could not write to logging process: %s", e.what()); #ifdef DGDEBUG std::cout << "Could not write to logging process: " << e.what() << std::endl; #endif } } } // check the request header is OK (client host/user/IP allowed to browse, site not banned, upload not too big) void ConnectionHandler::requestChecks(HTTPHeader *header, NaughtyFilter *checkme, String *urld, std::string *clientip, std::string *clientuser, int filtergroup, bool &isbanneduser, bool &isbannedip) { if (isbannedip) { (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyLog = o.language_list.getTranslation(100); // Your IP address is not allowed to web browse: (*checkme).whatIsNaughtyLog += clienthost ? *clienthost : *clientip; (*checkme).whatIsNaughty = o.language_list.getTranslation(101); // Your IP address is not allowed to web browse. (*checkme).whatIsNaughtyCategories = "Banned Client IP"; return; } else if (isbanneduser) { (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyLog = o.language_list.getTranslation(102); // Your username is not allowed to web browse: (*checkme).whatIsNaughtyLog += (*clientuser); (*checkme).whatIsNaughty = (*checkme).whatIsNaughtyLog; (*checkme).whatIsNaughtyCategories = "Banned User"; return; } char *i; int j; String temp; temp = (*urld); // only apply bans to things not in the grey lists bool is_ssl = header->requestType() == "CONNECT"; bool is_ip = isIPHostnameStrip(temp); if (!((*o.fg[filtergroup]).inGreySiteList(temp, true, is_ip, is_ssl) || (*o.fg[filtergroup]).inGreyURLList(temp, true, is_ip, is_ssl))) { if (!(*checkme).isItNaughty) { if ((i = (*o.fg[filtergroup]).inBannedSiteList(temp, true, is_ip, is_ssl)) != NULL) { // need to reintroduce ability to produce the blanket block messages (*checkme).whatIsNaughty = o.language_list.getTranslation(500); // banned site (*checkme).whatIsNaughty += i; (*checkme).whatIsNaughtyLog = (*checkme).whatIsNaughty; (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyCategories = (*o.lm.l[(*o.fg[filtergroup]).banned_site_list]).lastcategory.toCharArray(); } } if (!(*checkme).isItNaughty) { if ((i = (*o.fg[filtergroup]).inBannedURLList(temp, true, is_ip, is_ssl)) != NULL) { (*checkme).whatIsNaughty = o.language_list.getTranslation(501); // Banned URL: (*checkme).whatIsNaughty += i; (*checkme).whatIsNaughtyLog = (*checkme).whatIsNaughty; (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyCategories = (*o.lm.l[(*o.fg[filtergroup]).banned_url_list]).lastcategory.toCharArray(); } else if ((j = (*o.fg[filtergroup]).inBannedRegExpURLList(temp)) >= 0) { (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyLog = o.language_list.getTranslation(503); // Banned Regular Expression URL: (*checkme).whatIsNaughtyLog += (*o.fg[filtergroup]).banned_regexpurl_list_source[j].toCharArray(); (*checkme).whatIsNaughty = o.language_list.getTranslation(504); // Banned Regular Expression URL found. (*checkme).whatIsNaughtyCategories = (*o.lm.l[(*o.fg[filtergroup]).banned_regexpurl_list_ref[j]]).category.toCharArray(); } else if ((j = o.fg[filtergroup]->inBannedRegExpHeaderList(header->header)) >= 0) { checkme->isItNaughty = true; checkme->whatIsNaughtyLog = o.language_list.getTranslation(508); checkme->whatIsNaughtyLog += o.fg[filtergroup]->banned_regexpheader_list_source[j].toCharArray(); checkme->whatIsNaughty = o.language_list.getTranslation(509); checkme->whatIsNaughtyCategories = o.lm.l[o.fg[filtergroup]->banned_regexpheader_list_ref[j]]->category.toCharArray(); } } // look for URLs within URLs - ban, for example, images originating from banned sites during a Google image search. if (!(*checkme).isItNaughty && (*o.fg[filtergroup]).deep_url_analysis) { #ifdef DGDEBUG std::cout << "starting deep analysis" << std::endl; #endif String deepurl(temp.after("p://")); deepurl = header->decode(deepurl,true); while (deepurl.contains(":")) { deepurl = deepurl.after(":"); while (deepurl.startsWith(":") || deepurl.startsWith("/")) { deepurl.lop(); } #ifdef DGDEBUG std::cout << "deep analysing: " << deepurl << std::endl; #endif if (o.fg[filtergroup]->inExceptionSiteList(deepurl) || o.fg[filtergroup]->inGreySiteList(deepurl) || o.fg[filtergroup]->inExceptionURLList(deepurl) || o.fg[filtergroup]->inGreyURLList(deepurl)) { #ifdef DGDEBUG std::cout << "deep site found in exception/grey list; skipping" << std::endl; #endif continue; } if ((i = (*o.fg[filtergroup]).inBannedSiteList(deepurl)) != NULL) { (*checkme).whatIsNaughty = o.language_list.getTranslation(500); // banned site (*checkme).whatIsNaughty += i; (*checkme).whatIsNaughtyLog = (*checkme).whatIsNaughty; (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyCategories = (*o.lm.l[(*o.fg[filtergroup]).banned_site_list]).lastcategory.toCharArray(); #ifdef DGDEBUG std::cout << "deep site: " << deepurl << std::endl; #endif } else if ((i = (*o.fg[filtergroup]).inBannedURLList(deepurl)) != NULL) { (*checkme).whatIsNaughty = o.language_list.getTranslation(501); // Banned URL: (*checkme).whatIsNaughty += i; (*checkme).whatIsNaughtyLog = (*checkme).whatIsNaughty; (*checkme).isItNaughty = true; (*checkme).whatIsNaughtyCategories = (*o.lm.l[(*o.fg[filtergroup]).banned_url_list]).lastcategory.toCharArray(); #ifdef DGDEBUG std::cout << "deep url: " << deepurl << std::endl; #endif } } #ifdef DGDEBUG std::cout << "done deep analysis" << std::endl; #endif } } // grey site/URL list } // based on patch by Aecio F. Neto (afn@harvest.com.br) - Harvest Consultoria (http://www.harvest.com.br) // show the relevant banned page/image/CGI based on report level setting, request type etc. bool ConnectionHandler::denyAccess(Socket * peerconn, Socket * proxysock, HTTPHeader * header, HTTPHeader * docheader, String * url, NaughtyFilter * checkme, std::string * clientuser, std::string * clientip, int filtergroup, bool ispostblock, int headersent, bool wasinfected, bool scanerror) { int reporting_level = o.fg[filtergroup]->reporting_level; try { // writestring throws exception on error/timeout // flags to enable filter/infection bypass hash generation bool filterhash = false; bool virushash = false; // flag to enable internal generation of hashes (i.e. obey the "-1" setting; to allow the modes but disable hash generation) // (if disabled, just output '1' or '2' to show that the CGI should generate a filter/virus bypass hash; // otherwise, real hashes get put into substitution variables/appended to the ban CGI redirect URL) bool dohash = false; if (reporting_level > 0) { // generate a filter bypass hash if (!wasinfected && ((*o.fg[filtergroup]).bypass_mode != 0) && !ispostblock) { #ifdef DGDEBUG std::cout << "Enabling filter bypass hash generation" << std::endl; #endif filterhash = true; if (o.fg[filtergroup]->bypass_mode > 0) dohash = true; } // generate an infection bypass hash else if (wasinfected && (*o.fg[filtergroup]).infection_bypass_mode != 0) { // only generate if scanerror (if option to only bypass scan errors is enabled) if ((*o.fg[filtergroup]).infection_bypass_errors_only ? scanerror : true) { #ifdef DGDEBUG std::cout << "Enabling infection bypass hash generation" << std::endl; #endif virushash = true; if (o.fg[filtergroup]->infection_bypass_mode > 0) dohash = true; } } } // the user is using the full whack of custom banned images and/or HTML templates if (reporting_level == 3 || (headersent > 0 && reporting_level > 0)) { // if reporting_level = 1 or 2 and headersent then we can't // send a redirect so we have to display the template instead (*proxysock).close(); // finished with proxy (*peerconn).readyForOutput(10); if ((*header).requestType().startsWith("CONNECT")) { // if it's a CONNECT then headersent can't be set // so we don't need to worry about it // if preemptive banning is not in place then a redirect // is not guaranteed to ban the site so we have to write // an access denied page. Unfortunately IE does not // work with access denied pages on SSL more than a few // hundred bytes so we have to use a crap boring one // instead. Nothing can be done about it - blame // mickysoft. String writestring("HTTP/1.0 403 "); writestring += o.language_list.getTranslation(500); // banned site writestring += "\nContent-Type: text/html\n\nDansGuardian - "; writestring += o.language_list.getTranslation(500); // banned site writestring += "

DansGuardian - "; writestring += o.language_list.getTranslation(500); // banned site writestring += "

"; writestring += (*url); writestring += "\n"; try { // writestring throws exception on error/timeout (*peerconn).writeString(writestring.toCharArray()); } catch(std::exception & e) { } } else { // we're dealing with a non-SSL'ed request, and have the option of using the custom banned image/page directly bool replaceimage = false; if (o.use_custom_banned_image) { // It would be much nicer to do a mime comparison // and see if the type is image/* but the header // never (almost) gets back from squid because // it gets denied before then. // This method is prone to over image replacement // but will work most of the time. String lurl((*url)); lurl.toLower(); if (lurl.endsWith(".gif") || lurl.endsWith(".jpg") || lurl.endsWith(".jpeg") || lurl.endsWith(".jpe") || lurl.endsWith(".png") || lurl.endsWith(".bmp") || (*docheader).isContentType("image/")) { replaceimage = true; } } // if we're denying an image request, show the image; otherwise, show the HTML page. // (or advanced ad block page, or HTML page with bypass URLs) if (replaceimage) { if (headersent == 0) { (*peerconn).writeString("HTTP/1.0 200 OK\n"); } o.banned_image.display(peerconn); } else { // advanced ad blocking - if category contains ADs, wrap ad up in an "ad blocked" message, // which provides a link to the original URL if you really want it. primarily // for IFRAMEs, which will end up containing this link instead of the ad (standard non-IFRAMEd // ad images still get image-replaced.) if (strstr(checkme->whatIsNaughtyCategories.c_str(), "ADs") != NULL) { String writestring("HTTP/1.0 200 "); writestring += o.language_list.getTranslation(1101); // advert blocked writestring += "\nContent-Type: text/html\n\nGuardian - "; writestring += o.language_list.getTranslation(1101); // advert blocked writestring += "
"; writestring += o.language_list.getTranslation(1101); // advert blocked writestring += "
\n"; try { // writestring throws exception on error/timeout (*peerconn).writeString(writestring.toCharArray()); } catch (std::exception& e) {} } // Mod by Ernest W Lessenger Mon 2nd February 2004 // Other bypass code mostly written by Ernest also // create temporary bypass URL to show on denied page else { String hashed; // generate valid hash locally if enabled if (dohash) { hashed = hashedURL(url, filtergroup, clientip, virushash); } // otherwise, just generate flags showing what to generate else if (filterhash) { hashed = "HASH=1"; } else if (virushash) { hashed = "HASH=2"; } if (headersent == 0) { (*peerconn).writeString("HTTP/1.0 200 OK\n"); } if (headersent < 2) { (*peerconn).writeString("Content-type: text/html\n\n"); } // if the header has been sent then likely displaying the // template will break the download, however as this is // only going to be happening if the unsafe trickle // buffer method is used and we want the download to be // broken we don't mind too much o.fg[filtergroup]->getHTMLTemplate()->display(peerconn, url, (*checkme).whatIsNaughty, (*checkme).whatIsNaughtyLog, // grab either the full category list or the thresholded list (checkme->usedisplaycats ? checkme->whatIsNaughtyDisplayCategories : checkme->whatIsNaughtyCategories), clientuser, clientip, clienthost, filtergroup, hashed); } } } } // the user is using the CGI rather than the HTML template - so issue a redirect with parameters filled in on GET string else if (reporting_level > 0) { // grab either the full category list or the thresholded list std::string cats; cats = checkme->usedisplaycats ? checkme->whatIsNaughtyDisplayCategories : checkme->whatIsNaughtyCategories; String hashed; // generate valid hash locally if enabled if (dohash) { hashed = hashedURL(url, filtergroup, clientip, virushash); } // otherwise, just generate flags showing what to generate else if (filterhash) { hashed = "1"; } else if (virushash) { hashed = "2"; } (*proxysock).close(); // finshed with proxy (*peerconn).readyForOutput(10); if ((*checkme).whatIsNaughty.length() > 2048) { (*checkme).whatIsNaughty = String((*checkme).whatIsNaughty.c_str()).subString(0, 2048).toCharArray(); } if ((*checkme).whatIsNaughtyLog.length() > 2048) { (*checkme).whatIsNaughtyLog = String((*checkme).whatIsNaughtyLog.c_str()).subString(0, 2048).toCharArray(); } String writestring("HTTP/1.0 302 Redirect\n"); writestring += "Location: "; writestring += o.fg[filtergroup]->access_denied_address; if (o.non_standard_delimiter) { writestring += "?DENIEDURL=="; writestring += miniURLEncode((*url).toCharArray()).c_str(); writestring += "::IP=="; writestring += (*clientip).c_str(); writestring += "::USER=="; writestring += (*clientuser).c_str(); if (clienthost != NULL) { writestring += "::HOST=="; writestring += clienthost->c_str(); } writestring += "::CATEGORIES=="; writestring += miniURLEncode(cats.c_str()).c_str(); if (virushash || filterhash) { // output either a genuine hash, or just flags if (dohash) { writestring += "::"; writestring += hashed.before("=").toCharArray(); writestring += "=="; writestring += hashed.after("=").toCharArray(); } else { writestring += "::HASH=="; writestring += hashed.toCharArray(); } } writestring += "::REASON=="; } else { writestring += "?DENIEDURL="; writestring += miniURLEncode((*url).toCharArray()).c_str(); writestring += "&IP="; writestring += (*clientip).c_str(); writestring += "&USER="; writestring += (*clientuser).c_str(); if (clienthost != NULL) { writestring += "&HOST="; writestring += clienthost->c_str(); } writestring += "&CATEGORIES="; writestring += miniURLEncode(cats.c_str()).c_str(); if (virushash || filterhash) { // output either a genuine hash, or just flags if (dohash) { writestring += "&"; writestring += hashed.toCharArray(); } else { writestring += "&HASH="; writestring += hashed.toCharArray(); } } writestring += "&REASON="; } if (reporting_level == 1) { writestring += miniURLEncode((*checkme).whatIsNaughty.c_str()).c_str(); } else { writestring += miniURLEncode((*checkme).whatIsNaughtyLog.c_str()).c_str(); } writestring += "\n\n"; (*peerconn).writeString(writestring.toCharArray()); #ifdef DGDEBUG // debug stuff surprisingly enough std::cout << "******* redirecting to:" << std::endl; std::cout << writestring << std::endl; std::cout << "*******" << std::endl; #endif } // the user is using the barebones banned page else if (reporting_level == 0) { (*proxysock).close(); // finshed with proxy String writestring("HTTP/1.0 200 OK\n"); writestring += "Content-type: text/html\n\n"; writestring += "DansGuardian - "; writestring += o.language_list.getTranslation(1); // access denied writestring += "

DansGuardian - "; writestring += o.language_list.getTranslation(1); // access denied writestring += "

"; (*peerconn).readyForOutput(10); (*peerconn).writeString(writestring.toCharArray()); #ifdef DGDEBUG // debug stuff surprisingly enough std::cout << "******* displaying:" << std::endl; std::cout << writestring << std::endl; std::cout << "*******" << std::endl; #endif } // stealth mode else if (reporting_level == -1) { (*checkme).isItNaughty = false; // dont block } } catch(std::exception & e) { } // we blocked the request, so flush the client connection & close the proxy connection. if ((*checkme).isItNaughty) { try { (*peerconn).readyForOutput(10); //as best a flush as I can } catch(std::exception & e) { } (*proxysock).close(); // close connection to proxy // we said no to the request, so return true, indicating exit the connhandler return true; } return false; } // do content scanning (AV filtering) and naughty filtering void ConnectionHandler::contentFilter(HTTPHeader *docheader, HTTPHeader *header, DataBuffer *docbody, Socket *proxysock, Socket *peerconn, int *headersent, bool *pausedtoobig, off_t *docsize, NaughtyFilter *checkme, bool runav, bool wasclean, int filtergroup, std::deque *sendtoscanner, std::string *clientuser, std::string *clientip, bool *wasinfected, bool *wasscanned, bool isbypass, String &url, String &domain, bool *scanerror, bool &contentmodified, String *csmessage) { proxysock->checkForInput(120); bool compressed = docheader->isCompressed(); if (compressed) { #ifdef DGDEBUG std::cout << "Decompressing as we go....." << std::endl; #endif docbody->setDecompress(docheader->contentEncoding()); } #ifdef DGDEBUG std::cout << docheader->contentEncoding() << std::endl; std::cout << "about to get body from proxy" << std::endl; #endif (*pausedtoobig) = docbody->in(proxysock, peerconn, header, docheader, runav, headersent); // get body from proxy // checkme: surely if pausedtoobig is true, we just want to break here? // the content is larger than max_content_filecache_scan_size if it was downloaded for scanning, // and larger than max_content_filter_size if not. // in fact, why don't we check the content length (when it's not -1) before even triggering the download managers? #ifdef DGDEBUG if ((*pausedtoobig)) { std::cout << "got PARTIAL body from proxy" << std::endl; } else { std::cout << "got body from proxy" << std::endl; } #endif off_t dblen; bool isfile = false; if (docbody->tempfilesize > 0) { dblen = docbody->tempfilesize; isfile = true; } else { dblen = docbody->buffer_length; } // don't scan zero-length buffers (waste of AV resources, especially with external scanners (ICAP)). // these were encountered browsing opengroup.org, caused by a stats script. (PRA 21/09/2005) // if we wanted to honour a hypothetical min_content_scan_size, we'd do it here. if (((*docsize) = dblen) == 0) { #ifdef DGDEBUG std::cout << "Not scanning zero-length body" << std::endl; #endif // it's not inconceivable that we received zlib or gzip encoded content // that is, after decompression, zero length. we need to cater for this. // seen on SW's internal MediaWiki. docbody->swapbacktocompressed(); return; } if (!wasclean) { // was not clean or no urlcache // fixed to obey maxcontentramcachescansize if (runav && (isfile ? dblen <= o.max_content_filecache_scan_size : dblen <= o.max_content_ramcache_scan_size)) { int csrc = 0; std::deque::iterator j = sendtoscanner->begin(); #ifdef DGDEBUG int k = 0; #endif for (std::deque::iterator i = o.csplugins_begin; i != o.csplugins_end; i++) { if (*j) { (*wasscanned) = true; if (isfile) { #ifdef DGDEBUG std::cout << "Running scanFile" << std::endl; #endif csrc = ((CSPlugin*)(*i))->scanFile(header, docheader, clientuser->c_str(), filtergroup, clientip->c_str(), docbody->tempfilepath.toCharArray()); if ((csrc != DGCS_CLEAN) && (csrc != DGCS_WARNING)) { unlink(docbody->tempfilepath.toCharArray()); // delete infected (or unscanned due to error) file straight away } } else { #ifdef DGDEBUG std::cout << "Running scanMemory" << std::endl; #endif csrc = ((CSPlugin*)(*i))->scanMemory(header, docheader, clientuser->c_str(), filtergroup, clientip->c_str(), docbody->data, docbody->buffer_length); } #ifdef DGDEBUG std::cerr << "AV scan " << k << " returned: " << csrc << std::endl; #endif if (csrc < 0) { syslog(LOG_ERR, "scanFile/Memory returned error: %d", csrc); //TODO: have proper error checking/reporting here? //at the very least, integrate with the translation system. checkme->whatIsNaughty = "WARNING: Could not perform virus scan!"; checkme->whatIsNaughtyLog = ((CSPlugin*)(*i))->getLastMessage().toCharArray(); checkme->whatIsNaughtyCategories = "Content scanning"; checkme->isItNaughty = true; checkme->isException = false; (*wasinfected) = true; (*scanerror) = true; break; } else if (csrc == DGCS_INFECTED) { checkme->whatIsNaughty = o.language_list.getTranslation(1100); String virname(((CSPlugin*)(*i))->getLastVirusName()); if (virname.length() > 0) { checkme->whatIsNaughty += " "; checkme->whatIsNaughty += virname.toCharArray(); } checkme->whatIsNaughtyLog = checkme->whatIsNaughty; checkme->whatIsNaughtyCategories = "Content scanning"; checkme->isItNaughty = true; checkme->isException = false; (*wasinfected) = true; (*scanerror) = false; break; } else if (csrc == DGCS_WARNING) { // Scanner returned a warning. File wasn't infected, but wasn't scanned properly, either. (*wasscanned) = false; (*scanerror) = false; #ifdef DGDEBUG std::cout << ((CSPlugin*)(*i))->getLastMessage() << std::endl; #endif (*csmessage) = ((CSPlugin*)(*i))->getLastMessage(); } else if (csrc != DGCS_CLEAN) { syslog(LOG_ERR, "Unknown return code from content scanner: %d", csrc); } } j++; #ifdef DGDEBUG k++; #endif } #ifdef DGDEBUG std::cout << "finished running AV" << std::endl; system("date"); #endif } #ifdef DGDEBUG else if (runav) { std::cout << "content length large so skipping content scanning (virus) filtering" << std::endl; } system("date"); #endif if (!checkme->isItNaughty && !checkme->isException && !isbypass && (dblen <= o.max_content_filter_size) && !docheader->authRequired() && (docheader->isContentType("text") || docheader->isContentType("-"))) { checkme->checkme(docbody, url, domain); // content filtering } #ifdef DGDEBUG else { std::cout << "Skipping content filtering: "; if (dblen > o.max_content_filter_size) std::cout << "Content too large"; else if (checkme->isException) std::cout << "Is flagged as an exception"; else if (checkme->isItNaughty) std::cout << "Is already flagged as naughty (content scanning)"; else if (isbypass) std::cout << "Is flagged as a bypass"; else if (docheader->authRequired()) std::cout << "Is a set of auth required headers"; else if (!docheader->isContentType("text")) std::cout << "Not text"; std::cout << std::endl; } #endif } // don't do phrase filtering or content replacement on exception/bypass accesses if (checkme->isException || isbypass) { // don't forget to swap back to compressed! docbody->swapbacktocompressed(); return; } if ((dblen <= o.max_content_filter_size) && !checkme->isItNaughty && docheader->isContentType("text")) { contentmodified = docbody->contentRegExp(filtergroup); // content modifying uses global variable } #ifdef DGDEBUG else { std::cout << "Skipping content modification: "; if (dblen > o.max_content_filter_size) std::cout << "Content too large"; else if (!docheader->isContentType("text")) std::cout << "Not text"; else if (checkme->isItNaughty) std::cout << "Already flagged as naughty"; std::cout << std::endl; } system("date"); #endif if (contentmodified) { // this would not include infected/cured files // if the content was modified then it must have fit in ram so no // need to worry about swapped to disk stuff #ifdef DGDEBUG std::cout << "content modification made" << std::endl; #endif if (compressed) { docheader->removeEncoding(docbody->buffer_length); // need to modify header to mark as not compressed // it also modifies Content-Length as well } else { docheader->setContentLength(docbody->buffer_length); } } else { docbody->swapbacktocompressed(); // if we've not modified it might as well go back to // the original compressed version (if there) and send // that to the browser } } dansguardian-2.10.1.1/src/md5.hpp0000644001165000116500000001253611110523210013271 00000000000000/* Declaration of functions and data types used for MD5 sum computing library functions. Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MD5_H #define _MD5_H 1 #include #if defined HAVE_LIMITS_H || _LIBC # include #endif /* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that would require that the configure script compile and *run* the resulting executable. Locally running cross-compiled executables is usually not possible. */ #ifdef _LIBC # include typedef u_int32_t md5_uint32; #else # if defined __STDC__ && __STDC__ # define UINT_MAX_32_BITS 4294967295U # else # define UINT_MAX_32_BITS 0xFFFFFFFF # endif /* If UINT_MAX isn't defined, assume it's a 32-bit type. This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, and only modern systems (that certainly have ) have 64+-bit integral types. */ # ifndef UINT_MAX # define UINT_MAX UINT_MAX_32_BITS # endif # if UINT_MAX == UINT_MAX_32_BITS typedef unsigned int md5_uint32; # else # if USHRT_MAX == UINT_MAX_32_BITS typedef unsigned short md5_uint32; # else # if ULONG_MAX == UINT_MAX_32_BITS typedef unsigned long md5_uint32; # else /* The following line is intended to evoke an error. Using #error is not portable enough. */ "Cannot determine unsigned 32-bit data type." # endif # endif # endif #endif #undef __P #if defined (__STDC__) && __STDC__ # define __P(x) x #else # define __P(x) () #endif /* Structure to save state of computation between the single steps. */ struct md5_ctx { md5_uint32 A; md5_uint32 B; md5_uint32 C; md5_uint32 D; md5_uint32 total[2]; md5_uint32 buflen; #ifndef __attribute__ char buffer[128]; #else char buffer[128] __attribute__ ((__aligned__(__alignof__(md5_uint32)))); #endif }; #ifndef __attribute__ #define __alignof__(a) sizeof(a) #endif /* * The following three functions are build up the low level used in * the functions `md5_stream' and `md5_buffer'. */ /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ extern void __md5_init_ctx __P((struct md5_ctx * ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ extern void __md5_process_block __P((const void *buffer, size_t len, struct md5_ctx * ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ extern void __md5_process_bytes __P((const void *buffer, size_t len, struct md5_ctx * ctx)); /* Process the remaining bytes in the buffer and put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ extern void *__md5_finish_ctx __P((struct md5_ctx * ctx, void *resbuf)); /* Put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ extern void *__md5_read_ctx __P((const struct md5_ctx * ctx, void *resbuf)); /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ extern int __md5_stream __P((FILE * stream, void *resblock)); /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ extern void *__md5_buffer __P((const char *buffer, size_t len, void *resblock)); # define md5_init_ctx __md5_init_ctx # define md5_process_block __md5_process_block # define md5_process_bytes __md5_process_bytes # define md5_finish_ctx __md5_finish_ctx # define md5_read_ctx __md5_read_ctx # define md5_stream __md5_stream # define md5_buffer __md5_buffer #endif /* md5.h */ dansguardian-2.10.1.1/src/HTMLTemplate.cpp0000644001165000116500000001441111110523210015031 00000000000000//Implements the HTMLTemplate class, for displaying template-based banned pages to clients //Please refer to http://dansguardian.org/?page=copyright //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "HTMLTemplate.hpp" #include "RegExp.hpp" #include "String.hpp" #include "OptionContainer.hpp" #include #include #include #include //#include #include #include // GLOBALS extern bool is_daemonised; extern OptionContainer o; // IMPLEMENTATION // wipe the loaded template void HTMLTemplate::reset() { html.clear(); } // push a line onto our string list void HTMLTemplate::push(String s) { if (s.length() > 0) { html.push_back(s); } } // read in HTML template and find URL, reason, category etc. placeholders bool HTMLTemplate::readTemplateFile(const char *filename, const char *placeholders) { std::string linebuffer; RegExp re; // compile regexp for matching supported placeholders // allow optional custom placeholder string re.comp(placeholders ? placeholders : "-URL-|-REASONGIVEN-|-REASONLOGGED-|-USER-|-IP-|-HOST-|-FILTERGROUP-|-RAWFILTERGROUP-|-BYPASS-|-CATEGORIES-|-SHORTURL-|-SERVERIP-"); unsigned int offset; String result; String line; std::ifstream templatefile(filename, std::ios::in); // dansguardian.conf if (!templatefile.good()) { if (!is_daemonised) { std::cerr << "error reading: " << filename << std::endl; } syslog(LOG_ERR, "%s", "error reading HTML template file."); return false; } while (!templatefile.eof()) { std::getline(templatefile, linebuffer); line = linebuffer.c_str(); // look for placeholders re.match(line.toCharArray()); while (re.numberOfMatches() > 0) { // whenever we find one, push the text before it onto the list, then the placeholder, then the text after it offset = re.offset(0); result = re.result(0).c_str(); if (offset > 0) { push(line.subString(0, offset)); push(result); line = line.subString(offset + result.length(), line.length() - offset - result.length()); } else { push(result); line = line.subString(result.length(), line.length() - result.length()); } re.match(line.toCharArray()); } // if any text remains, or we didn't find a placeholder, push the remainder of the line if (line.length() > 0) { push(line); } } templatefile.close(); return true; } // encode quotes and angle brackets using URL encoding to prevent XSS in the block page void makeURLSafe(String &url) { url.replaceall("'", "%27"); url.replaceall("\"", "%22"); url.replaceall("<", "%3C"); url.replaceall(">", "%3E"); } // fill in placeholders with the given information and send the resulting page to the client // only useful if you used the default set of placeholders void HTMLTemplate::display(Socket *s, String *url, std::string &reason, std::string &logreason, std::string &categories, std::string *user, std::string *ip, std::string *host, int filtergroup, String &hashed) { #ifdef DGDEBUG std::cout << "Displaying TEMPLATE" << std::endl; #endif String line; bool newline; unsigned int sz = html.size() - 1; // the last line can have no thingy. erm... carriage return? String safeurl(*url); // Take a copy of the URL so we can encode it to stop XSS bool safe = false; for (unsigned int i = 0; i < sz; i++) { // preserve newlines from original file newline = false; line = html[i]; // look for placeholders (split onto their own line by readTemplateFile) and replace them if (line == "-URL-") { if (!safe) { makeURLSafe(safeurl); safe = true; } line = safeurl; } else if (line == "-SHORTURL-") { if (!safe) { makeURLSafe(safeurl); safe = true; } line = safeurl; if (line.length() > 41) { line = line.subString(0, 40); line += "..."; } } else if (line == "-SERVERIP-") { line = s->getLocalIP(); } else if (line == "-REASONGIVEN-") { line = reason; } else if (line == "-REASONLOGGED-") { line = logreason; } else if (line == "-USER-") { line = *user; } else if (line == "-IP-") { line = *ip; } else if (line == "-HOST-") { if (host == NULL) { #ifdef DGDEBUG std::cout<<"-HOST- placeholder encountered but hostname currently unknown; lookup forced."< *names = ipToHostname(ip->c_str()); if (names->size() > 0) host = new std::string(names->front().toCharArray()); delete names; } line = (host ? *host : ""); } else if (line == "-FILTERGROUP-") { line = o.fg[filtergroup]->name; } else if (line == "-RAWFILTERGROUP-") { line = String(filtergroup + 1); } else if (line == "-CATEGORIES-") { if (categories.length() > 0) { line = categories; } else { line = "N/A"; } } else if (line == "-BYPASS-") { if (hashed.length() > 0) { line = *url; if (!(url->after("://").contains("/"))) { line += "/"; } if (url->contains("?")) { line += "&" + hashed; } else { line += "?" + hashed; } } else { line = ""; } } else { // if this line wasn't a placeholder, and neither is the // next line, then output a newline, thus preserving line breaks // from the original template file. if (html[i + 1][0] != '-') { newline = true; } } if (line.length() > 0) { (*s).writeString(line.toCharArray()); } if (newline) { (*s).writeString("\n"); } } (*s).writeString(html[sz].toCharArray()); (*s).writeString("\n"); } dansguardian-2.10.1.1/src/FOptionContainer.cpp0000644001165000116500000013360011173344374016041 00000000000000// FOptionContainer class - contains the options for a filter group, // including the banned/grey/exception site lists and the content/site/url regexp lists //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "FOptionContainer.hpp" #include "OptionContainer.hpp" #include #include #include #include #include // for gethostby #include // for address structures #include // for inet_aton() #include //#include // remove // GLOBALS extern bool is_daemonised; extern OptionContainer o; // IMPLEMENTATION // reverse DNS lookup on IP. be aware that this can return multiple results, unlike a standard lookup. std::deque * ipToHostname(const char *ip) { std::deque *result = new std::deque; struct in_addr address, **addrptr; if (inet_aton(ip, &address)) { // convert to in_addr struct hostent *answer; answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET); if (answer) { // sucess in reverse dns result->push_back(String(answer->h_name)); for (addrptr = (struct in_addr **) answer->h_addr_list; *addrptr; addrptr++) { result->push_back(String(inet_ntoa(**addrptr))); } } } return result; } FOptionContainer::~FOptionContainer() { reset(); } void FOptionContainer::reset() { if (banned_phrase_flag) o.lm.deRefList(banned_phrase_list); if (exception_site_flag) o.lm.deRefList(exception_site_list); if (exception_url_flag) o.lm.deRefList(exception_url_list); if (banned_extension_flag) o.lm.deRefList(banned_extension_list); if (banned_mimetype_flag) o.lm.deRefList(banned_mimetype_list); if (banned_site_flag) o.lm.deRefList(banned_site_list); if (banned_url_flag) o.lm.deRefList(banned_url_list); if (grey_site_flag) o.lm.deRefList(grey_site_list); if (grey_url_flag) o.lm.deRefList(grey_url_list); if (banned_regexpurl_flag) o.lm.deRefList(banned_regexpurl_list); if (exception_regexpurl_flag) o.lm.deRefList(exception_regexpurl_list); if (banned_regexpheader_flag) o.lm.deRefList(banned_regexpheader_list); if (content_regexp_flag) o.lm.deRefList(content_regexp_list); if (url_regexp_flag) o.lm.deRefList(url_regexp_list); if (header_regexp_flag) o.lm.deRefList(header_regexp_list); if (exception_extension_flag) o.lm.deRefList(exception_extension_list); if (exception_mimetype_flag) o.lm.deRefList(exception_mimetype_list); if (exception_file_site_flag) o.lm.deRefList(exception_file_site_list); if (exception_file_url_flag) o.lm.deRefList(exception_file_url_list); if (log_site_flag) o.lm.deRefList(log_site_list); if (log_url_flag) o.lm.deRefList(log_url_list); if (log_regexpurl_flag) o.lm.deRefList(log_regexpurl_list); banned_phrase_flag = false; exception_site_flag = false; exception_url_flag = false; banned_extension_flag = false; banned_mimetype_flag = false; banned_site_flag = false; banned_url_flag = false; grey_site_flag = false; grey_url_flag = false; banned_regexpurl_flag = false; exception_regexpurl_flag = false; banned_regexpheader_flag = false; content_regexp_flag = false; url_regexp_flag = false; header_regexp_flag = false; exception_extension_flag = false; exception_mimetype_flag = false; exception_file_site_flag = false; exception_file_url_flag = false; log_site_flag = false; log_url_flag = false; log_regexpurl_flag = false; block_downloads = false; banned_phrase_list_index.clear(); conffile.clear(); content_regexp_list_comp.clear(); content_regexp_list_rep.clear(); url_regexp_list_comp.clear(); url_regexp_list_rep.clear(); header_regexp_list_comp.clear(); header_regexp_list_rep.clear(); banned_regexpurl_list_comp.clear(); banned_regexpurl_list_source.clear(); banned_regexpurl_list_ref.clear(); exception_regexpurl_list_comp.clear(); exception_regexpurl_list_source.clear(); exception_regexpurl_list_ref.clear(); banned_regexpheader_list_comp.clear(); banned_regexpheader_list_source.clear(); banned_regexpheader_list_ref.clear(); log_regexpurl_list_comp.clear(); log_regexpurl_list_source.clear(); log_regexpurl_list_ref.clear(); delete banned_page; banned_page = NULL; } // grab this FG's HTML template HTMLTemplate* FOptionContainer::getHTMLTemplate() { if (banned_page) return banned_page; return &(o.html_template); } // read in the given file, write the list's ID into the given identifier, // sort using startsWith or endsWith depending on sortsw, and create a cache file if desired. // listname is used in error messages. bool FOptionContainer::readFile(const char *filename, unsigned int* whichlist, bool sortsw, bool cache, const char *listname) { int res = o.lm.newItemList(filename, sortsw, 1, true); if (res < 0) { if (!is_daemonised) { std::cerr << "Error opening " << listname << std::endl; } syslog(LOG_ERR, "Error opening %s", listname); return false; } (*whichlist) = (unsigned) res; if (!(*o.lm.l[(*whichlist)]).used) { if (sortsw) (*o.lm.l[(*whichlist)]).doSort(true); else (*o.lm.l[(*whichlist)]).doSort(false); if (cache && createlistcachefiles) { if (!(*o.lm.l[(*whichlist)]).createCacheFile()) { return false; } } (*o.lm.l[(*whichlist)]).used = true; } return true; } bool FOptionContainer::read(const char *filename) { try { // all sorts of exceptions could occur reading conf files std::string linebuffer; String temp; // for tempory conversion and storage std::ifstream conffiles(filename, std::ios::in); // dansguardianfN.conf if (!conffiles.good()) { if (!is_daemonised) { std::cerr << "Error reading: " << filename << std::endl; } syslog(LOG_ERR, "Error reading %s", filename); return false; } while (!conffiles.eof()) { getline(conffiles, linebuffer); if (!conffiles.eof() && linebuffer.length() != 0) { if (linebuffer[0] != '#') { // i.e. not commented out temp = (char *) linebuffer.c_str(); if (temp.contains("#")) { temp = temp.before("#"); } temp.removeWhiteSpace(); // get rid of spaces at end of line linebuffer = temp.toCharArray(); conffile.push_back(linebuffer); // stick option in deque } } } conffiles.close(); #ifdef DGDEBUG std::cout << "Read conf into memory: " << filename << std::endl; #endif if (findoptionS("deepurlanalysis") == "on") { deep_url_analysis = true; } else { deep_url_analysis = false; } if (findoptionS("disablecontentscan") == "on") { disable_content_scan = true; } else { disable_content_scan = false; } #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier if (findoptionS("usesmtp") == "on") { use_smtp = true; } else { use_smtp = false; } if (findoptionS("thresholdbyuser") == "on") { byuser = true; } else { byuser = false; } if (findoptionS("notifyav") == "on") { if (!use_smtp) { if (!is_daemonised) std::cerr << "notifyav cannot be on while usesmtp is off." << std::endl; syslog(LOG_ERR, "notifyav cannot be on while usesmtp is off."); return false; } notifyav = true; } else { notifyav = false; } if (findoptionS("notifycontent") == "on") { if (!use_smtp) { if (!is_daemonised) std::cerr << "notifycontent cannot be on while usesmtp is off." << std::endl; syslog(LOG_ERR, "notifycontent cannot be on while usesmtp is off."); return false; } notifycontent = true; } else { notifycontent = false; } violations = findoptionI("violations"); current_violations=0; violationbody=""; threshold = findoptionI("threshold"); avadmin = findoptionS("avadmin"); if (avadmin.length()==0) { if (notifyav==1) { if (!is_daemonised) std::cerr << "avadmin cannot be blank while notifyav is on." << std::endl; syslog(LOG_ERR, "avadmin cannot be blank while notifyav is on."); return false; } } contentadmin = findoptionS("contentadmin"); if (contentadmin.length()==0) { if (use_smtp) { if (!is_daemonised) std::cerr << "contentadmin cannot be blank while usesmtp is on." << std::endl; syslog(LOG_ERR, "contentadmin cannot be blank while usesmtp is on."); return false; } } mailfrom = findoptionS("mailfrom"); if (mailfrom.length()==0) { if (use_smtp) { if (!is_daemonised) std::cerr << "mailfrom cannot be blank while usesmtp is on." << std::endl; syslog(LOG_ERR, "mailfrom cannot be blank while usesmtp is on."); return false; } } avsubject = findoptionS("avsubject"); if (avsubject.length()==0 && notifyav==1 && use_smtp==1) { if (!is_daemonised) std::cerr << "avsubject cannot be blank while notifyav is on." << std::endl; syslog(LOG_ERR, "avsubject cannot be blank while notifyav is on."); return false; } contentsubject = findoptionS("contentsubject"); if (contentsubject.length()==0 && use_smtp) { if (!is_daemonised) std::cerr << "contentsubject cannot be blank while usesmtp is on." << std::endl; syslog(LOG_ERR, "contentsubject cannot be blank while usesmtp is on."); return false; } #endif // override default reporting level String temp_reporting_level(findoptionS("reportinglevel")); if (temp_reporting_level != "") { reporting_level = temp_reporting_level.toInteger(); if ((reporting_level < -1) || (reporting_level > 3)) { if (!is_daemonised) std::cerr << "Invalid reportinglevel: " << reporting_level << std::endl; syslog(LOG_ERR, "Invalid reportinglevel: %d", reporting_level); return false; } } // override default access denied address if (reporting_level == 1 || reporting_level == 2) { String temp_ada, temp_add; temp_ada = findoptionS("accessdeniedaddress"); if (temp_ada != "") { access_denied_address = temp_ada.toCharArray(); access_denied_domain = access_denied_address.c_str(); access_denied_domain = access_denied_domain.after("://"); access_denied_domain.removeWhiteSpace(); if (access_denied_domain.contains("/")) { access_denied_domain = access_denied_domain.before("/"); // access_denied_domain now contains the FQ host name of the // server that serves the accessdenied.html file } if (access_denied_domain.contains(":")) { access_denied_domain = access_denied_domain.before(":"); // chop off the port number if any } } } // override default banned page else if (reporting_level == 3) { String html_template(findoptionS("htmltemplate")); if (html_template != "") { html_template = o.languagepath + html_template; banned_page = new HTMLTemplate; if (!(banned_page->readTemplateFile(html_template.toCharArray()))) { if (!is_daemonised) { std::cerr << "Error reading HTML Template file: " << html_template << std::endl; } syslog(LOG_ERR, "Error reading HTML Template file: %s", html_template.toCharArray()); return false; // HTML template file } } } // group mode: 0 = banned, 1 = filtered, 2 = exception group_mode = findoptionI("groupmode"); if ((group_mode < 0) || (group_mode > 2)) { if (!is_daemonised) std::cerr<<"Invalid groupmode"< 0) { // if zero wpl is deactivated #ifdef DGDEBUG std::cout << "Reading weighted phrase list" << std::endl; #endif result = (*o.lm.l[banned_phrase_list]).readPhraseList(weighted, false, -1, -1, false); if (!result) { if (!is_daemonised) { std::cerr << "Error opening weightedphraselist" << std::endl; } syslog(LOG_ERR, "%s", "Error opening weightedphraselist"); return false; } } if (!(*o.lm.l[banned_phrase_list]).makeGraph(force_quick_search)) return false; (*o.lm.l[banned_phrase_list]).used = true; } return true; } // read regexp url list bool FOptionContainer::readRegExMatchFile(const char *filename, const char *listname, unsigned int& listref, std::deque &list_comp, std::deque &list_source, std::deque &list_ref) { int result = o.lm.newItemList(filename, true, 32, true); if (result < 0) { if (!is_daemonised) { std::cerr << "Error opening " << listname << std::endl; } syslog(LOG_ERR, "Error opening %s", listname); return false; } listref = (unsigned) result; return compileRegExMatchFile(listref, list_comp, list_source, list_ref); } // NOTE TO SELF - MOVE TO LISTCONTAINER TO SOLVE FUDGE // compile regexp url list bool FOptionContainer::compileRegExMatchFile(unsigned int list, std::deque &list_comp, std::deque &list_source, std::deque &list_ref) { for (unsigned int i = 0; i < (*o.lm.l[list]).morelists.size(); i++) { if (!compileRegExMatchFile((*o.lm.l[list]).morelists[i],list_comp,list_source,list_ref)) { return false; } } RegExp r; bool rv = true; int len = (*o.lm.l[list]).getListLength(); String source; for (int i = 0; i < len; i++) { source = (*o.lm.l[list]).getItemAtInt(i).c_str(); rv = r.comp(source.toCharArray()); if (rv == false) { if (!is_daemonised) { std::cerr << "Error compiling regexp:" << source << std::endl; } syslog(LOG_ERR, "%s", "Error compiling regexp:"); syslog(LOG_ERR, "%s", source.toCharArray()); return false; } list_comp.push_back(r); list_source.push_back(source); list_ref.push_back(list); } (*o.lm.l[list]).used = true; return true; } // content and URL regular expression replacement files bool FOptionContainer::readRegExReplacementFile(const char *filename, const char *listname, unsigned int& listid, std::deque &list_rep, std::deque &list_comp) { int result = o.lm.newItemList(filename, true, 32, true); if (result < 0) { if (!is_daemonised) { std::cerr << "Error opening " << listname << std::endl; } syslog(LOG_ERR, "Error opening %s", listname); return false; } listid = (unsigned) result; if (!(*o.lm.l[listid]).used) { //(*o.lm.l[listid]).doSort(true); (*o.lm.l[listid]).used = true; } RegExp r; bool rv = true; String regexp; String replacement; for (int i = 0; i < (*o.lm.l[listid]).getListLength(); i++) { regexp = (*o.lm.l[listid]).getItemAtInt(i).c_str(); replacement = regexp.after("\"->\""); while (!replacement.endsWith("\"")) { if (replacement.length() < 2) { break; } replacement.chop(); } replacement.chop(); regexp = regexp.after("\"").before("\"->\""); // if (replacement.length() < 1 || regexp.length() < 1) { if (regexp.length() < 1) { // allow replace with nothing continue; } rv = r.comp(regexp.toCharArray()); if (rv == false) { if (!is_daemonised) { std::cerr << "Error compiling regexp: " << (*o.lm.l[listid]).getItemAtInt(i) << std::endl; } syslog(LOG_ERR, "%s", "Error compiling regexp: "); syslog(LOG_ERR, "%s", (*o.lm.l[listid]).getItemAtInt(i).c_str()); return false; } list_comp.push_back(r); list_rep.push_back(replacement); } return true; } // Recursively check site & URL lists for blanket matches char *FOptionContainer::testBlanketBlock(unsigned int list, bool ip, bool ssl) { if (not o.lm.l[list]->isNow()) return NULL; if (o.lm.l[list]->blanketblock) { return (char*)o.language_list.getTranslation(502); } else if (o.lm.l[list]->blanket_ip_block and ip) { return (char*)o.language_list.getTranslation(505); } else if (o.lm.l[list]->blanketsslblock and ssl) { return (char*)o.language_list.getTranslation(506); } else if (o.lm.l[list]->blanketssl_ip_block and ssl and ip) { return (char*)o.language_list.getTranslation(507); } for (std::vector::iterator i = o.lm.l[list]->morelists.begin(); i != o.lm.l[list]->morelists.end(); i++) { char *r = testBlanketBlock(*i, ip, ssl); if (r) { return r; } } return NULL; } // checkme: there's an awful lot of removing whitespace, PTP, etc. going on here. // perhaps connectionhandler could keep a suitably modified version handy to prevent repitition of work? char *FOptionContainer::inSiteList(String &url, unsigned int list, bool doblanket, bool ip, bool ssl) { // Perform blanket matching if desired if (doblanket) { char *r = testBlanketBlock(list, ip, ssl); if (r) { return r; } } url.removeWhiteSpace(); // just in case of weird browser crap url.toLower(); url.removePTP(); // chop off the ht(f)tp(s):// if (url.contains("/")) { url = url.before("/"); // chop off any path after the domain } char *i; bool isipurl = isIPHostname(url); if (reverse_lookups && isipurl) { // change that ip into hostname std::deque *url2s = ipToHostname(url.toCharArray()); String url2; for (std::deque::iterator j = url2s->begin(); j != url2s->end(); j++) { url2 = *j; while (url2.contains(".")) { i = (*o.lm.l[list]).findInList(url2.toCharArray()); if (i != NULL) { return i; // exact match } url2 = url2.after("."); // check for being in hld } } delete url2s; } while (url.contains(".")) { i = (*o.lm.l[list]).findInList(url.toCharArray()); if (i != NULL) { return i; // exact match } url = url.after("."); // check for being in higher level domains } if (url.length() > 1) { // allows matching of .tld url = "." + url; i = (*o.lm.l[list]).findInList(url.toCharArray()); if (i != NULL) { return i; // exact match } } return NULL; // and our survey said "UUHH UURRGHH" } // checkme: remove things like this & make inSiteList/inIPList public? char *FOptionContainer::inBannedSiteList(String url, bool doblanket, bool ip, bool ssl) { return inSiteList(url, banned_site_list, doblanket, ip, ssl); } bool FOptionContainer::inGreySiteList(String url, bool doblanket, bool ip, bool ssl) { return inSiteList(url, grey_site_list, doblanket, ip, ssl) != NULL; } bool FOptionContainer::inExceptionSiteList(String url, bool doblanket, bool ip, bool ssl) { return inSiteList(url, exception_site_list, doblanket, ip, ssl) != NULL; } bool FOptionContainer::inExceptionFileSiteList(String url) { if (inSiteList(url, exception_file_site_list) != NULL) return true; else return inURLList(url, exception_file_url_list) != NULL; } // look in given URL list for given URL char *FOptionContainer::inURLList(String &url, unsigned int list, bool doblanket, bool ip, bool ssl) { // Perform blanket matching if desired if (doblanket) { char *r = testBlanketBlock(list, ip, ssl); if (r) { return r; } } unsigned int fl; char *i; String foundurl; #ifdef DGDEBUG std::cout << "inURLList: " << url << std::endl; #endif url.removeWhiteSpace(); // just in case of weird browser crap url.toLower(); url.removePTP(); // chop off the ht(f)tp(s):// if (url.contains("/")) { String tpath("/"); tpath += url.after("/"); url = url.before("/"); tpath.hexDecode(); tpath.realPath(); url += tpath; // will resolve ../ and %2e2e/ and // etc } if (url.endsWith("/")) { url.chop(); // chop off trailing / if any } #ifdef DGDEBUG std::cout << "inURLList (processed): " << url << std::endl; #endif if (reverse_lookups && url.after("/").length() > 0) { String hostname(url.before("/")); if (isIPHostname(hostname)) { std::deque *url2s = ipToHostname(hostname.toCharArray()); String url2; for (std::deque::iterator j = url2s->begin(); j != url2s->end(); j++) { url2 = *j; url2 += "/"; url2 += url.after("/"); while (url2.before("/").contains(".")) { i = (*o.lm.l[list]).findStartsWith(url2.toCharArray()); if (i != NULL) { foundurl = i; fl = foundurl.length(); if (url2.length() > fl) { unsigned char c = url[fl]; if (c == '/' || c == '?' || c == '&' || c == '=') { return i; // matches /blah/ or /blah/foo // (or /blah?foo etc.) // but not /blahfoo } } else { return i; // exact match } } url2 = url2.after("."); // check for being in hld } } delete url2s; } } while (url.before("/").contains(".")) { i = (*o.lm.l[list]).findStartsWith(url.toCharArray()); if (i != NULL) { foundurl = i; fl = foundurl.length(); #ifdef DGDEBUG std::cout << "foundurl: " << foundurl << foundurl.length() << std::endl; std::cout << "url: " << url << fl << std::endl; #endif if (url.length() > fl) { if (url[fl] == '/' || url[fl] == '?' || url[fl] == '&' || url[fl] == '=') { return i; // matches /blah/ or /blah/foo but not /blahfoo } } else { return i; // exact match } } url = url.after("."); // check for being in higher level domains } return NULL; } char *FOptionContainer::inBannedURLList(String url, bool doblanket, bool ip, bool ssl) { #ifdef DGDEBUG std::cout<<"inBannedURLList"<lastcategory.toCharArray(); } return NULL; } const char* FOptionContainer::inLogSiteList(String url) { if (!log_site_flag) return NULL; if (inSiteList(url, log_site_list) != NULL) { return o.lm.l[log_site_list]->lastcategory.toCharArray(); } return NULL; } const char* FOptionContainer::inLogRegExpURLList(String url) { if (!log_regexpurl_flag) return NULL; int j = inRegExpURLList(url, log_regexpurl_list_comp, log_regexpurl_list_ref, log_regexpurl_list); if (j == -1) return NULL; return o.lm.l[log_regexpurl_list_ref[j]]->category.toCharArray(); } // TODO: Store the modified URL somewhere, instead of re-processing it every time. char *FOptionContainer::inExtensionList(unsigned int list, String url) { url.removeWhiteSpace(); // just in case of weird browser crap url.toLower(); url.hexDecode(); url.removePTP(); // chop off the ht(f)tp(s):// url = url.after("/"); // chop off any domain before the path if (url.length() < 2) { // will never match return NULL; } return (*o.lm.l[list]).findEndsWith(url.toCharArray()); } // is this line of the headers in the banned regexp header list? int FOptionContainer::inBannedRegExpHeaderList(std::deque &header) { for (std::deque::iterator k = header.begin(); k != header.end(); k++) { #ifdef DGDEBUG std::cout << "inBannedRegExpHeaderList: " << *k << std::endl; #endif unsigned int i = 0; for (std::deque::iterator j = banned_regexpheader_list_comp.begin(); j != banned_regexpheader_list_comp.end(); j++) { if (o.lm.l[banned_regexpheader_list_ref[i]]->isNow()) { j->match(k->toCharArray()); if (j->matched()) return i; } #ifdef DGDEBUG else std::cout << "Outside included regexp list's time limit" << std::endl; #endif i++; } } return -1; } // is this URL in the given regexp URL list? int FOptionContainer::inRegExpURLList(String &url, std::deque &list_comp, std::deque &list_ref, unsigned int list) { #ifdef DGDEBUG std::cout<<"inRegExpURLList: "<isNow()) { url.removeWhiteSpace(); // just in case of weird browser crap url.toLower(); // chop off the PTP (ht(f)tp(s)://) /*String ptp; if (url.contains("//")) { ptp = url.before("//"); url = url.after("//"); }*/ // whilst it would be nice to have regexes be able to match the PTP, // it has been assumed for too long that the URL string does not start with one, // and we don't want to break regexes that look explicitly for the start of // the string. changes here have therefore been reverted. 2005-12-07 url.removePTP(); if (url.contains("/")) { String tpath("/"); tpath += url.after("/"); url = url.before("/"); tpath.hexDecode(); tpath.realPath(); url += tpath; // will resolve ../ and %2e2e/ and // etc } if (url.endsWith("/")) { url.chop(); // chop off trailing / if any } // re-add the PTP /*if (ptp.length() > 0) url = ptp + "//" + url;*/ #ifdef DGDEBUG std::cout<<"inRegExpURLList (processed): "<::iterator j = list_comp.begin(); j != list_comp.end(); j++) { if (o.lm.l[list_ref[i]]->isNow()) { j->match(url.toCharArray()); if (j->matched()) return i; } #ifdef DGDEBUG else std::cout << "Outside included regexp list's time limit" << std::endl; #endif i++; } } #ifdef DGDEBUG else { std::cout << "Outside top level regexp list's time limit" << std::endl; } #endif return -1; } // use above to check banned/exception RegExp URLs int FOptionContainer::inBannedRegExpURLList(String url) { #ifdef DGDEBUG std::cout<<"inBannedRegExpURLList"< 0) && (l > maxl))) { if (!is_daemonised) { // when called we have not detached from // the console so we can write back an // error std::cerr << "Config problem; check allowed values for " << emessage << std::endl; } syslog(LOG_ERR, "Config problem; check allowed values for %s", emessage); return false; } return true; } bool FOptionContainer::precompileregexps() { if (!pics1.comp("pics-label\"[ \t]*content=[\'\"]([^>]*)[\'\"]")) { if (!is_daemonised) { std::cerr << "Error compiling RegExp pics1." << std::endl; } syslog(LOG_ERR, "%s", "Error compiling RegExp pics1."); return false; } if (!pics2.comp("[r|{ratings}] *\\(([^\\)]*)\\)")) { if (!is_daemonised) { std::cerr << "Error compiling RegExp pics2." << std::endl; } syslog(LOG_ERR, "%s", "Error compiling RegExp pics2."); return false; } if (!isiphost.comp(".*[a-z|A-Z].*")) { if (!is_daemonised) { std::cerr << "Error compiling RegExp isiphost." << std::endl; } syslog(LOG_ERR, "%s", "Error compiling RegExp isiphost."); return false; } return true; } bool FOptionContainer::isOurWebserver(String url) { // reporting levels 0 and 3 don't use the CGI if (reporting_level == 1 || reporting_level == 2) { url.removeWhiteSpace(); // just in case of weird browser crap url.toLower(); url.removePTP(); // chop off the ht(f)tp(s):// if (url.contains("/")) { url = url.before("/"); // chop off any path after the domain } if (url.startsWith(access_denied_domain)) { // don't filter our web server return true; } } return false; } dansguardian-2.10.1.1/src/UDSocket.hpp0000644001165000116500000000341011110523210014254 00000000000000// UDSocket class - implements BaseSocket for UNIX domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_UDSOCKET #define __HPP_UDSOCKET // INCLUDES #include "BaseSocket.hpp" // DECLARATIONS class UDSocket : public BaseSocket { public: // create default UNIX domain socket & clear address structs UDSocket(); // create socket from pre-existing FD (address structs will be empty!) UDSocket(int fd); // create socket from FD & local path (checkme: is it actually local that gets passed?) UDSocket(int newfd, struct sockaddr_un myadr); // connect socket to given server (following default constructor) int connect(const char *path); // bind socket to given path (for creating servers) int bind(const char *path); // accept incoming connection & return new UDSocket UDSocket* accept(); // close connection & clear address structs void reset(); private: // local & remote address structs struct sockaddr_un my_adr; struct sockaddr_un peer_adr; socklen_t my_adr_length; }; #endif dansguardian-2.10.1.1/src/FatController.cpp0000644001165000116500000020557211175556126015410 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb//.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_SEGV_BACKTRACE #include #endif #include "FatController.hpp" #include "ConnectionHandler.hpp" #include "DynamicURLList.hpp" #include "DynamicIPList.hpp" #include "String.hpp" #include "SocketArray.hpp" #include "UDSocket.hpp" #include "SysV.hpp" // GLOBALS // these are used in signal handlers - "volatile" indicates they can change at // any time, and therefore value reading on them does not get optimised. since // the values can get altered by outside influences, this is useful. static volatile bool ttg = false; static volatile bool gentlereload = false; static volatile bool sig_term_killall = false; volatile bool reloadconfig = false; extern OptionContainer o; extern bool is_daemonised; int numchildren; // to keep count of our children int busychildren; // to keep count of our children int waitingfor; // num procs waiting for to be preforked int *childrenpids; // so when one exits we know who int *childrenstates; // so we know what they're up to struct pollfd *pids; UDSocket **childsockets; int failurecount; int serversocketcount; SocketArray serversockets; // the sockets we will listen on for connections UDSocket loggersock; // the unix domain socket to be used for ipc with the forked children UDSocket urllistsock; UDSocket iplistsock; Socket *peersock(NULL); // the socket which will contain the connection String peersockip; // which will contain the connection ip // DECLARATIONS // Signal handlers extern "C" { void sig_chld(int signo); void sig_term(int signo); // This is so we can kill our children void sig_termsafe(int signo); // This is so we can kill our children safer void sig_hup(int signo); // This is so we know if we should re-read our config. void sig_usr1(int signo); // This is so we know if we should re-read our config but not kill current connections void sig_childterm(int signo); #ifdef ENABLE_SEGV_BACKTRACE void sig_segv(int signo/*, siginfo_t* info, void* p*/); // Generate a backtrace on segfault #endif } // logging & URL cache processes int log_listener(std::string log_location, bool logconerror, bool logsyslog); int url_list_listener(bool logconerror); // send flush message over URL cache IPC socket void flush_urlcache(); // fork off into background bool daemonise(); // create specified amount of child processes int prefork(int num); // check child process is ready to start work bool check_kid_readystatus(int tofind); // child process informs parent process that it is ready int send_readystatus(UDSocket &pipe); // child process main loop - sits waiting for incoming connections & processes them int handle_connections(UDSocket &pipe); // tell a non-busy child process to accept the incoming connection void tellchild_accept(int num, int whichsock); // child process accept()s connection from server socket bool getsock_fromparent(UDSocket &fd); // add known info about a child to our info lists void addchild(int pos, int fd, pid_t child_pid); // find ID of first non-busy child int getfreechild(); // find an empty slot in our child info lists int getchildslot(); // cull up to this number of non-busy children void cullchildren(int num); // delete this child from our info lists void deletechild(int child_pid); // clean up any dead child processes (calls deletechild with exit values) void mopup_afterkids(); // tidy up resources for a brand new child process (uninstall signal handlers, delete copies of unnecessary data, etc.) void tidyup_forchild(); // send SIGTERM or SIGHUP to call children void kill_allchildren(); void hup_allchildren(); // setuid() to proxy user (not just seteuid()) - used by child processes & logger/URL cache for security & resource usage reasons bool drop_priv_completely(); // IMPLEMENTATION // signal handlers extern "C" { // The kernel knows nothing of objects so // we have to have a lump of c void sig_term(int signo) { sig_term_killall = true; ttg = true; // its time to go } void sig_termsafe(int signo) { ttg = true; // its time to go } void sig_hup(int signo) { reloadconfig = true; #ifdef DGDEBUG std::cout << "HUP received." << std::endl; #endif } void sig_usr1(int signo) { gentlereload = true; #ifdef DGDEBUG std::cout << "USR1 received." << std::endl; #endif } void sig_childterm(int signo) { #ifdef DGDEBUG std::cout << "TERM recieved." << std::endl; #endif _exit(0); } #ifdef ENABLE_SEGV_BACKTRACE void sig_segv(int signo) { #ifdef DGDEBUG std::cout << "SEGV received." << std::endl; #endif // Generate backtrace void *addresses[10]; char **strings; int c = backtrace(addresses, 10); strings = backtrace_symbols(addresses,c); printf("backtrace returned: %d\n", c); for (int i = 0; i < c; i++) { syslog(LOG_ERR, "%d: %zX ", i, (size_t)addresses[i]); syslog(LOG_ERR, "%s", strings[i]); } // Kill off the current process raise(SIGTERM); } #endif } // completely drop our privs - i.e. setuid, not just seteuid bool drop_priv_completely() { // This is done to solve the problem where the total processes for the // uid rather than euid is taken for RLIMIT_NPROC and so can't fork() // as many as expected. // It is also more secure. // // Suggested fix by Lawrence Manning Tue 25th February 2003 // int rc = seteuid(o.root_user); // need to be root again to drop properly if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to seteuid(suid)"); #ifdef DGDEBUG std::cout << strerror(errno) << std::endl; #endif return false; // setuid failed for some reason so exit with error } rc = setuid(o.proxy_user); if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to setuid()"); return false; // setuid failed for some reason so exit with error } return true; } // signal the URL cache to flush via IPC void flush_urlcache() { if (o.url_cache_number < 1) { return; // no cache running to flush } UDSocket fipcsock; if (fipcsock.getFD() < 0) { syslog(LOG_ERR, "%s", "Error creating ipc socket to url cache for flush"); return; } if (fipcsock.connect((char *) o.urlipc_filename.c_str()) < 0) { // conn to dedicated url cach proc syslog(LOG_ERR, "%s", "Error connecting via ipc to url cache for flush"); #ifdef DGDEBUG std::cout << "Error connecting via ipc to url cache for flush" << std::endl; #endif return; } String request("f\n"); try { fipcsock.writeString(request.toCharArray()); // throws on err } catch(std::exception & e) { #ifdef DGDEBUG std::cerr << "Exception flushing url cache" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "%s", "Exception flushing url cache"); syslog(LOG_ERR, "%s", e.what()); } } // Fork ourselves off into the background bool daemonise() { if (o.no_daemon) { return true; } #ifdef DGDEBUG return true; // if debug mode is enabled we don't want to detach #endif if (is_daemonised) { return true; // we are already daemonised so this must be a // reload caused by a HUP } int nullfd = -1; if ((nullfd = open("/dev/null", O_WRONLY, 0)) == -1) { syslog(LOG_ERR, "%s", "Couldn't open /dev/null"); return false; } pid_t pid; if ((pid = fork()) < 0) { return false; } else if (pid != 0) { if (nullfd != -1) { close(nullfd); } exit(0); // parent goes bye-bye } // child continues dup2(nullfd, 0); // stdin dup2(nullfd, 1); // stdout dup2(nullfd, 2); // stderr close(nullfd); setsid(); // become session leader chdir("/"); // change working directory umask(0); // clear our file mode creation mask is_daemonised = true; return true; } // * // * // * child process code // * // * // prefork specified num of children and set them handling connections int prefork(int num) { if (num < waitingfor) { return 3; // waiting for forks already } #ifdef DGDEBUG std::cout << "attempting to prefork:" << num << std::endl; #endif int sv[2]; pid_t child_pid; while (num--) { if (numchildren >= o.max_children) { return 2; // too many - geddit? } if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { return -1; // error } child_pid = fork(); if (child_pid == -1) { // fork failed, for example, if the // process is not allowed to create // any more syslog(LOG_ERR, "%s", "Unable to fork() any more."); #ifdef DGDEBUG std::cout << "Unable to fork() any more." << std::endl; std::cout << strerror(errno) << std::endl; std::cout << "numchildren:" << numchildren << std::endl; #endif failurecount++; // log the error/failure // A DoS attack on a server allocated // too many children in the conf will // kill the server. But this is user // error. sleep(1); // need to wait until we have a spare slot num--; continue; // Nothing doing, go back to listening } else if (child_pid == 0) { // I am the child - I am alive! close(sv[0]); // we only need our copy of this tidyup_forchild(); if (!drop_priv_completely()) { return -1; //error } // no need to deallocate memory etc as already done when fork()ed // right - let's do our job! UDSocket sock(sv[1]); int rc = handle_connections(sock); // ok - job done, time to tidy up. _exit(rc); // baby go bye bye } else { // I am the parent // close the end of the socketpair we don't need close(sv[1]); // add the child and its FD/PID to an empty child slot addchild(getchildslot(), sv[0], child_pid); #ifdef DGDEBUG std::cout << "Preforked parent added child to list" << std::endl; #endif } } return 1; // parent returning } // cleaning up for brand new child processes - only the parent needs the signal handlers installed, and so forth void tidyup_forchild() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_childterm; if (sigaction(SIGTERM, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGTERM" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGTERM"); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; if (sigaction(SIGUSR1, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGUSR1" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGUSR1"); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_hup; if (sigaction(SIGHUP, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGHUP" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGHUP"); } // now close open socket pairs don't need for (int i = 0; i < o.max_children; i++) { if (pids[i].fd != -1) { delete childsockets[i]; } } delete[]childrenpids; delete[]childrenstates; delete[]childsockets; delete[]pids; // 4 deletes good, memory leaks bad } // send Ready signal to parent process over the socketpair (used in handle_connections) int send_readystatus(UDSocket &pipe) { // blocks until timeout String message("2\n"); try { if (!pipe.writeToSocket(message.toCharArray(), message.length(), 0, 15, true, true)) { return -1; } } catch(std::exception & e) { return -1; } return 0; } // handle any connections received by this child (also tell parent we're ready each time we become idle) int handle_connections(UDSocket &pipe) { ConnectionHandler h; // the class that handles the connections String ip; bool toldparentready = false; int cycle = o.maxage_children; int stat = 0; reloadconfig = false; // stay alive both for the maximum allowed age of child processes, and whilst we aren't supposed to be re-reading configuration while (cycle-- && !reloadconfig) { if (!toldparentready) { if (send_readystatus(pipe) == -1) { // non-blocking (timed) #ifdef DGDEBUG std::cout << "parent timed out telling it we're ready" << std::endl; #endif break; // parent timed out telling it we're ready // so either parent gone or problem so lets exit this joint } toldparentready = true; } if (!getsock_fromparent(pipe)) { // blocks waiting for a few mins continue; } toldparentready = false; // now check the connection is actually good if (peersock->getFD() < 0 || peersockip.length() < 7) { if (o.logconerror) syslog(LOG_INFO, "Error accepting. (Ignorable)"); continue; } h.handleConnection(*peersock, peersockip); // deal with the connection delete peersock; } if (!(++cycle) && o.logchildprocs) syslog(LOG_ERR, "Child has handled %d requests and is exiting", o.maxage_children); #ifdef DGDEBUG if (reloadconfig) { std::cout << "child been told to exit by hup" << std::endl; } #endif if (!toldparentready) { stat = 2; } return stat; } // the parent process recieves connections - children receive notifications of this over their socketpair, and accept() them for handling bool getsock_fromparent(UDSocket &fd) { String message; char buf; int rc; try { rc = fd.readFromSocket(&buf, 1, 0, 360, true, true); // blocks for a few mins } catch(std::exception & e) { // whoop! we received a SIGHUP. we should reload our configuration - and no, we didn't get an FD. reloadconfig = true; return false; } // that way if child does nothing for a long time it will eventually // exit reducing the forkpool depending on o.maxage_children which is // usually 500 so max time a child hangs around is lonngggg // it needs to be a long block to stop the machine needing to page in // the process // check the message from the parent if (rc < 1) { return false; } // woo! we have a connection. accept it. peersock = serversockets[buf]->accept(); peersockip = peersock->getPeerIP(); try { fd.writeToSockete("K", 1, 0, 10, true); // need to make parent wait for OK // so effectively providing a lock } catch(std::exception & e) { if (o.logconerror) syslog(LOG_ERR, "Error telling parent we accepted: %s", e.what()); peersock->close(); return false; } return true; } // * // * // * end of child process code // * // * // * // * // * start of child process handling (minus prefork) // * // * // look for any dead children, and clean them up void mopup_afterkids() { pid_t pid; int stat_val; while (true) { pid = waitpid(-1, &stat_val, WNOHANG); if (pid < 1) { break; } deletechild((int) pid); } } // get a free slot in out PID list, if there is one - return -1 if not int getchildslot() { int i; for (i = 0; i < o.max_children; i++) { if (childrenpids[i] == -1) { return i; } } return -1; } // add the given child, including FD & PID, to the given slot in our lists void addchild(int pos, int fd, pid_t child_pid) { childrenpids[pos] = (int) child_pid; childrenstates[pos] = 4; // busy waiting for init numchildren++; busychildren++; waitingfor++; pids[pos].fd = fd; UDSocket* sock = new UDSocket(fd); childsockets[pos] = sock; } // kill give number of non-busy children void cullchildren(int num) { #ifdef DGDEBUG std::cout << "culling childs:" << num << std::endl; #endif int i; int count = 0; for (i = o.max_children - 1; i >= 0; i--) { if (childrenstates[i] == 0) { kill(childrenpids[i], SIGTERM); count++; childrenstates[i] = -2; // dieing numchildren--; delete childsockets[i]; childsockets[i] = NULL; pids[i].fd = -1; if (count >= num) { break; } } } } // send SIGTERM to all child processes void kill_allchildren() { #ifdef DGDEBUG std::cout << "killing all childs:" << std::endl; #endif for (int i = o.max_children - 1; i >= 0; i--) { if (childrenstates[i] >= 0) { kill(childrenpids[i], SIGTERM); childrenstates[i] = -2; // dieing numchildren--; delete childsockets[i]; childsockets[i] = NULL; pids[i].fd = -1; } } } // send SIGHUP to all child processes void hup_allchildren() { #ifdef DGDEBUG std::cout << "huping all childs:" << std::endl; #endif for (int i = o.max_children - 1; i >= 0; i--) { if (childrenstates[i] >= 0) { kill(childrenpids[i], SIGHUP); } } } // attempt to receive the message from the child's send_readystatus call bool check_kid_readystatus(int tofind) { bool found = false; char *buf = new char[5]; int rc = -1; // for compiler warnings for (int f = 0; f < o.max_children; f++) { if (tofind < 1) { break; // no point looping through all if all found } if (pids[f].fd == -1) { continue; } if ((pids[f].revents & POLLIN) > 0) { if (childrenstates[f] < 0) { tofind--; continue; } try { rc = childsockets[f]->getLine(buf, 4, 100, true); } catch(std::exception & e) { kill(childrenpids[f], SIGTERM); deletechild(childrenpids[f]); tofind--; continue; } if (rc > 0) { if (buf[0] == '2') { if (childrenstates[f] == 4) { waitingfor--; } childrenstates[f] = 0; busychildren--; tofind--; } } else { // child -> parent communications failure so kill it kill(childrenpids[f], SIGTERM); deletechild(childrenpids[f]); tofind--; } } if (childrenstates[f] == 0) { found = true; } else { found = false; } } // if unbusy found then true otherwise false delete[]buf; return found; } // remove child from our PID/FD and slot lists void deletechild(int child_pid) { int i; for (i = 0; i < o.max_children; i++) { if (childrenpids[i] == child_pid) { childrenpids[i] = -1; // Delete a busy child if (childrenstates[i] == 1) busychildren--; // Delete a child which isn't "ready" yet if (childrenstates[i] == 4) { busychildren--; waitingfor--; } // Common code for any non-"culled" child if (childrenstates[i] != -2) { numchildren--; delete childsockets[i]; childsockets[i] = NULL; pids[i].fd = -1; } childrenstates[i] = -1; // unused break; } } // never should happen that passed pid is not known, // unless its the logger or url cache process, in which case we // don't want to do anything anyway. and this can only happen // when shutting down or restarting. } // get the index of the first non-busy child int getfreechild() { // check that there is 1 free done // before calling int i; for (i = 0; i < o.max_children; i++) { if (childrenstates[i] == 0) { // not busy (free) return i; } } return -1; } // tell given child process to accept an incoming connection void tellchild_accept(int num, int whichsock) { // include server socket number in message try { childsockets[num]->writeToSockete((char*)&whichsock, 1, 0, 5, true); } catch(std::exception & e) { kill(childrenpids[num], SIGTERM); deletechild(childrenpids[num]); return; } // check for response from child char buf; try { childsockets[num]->readFromSocket(&buf, 1, 0, 5, false, true); } catch(std::exception & e) { kill(childrenpids[num], SIGTERM); deletechild(childrenpids[num]); return; } // no need to check what it actually contains, // as the very fact the child sent something back is a good sign busychildren++; childrenstates[num] = 1; // busy } // * // * // * end of child process handling code // * // * // * // * // * logger, IP list and URL cache main loops // * // * int log_listener(std::string log_location, bool logconerror, bool logsyslog) { #ifdef DGDEBUG std::cout << "log listener started" << std::endl; #endif if (!drop_priv_completely()) { return 1; //error } UDSocket* ipcpeersock; // the socket which will contain the ipc connection int rc, ipcsockfd; #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier std::map violation_map; std::map timestamp_map; std::map vbody_map; int curv_tmp, stamp_tmp, byuser; #endif //String where, what, how; std::string cr("\n"); std::string where, what, how, cat, clienthost, from, who, mimetype, useragent, ssize, sweight; int port = 80, isnaughty = 0, isexception = 0, code = 200; int cachehit = 0, wasinfected = 0, wasscanned = 0, filtergroup = 0; long tv_sec = 0, tv_usec = 0; int contentmodified = 0, urlmodified = 0, headermodified = 0; std::ofstream* logfile = NULL; if (!logsyslog) { logfile = new std::ofstream(log_location.c_str(), std::ios::app); if (logfile->fail()) { syslog(LOG_ERR, "Error opening/creating log file."); #ifdef DGDEBUG std::cout << "Error opening/creating log file: " << log_location << std::endl; #endif delete logfile; return 1; // return with error } } ipcsockfd = loggersock.getFD(); fd_set fdSet; // our set of fds (only 1) that select monitors for us fd_set fdcpy; // select modifies the set so we need to use a copy FD_ZERO(&fdSet); // clear the set FD_SET(ipcsockfd, &fdSet); // add ipcsock to the set while (true) { // loop, essentially, for ever fdcpy = fdSet; // take a copy rc = select(ipcsockfd + 1, &fdcpy, NULL, NULL, NULL); // block // until something happens if (rc < 0) { // was an error if (errno == EINTR) { continue; // was interupted by a signal so restart } if (logconerror) { syslog(LOG_ERR, "ipc rc<0. (Ignorable)"); } continue; } if (rc < 1) { if (logconerror) { syslog(LOG_ERR, "ipc rc<1. (Ignorable)"); } continue; } if (FD_ISSET(ipcsockfd, &fdcpy)) { #ifdef DGDEBUG std::cout << "received a log request" << std::endl; #endif ipcpeersock = loggersock.accept(); if (ipcpeersock->getFD() < 0) { delete ipcpeersock; if (logconerror) { syslog(LOG_ERR, "Error accepting ipc. (Ignorable)"); } continue; // if the fd of the new socket < 0 there was error // but we ignore it as its not a problem } // Formatting code migration from ConnectionHandler // and email notification code based on patch provided // by J. Gauthier // read in the various parts of the log string bool error = false; int itemcount = 0; while(itemcount < (o.log_user_agent ? 24 : 23)) { try { char *logline = new char[8192]; rc = ipcpeersock->getLine(logline, 8192, 3, true); // throws on err if (rc < 0) { delete ipcpeersock; if (!is_daemonised) std::cout << "Error reading from log socket" < 3) { temp = "999"; } utime = temp; utime = "." + utime; utime = String((int) theend.tv_sec) + utime; } if (o.log_file_format != 3) { // "when" not used in format 3, and not if logging timestamps instead String temp; time_t tnow; // to hold the result from time() struct tm *tmnow; // to hold the result from localtime() time(&tnow); // get the time after the lock so all entries in order tmnow = localtime(&tnow); // convert to local time (BST, etc) year = String(tmnow->tm_year + 1900); month = String(tmnow->tm_mon + 1); day = String(tmnow->tm_mday); hour = String(tmnow->tm_hour); temp = String(tmnow->tm_min); if (temp.length() == 1) { temp = "0" + temp; } min = temp; temp = String(tmnow->tm_sec); if (temp.length() == 1) { temp = "0" + temp; } sec = temp; when = year + "." + month + "." + day + " " + hour + ":" + min + ":" + sec; // truncate long log items /*if ((o.max_logitem_length > 0) && (when.length() > o.max_logitem_length)) when.resize(o.max_logitem_length);*/ // append timestamp if desired if (o.log_timestamp) when += " " + utime; } // truncate long log items if (o.max_logitem_length > 0) { //where.limitLength(o.max_logitem_length); if (cat.length() > o.max_logitem_length) cat.resize(o.max_logitem_length); if (what.length() > o.max_logitem_length) what.resize(o.max_logitem_length); if (where.length() > o.max_logitem_length) where.resize(o.max_logitem_length); /*if (who.length() > o.max_logitem_length) who.resize(o.max_logitem_length); if (from.length() > o.max_logitem_length) from.resize(o.max_logitem_length); if (how.length() > o.max_logitem_length) how.resize(o.max_logitem_length); if (ssize.length() > o.max_logitem_length) ssize.resize(o.max_logitem_length);*/ } // blank out IP, hostname and username if desired if (o.anonymise_logs) { who = ""; from = "0.0.0.0"; clienthost.clear(); } String stringcode(code); String stringgroup(filtergroup+1); switch (o.log_file_format) { case 4: builtline = when +"\t"+ who + "\t" + from + "\t" + where + "\t" + what + "\t" + how + "\t" + ssize + "\t" + sweight + "\t" + cat + "\t" + stringgroup + "\t" + stringcode + "\t" + mimetype + "\t" + clienthost + "\t" + o.fg[filtergroup]->name + "\t" + (o.log_user_agent ? useragent : "-"); break; case 3: { // as certain bits of info are logged in format 3, their creation is best done here, not in all cases. std::string duration, hier, hitmiss; long durationsecs, durationusecs; durationsecs = (theend.tv_sec - tv_sec); durationusecs = theend.tv_usec - tv_usec; durationusecs = (durationusecs / 1000) + durationsecs * 1000; String temp((int) durationusecs); while (temp.length() < 6) { temp = " " + temp; } duration = temp; if (code == 403) { hitmiss = "TCP_DENIED/403"; } else { if (cachehit) { hitmiss = "TCP_HIT/"; hitmiss.append(stringcode); } else { hitmiss = "TCP_MISS/"; hitmiss.append(stringcode); } } hier = "DEFAULT_PARENT/"; hier += o.proxy_ip; /*if (o.max_logitem_length > 0) { if (utime.length() > o.max_logitem_length) utime.resize(o.max_logitem_length); if (duration.length() > o.max_logitem_length) duration.resize(o.max_logitem_length); if (hier.length() > o.max_logitem_length) hier.resize(o.max_logitem_length); if (hitmiss.length() > o.max_logitem_length) hitmiss.resize(o.max_logitem_length); }*/ builtline = utime + " " + duration + " " + ( (clienthost.length() > 0) ? clienthost : from) + " " + hitmiss + " " + ssize + " " + how + " " + where + " " + who + " " + hier + " " + mimetype ; break; } case 2: builtline = "\"" + when +"\",\""+ who + "\",\"" + from + "\",\"" + where + "\",\"" + what + "\",\"" + how + "\",\"" + ssize + "\",\"" + sweight + "\",\"" + cat + "\",\"" + stringgroup + "\",\"" + stringcode + "\",\"" + mimetype + "\",\"" + clienthost + "\",\"" + o.fg[filtergroup]->name + "\",\"" + (o.log_user_agent ? useragent : "-") + "\""; break; default: builtline = when +" "+ who + " " + from + " " + where + " " + what + " " + how + " " + ssize + " " + sweight + " " + cat + " " + stringgroup + " " + stringcode + " " + mimetype + " " + clienthost + " " + o.fg[filtergroup]->name + " " + (o.log_user_agent ? useragent : "-"); } if (!logsyslog) *logfile << builtline << std::endl; // append the line else syslog(LOG_INFO, "%s", builtline.c_str()); #ifdef DGDEBUG std::cout << itemcount << " " << builtline << std::endl; #endif delete ipcpeersock; // close the connection #ifdef ENABLE_EMAIL // do the notification work here, but fork for speed if (o.fg[filtergroup]->use_smtp==true) { // run through the gambit to find out of we're sending notification // because if we're not.. then fork()ing is a waste of time. // virus if ((wasscanned && wasinfected) && (o.fg[filtergroup]->notifyav)) { // Use a double fork to ensure child processes are reaped adequately. pid_t smtppid; if ((smtppid = fork()) != 0) { // Parent immediately waits for first child waitpid(smtppid, NULL, 0); } else { // First child forks off the *real* process, but immediately exits itself if (fork() == 0) { // Second child - do stuff setsid(); FILE* mail = popen (o.mailer.c_str(), "w"); if (mail==NULL) { syslog(LOG_ERR, "Unable to contact defined mailer."); } else { fprintf(mail, "To: %s\n", o.fg[filtergroup]->avadmin.c_str()); fprintf(mail, "From: %s\n", o.fg[filtergroup]->mailfrom.c_str()); fprintf(mail, "Subject: %s\n", o.fg[filtergroup]->avsubject.c_str()); fprintf(mail, "A virus was detected by DansGuardian.\n\n"); fprintf(mail, "%-10s%s\n", "Data/Time:", when.c_str()); if (who != "-") fprintf(mail, "%-10s%s\n", "User:", who.c_str()); fprintf(mail, "%-10s%s (%s)\n", "From:", from.c_str(), ((clienthost.length() > 0) ? clienthost.c_str() : "-")); fprintf(mail, "%-10s%s\n", "Where:", where.c_str()); // specifically, the virus name comes after message 1100 ("Virus or bad content detected.") String swhat(what); fprintf(mail, "%-10s%s\n", "Why:", swhat.after(o.language_list.getTranslation(1100)).toCharArray() + 1); fprintf(mail, "%-10s%s\n", "Method:", how.c_str()); fprintf(mail, "%-10s%s\n", "Size:", ssize.c_str()); fprintf(mail, "%-10s%s\n", "Weight:", sweight.c_str()); if (cat.c_str()!=NULL) fprintf(mail, "%-10s%s\n", "Category:", cat.c_str()); fprintf(mail, "%-10s%s\n", "Mime type:", mimetype.c_str()); fprintf(mail, "%-10s%s\n", "Group:", o.fg[filtergroup]->name.c_str()); fprintf(mail, "%-10s%s\n", "HTTP resp:", stringcode.c_str()); pclose(mail); } // Second child exits _exit(0); } // First child exits _exit(0); } } // naughty OR virus else if ((isnaughty || (wasscanned && wasinfected)) && (o.fg[filtergroup]->notifycontent)) { byuser = o.fg[filtergroup]->byuser; // if no violations so far by this user/group, // reset threshold counters if (byuser) { if (!violation_map[who]) { // set the time of the first violation timestamp_map[who] = time(0); vbody_map[who] = ""; } } else if (!o.fg[filtergroup]->current_violations) { // set the time of the first violation o.fg[filtergroup]->threshold_stamp = time(0); o.fg[filtergroup]->violationbody=""; } // increase per-user or per-group violation count if (byuser) violation_map[who]++; else o.fg[filtergroup]->current_violations++; // construct email report char *vbody_temp = new char[8192]; sprintf(vbody_temp, "%-10s%s\n", "Data/Time:", when.c_str()); vbody+=vbody_temp; if ((!byuser) && (who != "-")) { sprintf(vbody_temp, "%-10s%s\n", "User:", who.c_str()); vbody+=vbody_temp; } sprintf(vbody_temp, "%-10s%s (%s)\n", "From:", from.c_str(), ((clienthost.length() > 0) ? clienthost.c_str() : "-")); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Where:", where.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Why:", what.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Method:", how.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Size:", ssize.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Weight:", sweight.c_str()); vbody+=vbody_temp; if (cat.c_str()!=NULL) { sprintf(vbody_temp, "%-10s%s\n", "Category:", cat.c_str()); vbody+=vbody_temp; } sprintf(vbody_temp, "%-10s%s\n", "Mime type:", mimetype.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n", "Group:", o.fg[filtergroup]->name.c_str()); vbody+=vbody_temp; sprintf(vbody_temp, "%-10s%s\n\n", "HTTP resp:", stringcode.c_str()); vbody+=vbody_temp; delete[] vbody_temp; // store the report with the group/user if (byuser) { vbody_map[who]+=vbody; curv_tmp = violation_map[who]; stamp_tmp = timestamp_map[who]; } else { o.fg[filtergroup]->violationbody+=vbody; curv_tmp = o.fg[filtergroup]->current_violations; stamp_tmp = o.fg[filtergroup]->threshold_stamp; } // if threshold exceeded, send mail if (curv_tmp >= o.fg[filtergroup]->violations) { if ((o.fg[filtergroup]->threshold == 0) || ( (time(0) - stamp_tmp) <= o.fg[filtergroup]->threshold)) { // Use a double fork to ensure child processes are reaped adequately. pid_t smtppid; if ((smtppid = fork()) != 0) { // Parent immediately waits for first child waitpid(smtppid, NULL, 0); } else { // First child forks off the *real* process, but immediately exits itself if (fork() == 0) { // Second child - do stuff setsid(); FILE* mail = popen (o.mailer.c_str(), "w"); if (mail==NULL) { syslog(LOG_ERR, "Unable to contact defined mailer."); } else { fprintf(mail, "To: %s\n", o.fg[filtergroup]->contentadmin.c_str()); fprintf(mail, "From: %s\n", o.fg[filtergroup]->mailfrom.c_str()); if (byuser) fprintf(mail, "Subject: %s (%s)\n", o.fg[filtergroup]->contentsubject.c_str(), who.c_str()); else fprintf(mail, "Subject: %s\n", o.fg[filtergroup]->contentsubject.c_str()); fprintf(mail, "%i violation%s ha%s occured within %i seconds.\n", curv_tmp, (curv_tmp==1)?"":"s", (curv_tmp==1)?"s":"ve", o.fg[filtergroup]->threshold); fprintf(mail, "%s\n\n", "This exceeds the notification threshold."); if (byuser) fprintf(mail, "%s", vbody_map[who].c_str()); else fprintf(mail, "%s", o.fg[filtergroup]->violationbody.c_str()); pclose(mail); } // Second child exits _exit(0); } // First child exits _exit(0); } } if (byuser) violation_map[who]=0; else o.fg[filtergroup]->current_violations=0; } } // end naughty OR virus } // end usesmtp #endif continue; // go back to listening } } // should never get here syslog(LOG_ERR, "%s", "Something wicked has ipc happened"); if (logfile) { logfile->close(); // close the file delete logfile; } loggersock.close(); return 1; // It is only possible to reach here with an error } int url_list_listener(bool logconerror) { #ifdef DGDEBUG std::cout << "url listener started" << std::endl; #endif if (!drop_priv_completely()) { return 1; //error } UDSocket* ipcpeersock = NULL; // the socket which will contain the ipc connection int rc, ipcsockfd; char *logline = new char[32000]; char reply; DynamicURLList urllist; #ifdef DGDEBUG std::cout << "setting url list size-age:" << o.url_cache_number << "-" << o.url_cache_age << std::endl; #endif urllist.setListSize(o.url_cache_number, o.url_cache_age); ipcsockfd = urllistsock.getFD(); #ifdef DGDEBUG std::cout << "url ipcsockfd:" << ipcsockfd << std::endl; #endif fd_set fdSet; // our set of fds (only 1) that select monitors for us fd_set fdcpy; // select modifes the set so we need to use a copy FD_ZERO(&fdSet); // clear the set FD_SET(ipcsockfd, &fdSet); // add ipcsock to the set #ifdef DGDEBUG std::cout << "url listener entering select()" << std::endl; #endif while (true) { // loop, essentially, for ever fdcpy = fdSet; // take a copy rc = select(ipcsockfd + 1, &fdcpy, NULL, NULL, NULL); // block // until something happens #ifdef DGDEBUG std::cout << "url listener select returned" << std::endl; #endif if (rc < 0) { // was an error if (errno == EINTR) { continue; // was interupted by a signal so restart } if (logconerror) { syslog(LOG_ERR, "%s", "url ipc rc<0. (Ignorable)"); } continue; } if (FD_ISSET(ipcsockfd, &fdcpy)) { #ifdef DGDEBUG std::cout << "received an url request" << std::endl; #endif ipcpeersock = urllistsock.accept(); if (ipcpeersock->getFD() < 0) { delete ipcpeersock; if (logconerror) { #ifdef DGDEBUG std::cout << "Error accepting url ipc. (Ignorable)" << std::endl; #endif syslog(LOG_ERR, "%s", "Error accepting url ipc. (Ignorable)"); } continue; // if the fd of the new socket < 0 there was error // but we ignore it as its not a problem } try { rc = ipcpeersock->getLine(logline, 32000, 3, true); // throws on err } catch(std::exception & e) { delete ipcpeersock; // close the connection if (logconerror) { #ifdef DGDEBUG std::cout << "Error reading url ipc. (Ignorable)" << std::endl; std::cerr << e.what() << std::endl; #endif syslog(LOG_ERR, "%s", "Error reading url ipc. (Ignorable)"); syslog(LOG_ERR, "%s", e.what()); } continue; } // check the command type // f: flush the cache // g: add a URL to the cache // everything else: search the cache // n.b. we use command characters with ASCII encoding // > 100, because we can have up to 99 filter groups, and // group no. plus 1 is the first character in the 'everything else' // case. if (logline[0] == 'f') { delete ipcpeersock; // close the connection urllist.flush(); #ifdef DGDEBUG std::cout << "url FLUSH request" << std::endl; #endif continue; } if (logline[0] == 'g') { delete ipcpeersock; // close the connection urllist.addEntry(logline + 2, logline[1]-1); continue; } if (urllist.inURLList(logline + 1, logline[0]-1)) { reply = 'Y'; } else { reply = 'N'; } try { ipcpeersock->writeToSockete(&reply, 1, 0, 6); } catch(std::exception & e) { delete ipcpeersock; // close the connection if (logconerror) { syslog(LOG_ERR, "%s", "Error writing url ipc. (Ignorable)"); syslog(LOG_ERR, "%s", e.what()); } continue; } delete ipcpeersock; // close the connection #ifdef DGDEBUG std::cout << "url list reply: " << reply << std::endl; #endif continue; // go back to listening } } delete[]logline; urllistsock.close(); // be nice and neat return 1; // It is only possible to reach here with an error } int ip_list_listener(std::string stat_location, bool logconerror) { #ifdef DGDEBUG std::cout << "ip listener started" << std::endl; #endif if (!drop_priv_completely()) { return 1; //error } UDSocket *ipcpeersock; int rc, ipcsockfd; char* inbuff = new char[16]; // pass in size of list, and max. age of entries (7 days, apparently) DynamicIPList iplist(o.max_ips, 604799); ipcsockfd = iplistsock.getFD(); unsigned long int ip; char reply; struct in_addr inaddr; struct timeval sleep; // used later on for a short sleep sleep.tv_sec = 180; sleep.tv_usec = 0; struct timeval scopy; // copy to use as select() can modify int maxusage = 0; // usage statistics: // current & highest no. of concurrent IPs using the filter double elapsed = 0; // keep a 3 minute counter so license statistics time_t before; // are written even on busy networks (don't rely on timeout) fd_set fdSet; // our set of fds (only 1) that select monitors for us fd_set fdcpy; // select modifes the set so we need to use a copy FD_ZERO(&fdSet); // clear the set FD_SET(ipcsockfd, &fdSet); // add ipcsock to the set #ifdef DGDEBUG std::cout << "ip listener entering select()" << std::endl; #endif scopy = sleep; // loop, essentially, for ever while (true) { fdcpy = fdSet; // take a copy before = time(NULL); rc = select(ipcsockfd + 1, &fdcpy, NULL, NULL, &scopy); // block until something happens elapsed += difftime(time(NULL), before); #ifdef DGDEBUG std::cout << "ip listener select returned: " << rc << ", 3 min timer: " << elapsed << ", scopy: " << scopy.tv_sec << " " << scopy.tv_usec << std::endl; #endif if (rc < 0) { // was an error if (errno == EINTR) { continue; // was interupted by a signal so restart } if (logconerror) { syslog(LOG_ERR, "ip ipc rc<0. (Ignorable)"); } continue; } if (rc == 0 || elapsed >= 180) { #ifdef DGDEBUG std::cout << "ips in list: " << iplist.getNumberOfItems() << std::endl; std::cout << "purging old ip entries" << std::endl; std::cout << "ips in list: " << iplist.getNumberOfItems() << std::endl; #endif // should only get here after a timeout iplist.purgeOldEntries(); // write usage statistics int currusage = iplist.getNumberOfItems(); if (currusage > maxusage) maxusage = currusage; String usagestats; usagestats += String(currusage) + "\n" + String(maxusage) + "\n"; #ifdef DGDEBUG std::cout << "writing usage stats: " << currusage << " " << maxusage << std::endl; #endif int statfd = open(stat_location.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (statfd > 0) { write(statfd, usagestats.toCharArray(), usagestats.length()); } close(statfd); // reset sleep timer scopy = sleep; elapsed = 0; // only skip back to top of loop if there was a genuine timeout if (rc == 0) continue; } if (FD_ISSET(ipcsockfd, &fdcpy)) { #ifdef DGDEBUG std::cout << "received an ip request" << std::endl; #endif ipcpeersock = iplistsock.accept(); if (ipcpeersock->getFD() < 0) { delete ipcpeersock; if (logconerror) { #ifdef DGDEBUG std::cout << "Error accepting ip ipc. (Ignorable)" << std::endl; #endif syslog(LOG_ERR, "Error accepting ip ipc. (Ignorable)"); } continue; // if the fd of the new socket < 0 there was error // but we ignore it as its not a problem } try { rc = ipcpeersock->getLine(inbuff, 16, 3); // throws on err } catch (std::exception& e) { delete ipcpeersock; if (logconerror) { #ifdef DGDEBUG std::cout << "Error reading ip ipc. (Ignorable)" << std::endl; #endif syslog(LOG_ERR, "Error reading ip ipc. (Ignorable)"); } continue; } #ifdef DGDEBUG std::cout << "recieved ip:" << inbuff << std::endl; #endif inet_aton(inbuff, &inaddr); ip = inaddr.s_addr; // is the ip in our list? this also takes care of adding it if not. if (iplist.inList(ip)) reply = 'Y'; else reply = 'N'; try { ipcpeersock->writeToSockete(&reply, 1, 0, 6); } catch (std::exception& e) { delete ipcpeersock; if (logconerror) { #ifdef DGDEBUG std::cout << "Error writing ip ipc. (Ignorable)" << std::endl; #endif syslog(LOG_ERR, "Error writing ip ipc. (Ignorable)"); } continue; } delete ipcpeersock; // close the connection #ifdef DGDEBUG std::cout << "ip list reply: " << reply << std::endl; #endif continue; // go back to listening } } delete[] inbuff; iplistsock.close(); // be nice and neat return 1; // It is only possible to reach here with an error } // * // * // * end logger, IP list and URL cache code // * // * // Does lots and lots of things - forks off url cache & logger processes, preforks child processes for connection handling, does tidying up on exit // also handles the various signalling options DG supports (reload config, flush cache, kill all processes etc.) int fc_controlit() { int rc, fds; o.lm.garbageCollect(); // allocate & create our server sockets serversocketcount = o.filter_ip.size(); serversockets.reset(serversocketcount); int *serversockfds = serversockets.getFDAll(); for (int i = 0; i < serversocketcount; i++) { // if the socket fd is not +ve then the socket creation failed if (serversockfds[i] < 0) { if (!is_daemonised) { std::cerr << "Error creating server socket " << i << std::endl; } syslog(LOG_ERR, "Error creating server socket %d", i); return 1; } } if (o.no_logger) { loggersock.close(); } else { loggersock.reset(); } if (o.url_cache_number > 0) { urllistsock.reset(); } else { urllistsock.close(); } if (o.max_ips > 0) { iplistsock.reset(); } else { iplistsock.close(); } pid_t loggerpid = 0; // to hold the logging process pid pid_t urllistpid = 0; // url cache process id pid_t iplistpid = 0; // ip cache process id if (!o.no_logger) { if (loggersock.getFD() < 0) { if (!is_daemonised) { std::cerr << "Error creating ipc socket" << std::endl; } syslog(LOG_ERR, "%s", "Error creating ipc socket"); return 1; } } // Made unconditional such that we have root privs when creating pidfile & deleting old IPC sockets // PRA 10-10-2005 /*bool needdrop = false; if (o.filter_port < 1024) {*/ #ifdef DGDEBUG std::cout << "seteuiding for low port binding/pidfile creation" << std::endl; #endif //needdrop = true; #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, o.root_user); #else rc = seteuid(o.root_user); #endif if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to seteuid() to bind filter port."); #ifdef DGDEBUG std::cerr << "Unable to seteuid() to bind filter port." << std::endl; #endif return 1; } //} // we have to open/create as root before drop privs int pidfilefd = sysv_openpidfile(o.pid_filename); if (pidfilefd < 0) { syslog(LOG_ERR, "%s", "Error creating/opening pid file."); std::cerr << "Error creating/opening pid file:" << o.pid_filename << std::endl; return 1; } // we expect to find a valid filter ip 0 specified in conf if multiple IPs are in use. // if we don't find one, bind to any, as per old behaviour. if (o.filter_ip[0].length() > 6) { if (serversockets.bindAll(o.filter_ip, o.filter_port)) { if (!is_daemonised) { std::cerr << "Error binding server socket (is something else running on the filter port and ip?" << std::endl; } syslog(LOG_ERR, "Error binding server socket (is something else running on the filter port and ip?"); return 1; } } else { // listen/bind to a port on any interface if (serversockets.bindSingle(o.filter_port)) { if (!is_daemonised) { std::cerr << "Error binding server socket: [" << o.filter_port << "] (" << strerror(errno) << ")" << std::endl; } syslog(LOG_ERR, "Error binding server socket: [%d] (%s)", o.filter_port, strerror(errno)); return 1; } } // Made unconditional for same reasons as above //if (needdrop) { #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, o.proxy_user); #else rc = seteuid(o.proxy_user); // become low priv again #endif if (rc == -1) { syslog(LOG_ERR, "Unable to re-seteuid()"); #ifdef DGDEBUG std::cerr << "Unable to re-seteuid()" << std::endl; #endif return 1; // seteuid failed for some reason so exit with error } //} // Needs deleting if its there unlink(o.ipc_filename.c_str()); // this would normally be in a -r situation. // disabled as requested by Christopher Weimann // Fri, 11 Feb 2005 15:42:28 -0500 // re-enabled temporarily unlink(o.urlipc_filename.c_str()); unlink(o.ipipc_filename.c_str()); if (!o.no_logger) { if (loggersock.bind((char *) o.ipc_filename.c_str())) { // bind to file if (!is_daemonised) { std::cerr << "Error binding ipc server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm " << o.ipc_filename << "')." << std::endl; } syslog(LOG_ERR, "Error binding ipc server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm %s').", o.ipc_filename.c_str()); return 1; } if (loggersock.listen(256)) { // set it to listen mode with a kernel // queue of 256 backlog connections if (!is_daemonised) { std::cerr << "Error listening to ipc server file" << std::endl; } syslog(LOG_ERR, "Error listening to ipc server file"); return 1; } } if (o.url_cache_number > 0) { if (urllistsock.bind((char *) o.urlipc_filename.c_str())) { // bind to file if (!is_daemonised) { std::cerr << "Error binding urllistsock server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm " << o.urlipc_filename << "')." << std::endl; } syslog(LOG_ERR, "Error binding urllistsock server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm %s').", o.urlipc_filename.c_str()); return 1; } if (urllistsock.listen(256)) { // set it to listen mode with a kernel // queue of 256 backlog connections if (!is_daemonised) { std::cerr << "Error listening to url ipc server file" << std::endl; } syslog(LOG_ERR, "Error listening to url ipc server file"); return 1; } } if (o.max_ips > 0) { if (iplistsock.bind(o.ipipc_filename.c_str())) { // bind to file if (!is_daemonised) { std::cerr << "Error binding iplistsock server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm " << o.ipipc_filename << "')." << std::endl; } syslog(LOG_ERR, "Error binding iplistsock server file (try using the SysV to stop DansGuardian then try starting it again or doing an 'rm %s').", o.ipipc_filename.c_str()); return 1; } if (iplistsock.listen(256)) { // set it to listen mode with a kernel // queue of 256 backlog connections if (!is_daemonised) { std::cerr << "Error listening to ip ipc server file" << std::endl; } syslog(LOG_ERR, "Error listening to ip ipc server file"); return 1; } } if (serversockets.listenAll(256)) { // set it to listen mode with a kernel // queue of 256 backlog connections if (!is_daemonised) { std::cerr << "Error listening to server socket" << std::endl; } syslog(LOG_ERR, "Error listening to server socket"); return 1; } if (!daemonise()) { // become a detached daemon if (!is_daemonised) { std::cerr << "Error daemonising" << std::endl; } syslog(LOG_ERR, "Error daemonising"); return 1; } // this has to be done after daemonise to ensure we get the correct PID. rc = sysv_writepidfile(pidfilefd); // also closes the fd if (rc != 0) { syslog(LOG_ERR, "Error writing to the dansguardian.pid file: %s", strerror(errno)); return false; } // We are now a daemon so all errors need to go in the syslog, rather // than being reported on screen as we've detached from the console and // trying to write to stdout will not be nice. struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &sa, NULL)) { // ignore SIGPIPE so we can handle // premature disconections better syslog(LOG_ERR, "%s", "Error ignoring SIGPIPE"); return (1); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; if (sigaction(SIGHUP, &sa, NULL)) { // ignore HUP syslog(LOG_ERR, "%s", "Error ignoring HUP"); return (1); } // Next thing we need to do is to split into two processes - one to // handle incoming TCP connections from the clients and one to handle // incoming UDS ipc from our forked children. This helps reduce // bottlenecks by not having only one select() loop. if (!o.no_logger) { loggerpid = fork(); // make a child processes copy of self to be logger if (loggerpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it delete[] serversockfds; urllistsock.close(); // we don't need our copy of this so close it log_listener(o.log_location, o.logconerror, o.log_syslog); #ifdef DGDEBUG std::cout << "Log listener exiting" << std::endl; #endif _exit(0); // is reccomended for child and daemons to use this instead } } // Same for URL list listener if (o.url_cache_number > 0) { urllistpid = fork(); if (urllistpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it delete[] serversockfds; if (!o.no_logger) { loggersock.close(); // we don't need our copy of this so close it } url_list_listener(o.logconerror); #ifdef DGDEBUG std::cout << "URL List listener exiting" << std::endl; #endif _exit(0); // is reccomended for child and daemons to use this instead } } // and for IP list listener if (o.max_ips > 0) { iplistpid = fork(); if (iplistpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it delete[] serversockfds; if (!o.no_logger) { loggersock.close(); // we don't need our copy of this so close it } ip_list_listener(o.stat_location, o.logconerror); #ifdef DGDEBUG std::cout << "IP List listener exiting" << std::endl; #endif _exit(0); // is reccomended for child and daemons to use this instead } } // I am the parent process here onwards. #ifdef DGDEBUG std::cout << "Parent process created children" << std::endl; #endif if (o.url_cache_number > 0) { urllistsock.close(); // we don't need our copy of this so close it } if (!o.no_logger) { loggersock.close(); // we don't need our copy of this so close it } if (o.max_ips > 0) { iplistsock.close(); } memset(&sa, 0, sizeof(sa)); if (!o.soft_restart) { sa.sa_handler = &sig_term; // register sig_term as our handler } else { sa.sa_handler = &sig_termsafe; } if (sigaction(SIGTERM, &sa, NULL)) { // when the parent process gets a // sigterm we need to kill our // children which this will do, // then we need to exit syslog(LOG_ERR, "Error registering SIGTERM handler"); return (1); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_hup; // register sig_hup as our handler if (sigaction(SIGHUP, &sa, NULL)) { // when the parent process gets a // sighup we need to kill our // children which this will do, // then we need to read config syslog(LOG_ERR, "Error registering SIGHUP handler"); return (1); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_usr1; // register sig_usr1 as our handler if (sigaction(SIGUSR1, &sa, NULL)) { // when the parent process gets a // sigusr1 we need to hup our // children to make them exit // then we need to read fg config syslog(LOG_ERR, "Error registering SIGUSR handler"); return (1); } #ifdef ENABLE_SEGV_BACKTRACE memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_segv; if (sigaction(SIGSEGV, &sa, NULL)) { syslog(LOG_ERR, "Error registering SIGSEGV handler"); return 1; } #endif #ifdef DGDEBUG std::cout << "Parent process sig handlers done" << std::endl; #endif numchildren = 0; // to keep count of our children busychildren = 0; // to keep count of our children int freechildren = 0; // to keep count of our children childrenpids = new int[o.max_children]; // so when one exits we know who childrenstates = new int[o.max_children]; // so we know what they're up to childsockets = new UDSocket* [o.max_children]; fds = o.max_children + serversocketcount; pids = new struct pollfd[fds]; int i; time_t tnow; time_t tmaxspare; time(&tmaxspare); #ifdef DGDEBUG std::cout << "Parent process pid structs allocated" << std::endl; #endif // store child fds... for (i = 0; i < o.max_children; i++) { childrenpids[i] = -1; childrenstates[i] = -1; pids[i].fd = -1; pids[i].events = POLLIN; } // ...and server fds for (i = o.max_children; i < fds; i++) { pids[i].fd = serversockfds[i - o.max_children]; pids[i].events = POLLIN; } #ifdef DGDEBUG std::cout << "Parent process pid structs zeroed" << std::endl; #endif failurecount = 0; // as we don't exit on an error with select() // due to the fact that these errors do happen // every so often on a fully working, but busy // system, we just watch for too many errors // consecutivly. waitingfor = 0; rc = prefork(o.min_children); sleep(1); // need to allow some of the forks to complete #ifdef DGDEBUG std::cout << "Parent process preforked rc:" << rc << std::endl; std::cout << "Parent process pid:" << getpid() << std::endl; #endif if (rc < 0) { ttg = true; syslog(LOG_ERR, "%s", "Error creating initial fork pool - exiting..."); } int tofind; reloadconfig = false; syslog(LOG_INFO, "Started sucessfully."); while (failurecount < 30 && !ttg && !reloadconfig) { // loop, essentially, for ever until 30 // consecutive errors in which case something // is badly wrong. // OR, its timetogo - got a sigterm // OR, we need to exit to reread config if (gentlereload) { #ifdef DGDEBUG std::cout << "gentle reload activated" << std::endl; #endif o.deleteFilterGroups(); if (!o.readFilterGroupConf()) { reloadconfig = true; // filter groups problem so lets // try and reload entire config instead // if that fails it will bomb out } else { if (o.use_filter_groups_list) { o.filter_groups_list.reset(); if (!o.doReadItemList(o.filter_groups_list_location.c_str(),&(o.filter_groups_list),"filtergroupslist",true)) reloadconfig = true; // filter groups problem... } if (!reloadconfig) { o.deletePlugins(o.csplugins); if (!o.loadCSPlugins()) reloadconfig = true; // content scan plugs problem if (!reloadconfig) { o.deletePlugins(o.authplugins); if (!o.loadAuthPlugins()) reloadconfig = true; // auth plugs problem } if (!reloadconfig) { hup_allchildren(); o.lm.garbageCollect(); prefork(o.min_children); gentlereload = false; // everything ok - no full reload needed // clear gentle reload flag for next run of the loop } } } flush_urlcache(); continue; } // Lets take the opportunity to clean up our dead children if any for (i = 0; i < fds; i++) { pids[i].revents = 0; } mopup_afterkids(); rc = poll(pids, fds, 60 * 1000); mopup_afterkids(); if (rc < 0) { // was an error #ifdef DGDEBUG std::cout << "errno:" << errno << " " << strerror(errno) << std::endl; #endif if (errno == EINTR) { continue; // was interupted by a signal so restart } if (o.logconerror) syslog(LOG_ERR, "Error polling child process sockets: %s", strerror(errno)); failurecount++; // log the error/failure continue; // then continue with the looping } tofind = rc; if (rc > 0) { for (i = o.max_children; i < fds; i++) { if (pids[i].revents) { tofind--; } } } if (tofind > 0) { check_kid_readystatus(tofind); mopup_afterkids(); } freechildren = numchildren - busychildren; #ifdef DGDEBUG std::cout << "numchildren:" << numchildren << std::endl; std::cout << "busychildren:" << busychildren << std::endl; std::cout << "freechildren:" << freechildren << std::endl; std::cout << "waitingfor:" << waitingfor << std::endl << std::endl; #endif if (rc > 0) { for (i = o.max_children; i < fds; i++) { if ((pids[i].revents & POLLIN) > 0) { // socket ready to accept() a connection failurecount = 0; // something is clearly working so reset count if (freechildren < 1 && numchildren < o.max_children) { if (waitingfor == 0) { int num = o.prefork_children; if ((o.max_children - numchildren) < num) num = o.max_children - numchildren; if (o.logchildprocs) syslog(LOG_ERR, "Under load - Spawning %d process(es)", num); rc = prefork(num); if (rc < 0) { syslog(LOG_ERR, "Error forking %d extra process(es).", num); failurecount++; } } else usleep(1000); continue; } if (freechildren > 0) { #ifdef DGDEBUG std::cout<<"telling child to accept "<<(i-o.max_children)< o.maxspare_children) { time(&tnow); if ((tnow - tmaxspare) > (2 * 60)) { if (o.logchildprocs) syslog(LOG_ERR, "More than %d free children - Killing %d process(es)", o.maxspare_children, freechildren - o.maxspare_children); cullchildren(freechildren - o.maxspare_children); } } } cullchildren(numchildren); // remove the fork pool of spare children for (int i = 0; i < o.max_children; i++) { if (pids[i].fd != -1) { delete childsockets[i]; childsockets[i] = NULL; } } if (numchildren > 0) { hup_allchildren(); sleep(2); // give them a small chance to exit nicely before we force // hmmmm I wonder if sleep() will get interupted by sigchlds? } if (numchildren > 0) { kill_allchildren(); } // we might not giving enough time for defuncts to be created and then // mopped but on exit or reload config they'll get mopped up sleep(1); mopup_afterkids(); delete[]childrenpids; delete[]childrenstates; delete[]childsockets; delete[]pids; // 4 deletes good, memory leaks bad if (failurecount >= 30) { syslog(LOG_ERR, "%s", "Exiting due to high failure count."); #ifdef DGDEBUG std::cout << "Exiting due to high failure count." << std::endl; #endif } #ifdef DGDEBUG std::cout << "Main parent process exiting." << std::endl; #endif serversockets.deleteAll(); delete[] serversockfds; // be nice and neat memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; if (sigaction(SIGTERM, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGTERM" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGTERM"); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; if (sigaction(SIGHUP, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGHUP" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGHUP"); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; if (sigaction(SIGUSR1, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGUSR1" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGUSR1"); } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; if (sigaction(SIGPIPE, &sa, NULL)) { // restore sig handler // in child process #ifdef DGDEBUG std::cerr << "Error resetting signal for SIGPIPE" << std::endl; #endif syslog(LOG_ERR, "%s", "Error resetting signal for SIGPIPE"); } if (sig_term_killall) { struct sigaction sa, oldsa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGTERM, &sa, &oldsa); // ignore sigterm for us kill(0, SIGTERM); // send everyone in this process group a TERM // which causes them to exit as the default action // but it also seems to send itself a TERM // so we ignore it sigaction(SIGTERM, &oldsa, NULL); // restore prev state } if (reloadconfig || ttg) { if (!o.no_logger) ::kill(loggerpid, SIGTERM); // get rid of logger if (o.url_cache_number > 0) ::kill(urllistpid, SIGTERM); // get rid of url cache if (o.max_ips > 0) ::kill(iplistpid, SIGTERM); // get rid of iplist return reloadconfig ? 2 : 0; } if (o.logconerror) { syslog(LOG_ERR, "%s", "Main parent process exiting."); } return 1; // It is only possible to reach here with an error } dansguardian-2.10.1.1/src/DynamicIPList.hpp0000644001165000116500000000367711110523210015263 00000000000000// DynamicIPList - maintains a sorted list of IP addresses, for checking & // limiting the number of concurrent proxy users. //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_DYNAMICIPLIST #define __HPP_DYNAMICIPLIST // DECLARATIONS class DynamicIPList { public: DynamicIPList(int maxitems, int maxitemage); ~DynamicIPList(); #ifdef DGDEBUG int getListSize() { return size; }; #endif int getNumberOfItems() { return items; }; // return whether or not given IP is in/could be added to list // (i.e. returns false if list already full & this IP's not in it) bool inList(unsigned long int ip); // remove entries older than maxage void purgeOldEntries(); private: // IPs and their ages unsigned long int *data; unsigned long int *datatime; // list size; no. of items currently in list; max. allowed item age int size; int items; int maxage; void stamp(unsigned int pos); // binary search for given ip int search(int a, int s, unsigned long int ip); // compacts list removing blanks void empties(); // returns position of given IP in list, or (0-pos)-1 where pos is where // IP should be inserted to retain sorting. int posInList(unsigned long int ip); }; #endif dansguardian-2.10.1.1/src/DynamicURLList.hpp0000644001165000116500000000440011110523210015376 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_DYNAMICURLLIST #define __HPP_DYNAMICURLLIST // dynamic URL lists - used to cache known clean URLs so filtering can be bypassed class DynamicURLList { public: DynamicURLList(); ~DynamicURLList(); // set list size and timeout on entries (old entries aren't deleted, simply overwritten) bool setListSize(unsigned int s, unsigned int t); // flush the list (set all entries to old) void flush(); // is an entry in the list? bool inURLList(const char *url, const int fg); // add a URL - if it's already there but marked as too old, simply rejuvenate it void addEntry(const char *url, const int fg); private: // index list - points to URL list entries in alphabetical order unsigned int *index; // age list, sorted in the same order as index unsigned long int *urlreftime; // actual URL list char *urls; // group list - which group(s) is this URL clean for? std::string *groups; // size of list int size; // pointer to oldest entry (real entry, not sorted index) int agepos; unsigned int timeout; int items; // binary search for the pos of the given url in the sorted index // returns 0-(pos+1) on failure, where pos is where the entry would be inserted to retain sorting int search(int a, int s, const char *url); // find the index for the given url - makes use of the above search func int posInList(const char *url); }; #endif dansguardian-2.10.1.1/src/OptionContainer.cpp0000644001165000116500000007255511151226434015736 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "OptionContainer.hpp" #include "RegExp.hpp" #include "ConfigVar.hpp" #include #include #include #include #include // checkme: remove? // GLOBALS extern bool is_daemonised; // IMPLEMENTATION OptionContainer::OptionContainer():numfg(0) { } OptionContainer::~OptionContainer() { reset(); } void OptionContainer::reset() { deleteFilterGroups(); deletePlugins(dmplugins); deletePlugins(csplugins); deletePlugins(authplugins); exception_ip_list.reset(); banned_ip_list.reset(); html_template.reset(); language_list.reset(); conffile.clear(); if (use_filter_groups_list) filter_groups_list.reset(); filter_ip.clear(); } void OptionContainer::deleteFilterGroups() { for (int i = 0; i < numfg; i++) { if (fg[i] != NULL) { #ifdef DGDEBUG std::cout << "In deleteFilterGroups loop" << std::endl; #endif delete fg[i]; // delete extra FOptionContainer objects fg[i] = NULL; } } if (numfg > 0) { delete[]fg; numfg = 0; } } void OptionContainer::deletePlugins(std::deque &list) { for (std::deque::iterator i = list.begin(); i != list.end(); i++) { if ((*i) != NULL) { (*i)->quit(); delete (*i); } } list.clear(); } bool OptionContainer::read(const char *filename, int type) { conffilename = filename; // all sorts of exceptions could occur reading conf files try { std::string linebuffer; String temp; // for tempory conversion and storage std::ifstream conffiles(filename, std::ios::in); // dansguardian.conf if (!conffiles.good()) { if (!is_daemonised) { std::cerr << "error reading: " << filename << std::endl; } syslog(LOG_ERR, "%s", "error reading dansguardian.conf"); return false; } while (!conffiles.eof()) { getline(conffiles, linebuffer); if (!conffiles.eof() && linebuffer.length() != 0) { if (linebuffer[0] != '#') { // i.e. not commented out temp = (char *) linebuffer.c_str(); if (temp.contains("#")) { temp = temp.before("#"); } temp.removeWhiteSpace(); // get rid of spaces at end of line linebuffer = temp.toCharArray(); conffile.push_back(linebuffer); // stick option in deque } } } conffiles.close(); if (type == 0 || type == 2) { if ((ipc_filename = findoptionS("ipcfilename")) == "") ipc_filename = "/tmp/.dguardianipc"; if ((urlipc_filename = findoptionS("urlipcfilename")) == "") urlipc_filename = "/tmp/.dguardianurlipc"; if ((ipipc_filename = findoptionS("ipipcfilename")) == "") ipipc_filename = "/tmp/.dguardianipipc"; if ((pid_filename = findoptionS("pidfilename")) == "") { pid_filename = __PIDDIR; pid_filename += "/dansguardian.pid"; } if (findoptionS("logsyslog") == "on") { log_syslog = true; } else if ((log_location = findoptionS("loglocation")) == "") { log_location = __LOGLOCATION; log_location += "/access.log"; log_syslog = false; } if ((stat_location = findoptionS("statlocation")) == "") { stat_location = __LOGLOCATION; stat_location += "/stats"; } if (type == 0) { return true; } } if ((daemon_user_name = findoptionS("daemonuser")) == "") { daemon_user_name = __PROXYUSER; } if ((daemon_group_name = findoptionS("daemongroup")) == "") { daemon_group_name = __PROXYGROUP; } if (findoptionS("nodaemon") == "on") { no_daemon = true; } else { no_daemon = false; } if (findoptionS("nologger") == "on") { no_logger = true; } else { no_logger = false; } if (findoptionS("softrestart") == "on") { soft_restart = true; } else { soft_restart = false; } #ifdef ENABLE_EMAIL // Email notification patch by J. Gauthier mailer = findoptionS("mailer"); #endif // the dansguardian.conf and pics files get amalgamated into one // deque. They are only seperate files for clarity. max_logitem_length = findoptionI("maxlogitemlength"); if (!realitycheck(max_logitem_length, 0, 0, "maxlogitemlength")) { return false; } max_children = findoptionI("maxchildren"); if (!realitycheck(max_children, 4, 0, "maxchildren")) { return false; } // check its a reasonable value min_children = findoptionI("minchildren"); if (!realitycheck(min_children, 1, max_children-1, "minchildren")) { return false; } // check its a reasonable value maxspare_children = findoptionI("maxsparechildren"); if (!realitycheck(maxspare_children, min_children, max_children, "maxsparechildren")) { return false; } // check its a reasonable value prefork_children = findoptionI("preforkchildren"); if (!realitycheck(prefork_children, 1, max_children, "preforkchildren")) { return false; } // check its a reasonable value minspare_children = findoptionI("minsparechildren"); if (!realitycheck(minspare_children, 0, maxspare_children-1, "minsparechildren")) { return false; } // check its a reasonable value maxage_children = findoptionI("maxagechildren"); if (!realitycheck(maxage_children, 1, 0, "maxagechildren")) { return false; } // check its a reasonable value max_ips = findoptionI("maxips"); if (!realitycheck(max_ips, 0, 0, "maxips")) { return false; } // TODO: Implement a "findoptionO" and a version of // reality check which uses off_t, for large file support? max_upload_size = findoptionI("maxuploadsize"); if (!realitycheck(max_upload_size, -1, 0, "maxuploadsize")) { return false; } // check its a reasonable value max_upload_size = max_upload_size * 1024; max_content_filter_size = findoptionI("maxcontentfiltersize"); if (!realitycheck(max_content_filter_size, 0, 0, "maxcontentfiltersize")) { return false; } // check its a reasonable value max_content_filter_size = max_content_filter_size * 1024; max_content_ramcache_scan_size = findoptionI("maxcontentramcachescansize"); if (!realitycheck(max_content_ramcache_scan_size, 0, 0, "maxcontentramcachescansize")) { return false; } max_content_ramcache_scan_size = max_content_ramcache_scan_size * 1024; max_content_filecache_scan_size = findoptionI("maxcontentfilecachescansize"); if (!realitycheck(max_content_filecache_scan_size, 1, 0, "maxcontentfilecachescansize")) { return false; } max_content_filecache_scan_size = max_content_filecache_scan_size * 1024; if (max_content_ramcache_scan_size == 0) { max_content_ramcache_scan_size = max_content_filecache_scan_size; } if (max_content_filter_size == 0) { max_content_filter_size = max_content_ramcache_scan_size; if (max_content_filter_size == 0) { if (!is_daemonised) std::cerr << "maxcontent* settings cannot be zero (to disable phrase filtering, set weightedphrasemode to 0)" << std::endl; syslog(LOG_ERR, "%s", "maxcontent* settings cannot be zero (to disable phrase filtering, set weightedphrasemode to 0)"); return false; } } if (max_content_filter_size > max_content_ramcache_scan_size) { if (!is_daemonised) { std::cerr << "maxcontentfiltersize can not be greater than maxcontentramcachescansize" << std::endl; } syslog(LOG_ERR, "%s", "maxcontentfiltersize can not be greater than maxcontentramcachescansize"); return false; } if (max_content_ramcache_scan_size > max_content_filecache_scan_size) { if (!is_daemonised) { std::cerr << "maxcontentramcachescansize can not be greater than maxcontentfilecachescansize" << std::endl; } syslog(LOG_ERR, "%s", "maxcontentramcachescansize can not be greater than maxcontentfilecachescansize"); return false; } bool contentscanning = findoptionM("contentscanner").size() > 0; if (contentscanning) { trickle_delay = findoptionI("trickledelay"); if (!realitycheck(trickle_delay, 1, 0, "trickledelay")) { return false; } initial_trickle_delay = findoptionI("initialtrickledelay"); if (!realitycheck(initial_trickle_delay, 1, 0, "initialtrickledelay")) { return false; } content_scanner_timeout = findoptionI("contentscannertimeout"); if (!realitycheck(content_scanner_timeout, 1, 0, "contentscannertimeout")) { return false; } if (findoptionS("scancleancache") == "off") { scan_clean_cache = false; } else { scan_clean_cache = true; } if (findoptionS("contentscanexceptions") == "on") { content_scan_exceptions = true; } else { content_scan_exceptions = false; } } if (findoptionS("deletedownloadedtempfiles") == "off") { delete_downloaded_temp_files = false; } else { delete_downloaded_temp_files = true; } url_cache_number = findoptionI("urlcachenumber"); if (!realitycheck(url_cache_number, 0, 0, "urlcachenumber")) { return false; } // check its a reasonable value url_cache_age = findoptionI("urlcacheage"); if (!realitycheck(url_cache_age, 0, 0, "urlcacheage")) { return false; } // check its a reasonable value phrase_filter_mode = findoptionI("phrasefiltermode"); if (!realitycheck(phrase_filter_mode, 0, 3, "phrasefiltermode")) { return false; } preserve_case = findoptionI("preservecase"); if (!realitycheck(preserve_case, 0, 2, "preservecase")) { return false; } if (findoptionS("hexdecodecontent") == "on") { hex_decode_content = true; } else { hex_decode_content = false; } if (findoptionS("forcequicksearch") == "on") { force_quick_search = true; } else { force_quick_search = false; } if (findoptionS("usecustombannedimage") == "off") { use_custom_banned_image = false; } else { use_custom_banned_image = true; } custom_banned_image_file = findoptionS("custombannedimagefile"); banned_image.read(custom_banned_image_file.c_str()); filter_port = findoptionI("filterport"); if (!realitycheck(filter_port, 1, 65535, "filterport")) { return false; } // check its a reasonable value proxy_port = findoptionI("proxyport"); if (!realitycheck(proxy_port, 1, 65535, "proxyport")) { return false; } // etc proxy_ip = findoptionS("proxyip"); // multiple listen IP support filter_ip = findoptionM("filterip"); if (filter_ip.size() > 127) { if (!is_daemonised) { std::cerr << "Can not listen on more than 127 IPs" << std::endl; } syslog(LOG_ERR, "%s", "Can not listen on more than 127 IPs"); return false; } #ifdef ENABLE_ORIG_IP if (findoptionS("originalip") == "off") { get_orig_ip = false; } else { get_orig_ip = true; } #endif ll = findoptionI("loglevel"); if (!realitycheck(ll, 0, 3, "loglevel")) { return false; } // etc log_file_format = findoptionI("logfileformat"); if (!realitycheck(log_file_format, 1, 4, "logfileformat")) { return false; } // etc if (findoptionS("anonymizelogs") == "on") { anonymise_logs = true; } else { anonymise_logs = false; } if (findoptionS("logadblocks") == "on") { log_ad_blocks = true; } else { log_ad_blocks = false; } if (findoptionS("logtimestamp") == "on") { log_timestamp = true; } else { log_timestamp = false; } if (findoptionS("loguseragent") == "on") { log_user_agent = true; } else { log_user_agent = false; } if (findoptionS("showweightedfound") == "on") { show_weighted_found = true; } else { show_weighted_found = false; } weighted_phrase_mode = findoptionI("weightedphrasemode"); if (!realitycheck(weighted_phrase_mode, 0, 2, "weightedphrasemode")) { return false; } reporting_level = findoptionI("reportinglevel"); if (!realitycheck(reporting_level, -1, 3, "reportinglevel")) { return false; } languagepath = findoptionS("languagedir") + "/" + findoptionS("language") + "/"; html_template_location = languagepath + "template.html"; if (findoptionS("forwardedfor") == "on") { forwarded_for = true; } else { forwarded_for = false; } log_exception_hits = findoptionI("logexceptionhits"); if (!realitycheck(log_exception_hits, 0, 2, "logexceptionhits")) { return false; } if (findoptionS("nonstandarddelimiter") == "off") { non_standard_delimiter = false; } else { non_standard_delimiter = true; } if (findoptionS("createlistcachefiles") == "off") { createlistcachefiles = false; } else { createlistcachefiles = true; } if (findoptionS("logconnectionhandlingerrors") == "on") { logconerror = true; } else { logconerror = false; } if (findoptionS("logchildprocesshandling") == "on") { logchildprocs = true; } else { logchildprocs = false; } if (findoptionS("reverseaddresslookups") == "on") { reverse_lookups = true; } else { reverse_lookups = false; } if (findoptionS("reverseclientiplookups") == "on") { reverse_client_ip_lookups = true; } else { reverse_client_ip_lookups = false; } if (findoptionS("logclienthostnames") == "on") { log_client_hostnames = true; } else { log_client_hostnames = false; } if (findoptionS("recheckreplacedurls") == "on") { recheck_replaced_urls = true; } else { recheck_replaced_urls = false; } if (findoptionS("usexforwardedfor") == "on") { use_xforwardedfor = true; } else { use_xforwardedfor = false; } filter_groups = findoptionI("filtergroups"); if (!realitycheck(filter_groups, 1, 0, "filtergroups")) { return false; } if (filter_groups < 1) { if (!is_daemonised) { std::cerr << "filtergroups too small" << std::endl; } syslog(LOG_ERR, "filtergroups too small"); return false; } if (!loadDMPlugins()) { if (!is_daemonised) { std::cerr << "Error loading DM plugins" << std::endl; } syslog(LOG_ERR, "Error loading DM plugins"); return false; } // this needs to be known before loading CS plugins, // because ClamAV plugin makes use of it during init() download_dir = findoptionS("filecachedir"); if (contentscanning) { if (!loadCSPlugins()) { if (!is_daemonised) { std::cerr << "Error loading CS plugins" << std::endl; } syslog(LOG_ERR, "Error loading CS plugins"); return false; } } if (!loadAuthPlugins()) { if (!is_daemonised) { std::cerr << "Error loading auth plugins" << std::endl; } syslog(LOG_ERR, "Error loading auth plugins"); return false; } // if there's no auth enabled, we only need the first group's settings if (authplugins.size() == 0) filter_groups = 1; filter_groups_list_location = findoptionS("filtergroupslist"); std::string banned_ip_list_location(findoptionS("bannediplist")); std::string exception_ip_list_location(findoptionS("exceptioniplist")); group_names_list_location = findoptionS("groupnamesfile"); std::string language_list_location(languagepath + "messages"); if (reporting_level == 1 || reporting_level == 2) { access_denied_address = findoptionS("accessdeniedaddress"); access_denied_domain = access_denied_address.c_str(); access_denied_domain = access_denied_domain.after("://"); access_denied_domain.removeWhiteSpace(); if (access_denied_domain.contains("/")) { access_denied_domain = access_denied_domain.before("/"); // access_denied_domain now contains the FQ host nom of the // server that serves the accessdenied.html file } if (access_denied_domain.contains(":")) { access_denied_domain = access_denied_domain.before(":"); // chop off the port number if any } if (access_denied_domain.length() < 4) { if (!is_daemonised) { std::cerr << "accessdeniedaddress setting appears to be wrong." << std::endl; } syslog(LOG_ERR, "%s", "accessdeniedaddress setting appears to be wrong."); return false; } } if (filter_groups_list_location.length() == 0) { use_filter_groups_list = false; #ifdef DGDEBUG std::cout << "Not using filtergroupslist" << std::endl; #endif } else if (!doReadItemList(filter_groups_list_location.c_str(),&filter_groups_list,"filtergroupslist",true)) { return false; } else { use_filter_groups_list = true; } if (group_names_list_location.length() == 0) { use_group_names_list = false; #ifdef DGDEBUG std::cout << "Not using groupnameslist" << std::endl; #endif } else { use_group_names_list = true; } if (!exception_ip_list.readIPMelangeList(exception_ip_list_location.c_str())) { std::cout << "Failed to read exceptioniplist" << std::endl; return false; } if (!banned_ip_list.readIPMelangeList(banned_ip_list_location.c_str())) { std::cout << "Failed to read bannediplist" << std::endl; return false; } if (!language_list.readLanguageList(language_list_location.c_str())) { return false; } // messages language file if (reporting_level == 3) { // only if reporting set to HTML templ if (!html_template.readTemplateFile(html_template_location.c_str())) { if (!is_daemonised) { std::cerr << "Error reading HTML Template file: " << html_template_location << std::endl; } syslog(LOG_ERR, "Error reading HTML Template file: %s", html_template_location.c_str()); return false; // HTML template file } } if (!readFilterGroupConf()) { if (!is_daemonised) { std::cerr << "Error reading filter group conf file(s)." << std::endl; } syslog(LOG_ERR, "%s", "Error reading filter group conf file(s)."); return false; } } catch(std::exception & e) { if (!is_daemonised) { std::cerr << e.what() << std::endl; // when called the daemon has not // detached so we can do this } return false; } return true; } bool OptionContainer::doReadItemList(const char* filename, ListContainer* lc, const char* fname, bool swsort) { bool result = lc->readItemList(filename, false, 0); if (!result) { if (!is_daemonised) { std::cerr << "Error opening " << fname << std::endl; } syslog(LOG_ERR, "Error opening %s", fname); return false; } if (swsort) lc->doSort(true); else lc->doSort(false); return true; } bool OptionContainer::inExceptionIPList(const std::string *ip, std::string *&host) { return exception_ip_list.inList(*ip, host); } bool OptionContainer::inBannedIPList(const std::string *ip, std::string *&host) { return banned_ip_list.inList(*ip, host); } long int OptionContainer::findoptionI(const char *option) { long int res = String(findoptionS(option).c_str()).toLong(); return res; } std::string OptionContainer::findoptionS(const char *option) { // findoptionS returns a found option stored in the deque String temp; String temp2; String o(option); for (int i = 0; i < (signed) conffile.size(); i++) { temp = conffile[i].c_str(); temp2 = temp.before("="); while (temp2.endsWith(" ")) { // get rid of tailing spaces before = temp2.chop(); } if (o == temp2) { temp = temp.after("="); while (temp.startsWith(" ")) { // get rid of heading spaces temp.lop(); } if (temp.startsWith("'")) { // inverted commas temp.lop(); } while (temp.endsWith(" ")) { // get rid of tailing spaces temp.chop(); } if (temp.endsWith("'")) { // inverted commas temp.chop(); } return temp.toCharArray(); } } return ""; } std::deque OptionContainer::findoptionM(const char *option) { // findoptionS returns all the matching options String temp; String temp2; String o(option); std::deque results; for (int i = 0; i < (signed) conffile.size(); i++) { temp = conffile[i].c_str(); temp2 = temp.before("="); while (temp2.endsWith(" ")) { // get rid of tailing spaces before = temp2.chop(); } if (o == temp2) { temp = temp.after("="); while (temp.startsWith(" ")) { // get rid of heading spaces temp.lop(); } if (temp.startsWith("'")) { // inverted commas temp.lop(); } while (temp.endsWith(" ")) { // get rid of tailing spaces temp.chop(); } if (temp.endsWith("'")) { // inverted commas temp.chop(); } results.push_back(temp); } } return results; } bool OptionContainer::realitycheck(long int l, long int minl, long int maxl, const char *emessage) { // realitycheck checks an amount for certain expected criteria // so we can spot problems in the conf files easier if ((l < minl) || ((maxl > 0) && (l > maxl))) { if (!is_daemonised) { // when called we have not detached from // the console so we can write back an // error std::cerr << "Config problem; check allowed values for " << emessage << std::endl; } syslog(LOG_ERR, "Config problem; check allowed values for %s", emessage); return false; } return true; } bool OptionContainer::readFilterGroupConf() { String prefix(conffilename); prefix = prefix.before(".conf"); prefix += "f"; String file; ConfigVar groupnamesfile; String groupname; bool need_html = false; if (use_group_names_list) { int result = groupnamesfile.readVar(group_names_list_location.c_str(), "="); if (result != 0) { if (!is_daemonised) std::cerr << "Error opening group names file: " << group_names_list_location << std::endl; syslog(LOG_ERR, "Error opening group names file: %s", group_names_list_location.c_str()); return false; } } for (int i = 1; i <= filter_groups; i++) { file = prefix + String(i); file += ".conf"; if (use_group_names_list) { std::ostringstream groupnum; groupnum << i; groupname = groupnamesfile[groupnum.str().c_str()]; if (groupname.length() == 0) { if (!is_daemonised) std::cerr << "Group names file too short: " << group_names_list_location << std::endl; syslog(LOG_ERR, "Group names file too short: %s", group_names_list_location.c_str()); return false; } #ifdef DGDEBUG std::cout << "Group name: " << groupname << std::endl; #endif } if (!readAnotherFilterGroupConf(file.toCharArray(), groupname.toCharArray(), need_html)) { if (!is_daemonised) { std::cerr << "Error opening filter group config: " << file << std::endl; } syslog(LOG_ERR, "Error opening filter group config: %s", file.toCharArray()); return false; } } if (!need_html && (reporting_level != 3)) { #ifdef DGDEBUG std::cout << "Global reporting level not 3 & no filter groups using the template; so resetting it." << std::endl; #endif html_template.reset(); } return true; } bool OptionContainer::readAnotherFilterGroupConf(const char *filename, const char *groupname, bool &need_html) { #ifdef DGDEBUG std::cout << "adding filter group: " << numfg << " " << filename << std::endl; #endif // array of pointers to FOptionContainer typedef FOptionContainer *PFOptionContainer; FOptionContainer **temp = new PFOptionContainer[numfg + 1]; for (int i = 0; i < numfg; i++) { temp[i] = fg[i]; } if (numfg > 0) { delete[]fg; } fg = temp; fg[numfg] = new FOptionContainer; #ifdef DGDEBUG std::cout << "added filter group: " << numfg << " " << filename << std::endl; #endif // pass all the vars from OptionContainer needed (*fg[numfg]).weighted_phrase_mode = weighted_phrase_mode; (*fg[numfg]).force_quick_search = force_quick_search; (*fg[numfg]).createlistcachefiles = createlistcachefiles; (*fg[numfg]).reverse_lookups = reverse_lookups; // pass in default access denied address - can be overidden (*fg[numfg]).access_denied_domain = access_denied_domain; (*fg[numfg]).access_denied_address = access_denied_address; // pass in the group name (*fg[numfg]).name = groupname; // pass in the reporting level - can be overridden (*fg[numfg]).reporting_level = reporting_level; #ifdef DGDEBUG std::cout << "passed variables to filter group: " << numfg << " " << filename << std::endl; #endif bool rc = (*fg[numfg]).read(filename); #ifdef DGDEBUG std::cout << "read filter group: " << numfg << " " << filename << std::endl; #endif numfg++; if (!rc) { return false; } if ((fg[numfg-1]->reporting_level == 3) && (html_template.html.size() == 0)) { #ifdef DGDEBUG std::cout << "One of the groups has overridden the reporting level! Loading the HTML template." << std::endl; #endif need_html = true; if (!html_template.readTemplateFile(html_template_location.c_str())) { if (!is_daemonised) { std::cerr << "Error reading HTML Template file: " << html_template_location << std::endl; } syslog(LOG_ERR, "Error reading HTML Template file: %s", html_template_location.c_str()); return false; // HTML template file } } return true; } bool OptionContainer::loadDMPlugins() { std::deque dq = findoptionM("downloadmanager"); unsigned int numplugins = dq.size(); if (numplugins < 1) { if (!is_daemonised) { std::cerr << "There must be at least one download manager option" << std::endl; } syslog(LOG_ERR, "%s", "There must be at least one download manager option"); return false; } String config; for (unsigned int i = 0; i < numplugins; i++) { config = dq[i]; #ifdef DGDEBUG std::cout << "loading download manager config: " << config << std::endl; #endif DMPlugin *dmpp = dm_plugin_load(config.toCharArray()); if (dmpp == NULL) { if (!is_daemonised) { std::cerr << "dm_plugin_load() returned NULL pointer with config file: " << config << std::endl; } syslog(LOG_ERR, "dm_plugin_load() returned NULL pointer with config file: %s", config.toCharArray()); return false; } bool lastplugin = (i == (numplugins - 1)); int rc = dmpp->init(&lastplugin); if (rc < 0) { if (!is_daemonised) { std::cerr << "Download manager plugin init returned error value: " << rc << std::endl; } syslog(LOG_ERR, "Download manager plugin init returned error value: %d", rc); return false; } else if (rc > 0) { if (!is_daemonised) { std::cerr << "Download manager plugin init returned warning value: " << rc << std::endl; } syslog(LOG_ERR, "Download manager plugin init returned warning value: %d", rc); } dmplugins.push_back(dmpp); } // cache reusable iterators dmplugins_begin = dmplugins.begin(); dmplugins_end = dmplugins.end(); return true; } bool OptionContainer::loadCSPlugins() { std::deque dq = findoptionM("contentscanner"); unsigned int numplugins = dq.size(); if (numplugins < 1) { return true; // to have one is optional } String config; for (unsigned int i = 0; i < numplugins; i++) { config = dq[i]; // worth adding some input checking on config #ifdef DGDEBUG std::cout << "loading content scanner config: " << config << std::endl; #endif CSPlugin *cspp = cs_plugin_load(config.toCharArray()); if (cspp == NULL) { if (!is_daemonised) { std::cerr << "cs_plugin_load() returned NULL pointer with config file: " << config << std::endl; } syslog(LOG_ERR, "cs_plugin_load() returned NULL pointer with config file: %s", config.toCharArray()); return false; } #ifdef DGDEBUG std::cout << "Content scanner plugin is good, calling init..." << std::endl; #endif int rc = cspp->init(NULL); if (rc < 0) { if (!is_daemonised) { std::cerr << "Content scanner plugin init returned error value: " << rc << std::endl; } syslog(LOG_ERR, "Content scanner plugin init returned error value: %d", rc); return false; } else if (rc > 0) { if (!is_daemonised) { std::cerr << "Content scanner plugin init returned warning value: " << rc << std::endl; } syslog(LOG_ERR, "Content scanner plugin init returned warning value: %d", rc); } csplugins.push_back(cspp); } // cache reusable iterators csplugins_begin = csplugins.begin(); csplugins_end = csplugins.end(); return true; } bool OptionContainer::loadAuthPlugins() { // Assume no auth plugins need an upstream proxy query (NTLM, BASIC) until told otherwise auth_needs_proxy_query = false; std::deque dq = findoptionM("authplugin"); unsigned int numplugins = dq.size(); if (numplugins < 1) { return true; // to have one is optional } String config; for (unsigned int i = 0; i < numplugins; i++) { config = dq[i]; // worth adding some input checking on config #ifdef DGDEBUG std::cout << "loading auth plugin config: " << config << std::endl; #endif AuthPlugin *app = auth_plugin_load(config.toCharArray()); if (app == NULL) { if (!is_daemonised) { std::cerr << "auth_plugin_load() returned NULL pointer with config file: " << config << std::endl; } syslog(LOG_ERR, "auth_plugin_load() returned NULL pointer with config file: %s", config.toCharArray()); return false; } #ifdef DGDEBUG std::cout << "Auth plugin is good, calling init..." << std::endl; #endif int rc = app->init(NULL); if (rc < 0) { if (!is_daemonised) { std::cerr << "Auth plugin init returned error value: " << rc << std::endl; } syslog(LOG_ERR, "Auth plugin init returned error value: %d", rc); return false; } else if (rc > 0) { if (!is_daemonised) { std::cerr << "Auth plugin init returned warning value: " << rc << std::endl; } syslog(LOG_ERR, "Auth plugin init returned warning value: %d", rc); } if (app->needs_proxy_query) { auth_needs_proxy_query = true; #ifdef DGDEBUG std::cout << "Auth plugin relies on querying parent proxy" << std::endl; #endif } authplugins.push_back(app); } // cache reusable iterators authplugins_begin = authplugins.begin(); authplugins_end = authplugins.end(); return true; } dansguardian-2.10.1.1/src/FDFuncs.hpp0000644001165000116500000000235611110523210014073 00000000000000// File descriptor functions - generic functions for reading, writing, // and (in future) creating files // Please use *only* for files, not sockets! //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_FDFUNCS #define __HPP_FDFUNCS // INCLUDES #include #include // IMPLEMENTATION // wrappers around FD read/write that restart on EINTR int readEINTR(int fd, char *buf, unsigned int count); int writeEINTR(int fd, char *buf, unsigned int count); #endif dansguardian-2.10.1.1/src/DynamicURLList.cpp0000644001165000116500000002610111110523210015373 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "OptionContainer.hpp" #include "DynamicURLList.hpp" #include #include #include #include #include // GLOBALS extern OptionContainer o; extern bool is_daemonised; // IMPLEMENTATION // note - the list of URLs itself is simply a ring buffer, so the oldest entry/next empty entry is always the // last position we wrote to plus one, wrapping round when we get to the top. // however, we also maintain a seperate index list, which points to the entries in alphabetical order. // constructor - initialise values to empty defaults DynamicURLList::DynamicURLList() :index(NULL), urlreftime(NULL), urls(NULL), groups(NULL), size(0), agepos(0), timeout(0) { } // delete the memory block when the class is destryed DynamicURLList::~DynamicURLList() { delete[]index; delete[]urlreftime; delete[]urls; delete[]groups; } // "flush" the list (not quite) void DynamicURLList::flush() { // make all entries old so they won't be used for (int i = 0; i < items; i++) { urlreftime[index[i]] = 0; } } // find the position of the given URL in the list // return value ranges: // -ve if not found. 0-(pos + 1) is where it should be inserted to retain sorting. // 0 to size if found int DynamicURLList::posInList(const char *url) { if (items == 0) { #ifdef DGDEBUG std::cout << "url list cache is empty" << std::endl; #endif // if the list is empty, indicate that the entry should go in pos 0 return -1; } #ifdef DGDEBUG std::cout << "url list cache: performing search..." << std::endl; #endif return search(0, items - 1, url); } // binary search the list for a given URL // note the list itself is not ordered, but the index array is int DynamicURLList::search(int a, int s, const char *url) { if (a > s) return (-1 - a); int m = (a + s) / 2; // look up the url pointed to by this entry in the index char *i = index[m] * 1000 + urls; /*#ifdef DGDEBUG std::cout << "url list cache: comparing " << i << " to " << url << std::endl; #endif*/ int alen = strlen(i); int blen = strlen(url); int maxlen = alen < blen ? alen : blen; char *apos = (char *) i; char *bpos = (char *) url; int j = 0; int c = 0; unsigned char achar; unsigned char bchar; while (j < maxlen) { achar = apos[0]; bchar = bpos[0]; if (achar > bchar) { c = 1; break; } if (achar < bchar) { c = -1; break; } j++; apos++; bpos++; } if (c == 0) { if (alen > blen) { c = 1; } else if (alen < blen) { c = -1; } } // otherwise, assume both equal // we found the entry if (c == 0) return m; // we didn't, but it's in the lower half if (c == -1) return search(m + 1, s, url); // we got the search window down to 1 entry if (a == s) // therefore, we know where the entry we were looking for // should be added if we are to maintain a sorted list. // return its position, -ve (and strictly below 0), so as to // provide useful information and not mess up return value checks. return (-1 - a); // we didn't find it, but it's in the upper half return search(a, m - 1, url); } // sets how many URLs the list should store, and the maximum age of an entry before it goes inactive bool DynamicURLList::setListSize(unsigned int s, unsigned int t) { if (s < 2) { return false; } if (t < 2) { return false; } size = s; timeout = t; agepos = 0; items = 0; delete[]index; delete[]urlreftime; delete[]urls; delete[]groups; index = new unsigned int[size]; urlreftime = new unsigned long int[size]; urls = new char[size * 1000]; // allows url up to 999 in length groups = new std::string[size]; return true; } // see if the given URL is in the list bool DynamicURLList::inURLList(const char *url, const int fg) { #ifdef DGDEBUG std::cout << "url cache search request: " << fg << " " << url << std::endl; #endif if (items == 0) { return false; } #ifdef DGDEBUG std::cout << "****** url cache table ******" << std::endl; std::cout << "items: " << items << std::endl; for (int i = 0; i < items; i++) { for (unsigned int j = 0; j < groups[index[i]].length(); j++) { std::cout << (unsigned int) (groups[index[i]][j]) << " "; } std::cout << (char*) (index[i] * 1000 + urls) << std::endl; } std::cout << "****** url cache table ******" << std::endl; #endif // truncate URL if necessary, as we have a length limit on our buffers int pos; if (strlen(url) > 999) { String r(String(url, 999)); pos = posInList(r.toCharArray()); } else { pos = posInList(url); } #ifdef DGDEBUG std::cout << "pos: " << pos << std::endl; #endif // if we have found an entry, also check to see that it hasn't gone inactive. // todo: could we speed things up a little by simply refreshing the timer on the // old entry here, instead of having addEntry look for possible duplicates? // actually, i dunno. are URLs from time-limited lists cached? this might cause them to // continue being seen as good/bad (depending on the nature of the list) outside the // allotted window if they get put in the cache during it. if (pos > -1) { unsigned long int timenow = time(NULL); if ((timenow - urlreftime[index[pos]]) > timeout) { #ifdef DGDEBUG std::cout << "found but url ttl exceeded: " << (timenow - urlreftime[index[pos]]) << std::endl; #endif return false; } // o.filter_groups + 1 is a special case, meaning clean for all groups std::string lookfor; lookfor += (char)fg; lookfor += (char)o.filter_groups + 1; if (groups[index[pos]].find_first_of(lookfor) == std::string::npos) { #ifdef DGDEBUG std::cout << "found but url not flagged clean for this group: " << fg << " (is clean for: "; for (unsigned int j = 0; j < groups[index[pos]].length(); j++) { std::cout << (unsigned int) (groups[index[pos]][j]) << " "; } std::cout << ")" << std::endl; #endif return false; } return true; } return false; } // add an entry to the URL list - if it's already there, but timed out due to age, simply refresh the timer // also, maintain the lists' sorting, to allow binary search to be performed void DynamicURLList::addEntry(const char *url, const int fg) { #ifdef DGDEBUG std::cout << "url cache add request: " << fg << " " << url << std::endl; std::cout << "itemsbeforeadd: " << items << std::endl; #endif int len = strlen(url); bool resized = false; char *u; // truncate the URL if it's too long if (len > 999) { u = new char[1000]; u[999] = '\0'; // bugfix - previously, truncation did the above termination, but no string copy! // this might never have been noticed due to high buffer size & correct termination preventing the bug causing a crash. memcpy(u, url, 999); resized = true; len = 999; } else { u = (char *) url; } int pos = posInList(u); if (pos >= 0) { // found if (resized) { delete[]u; } #ifdef DGDEBUG std::cout << "Entry found at pos: " << pos << std::endl; #endif urlreftime[index[pos]] = time(NULL); // reset refresh counter if (groups[index[pos]].find((char)fg, 0) == std::string::npos) groups[index[pos]] += (char)fg; // flag it as clean for this filter group return; // not going to add entry thats there already } pos = 0 - pos - 1; // now contains the insertion point #ifdef DGDEBUG std::cout << "insertion pos: " << pos << std::endl; std::cout << "size: " << size << std::endl; #endif // the list isn't full, so simply push new entry onto the back if (items < size) { #ifdef DGDEBUG std::cout << "items pos; i--) { index[i] = index[i - 1]; } index[pos] = items; groups[items] = (char)fg; items++; if (resized) { delete[]u; } return; } // list is full, so we can't simply push a new entry on to it. // now replace the oldest entry but first need to find it in // the index to remove from there. old entries don't get deleted, just overwritten! // we know the pos in the list of the oldest URL, but not where it is in our sorted index list char *oldestref = urls + agepos * 1000; // now contains pos in sorted index of what we're going to overwrite int delpos = posInList(oldestref); // do the actual overwriting, including termination and setting birthdate to now memcpy(oldestref, u, len); oldestref[len] = '\0'; urlreftime[agepos] = time(NULL); groups[agepos] = (char)fg; // now shuffle the index list to remain sorted // remember: pos contains the alphabetical position of what we just added, // delpos contains the alphabetical position of the previous oldest entry, // and agepos contains the actual position in the string list of the entry we just wrote if (delpos == pos) { // the alphabetical pos of what we just deleted and what we just wrote are one and the same // so simply update the one index value to contain a ref to the new entry index[pos] = agepos; } else if (delpos < pos) { // the alphabetical pos of what we deleted was less than what we just wrote // so shift the list entries between the two up by one (losing delpos), and insert our entry int endpos = pos - 1; for (int i = delpos; i < endpos; i++) { index[i] = index[i + 1]; } index[pos - 1] = agepos; } else if (delpos > pos) { // the alphabetical pos of what we just deleted was greater than what we just added, // so starting from the old pos, work backwards, shifting the entries down by one // then insert our new entry for (int i = delpos; i > pos; i--) { index[i] = index[i - 1]; } index[pos] = agepos; } // the index is now sorted, but the actual list of strings itself is sorted oldest first. // increase the age pointer to the next empty entry - once we get to the end, wrap round // to the top, and overwrite the entries oldest first. // todo: things might speed up if we simply maintain the agepos as an index into the sorted index array, // rather than an index on the real URL list. then we wouldn't need to do a posInList to find the agepos's // sorted index every time we do an add. agepos++; if (agepos == size) { agepos = 0; } if (resized) { delete[]u; } } dansguardian-2.10.1.1/src/BaseSocket.cpp0000644001165000116500000003232311110523210014616 00000000000000// Base socket class - inherit this to implement UNIX/INET domain sockets //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include #include #include #include #include #include #include #include #include #ifdef DGDEBUG #include #endif #include "BaseSocket.hpp" // GLOBALS extern bool reloadconfig; // DEFINITIONS #define dgtimercmp(a, b, cmp) \ (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec cmp (b)->tv_usec) : ((a)->tv_sec cmp (b)->tv_sec)) #define dgtimersub(a, b, result) \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ (result)->tv_sec--; \ (result)->tv_usec += 1000000; \ } // IMPLEMENTATION // a wrapper for select so that it auto-restarts after an EINTR. // can be instructed to watch out for signal triggered config reloads. int selectEINTR(int numfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout, bool honour_reloadconfig) { int rc; errno = 0; // Fix for OSes that do not explicitly modify select()'s timeout value // from Soner Tari (namely OpenBSD) // Modified to use custom code in preference to timersub/timercmp etc. // to avoid that particular portability nightmare. timeval entrytime; timeval exittime; timeval elapsedtime; timeval timeoutcopy; while (true) { // using the while as a restart point with continue if (timeout != NULL) { gettimeofday(&entrytime, NULL); timeoutcopy = *timeout; rc = select(numfds, readfds, writefds, exceptfds, &timeoutcopy); // explicitly modify the timeout if the OS hasn't done this for us if (timeoutcopy.tv_sec == timeout->tv_sec && timeoutcopy.tv_usec == timeout->tv_usec) { gettimeofday(&exittime, NULL); // calculate time spent sleeping this iteration dgtimersub(&exittime, &entrytime, &elapsedtime); // did we wait longer than/as long as was left? if (!dgtimercmp(timeout, &elapsedtime, <)) { // no - reduce the amount that is left dgtimersub(timeout, &elapsedtime, timeout); } else { // yes - we've timed out, so exit timeout->tv_sec = timeout->tv_usec = 0; break; } } else { // if the OS has modified the timeout for us, // propogate the change back to the caller *timeout = timeoutcopy; } } else rc = select(numfds, readfds, writefds, exceptfds, NULL); if (rc < 0) { if (errno == EINTR && (honour_reloadconfig? !reloadconfig : true)) { continue; // was interupted by a signal so restart } } break; // end the while } return rc; // return status } // This class contains client and server socket init and handling // code as well as functions for testing and working with the socket FDs. // constructor - override this if desired to create an actual socket at startup BaseSocket::BaseSocket():timeout(5), sck(-1), buffstart(0), bufflen(0) {} // create socket from FD - must be overridden to clear the relevant address structs BaseSocket::BaseSocket(int fd):timeout(5), buffstart(0), bufflen(0) { sck = fd; } // destructor - close socket BaseSocket::~BaseSocket() { // close fd if socket not used if (sck > -1) { ::close(sck); } } // reset - close socket & reset timeout. // call this in derived classes' reset() method, which should also clear address structs void BaseSocket::baseReset() { if (sck > -1) { ::close(sck); sck = -1; } timeout = 5; buffstart = 0; bufflen = 0; } // mark a socket as a listening server socket int BaseSocket::listen(int queue) { return ::listen(sck, queue); } // "template adaptor" for accept - basically, let G++ do the hard work of // figuring out the type of the third parameter ;) template inline int local_accept_adaptor (int (*accept_func)(int, struct sockaddr*, T), int sck, struct sockaddr *acc_adr, socklen_t *acc_adr_length) { return accept_func (sck, acc_adr, (T) acc_adr_length); } // receive an incoming connection & return FD // call this in accept methods of derived classes, which should pass in empty sockaddr & socklen_t to be filled out int BaseSocket::baseAccept(struct sockaddr *acc_adr, socklen_t *acc_adr_length) { // OS X defines accept as: // int accept(int s, struct sockaddr *addr, int *addrlen); // but everyone else as: // int accept(int s, struct sockaddr *addr, socklen_t *addrlen); // NB: except 10.4, which seems to use the more standard definition. grrr. return local_accept_adaptor(::accept, sck, acc_adr, acc_adr_length); } // return socket's FD - please use sparingly and DO NOT do manual data transfer using it int BaseSocket::getFD() { return sck; } // close the socket void BaseSocket::close() { if (sck > -1) { ::close(sck); sck = -1; } buffstart = 0; bufflen = 0; } // set the socket-wide timeout void BaseSocket::setTimeout(int t) { timeout = t; } // return timeout int BaseSocket::getTimeout() { return timeout; } // non-blocking check to see if there is data waiting on socket bool BaseSocket::checkForInput() { if ((bufflen - buffstart) > 0) return true; fd_set fdSet; FD_ZERO(&fdSet); // clear the set FD_SET(sck, &fdSet); // add fd to the set timeval t; // timeval struct t.tv_sec = 0; t.tv_usec = 0; if (selectEINTR(sck + 1, &fdSet, NULL, NULL, &t) < 1) { return false; } return true; } // blocking check for waiting data - blocks for up to given timeout, can be told to break on signal-triggered config reloads void BaseSocket::checkForInput(int timeout, bool honour_reloadconfig) throw(std::exception) { if ((bufflen - buffstart) > 0) return; // blocks if socket blocking // until timeout fd_set fdSet; FD_ZERO(&fdSet); // clear the set FD_SET(sck, &fdSet); // add fd to the set timeval t; // timeval struct t.tv_sec = timeout; t.tv_usec = 0; if (selectEINTR(sck + 1, &fdSet, NULL, NULL, &t, honour_reloadconfig) < 1) { std::string err("select() on input: "); throw std::runtime_error(err + (errno ? strerror(errno) : "timeout")); } } // non-blocking check to see if a socket is ready to be written bool BaseSocket::readyForOutput() { fd_set fdSet; FD_ZERO(&fdSet); // clear the set FD_SET(sck, &fdSet); // add fd to the set timeval t; // timeval struct t.tv_sec = 0; t.tv_usec = 0; if (selectEINTR(sck + 1, NULL, &fdSet, NULL, &t) < 1) { return false; } return true; } // blocking equivalent of above, can be told to break on signal-triggered reloads void BaseSocket::readyForOutput(int timeout, bool honour_reloadconfig) throw(std::exception) { // blocks if socket blocking // until timeout fd_set fdSet; FD_ZERO(&fdSet); // clear the set FD_SET(sck, &fdSet); // add fd to the set timeval t; // timeval struct t.tv_sec = timeout; t.tv_usec = 0; if (selectEINTR(sck + 1, NULL, &fdSet, NULL, &t, honour_reloadconfig) < 1) { std::string err("select() on output: "); throw std::runtime_error(err + (errno ? strerror(errno) : "timeout")); } } // read a line from the socket, can be told to break on config reloads int BaseSocket::getLine(char *buff, int size, int timeout, bool honour_reloadconfig, bool *chopped) throw(std::exception) { // first, return what's left from the previous buffer read, if anything int i = 0; if ((bufflen - buffstart) > 0) { /*#ifdef DGDEBUG std::cout << "data already in buffer; bufflen: " << bufflen << " buffstart: " << buffstart << std::endl; #endif*/ int tocopy = size; if ((bufflen - buffstart) < size) tocopy = bufflen - buffstart; char* result = (char*)memccpy(buff, buffer + buffstart, '\n', tocopy); if (result != NULL) { // indicate that a newline was chopped off, if desired if (chopped) *chopped = true; *(--result) = '\0'; buffstart += (result - buff) + 1; return result - buff; } else { i += tocopy; } } while (i < (size - 1)) { buffstart = 0; bufflen = 0; try { checkForInput(timeout, honour_reloadconfig); } catch(std::exception & e) { throw std::runtime_error(std::string("Can't read from socket: ") + strerror(errno)); // on error } bufflen = recv(sck, buffer, 1024, 0); #ifdef DGDEBUG std::cout << "read into buffer; bufflen: " << bufflen << std::endl; #endif if (bufflen < 0) { if (errno == EINTR && (honour_reloadconfig ? !reloadconfig : true)) { continue; } throw std::runtime_error(std::string("Can't read from socket: ") + strerror(errno)); // on error } //if socket closed or newline received... if (bufflen == 0) { buff[i] = '\0'; // ...terminate string & return what read return i; } int tocopy = bufflen; if ((i + bufflen) > (size-1)) tocopy = (size-1) - i; char* result = (char*)memccpy(buff+i, buffer, '\n', tocopy); if (result != NULL) { // indicate that a newline was chopped off, if desired if (chopped) *chopped = true; *(--result) = '\0'; buffstart += (result - (buff+i)) + 1; return i + (result - (buff+i)); } i += tocopy; } // oh dear - buffer end reached before we found a newline buff[i] = '\0'; return i; } // write line to socket void BaseSocket::writeString(const char *line) throw(std::exception) { int l = strlen(line); if (!writeToSocket(line, l, 0, timeout)) { throw std::runtime_error(std::string("Can't write to socket: ") + strerror(errno)); } } // write data to socket - throws exception on failure, can be told to break on config reloads void BaseSocket::writeToSockete(const char *buff, int len, unsigned int flags, int timeout, bool honour_reloadconfig) throw(std::exception) { if (!writeToSocket(buff, len, flags, timeout, honour_reloadconfig)) { throw std::runtime_error(std::string("Can't write to socket: ") + strerror(errno)); } } // write data to socket - can be told not to do an initial readyForOutput, and to break on config reloads bool BaseSocket::writeToSocket(const char *buff, int len, unsigned int flags, int timeout, bool check_first, bool honour_reloadconfig) { int actuallysent = 0; int sent; while (actuallysent < len) { if (check_first) { try { readyForOutput(timeout, honour_reloadconfig); // throws exception on error or timeout } catch(std::exception & e) { return false; } } sent = send(sck, buff + actuallysent, len - actuallysent, 0); if (sent < 0) { if (errno == EINTR && (honour_reloadconfig ? !reloadconfig : true)) { continue; // was interupted by signal so restart } return false; } if (sent == 0) { return false; // other end is closed } actuallysent += sent; } return true; } // read a specified expected amount and return what actually read int BaseSocket::readFromSocketn(char *buff, int len, unsigned int flags, int timeout) { int cnt, rc; cnt = len; // first, return what's left from the previous buffer read, if anything if ((bufflen - buffstart) > 0) { /*#ifdef DGDEBUG std::cout << "readFromSocketn: data already in buffer; bufflen: " << bufflen << " buffstart: " << buffstart << std::endl; #endif*/ int tocopy = len; if ((bufflen - buffstart) < len) tocopy = bufflen - buffstart; memcpy(buff, buffer + buffstart, tocopy); cnt -= tocopy; buffstart += tocopy; buff += tocopy; if (cnt == 0) return len; } while (cnt > 0) { try { checkForInput(timeout); // throws exception on error or timeout } catch(std::exception & e) { return -1; } rc = recv(sck, buff, cnt, flags); if (rc < 0) { if (errno == EINTR) { continue; } return -1; } if (rc == 0) { // eof return len - cnt; } buff += rc; cnt -= rc; } return len; } // read what's available and return error status - can be told not to do an initial checkForInput, and to break on reloads int BaseSocket::readFromSocket(char *buff, int len, unsigned int flags, int timeout, bool check_first, bool honour_reloadconfig) { // first, return what's left from the previous buffer read, if anything int cnt = len; int tocopy = 0; if ((bufflen - buffstart) > 0) { /*#ifdef DGDEBUG std::cout << "readFromSocket: data already in buffer; bufflen: " << bufflen << " buffstart: " << buffstart << std::endl; #endif*/ tocopy = len; if ((bufflen - buffstart) < len) tocopy = bufflen - buffstart; memcpy(buff, buffer + buffstart, tocopy); cnt -= tocopy; buffstart += tocopy; buff += tocopy; if (cnt == 0) return len; } int rc; if (check_first) { try { checkForInput(timeout, honour_reloadconfig); } catch(std::exception & e) { return -1; } } while (true) { rc = recv(sck, buff, cnt, flags); if (rc < 0) { if (errno == EINTR && (honour_reloadconfig ? !reloadconfig : true)) { continue; } } break; } return rc + tocopy; } dansguardian-2.10.1.1/src/LanguageContainer.hpp0000644001165000116500000000243411110523210016166 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb/.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_LANGUAGECONTAINER #define __HPP_LANGUAGECONTAINER // INCLUDES #include #include "String.hpp" // DECLARATIONS class LanguageContainer { public: void reset(); bool readLanguageList(const char *filename); const char *getTranslation(const unsigned int index); private: std::deque keys; std::deque values; }; #endif dansguardian-2.10.1.1/src/ImageContainer.cpp0000644001165000116500000000611011110523210015453 00000000000000//Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@jadeb//.com) but heavily based on code //written by Aecio F. Neto (afn@harvest.com.br). //For support go to http://groups.yahoo.com/group/dansguardian // 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 // INCLUDES #ifdef HAVE_CONFIG_H #include "dgconfig.h" #endif #include "ImageContainer.hpp" #include #include #include #include #include #include // GLOBALS extern bool is_daemonised; // IMPLEMENTATION ImageContainer::ImageContainer() { image = NULL; imagelength = 0; } ImageContainer::~ImageContainer() { delete[]image; } // wipe the loaded image void ImageContainer::reset() { delete[]image; image = NULL; mimetype = ""; imagelength = 0; } // send image to client void ImageContainer::display(Socket * s) { #ifdef DGDEBUG std::cout << "Displaying custom image file" << std::endl; std::cout << "mimetype: " << mimetype << std::endl; #endif (*s).writeString("Content-type: "); (*s).writeString(mimetype.toCharArray()); (*s).writeString("\n\n"); (*s).writeToSocket(image, imagelength, 0, (*s).getTimeout()); } // read image from file bool ImageContainer::read(const char *filename) { String temp; temp = (char *) filename; temp.toLower(); if (temp.endsWith(".jpg") || temp.endsWith(".jpeg") || temp.endsWith(".jpe")) { mimetype = "image/jpg"; } else if (temp.endsWith("png")) mimetype = "image/png"; else { mimetype = "image/gif"; } std::ifstream imagefile; imagefile.open(filename, std::ifstream::binary); imagefile.seekg(0, std::ios::end); imagelength = imagefile.tellg(); imagefile.seekg(0, std::ios::beg); if (imagelength) { if (image != NULL) delete[] image; image = new char[imagelength + 1]; imagefile.read(image, imagelength); if (!imagefile.good()) { if (!is_daemonised) std::cerr << "Error reading custom image file: " << filename << std::endl; syslog(LOG_ERR, "%s", "Error reading custom image file."); return false; } } else { if (!is_daemonised) std::cerr << "Error reading custom image file: " << filename << std::endl; syslog(LOG_ERR, "%s", "Error reading custom image file."); return false; } imagefile.close(); // #ifdef DGDEBUG // for (long int i = 0; i < imagelength; i++) // printf("Image byte content: %x\n", image[i]); // #endif return true; } dansguardian-2.10.1.1/src/DownloadManager.hpp0000644001165000116500000000544311110523210015645 00000000000000//Defines the DMPlugin base class, and dm_plugin_loader function //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. // 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 #ifndef __HPP_DOWNLOADMANAGER #define __HPP_DOWNLOADMANAGER // INCLUDES #include "String.hpp" #include "ConfigVar.hpp" #include "DataBuffer.hpp" #include "Socket.hpp" #include "HTTPHeader.hpp" #include "ListContainer.hpp" #include "Plugin.hpp" #include // DECLARATIONS class DMPlugin; // class factory functions for DM plugins typedef DMPlugin* dmcreate_t(ConfigVar &); // the DMPlugin interface - inherit & implement this to make download managers class DMPlugin:public Plugin { public: DMPlugin(ConfigVar &definition); virtual ~DMPlugin() {}; // plugin initialise/quit routines. // if lastplugin is true, this is being loaded as the fallback option, // and needn't load in purely request matching related options. virtual int init(void* args); virtual int quit() { return 0; }; // will this download manager handle this request? virtual bool willHandle(HTTPHeader *requestheader, HTTPHeader *docheader); // download the body for the given request virtual int in(DataBuffer *d, Socket *sock, Socket *peersock, HTTPHeader *requestheader, HTTPHeader *docheader, bool wantall, int *headersent, bool *toobig) = 0; // send a download link to the client (the actual link, and the clean "display" version of the link) virtual void sendLink(Socket &peersock, String &linkurl, String &prettyurl); private: // regular expression for matching supported user agents RegExp ua_match; // if there isn't one, set this flag bool alwaysmatchua; protected: // our configuration values // derived classes could definitely have a use for these ConfigVar cv; // standard lists ListContainer mimetypelist; ListContainer extensionlist; // .. and their enable flags bool mimelistenabled; bool extensionlistenabled; // read managedmimetypelist and managedextensionlist bool readStandardLists(); }; // create an instance of the plugin given in the configuration file DMPlugin* dm_plugin_load(const char *pluginConfigPath); #endif dansguardian-2.10.1.1/src/Auth.hpp0000644001165000116500000000564111110523210013504 00000000000000// AuthPlugin class - interface for plugins for retrieving client usernames // and filter group membership //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_AUTH #define __HPP_AUTH // INCLUDES #include "Plugin.hpp" #include "ConfigVar.hpp" #include "HTTPHeader.hpp" // DEFINES // success #define DGAUTH_OK 0 // auth info required for this method not found (continue querying other plugins) #define DGAUTH_NOMATCH 2 // auth info found, but no such user in filtergroupslist (stop querying plugins - use this code with caution!) #define DGAUTH_NOUSER 3 // redirect the user to a login page #define DGAUTH_REDIRECT 4 // any < 0 return code signifies error // DECLARATIONS class AuthPlugin:public Plugin { public: AuthPlugin(ConfigVar &definition); virtual int init(void* args); virtual int quit(); // determine the username // return one of these codes: // OK - success, username in string // REDIRECT - redirect user to URL in string // NOMATCH - did not find the necessary info in the request (query remaining plugins) // any < 0 - error virtual int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) = 0; // determine what filter group the given username is in // queries the standard filtergroupslist // return one of these codes: // OK - success, group no. in fg // NOMATCH - did not find a group for this user (query remaining plugins) // NOUSER - did not find a group for this user (do not query remaining plugins) // any < 0 - error virtual int determineGroup(std::string &user, int &fg); // is this a connection-based auth type, i.e. assume all subsequent requests on the pconn are from the same user? bool is_connection_based; // does this auth type rely on queries from the parent proxy (e.g. NTLM, basic auth)? bool needs_proxy_query; protected: ConfigVar cv; }; // class factory functions for Auth plugins typedef AuthPlugin* authcreate_t(ConfigVar &); // Return an instance of the plugin defined in the given configuration file AuthPlugin* auth_plugin_load(const char *pluginConfigPath); #endif dansguardian-2.10.1.1/src/HTMLTemplate.hpp0000644001165000116500000000406611110523210015043 00000000000000//Declares the HTMLTemplate class, for displaying template-based banned pages to clients //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. //Written by Daniel Barron (daniel@//jadeb.com). //For support go to http://groups.yahoo.com/group/dansguardian // 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 #ifndef __HPP_HTMLTEMPLATE #define __HPP_HTMLTEMPLATE // INCLUDES #include "String.hpp" #include "Socket.hpp" #include #include // DECLARATIONS class HTMLTemplate { public: // string list for holding the template // public so that it can be accessed directly for display without using // the default set of placeholders std::deque html; // wipe the loaded template void reset(); // load in a template from the given file, looking for placeholder strings (reason, URL, category etc.) // optionally, provide your own set of placeholders bool readTemplateFile(const char *filename, const char *placeholders = NULL); // fill in the template with the given info and send it to the client over the given socket // only useful if you used the default set of placeholders void display(Socket *s, String *url, std::string &reason, std::string &logreason, std::string &categories, std::string *user, std::string *ip, std::string *host, int filtergroup, String &hashed); private: // add a string to the list void push(String s); }; #endif dansguardian-2.10.1.1/configure.ac0000644001165000116500000004473611157440673013627 00000000000000# Autoconf script # Inspired by a script provided by Alex Ott # 2004,2005 - Daniel Barron AC_PREREQ(2.57) AC_INIT(dansguardian, 2.10.1.1) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS([dgconfig.h]) AC_CACHE_LOAD # Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_LANG(C++) AC_CACHE_SAVE # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdlib.h]) AC_CHECK_HEADERS([string.h sys/socket.h sys/time.h syslog.h unistd.h locale.h]) AC_CHECK_HEADERS([sys/types.h sys/un.h sys/poll.h sys/resource.h]) AC_CHECK_HEADERS([pwd.h grp.h]) AC_CHECK_HEADERS([byteswap.h]) # Check system endianness AC_C_BIGENDIAN # check for zlib AC_MSG_CHECKING(if zlib should be statically linked) AC_ARG_ENABLE(static-zlib, [AC_HELP_STRING([--enable-static-zlib@<:@=no@:>@], [Enable static linking of zlib])], [ if test "x$enableval" = "xno"; then staticzlib=false AC_MSG_RESULT(no) else staticzlib=true AC_MSG_RESULT(yes) fi ], [ staticzlib=false AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(for zlib) AC_ARG_WITH(zlib, [AC_HELP_STRING([--with-zlib@<:@=NONE@:>@], [non-standard search path for zlib library])], [ # check for header & func (in library) in given prefix CPPFLAGS="${CPPFLAGS} -I${withval}/include" if test "x$staticzlib" = "xtrue"; then LIBS="-Bstatic -L${withval} -lz -Bdynamic ${LIBS}" else LIBS="-L${withval}/lib -lz ${LIBS}" fi ], [ # if --with-zlib is not supplied, we still need -lz in LIBS. if test "x$staticzlib" = "xtrue"; then LIBS="-Bstatic -lz -Bdynamic ${LIBS}" else LIBS="-lz ${LIBS}" fi ]) AC_CHECK_HEADERS([zlib.h]) if ! test "x$staticzlib" = "xtrue"; then AC_CHECK_LIB(z, gzdopen, [AC_MSG_RESULT(yes)], [AC_MSG_ERROR([no zlib!])]) fi AC_CACHE_SAVE # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_OFF_T AC_TYPE_UID_T # Checks for library functions. AC_FUNC_FORK AC_CHECK_FUNCS([dup2 gettimeofday memset select]) AC_CHECK_FUNCS([strerror strstr strtol]) AC_CHECK_FUNCS([setuid setgid umask seteuid setreuid setlocale]) AC_SEARCH_LIBS([floor], [m]) AC_SEARCH_LIBS([gethostbyname], [nsl]) AC_SEARCH_LIBS([socket], [socket], [], [ AC_CHECK_LIB( [socket], [socket], [LIBS="-lsocket -lnsl $LIBS"], [], [-lnsl] ) ]) AC_SEARCH_LIBS([inet_aton], [resolv]) AC_CACHE_SAVE AC_MSG_CHECKING(for backside with both hands) AC_MSG_RESULT(no) AC_MSG_CHECKING(build os) AC_CANONICAL_BUILD AC_MSG_RESULT($build_os) AC_MSG_CHECKING(for debug option) AC_ARG_WITH(dgdebug, [AC_HELP_STRING([--with-dgdebug@<:@=off@:>@], [switch on debug build mode])], [if test "x${withval}" == "xoff" ; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) dgdebug=${withval} AC_DEFINE(DGDEBUG, 1, [Define to enable debug build mode]) fi], [ # disable by default AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(for proxy user) AC_ARG_WITH(proxyuser, [AC_HELP_STRING([--with-proxyuser@<:@=nobody@:>@], [name of proxy user])], [if test "x${withval}" != "x" ; then AC_MSG_RESULT(yes) proxyuser=${withval} else AC_MSG_RESULT(no) proxyuser=nobody fi], [ # disable by default AC_MSG_RESULT(no) proxyuser=nobody ]) AC_SUBST(DGPROXYUSER, "$proxyuser") AC_MSG_CHECKING(for proxy group) AC_ARG_WITH(proxygroup, [AC_HELP_STRING([--with-proxygroup@<:@=nobody@:>@], [name of proxy group])], [if test "x${withval}" != "x" ; then AC_MSG_RESULT(yes) proxygroup=${withval} else AC_MSG_RESULT(no) proxygroup=nobody fi], [ # disable by default AC_MSG_RESULT(no) proxygroup=nobody ]) AC_SUBST(DGPROXYGROUP, "$proxygroup") AC_MSG_CHECKING(for piddir) AC_ARG_WITH(piddir, [AC_HELP_STRING([--with-piddir@<:@=PREFIX/LOCALSTATEDIR/run@:>@], [path for pid file])], [if test "x${withval}" != "x" ; then AC_MSG_RESULT(yes) piddir=${withval} else AC_MSG_RESULT(no) piddir="${localstatedir}/run" fi], [ # disable by default AC_MSG_RESULT(no) piddir="${localstatedir}/run" ]) AC_FINALIZE_VAR(DGPIDDIR,"$piddir") AC_SUBST(DGPIDDIR) AC_MSG_CHECKING(for logdir) AC_ARG_WITH(logdir, [AC_HELP_STRING([--with-logdir@<:@=PREFIX/LOCALSTATEDIR/log/dansguardian@:>@], [path for log files])], [if test "x${withval}" != "x" ; then AC_MSG_RESULT(yes) logdir=${withval} else AC_MSG_RESULT(no) logdir="${localstatedir}/log/${PACKAGE_NAME}" fi], [ # disable by default AC_MSG_RESULT(no) logdir="${localstatedir}/log/${PACKAGE_NAME}" ]) AC_FINALIZE_VAR(DGLOGLOCATION,"$logdir") AC_SUBST(DGLOGLOCATION) PKG_PROG_PKG_CONFIG # asking user if they want PCRE support AC_MSG_CHECKING(for PCRE support) AC_ARG_ENABLE( pcre, [AC_HELP_STRING([--enable-pcre@<:@=yes@:>@], [Enable support for the PCRE library])], [ if test "x$enableval" = "xno"; then pcre=false AC_MSG_RESULT(no) else pcre=true AC_MSG_RESULT(yes) fi ], [ # enable by default pcre=true AC_MSG_RESULT(yes) ] ) if test "x$pcre" = "xtrue"; then PKG_CHECK_MODULES([PCRE],[libpcre >= 6.0]) AC_DEFINE([HAVE_PCRE],[],[Define to enable PCRE support]) PCRE_LIBS="-lpcreposix ${PCRE_LIBS}" else AC_CHECK_FUNCS([regcomp]) fi AM_CONDITIONAL(HAVE_PCRE, test "x$pcre" = "xtrue") # ask user if they want a backtrace logged after segfault AC_MSG_CHECKING(for backtrace on segfault support) AC_ARG_ENABLE( segv_backtrace, [AC_HELP_STRING([--enable-segv-backtrace@<:@=no@:>@], [Enable logging a backtrace when a segmentation fault occurs])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) else # check for native header & func (no library) AC_CHECK_FUNCS(backtrace, [AC_MSG_RESULT(native)], [ AC_MSG_RESULT(no) # native not found, so look for linked LIBS="-lexecinfo ${LIBS}" AC_CHECK_LIB(execinfo, backtrace, [ AC_MSG_RESULT(linked) ], [ AC_MSG_RESULT(no) AC_MSG_ERROR([no native or standard library backtrace function found! (needed by "--enable-segv-backtrace")]) ]) ]) AC_DEFINE([ENABLE_SEGV_BACKTRACE],[],[Define to enable backtrace on segmentation fault]) # add -rdynamic to compiler flags to force output of symbol tables CXXFLAGS="-rdynamic ${CXXFLAGS}" fi ], [ # disable by default AC_MSG_RESULT(no) ]) # ask user if they want large file support on 32 bit systems AC_MSG_CHECKING([for large file support]) AC_ARG_ENABLE( lfs, [AC_HELP_STRING([--enable-lfs@<:@=yes@:>@], [Enable large file support on 32 bit systems])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) else lfsflags=`getconf LFS_CFLAGS` lfsld=`getconf LFS_LDFLAGS` lfslib=`getconf LFS_LIBS` CXXFLAGS="${CXXFLAGS} $lfsflags" LDFLAGS="${LDFLAGS} $lfsld" LIBS="${LIBS} $lfslib" AC_MSG_RESULT(yes) fi ], [ # enable by default lfsflags=`getconf LFS_CFLAGS` lfsld=`getconf LFS_LDFLAGS` lfslib=`getconf LFS_LIBS` CXXFLAGS="${CXXFLAGS} $lfsflags" LDFLAGS="${LDFLAGS} $lfsld" LIBS="${LIBS} $lfslib" AC_MSG_RESULT(yes) ]) # ask the user if they want support for retrieving original destination IPs # when acting as a transparent proxy AC_MSG_CHECKING([for original destination IP checking support]) AC_ARG_ENABLE( orig-ip, [AC_HELP_STRING([--enable-orig-ip@<:@=no@:>@], [Enable support for checking the client's original destination IP address against HTTP request details when deployed as a transparent proxy (US-CERT VU@%:@435052). Currently only works on Linux.])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) origip=false ORIGIPSUPPORT="#!! Not compiled !! " else AC_MSG_RESULT(yes) origip=true AC_DEFINE([ENABLE_ORIG_IP],[],[Define to enable original destination IP checking]) ORIGIPSUPPORT="" fi ], [ # disable by default AC_MSG_RESULT(no) origip=false ORIGIPSUPPORT="#!! Not compiled !! " ]) AC_SUBST(ORIGIPSUPPORT) # determine whether or not "off_t" is simply a typedef of # "int", "unsigned int", "long", etc. - if it is, the String # class won't compile if its off_t constructor is defined, # as that would represent a function redefinition. AC_MSG_CHECKING([for type collision with off_t]) AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM( [[#include ]],[[ struct Foo{ void f(const int); void f(const long); void f(const long unsigned); void f(const unsigned int); void f(const off_t); };]]) ],[ AC_MSG_RESULT([no]) ],[ AC_MSG_RESULT([yes]) AC_DEFINE([OFFT_COLLISION],[],[Define if type "off_t" is a typedef of another type for which String already has a constructor]) ]) # by default, we do not need the content scanner list or config directories, nor the download manager list directory cslists=false csconfigs=false dmlists=false # asking user if they want clamav support AC_MSG_CHECKING(for libclamav support) AC_ARG_ENABLE( clamav, [AC_HELP_STRING([--enable-clamav@<:@=no@:>@], [Enable support for the libClamAV content scanner. Please note that the ClamD-compatible scanner is always built, and is preferable to this plugin for most usage scenarios.])], [ if test "x$enableval" = "xno"; then clamav=false AC_MSG_RESULT(no) CLAMAVSUPPORT="!! Not compiled !! " CLAMAVSHM="!! Not supported on this platform !!" else AC_MSG_RESULT(yes) PKG_CHECK_MODULES([CLAMAV],[libclamav >= 4]) AC_DEFINE([HAVE_CLAMAV],[],[Define to enable ClamAV content scanner]) # check for shm_open (& shm_unlink) AC_CHECK_HEADERS([sys/mman.h]) AC_CHECK_FUNCS([shm_open]) if test "x$ac_cv_func_shm_open" = "xno"; then AC_CHECK_LIB(rt, shm_open, [ AC_MSG_RESULT(yes) AC_DEFINE([HAVE_CLAMAV_SHM],[],[Define to enable POSIX Shared Memory support in ClamAV content scanner]) LIBS="-lrt ${LIBS}" CLAMAVSHM="" ], [ AC_MSG_RESULT(no) CLAMAVSHM="!! Not supported on this platform !!" ]) fi clamav=true cslists=true csconfigs=true CLAMAVSUPPORT="" fi ], [ #disable by default clamav=false AC_MSG_RESULT(no) CLAMAVSUPPORT="!! Not compiled !! " CLAMAVSHM="!! Not supported on this platform !!" ] ) AM_CONDITIONAL(HAVE_CLAMAV, test "x$clamav" = "xtrue") AC_SUBST(CLAMAVSUPPORT) AC_SUBST(CLAMAVSHM) # asking user if they want clamd support AC_MSG_CHECKING(for clamd support) AC_ARG_ENABLE( clamd, [AC_HELP_STRING([--enable-clamd@<:@=no@:>@], [Enable support for the ClamD content scanner])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) clamd=false CLAMDSUPPORT="!! Not compiled !! " else AC_MSG_RESULT(yes) clamd=true cslists=true csconfigs=true CLAMDSUPPORT="" AC_DEFINE([ENABLE_CLAMD],[],[Define to enable ClamD content scanner]) fi], [ AC_MSG_RESULT(no) clamd=false CLAMDSUPPORT="!! Not compiled !! " ] ) AM_CONDITIONAL(ENABLE_CLAMD, test "x$clamd" = "xtrue") AC_SUBST(CLAMDSUPPORT) # asking user if they want icap support AC_MSG_CHECKING(for icap support) AC_ARG_ENABLE( icap, [AC_HELP_STRING([--enable-icap@<:@=no@:>@], [Enable support for ICAP AV server content scanner])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) icap=false ICAPSUPPORT="!! Not compiled !! " else AC_MSG_RESULT(yes) icap=true cslists=true csconfigs=true AC_DEFINE([ENABLE_ICAP],[],[Define to enable ICAP content scanner]) ICAPSUPPORT="" fi], [ AC_MSG_RESULT(no) icap=false ICAPSUPPORT="!! Not compiled !! " ] ) AM_CONDITIONAL(ENABLE_ICAP, test "x$icap" = "xtrue") AC_SUBST(ICAPSUPPORT) # asking user if they want kavd support AC_MSG_CHECKING(for kavd support) AC_ARG_ENABLE( kavd, [AC_HELP_STRING([--enable-kavd@<:@=no@:>@], [Enable support for the Kaspersky AV daemon content scanner])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) kavd=false KAVDSUPPORT="!! Not compiled !! " else AC_MSG_RESULT(yes) kavd=true cslists=true csconfigs=true KAVDSUPPORT="" AC_DEFINE([ENABLE_KAVD],[],[Define to enable KAVD content scanner]) fi], [ AC_MSG_RESULT(no) kavd=false KAVDSUPPORT="!! Not compiled !! " ] ) AM_CONDITIONAL(ENABLE_KAVD, test "x$kavd" = "xtrue") AC_SUBST(KAVDSUPPORT) dnl detecting kaspersky antivirus client #KAV_PATH_KAVCLIENT #AM_CONDITIONAL(HAVE_KAVCLIENT, test "x$kavclient_found" = "xyes") #kav stuff is not finished Wed 09th February 2005 - DB KAVAVSUPPORT="!! Unimplemented !! " AC_SUBST(KAVAVSUPPORT) # asking user if they want command-line content scanner support AC_MSG_CHECKING(for command-line content scanner support) AC_ARG_ENABLE( commandline, [AC_HELP_STRING([--enable-commandline@<:@=no@:>@], [Enable support for command-line content scanners])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) commandline=false COMMANDLINESUPPORT="!! Not compiled !! " else AC_MSG_RESULT(yes) commandline=true cslists=true csconfigs=true COMMANDLINESUPPORT="" AC_DEFINE([ENABLE_COMMANDLINE],[],[Define to enable command-line content scanner]) fi], [ AC_MSG_RESULT(no) commandline=false COMMANDLINESUPPORT="!! Not compiled !! " ]) AM_CONDITIONAL(ENABLE_COMMANDLINE, test "x$commandline" = "xtrue") AC_SUBST(COMMANDLINESUPPORT) # install CS configs and lists if necessary AM_CONDITIONAL(NEED_CSLISTS, test "x$cslists" = "xtrue") AM_CONDITIONAL(NEED_CSCONFIGS, test "x$csconfigs" = "xtrue") # asking user if they want fancy downloadmanager support AC_MSG_CHECKING(for fancy download manager support) AC_ARG_ENABLE( fancydm, [AC_HELP_STRING([--enable-fancydm@<:@=yes@:>@], [Enable support for the fancy download manager])], [ if test "x$enableval" = "xno"; then fancydm=false FANCYSUPPORT="#!! Not compiled !! " AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) fancydm=true dmlists=true FANCYSUPPORT="" AC_DEFINE([ENABLE_FANCYDM],[],[Define to enable fancy download manager]) fi], [ fancydm=true dmlists=true FANCYSUPPORT="" AC_MSG_RESULT(yes) AC_DEFINE([ENABLE_FANCYDM],[],[Define to enable fancy download manager]) ] ) AM_CONDITIONAL(ENABLE_FANCYDM, test "x$fancydm" = "xtrue") AC_SUBST(FANCYSUPPORT) # asking user if they want trickle downloadmanager support AC_MSG_CHECKING(for trickle download manager support) AC_ARG_ENABLE( trickledm, [AC_HELP_STRING([--enable-trickledm@<:@=no@:>@], [Enable support for the trickle download manager])], [ if test "x$enableval" = "xno"; then trickledm=false TRICKLESUPPORT="#!! Not compiled !! " AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) trickledm=true dmlists=true TRICKLESUPPORT="" AC_DEFINE([ENABLE_TRICKLEDM],[],[Define to enable trickle download manager]) fi], [ trickledm=false TRICKLESUPPORT="#!! Not compiled !! " AC_MSG_RESULT(no) ] ) AM_CONDITIONAL(ENABLE_TRICKLEDM, test "x$trickledm" = "xtrue") AC_SUBST(TRICKLESUPPORT) # install DM lists if necessary AM_CONDITIONAL(NEED_DMLISTS, test "x$dmlists" = "xtrue") # asking user if they want NTLM auth support AC_MSG_CHECKING(for NTLM support) AC_ARG_ENABLE( ntlm, [AC_HELP_STRING([--enable-ntlm@<:@=no@:>@], [Enable support for the NTLM auth plugin])], [ if test "x$enableval" = "xno"; then AC_MSG_RESULT(no) ntlm=false NTLMSUPPORT="!! Not compiled !! " else AC_MSG_RESULT(yes) ntlm=true NTLMSUPPORT="" AC_DEFINE([ENABLE_NTLM],[],[Define to enable NTLM auth plugin]) # now need to check if they're using an iconv library, rather # than a native iconv implementation AC_ARG_WITH(libiconv, [AC_HELP_STRING([--with-libiconv@<:@=NONE@:>@], [Specify search path on a system which requires an external iconv library (only used in conjunction with NTLM auth plugin).])], [ # check for header & func (in library) in given prefix if test "x$withval" != "x"; then CPPFLAGS="${CPPFLAGS} -I${withval}/include" LIBS="-L${withval}/lib -liconv ${LIBS}" else LIBS="-liconv ${LIBS}" fi AC_CHECK_LIB(iconv, iconv, [AC_MSG_RESULT(linked)], [ AC_MSG_RESULT(no) AC_CHECK_LIB(iconv, libiconv, [AC_MSG_RESULT(linked)], [ AC_MSG_ERROR([no libiconv found in given search path! (needed by NTLM plugin)]) ]) ]) ], [ # check for native header & func (no library) AC_CHECK_FUNCS(iconv, [AC_MSG_RESULT(native)], [ AC_MSG_RESULT(no) # native not found, so look for linked LIBS="-liconv ${LIBS}" AC_CHECK_LIB(iconv, iconv, [ AC_MSG_RESULT(linked) ], [ AC_MSG_RESULT(no) AC_CHECK_LIB(iconv, libiconv, [AC_MSG_RESULT(linked)], [ AC_MSG_ERROR([no native or standard library iconv function found! (needed by NTLM plugin - try again with "--with-libiconv"?)]) ]) ]) ]) ] ) fi], [ AC_MSG_RESULT(no) ntlm=false NTLMSUPPORT="!! Not compiled !! " ] ) AM_CONDITIONAL(ENABLE_NTLM, test "x$ntlm" = "xtrue") AC_SUBST(NTLMSUPPORT) # asking the user if they want email notifications AC_MSG_CHECKING(for email notification support) AC_ARG_ENABLE( email, [AC_HELP_STRING([--enable-email@<:@=no@:>@], [Enable support for email reporting functionality])], [ if test "x$enableval" = "xyes"; then email=true EMAILSUPPORT="" AC_MSG_RESULT(yes) AC_DEFINE([ENABLE_EMAIL],[],[Define to enable email reporting]) else email=false EMAILSUPPORT="#!! Not compiled !!" AC_MSG_RESULT(no) fi], [ email=false EMAILSUPPORT="#!! Not compiled !!" AC_MSG_RESULT(no) ]) AC_SUBST(EMAILSUPPORT) AC_DEFINE_UNQUOTED([DG_CONFIGURE_OPTIONS], ["$ac_configure_args"], [Record configure-time options]) libdir="${libdir}/${PACKAGE_NAME}" AC_ARG_WITH(sysconfsubdir, [AC_HELP_STRING([--with-sysconfsubdir@<:@=dansguardian@:>@], [subdirectory under sysconfdir in which to place config files])], [if test "x$withval" != "x"; then dgsysconfdir="${sysconfdir}/${withval}" else dgsysconfdir="${sysconfdir}" fi], [dgsysconfdir="${sysconfdir}/${PACKAGE_NAME}"]) AC_FINALIZE_VAR(DGLIBDIR,"${libdir}") AC_SUBST(DGLIBDIR) AC_FINALIZE_VAR(DGBINDIR,"${sbindir}") AC_SUBST(DGBINDIR) AC_FINALIZE_VAR(DGCONFDIR,"${dgsysconfdir}") AC_SUBST(DGCONFDIR) AC_FINALIZE_VAR(DGDATADIR,"${datadir}/${PACKAGE_NAME}") AC_SUBST(DGDATADIR) AC_FINALIZE_VAR(DGCONFFILE,"${dgsysconfdir}/${PACKAGE_NAME}.conf") AC_SUBST(DGCONFFILE) AC_CONFIG_FILES([Makefile data/Makefile data/languages/Makefile data/scripts/Makefile data/scripts/bsd-init data/scripts/dansguardian data/scripts/logrotation data/scripts/solaris-init data/scripts/systemv-init doc/Makefile configs/dansguardian.conf configs/dansguardianf1.conf configs/Makefile configs/lists/Makefile configs/lists/phraselists/Makefile configs/lists/blacklists/Makefile configs/lists/contentscanners/Makefile configs/lists/weightedphraselist configs/lists/exceptionphraselist configs/lists/bannedphraselist configs/lists/bannedurllist configs/lists/bannedsitelist configs/downloadmanagers/Makefile configs/downloadmanagers/default.conf configs/downloadmanagers/fancy.conf configs/downloadmanagers/trickle.conf configs/contentscanners/Makefile configs/contentscanners/clamav.conf configs/contentscanners/clamdscan.conf configs/contentscanners/icapscan.conf configs/contentscanners/kavav.conf configs/contentscanners/kavdscan.conf configs/contentscanners/commandlinescan.conf configs/authplugins/Makefile configs/authplugins/ip.conf configs/lists/authplugins/Makefile configs/lists/downloadmanagers/Makefile src/Makefile ]) AC_OUTPUT dansguardian-2.10.1.1/ChangeLog0000644001165000116500000000014111110523211013044 00000000000000For changes go to http://dansguardian.org/?page=history This file is required by the autotools. dansguardian-2.10.1.1/AUTHORS0000644001165000116500000000012111110523211012340 00000000000000For authors go to http://dansguardian.org/ This file required by the autotools. dansguardian-2.10.1.1/COPYING0000644001165000116500000004311011110523211012330 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. dansguardian-2.10.1.1/Makefile.in0000644001165000116500000004715611212164523013372 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/dgconfig.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ config.guess config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = dgconfig.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in SUBDIRS = doc . data configs src EXTRA_DIST = autogen.sh UPGRADING all: dgconfig.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) dgconfig.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/dgconfig.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status dgconfig.h $(srcdir)/dgconfig.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f dgconfig.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) dgconfig.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) dgconfig.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) dgconfig.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) dgconfig.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d $(distdir) || mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile dgconfig.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/Makefile.am0000644001165000116500000000014511110523211013332 00000000000000MAINTAINERCLEANFILES = Makefile.in SUBDIRS= doc . data configs src EXTRA_DIST = autogen.sh UPGRADING dansguardian-2.10.1.1/configs/0000777001165000116500000000000011212164550013024 500000000000000dansguardian-2.10.1.1/configs/contentscanners/0000777001165000116500000000000011212164550016233 500000000000000dansguardian-2.10.1.1/configs/contentscanners/commandlinescan.conf.in0000644001165000116500000000316711110523210022552 00000000000000plugname = 'commandlinescan' # Standard lists of file types & websites not to scan exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' # Program to run & initial arguments - filename for scanning will be appended #progname = /path/to/scanner # At least one of the following three options must be defined! # They are checked in the following order, with the first match determining # the scan result: # virusregexp - regular expression for extracting virus names from # the scanner's output # cleancodes - program return code(s), as a comma-separated list, for # uninfected files # infectedcodes - program return code(s), as a comma-separated list, for # infected files #virusregexp = (someregexp) # Which submatch of the above contains the virus name? (0 = all matched text) #submatch = 1 # cleancodes = 0 # infectedcodes = 1,2,3 # Default result when none of the other options triggers a match # Valid values are "infected" and "clean" #defaultresult = infected # # Example configuration for clamdscan # ## Path to binary #progname = '/usr/bin/clamdscan' ## Program returns 0 for clean files (for an easy out) #cleancodes = 0 ## Regular expression for virus names #virusregexp = : ([ -/a-zA-Z0-9\.]+) FOUND #submatch = 1 ## Default scan result when the above don't match #defaultresult = infected dansguardian-2.10.1.1/configs/contentscanners/Makefile.in0000644001165000116500000004105011212164522020213 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ @ENABLE_CLAMD_TRUE@am__append_1 = clamdscan.conf @HAVE_CLAMAV_TRUE@am__append_2 = clamav.conf @ENABLE_ICAP_TRUE@am__append_3 = icapscan.conf @ENABLE_KAVD_TRUE@am__append_4 = kavdscan.conf #if HAVE_KAVCLIENT #FLISTS += kavav.conf #endif @ENABLE_COMMANDLINE_TRUE@am__append_5 = commandlinescan.conf subdir = configs/contentscanners DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/clamav.conf.in $(srcdir)/clamdscan.conf.in \ $(srcdir)/commandlinescan.conf.in $(srcdir)/icapscan.conf.in \ $(srcdir)/kavav.conf.in $(srcdir)/kavdscan.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = clamav.conf clamdscan.conf icapscan.conf \ kavav.conf kavdscan.conf commandlinescan.conf SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = $(DGCONFDIR)/contentscanners DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in \ clamav.conf clamdscan.conf icapscan.conf \ kavav.conf kavdscan.conf commandlinescan.conf SUBDIRS = . FLISTS = $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) EXTRA_DIST = clamav.conf.in clamdscan.conf.in icapscan.conf.in \ kavav.conf.in kavdscan.conf.in commandlinescan.conf.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu configs/contentscanners/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu configs/contentscanners/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clamav.conf: $(top_builddir)/config.status $(srcdir)/clamav.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clamdscan.conf: $(top_builddir)/config.status $(srcdir)/clamdscan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ icapscan.conf: $(top_builddir)/config.status $(srcdir)/icapscan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ kavav.conf: $(top_builddir)/config.status $(srcdir)/kavav.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ kavdscan.conf: $(top_builddir)/config.status $(srcdir)/kavdscan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ commandlinescan.conf: $(top_builddir)/config.status $(srcdir)/commandlinescan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local install-data-local: $(mkinstalldirs) $(DESTDIR)$(DGDATADIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DGDATADIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DGDATADIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DGDATADIR)/$$l ; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/configs/contentscanners/Makefile.am0000644001165000116500000000165511110523210020177 00000000000000MAINTAINERCLEANFILES = Makefile.in \ clamav.conf clamdscan.conf icapscan.conf \ kavav.conf kavdscan.conf commandlinescan.conf DGDATADIR = $(DGCONFDIR)/contentscanners SUBDIRS = . FLISTS = if ENABLE_CLAMD FLISTS += clamdscan.conf endif if HAVE_CLAMAV FLISTS += clamav.conf endif if ENABLE_ICAP FLISTS += icapscan.conf endif if ENABLE_KAVD FLISTS += kavdscan.conf endif #if HAVE_KAVCLIENT #FLISTS += kavav.conf #endif if ENABLE_COMMANDLINE FLISTS += commandlinescan.conf endif EXTRA_DIST = clamav.conf.in clamdscan.conf.in icapscan.conf.in \ kavav.conf.in kavdscan.conf.in commandlinescan.conf.in install-data-local: $(mkinstalldirs) $(DESTDIR)$(DGDATADIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DGDATADIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DGDATADIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DGDATADIR)/$$l ; \ done dansguardian-2.10.1.1/configs/contentscanners/icapscan.conf.in0000644001165000116500000000075711110523210021202 00000000000000plugname = 'icapscan' # ICAP URL # Use hostname rather than IP address # Always specify the port # icapurl = 'icap://icapserver:1344/avscan' exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' dansguardian-2.10.1.1/configs/contentscanners/kavav.conf.in0000644001165000116500000000066511110523210020527 00000000000000plugname = 'kavav' # kaspersky unix domain socket file #kavdudsfile = '/tmp/kavav' exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' dansguardian-2.10.1.1/configs/contentscanners/clamdscan.conf.in0000644001165000116500000000166311110523210021343 00000000000000plugname = 'clamdscan' # edit this to match the location of your ClamD UNIX domain socket #clamdudsfile = '/var/run/clamav/clamd.sock' # If this string is set, the text it contains shall be removed from the # beginning of filenames when passing them to ClamD. # Use it to - for example - support a ClamD running inside a chroot jail: # if DG's filecachedir is set to "/var/clamdchroot/downloads/" and pathprefix # is set to "/var/clamdchroot", then file names given to ClamD will be of the # form "/downloads/tf*" instead of "/var/clamdchroot/downloads/tf*". #pathprefix = '/var/clamdchroot' exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' dansguardian-2.10.1.1/configs/contentscanners/clamav.conf.in0000644001165000116500000000335311110523210020657 00000000000000plugname = 'clamav' # scanbuffmethod # # As of 2.9.4.0, DG uses libclamav's cl_scandesc method instead of # cl_scanbuff when scanning memory buffers. Unfortunately, this means # that memory contents must be written to a file before scanning even # if the file is below maxcontentramcachescansize. # This option specifies how temp files will be created: # # file - create files in scanbuffdir # # @CLAMAVSHM@ shm - use POSIX shared memory # scanbuffmethod = 'file' # scanbuffdir - where to create temp files in scanbuffmethod 'file'. # You can specify a ramfs/tmpfs partition to minimise performance # impact. # Defaults to the configured filecachedir. #scanbuffdir = '/path/to/tmpfs' # tempdir - temporary directory for internal use by clamav. # When scanning archive files, clamav can create temporary files of # its own; this allows you to specify where they will be created. # Used regardless of scanbuffmethod. # Defaults to the configured filecachedir. #tempdir = '/path/to/tmpfs' #maxfiles - The maximum number of files to scan from a single # archive. Like clamd.conf's MaxFiles. maxfiles = 15000 #maxreclevel - The maximum recursion level when unpacking archives # within archives. Like clamd.conf's MaxRecursion. maxreclevel = 10 #maxscansize - Upper limit on the amount of data that whill be # scanned when unpacking an archive, in kilobytes. Like clamd.conf's # MaxScanSize. maxscansize = 100000 exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' dansguardian-2.10.1.1/configs/contentscanners/kavdscan.conf.in0000644001165000116500000000164111110523210021204 00000000000000plugname = 'kavdscan' # edit this to match the location of your KAVD UNIX domain socket #kavdudsfile = '/var/run/aveserver' # If this string is set, the text it contains shall be removed from the # beginning of filenames when passing them to KAVD. # Use it to - for example - support a KAVD running inside a chroot jail: # if DG's filecachedir is set to "/var/kavdchroot/downloads/" and pathprefix # is set to "/var/kavdchroot", then file names given to KAVD will be of the # form "/downloads/tf*" instead of "/var/kavdchroot/downloads/tf*". #pathprefix = '/var/kavdchroot' exceptionvirusmimetypelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusmimetypelist' exceptionvirusextensionlist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusextensionlist' exceptionvirussitelist = '@DGCONFDIR@/lists/contentscanners/exceptionvirussitelist' exceptionvirusurllist = '@DGCONFDIR@/lists/contentscanners/exceptionvirusurllist' dansguardian-2.10.1.1/configs/Makefile.in0000644001165000116500000003700411212164522015010 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ @NEED_CSCONFIGS_TRUE@am__append_1 = contentscanners subdir = configs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/dansguardian.conf.in \ $(srcdir)/dansguardianf1.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/dgconfig.h CONFIG_CLEAN_FILES = dansguardian.conf dansguardianf1.conf SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = lists downloadmanagers authplugins . contentscanners DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLAMAVSHM = @CLAMAVSHM@ CLAMAVSUPPORT = @CLAMAVSUPPORT@ CLAMAV_CFLAGS = @CLAMAV_CFLAGS@ CLAMAV_LIBS = @CLAMAV_LIBS@ CLAMDSUPPORT = @CLAMDSUPPORT@ COMMANDLINESUPPORT = @COMMANDLINESUPPORT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGBINDIR = @DGBINDIR@ DGCONFDIR = @DGCONFDIR@ DGCONFFILE = @DGCONFFILE@ DGDATADIR = @DGDATADIR@ DGLIBDIR = @DGLIBDIR@ DGLOGLOCATION = @DGLOGLOCATION@ DGPIDDIR = @DGPIDDIR@ DGPROXYGROUP = @DGPROXYGROUP@ DGPROXYUSER = @DGPROXYUSER@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EMAILSUPPORT = @EMAILSUPPORT@ EXEEXT = @EXEEXT@ FANCYSUPPORT = @FANCYSUPPORT@ GREP = @GREP@ ICAPSUPPORT = @ICAPSUPPORT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KAVAVSUPPORT = @KAVAVSUPPORT@ KAVDSUPPORT = @KAVDSUPPORT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NTLMSUPPORT = @NTLMSUPPORT@ OBJEXT = @OBJEXT@ ORIGIPSUPPORT = @ORIGIPSUPPORT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRICKLESUPPORT = @TRICKLESUPPORT@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in \ dansguardian.conf dansguardianf1.conf SUBDIRS = lists downloadmanagers authplugins . $(am__append_1) FLISTS = dansguardian.conf dansguardianf1.conf EXTRA_DIST = dansguardian.conf.in dansguardianf1.conf.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu configs/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu configs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh dansguardian.conf: $(top_builddir)/config.status $(srcdir)/dansguardian.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ dansguardianf1.conf: $(top_builddir)/config.status $(srcdir)/dansguardianf1.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local install-data-local: $(mkinstalldirs) $(DESTDIR)$(DGCONFDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DGCONFDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DGCONFDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DGCONFDIR)/$$l ; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dansguardian-2.10.1.1/configs/Makefile.am0000644001165000116500000000113711110523211014764 00000000000000MAINTAINERCLEANFILES = Makefile.in \ dansguardian.conf dansguardianf1.conf SUBDIRS = lists downloadmanagers authplugins . if NEED_CSCONFIGS SUBDIRS += contentscanners endif FLISTS = dansguardian.conf dansguardianf1.conf EXTRA_DIST = dansguardian.conf.in dansguardianf1.conf.in install-data-local: $(mkinstalldirs) $(DESTDIR)$(DGCONFDIR) && \ for l in $(FLISTS) ; do \ echo "$(INSTALL_DATA) $$l $(DESTDIR)$(DGCONFDIR)/$$l"; \ $(INSTALL_DATA) $$l $(DESTDIR)$(DGCONFDIR)/$$l; \ done uninstall-local: for l in $(FLISTS) ; do \ rm -f $(DESTDIR)$(DGCONFDIR)/$$l ; \ done dansguardian-2.10.1.1/configs/downloadmanagers/0000777001165000116500000000000011212164550016351 500000000000000dansguardian-2.10.1.1/configs/downloadmanagers/fancy.conf.in0000644001165000116500000000370711110523210020635 00000000000000# The 'fancy' download manager. # This outputs a Javascript progress bar to the browser when a file is taking # a long time to download, and hence is unsuitable for browsers without # javascript support; also you may wish to enable it only for types/extensions # that are usually downloaded individually, rather than embedded in a web page, # such as executables and archives. # Which plugin should be loaded? plugname = 'fancy' # Regular expression for matching user agents # When not defined, matches all agents. # # 'mozilla' also matches firefox, IE, etc. useragentregexp = 'mozilla' # Lists of mime types and extensions to manage # When not defined, matches everything. # These can be enabled separately; when both enabled, # a request may match either list. #managedmimetypelist = '@DGCONFDIR@/lists/downloadmanagers/managedmimetypelist' managedextensionlist = '@DGCONFDIR@/lists/downloadmanagers/managedextensionlist' # HTML/JavaScript Template # The contents of this file determine what is presented to the user during # and after downloading/scanning. It is essentially an HTML file, but must # define certain JavaScript functions - called at various stages during # the process - allowing the page to be modified to reflect current progress. # This option generates a path of the form //