<?php # ------------------------------------------------------------------------------ /* squidguard_configurator.inc (C)2006-2008 Serg Dvoriancev Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ # ------------------------------------------------------------------------------ # SquidGuard Configurator # email: dv_serg@mail.ru # ------------------------------------------------------------------------------ # squidGuard inline options: # squidGuard -C all - update database # squidGuard -c <configfile> - create squidGuard with specified config file # ------------------------------------------------------------------------------ # Notes: # for work squidGuard need present ALL destinations; # if dest not present in config - then this item will ignored in operations # (in rebuild DB for example) # ------------------------------------------------------------------------------ # Directories: # work path - $workdir # log path - $workdir + $logdir # ------------------------------------------------------------------------------ require_once('globals.inc'); require_once('config.inc'); require_once('util.inc'); require_once('pfsense-utils.inc'); require_once('pkg-utils.inc'); require_once('filter.inc'); require_once('service-utils.inc'); require_once('squid.inc'); /* Allow additional execution time 0 = no limit. */ ini_set('max_execution_time', '3600'); ini_set('max_input_time', '3600'); ini_set('memory_limit', '100M'); # ------------------------------------------------------------------------------ # files header # ------------------------------------------------------------------------------ define('FILES_DB_HEADER', ' # ------------------------------------------------------------------------------ # File created by squidGuard package GUI # (C)2006-2008 Serg Dvoriancev # ------------------------------------------------------------------------------ '); define('CONFIG_SG_HEADER', " # ============================================================ # SquidGuard configuration file # This file generated automaticly with SquidGuard configurator # (C)2006 Serg Dvoriancev # email: dv_serg@mail.ru # ============================================================ "); define('ACL_WARNING_ABSENSE_PASS', "!WARNING! Absence PASS 'all' or 'none' added as 'none'"); # ------------------------------------------------------------------------------ # squid config options # ------------------------------------------------------------------------------ define('REDIRECTOR_OPTIONS_REM', '# squidGuard options'); define('REDIRECTOR_PROGRAM_OPT', 'redirect_program'); define('REDIRECT_BYPASS_OPT', 'redirector_bypass'); define('REDIRECT_CHILDREN_OPT', 'redirect_children'); # ------------------------------------------------------------------------------ # setup count redirector processes will started # * for big count users service increase this option, but you need use this on powerful system # ------------------------------------------------------------------------------ define('REDIRECTOR_PROCESS_COUNT', '3'); # ------------------------------------------------------------------------------ # squidguard config options # ------------------------------------------------------------------------------ # define default redirection url (redirector get this url for all blocked url's) # * !ATTENTION! this url must be exists; IF url not exist, redirector will't block # (returned to squid some url, what blocked) # ------------------------------------------------------------------------------ define('REDIRECT_BASE_URL', '/sgerror.php'); define('REDIRECT_URL_ARGS', '&a=%a&n=%n&i=%i&s=%s&t=%t&u=%u'); # ------------------------------------------------------------------------------ # squidguard system defines # ------------------------------------------------------------------------------ define('SQUID_CONFIGFILE', '/usr/local/etc/squid/squid.conf'); define('TMP_DIR', '/var/tmp'); define('SQUIDGUARD_CONFIGFILE', '/squidGuard.conf'); define('SQUIDGUARDCONF_LOGFILE', '/sg_configurator.log'); define('SQUIDGUARD_ACCESSBLOCK_FILE', 'block.log'); define('SQUIDGUARD_CONFBASE_DEF', '/usr/local/etc/squid'); define('SQUIDGUARD_LOGDIR_DEF', '/tmp'); define('SQUIDGUARD_WORKDIR_DEF', '/usr/local/etc/squidGuard'); define('SQUIDGUARD_BINPATH_DEF', '/usr/local/bin'); define('SQUIDGUARD_TMP', '/var/tmp/squidGuard'); # SG temp define('SQUIDGUARD_VAR', '/var/squidGuard'); # SG variables define('SQUIDGUARD_STATE', '/squidGuard.state'); define('SQUIDGUARD_REBUILD', '/squidGuard.rebuild'); # DB home catalog contains 'Blacklist' and 'User' sub-catalogs define('SQUIDGUARD_DBHOME_DEF', '/var/db/squidGuard'); define('SQUIDGUARD_DB_BLACKLIST', '/bl'); define('SQUIDGUARD_DB_USER', '/usr'); define('SQUIDGUARD_BL_UNPACK', '/unpack'); define('SQUIDGUARD_BL_DB', '/db'); # DB/Blacklist defines define('SQUIDGUARD_BLK_ENTRIES', '/blacklist.files'); define('BLACKLIST_ARCHIVE', '/blacklists.tar'); define('BLK_LOCALFILE', '/root/sg_blacklists.tar'); define('DB_REBUILD_SH', '/tmp/squidGuard_db_rebuild.sh'); define('DB_REBUILD_CONF', '/tmp/squidGuard_db_rebuild.conf'); define('DB_REBUILD_BLK_CONF', '/squidGuard_blk_rebuild.conf'); define('BLK_TEMP', '/tmp/sg_blk'); define('SG_BLK_ARC', '/arcdb'); # blk db archive define('SG_INFO_FILE', '/var/squidGuard/sg_db_upd.inf'); # error_res define('SG_ERR0', "Error! Check squidGuard configuration data."); # redirect mode define('RMOD_NONE', 'rmod_none'); define('RMOD_INT_ERRORPAGE', 'rmod_int'); define('RMOD_INT_BLANKPAGE', 'rmod_int_bpg'); define('RMOD_INT_BLANKIMG', 'rmod_int_bim'); define('RMOD_INT_SIZELIMIT', 'rmod_int_szl'); define('RMOD_EXT_ERR', 'rmod_ext_err'); define('RMOD_EXT_RDR', 'rmod_ext_rdr'); define('RMOD_EXT_MOVED', 'rmod_ext_mov'); define('RMOD_EXT_FOUND', 'rmod_ext_fnd'); # GUI options define('SQUIDGUARD_LOG_MAXCOUNT', 500); # max log lines # 0-all, 1-medium; 2-low define('SQUIDGUARD_LOG_LEVEL', 0); # define('FLT_DEFAULT_ALL', 'all'); define('FLT_NOTALLOWIP', '!in-addr'); # owner user name (squid system user - need for define rights access) define('OWNER_NAME', 'proxy'); # Debug define('DEBUG_ON', 'true'); # ============================================================================== # black list # ============================================================================== # known black list standard names # ------------------------------------------------------------------------------ define('FLT_AD', 'ads'); define('FLT_AGGRESSIVE', 'aggressive'); define('FLT_AUDIOVIDEO', 'audio-video'); define('FLT_DRUGGS', 'druggs'); define('FLT_GAMBLING', 'gambling'); define('FLT_HACKING', 'hacking'); define('FLT_MAIL', 'mail'); define('FLT_PORN', 'porn'); define('FLT_PROXY', 'proxy'); define('FLT_VIOLENCE', 'viol'); define('FLT_WAREZ', 'warez'); # ============================================================================== # SquidGuard Configurator # ============================================================================== $squidguard_config = array(); # squidGuard config array # call default init sg_init(); # ------------------------------------------------------------------------------ # squidguard system fields # ------------------------------------------------------------------------------ define('F_SQUIDGUARD', 'squidGuard'); define('F_LOGDIR', 'logdir'); define('F_DBHOME', 'dbhome'); define('F_WORKDIR', 'workdir'); define('F_BINPATH', 'binpath'); define('F_PROCCESSCOUNT', 'process_count'); define('F_SQUIDCONFIGFILE', 'squid_configfile'); define('F_ENABLED', 'enabled'); define('F_BLACKLISTENABLED', 'blacklist_enabled'); define('F_SGCONF_XML', 'sgxml_file'); # other fields define('F_ITEM', 'item'); define('F_TIMES', 'times'); define('F_SOURCES', 'sources'); define('F_DESTINATIONS', 'destinations'); define('F_REWRITES', 'rewrites'); define('F_ACLS', 'acls'); define('F_DEFAULT', 'default'); define('F_NAME', 'name'); define('F_DESCRIPTION', 'description'); define('F_IP', 'ip'); define('F_URLS', 'urls'); define('F_DOMAINS', 'domains'); define('F_EXPRESSIONS', 'expressions'); define('F_REDIRECT', 'redirect'); define('F_TARGETURL', 'targeturl'); define('F_REPLACETO', 'replaceto'); define('F_LOG', 'log'); define('F_ITEM', 'item'); define('F_DISABLED', 'disabled'); define('F_TIMENAME', 'timename'); define('F_DESTINATIONNAME', 'destname'); define('F_REDIRECT', 'redirect'); define('F_REWRITE', 'rewrite'); define('F_MODE', 'mode'); define('F_REWRITENAME', 'rewritename'); define('F_OVERDESTINATIONNAME', 'overdestname'); define('F_OVERREDIRECT', 'overredirect'); define('F_OVERREWRITE', 'overrewrite'); define('F_OVERREWRITENAME', 'overrewritename'); define('F_TIMETYPE', 'timetype'); define('F_TIMEDAYS', 'timedays'); define('F_DATRANGE', 'daterange'); define('F_TIMERANGE', 'sg_timerange'); define('F_RMOD', 'redirect_mode'); # [redirect_mode] = rmod_int <base- use sgerror.php>; rmod_301; rmod_302; define('F_NOTALLOWINGIP', 'notallowingip'); # not allowing ip in URL define('F_USERNAME', 'username'); define('F_ORDER', 'order'); # transparent mode define('F_SQUID_TRANSPARENT_MODE', 'squid_transparent_mode'); define('F_CURRENT_LAN_IP', 'current_lan_ip'); define('F_CURRENT_GUI_PORT', 'current_gui_port'); define('F_CURRENT_GUI_PROTO', 'current_gui_protocol'); # ------------------------------------------------------------------------------ # sg_init - initialize config array # ------------------------------------------------------------------------------ function sg_init($init = '') { global $squidguard_config; $squidguard_config = array(); if(empty($init) or !is_array($init) ) { # default init (for generate minimal config) $squidguard_config[F_LOGDIR] = SQUIDGUARD_LOGDIR_DEF; $squidguard_config[F_DBHOME] = SQUIDGUARD_DBHOME_DEF; $squidguard_config[F_WORKDIR] = SQUIDGUARD_WORKDIR_DEF; $squidguard_config[F_BINPATH] = SQUIDGUARD_BINPATH_DEF; $squidguard_config[F_SQUIDCONFIGFILE] = SQUID_CONFIGFILE; $squidguard_config[F_PROCCESSCOUNT] = REDIRECTOR_PROCESS_COUNT; } else { $squidguard_config = $init; } return $squidguard_config; } # ------------------------------------------------------------------------------ # sg_loadconfig_xml # ------------------------------------------------------------------------------ function sg_load_configxml($filename) { global $squidguard_config; sg_init(); if (file_exists($filename)) { $xmlconf = file_get_contents($filename); if (!empty($xmlconf)) { $squidguard_config = $xmlconf[F_SQUIDGUARD]; sg_addlog("sg_load_configxml: Success update from '$filename'.", 1); } else sg_addlog("sg_load_configxml: Error, file '$filename' is empty.", 2); } else sg_addlog("sg_load_configxml: Error, file '$filename' does not exists.", 2); } # ------------------------------------------------------------------------------ # sg_saveconfig_xml # ------------------------------------------------------------------------------ function sg_save_configxml($filename) { global $squidguard_config; conf_mount_rw(); file_put_contents($filename, dump_xml_config($squidguard_config, F_SQUIDGUARD)); conf_mount_ro(); } # ------------------------------------------------------------------------------ # sg_reconfigure - squidguard reconfiguration # ------------------------------------------------------------------------------ function sg_reconfigure() { global $squidguard_config; $conf_file = SQUIDGUARD_LOGDIR_DEF . SQUIDGUARD_CONFIGFILE; # 1. check system sg_check_system(); # 2. reconfigure user db sg_reconfigure_user_db(); # 3. generate squidGuard config $conf = sg_create_config(); if ($conf) { conf_mount_rw(); if ($squidguard_config[F_WORKDIR]) $conf_file = $squidguard_config[F_WORKDIR] . SQUIDGUARD_CONFIGFILE; file_put_contents($conf_file, $conf); file_put_contents('/usr/local/etc/squid' . SQUIDGUARD_CONFIGFILE, $conf); # << squidGuard want config '/usr/local/etc/squid' by default set_file_access($squidguard_config[F_WORKDIR], OWNER_NAME, 0755); conf_mount_ro(); sg_addlog("sg_reconfigure: save squidGuard config to '$conf_file'.", 1); } else sg_addlog("sg_reconfigure: error make squidGuard config.", 2); # 4. reconfigure squid squid_reconfigure(); } # ------------------------------------------------------------------------------ # squid_reconfigure # Insert in '/usr/local/squid/etc/squid.conf' options: # redirector_bypass on # redirect_program /usr/local/squidGuard/bin/squidGuard -c /path_to_config_file # redirect_children 1 # ------------------------------------------------------------------------------ function squid_reconfigure($remove_only = '') { global $config; global $squidguard_config; $conf = ''; $cust_opt = $config['installedpackages']['squid']['config'][0]['custom_options']; # remove old options if (!empty($cust_opt)) { $conf = explode(";", $cust_opt); foreach ($conf as $key => $c_opt) { $t_opt = ltrim($c_opt); if ((strpos($t_opt, REDIRECTOR_PROGRAM_OPT) === 0) or (strpos($t_opt, REDIRECT_BYPASS_OPT) === 0) or (strpos($t_opt, REDIRECT_CHILDREN_OPT) === 0)) unset($conf[$key]); } sg_addlog("squid_reconfigure: Remove old redirector options from Squid config.", 1); } # add new options - if squidGuard enabled if (empty($remove_only) && ($squidguard_config[F_ENABLED] === 'on')) { $redirector_path = $squidguard_config[F_BINPATH] . '/squidGuard'; $redirector_conf = $squidguard_config[F_WORKDIR] . SQUIDGUARD_CONFIGFILE; $conf[] = REDIRECTOR_PROGRAM_OPT . " $redirector_path -c $redirector_conf"; $conf[] = REDIRECT_BYPASS_OPT . " on"; $conf[] = REDIRECT_CHILDREN_OPT . " " . REDIRECTOR_PROCESS_COUNT; sg_addlog("squid_reconfigure: Add new redirector options to Squid config.", 1); } # update config if (is_array($conf)) $conf = implode(";", $conf); $config['installedpackages']['squid']['config'][0]['custom_options'] = $conf; write_config('Update redirector options to squid config.'); squid_resync(); } # ------------------------------------------------------------------------------ # sg_check_system - check squidguard catalog's and access right's # ------------------------------------------------------------------------------ function sg_check_system() { global $squidguard_config; conf_mount_rw(); # check work_dir & create if not exists $work_dir = $squidguard_config[F_WORKDIR]; if (!empty($work_dir)) { # check dir's if (!file_exists($work_dir)) { mwexec("mkdir -p $work_dir"); set_file_access($work_dir, OWNER_NAME, 0755); sg_addlog("sg_check_system: Create work dir '$work_dir'.", 1); } } unset($work_dir); # check log_dir & create if not exists $log_dir = $squidguard_config[F_LOGDIR]; if (!empty($log_dir)) { if (!file_exists($log_dir)) { mwexec("mkdir -p $log_dir"); sg_addlog("sg_check_system: Create log dir '$log_dir'.", 1); } # set access right - need start any time; # (SG possible start from console and log file will have only root access) set_file_access($log_dir, OWNER_NAME, 0755); } unset($log_dir); # check db dir $db_dir = $squidguard_config[F_DBHOME]; if (!empty($db_dir)) { if (!file_exists($db_dir)) { mwexec("mkdir -p $db_dir"); sg_addlog("sg_check_system: Create db dir '$db_dir'.", 1); } # set access right set_file_access($db_dir, OWNER_NAME, 0755); } unset($db_dir); conf_mount_ro(); } # ============================================================================== # squidGuard DB # ============================================================================== # sg_reconfigure_user_db - reconfigure(update) db user entries # ------------------------------------------------------------------------------ function sg_reconfigure_user_db() { global $squidguard_config; conf_mount_rw(); $dbhome = $squidguard_config[F_DBHOME]; sg_addlog("sg_reconfigure_user_db: Begin with '$dbhome'", 1); # create user DB catalog, if not extsts if (!file_exists($dbhome)) { if (!mkdir($dbhome, 0755)) { sg_addlog("sg_reconfigure_user_db: Error create user DB directory '$dbhome'.", 2); return; } set_file_access($dbhome, OWNER_NAME, 0755); sg_addlog("sg_reconfigure_user_db: Create user DB directory '$dbhome'.", 1); } # update destinations to db $dests = $squidguard_config[F_DESTINATIONS]; if(!empty($dests)){ $dst_names = Array(); $dst_list = Array(); sg_addlog("sg_reconfigure_user_db: Add user entries", 1); foreach($dests[F_ITEM] as $dst) { $path = "$dbhome/" . $dst[F_NAME]; $dst_names[] = $path; $dst_list["usr_{$dst[F_NAME]}"] = $dst[F_NAME]; # 1. check destination catalog and create them, if need if (!file_exists($path)) { if (!mkdir ($path, 0755)) { sg_addlog("sg_reconfigure_user_db: Error create dir '$path'.", 2); return; } sg_addlog("sg_reconfigure_user_db: Create dir '$path'.", 1); } # 2. build domains file $domains = $dst[F_DOMAINS]; if (!empty($domains)) { $content = trim(str_replace(" ", "\n", $domains)); file_put_contents($path . '/domains', $content); sg_addlog("sg_reconfigure_user_db: -- add {$dst[F_NAME]} domains '$domains';", 1); } unset($domains); # 3. build urls file $urls = $dst[F_URLS]; if (!empty($urls)) { $content = trim(str_replace(" ", "\n", $urls)); file_put_contents($path . '/urls', $content); sg_addlog("sg_reconfigure_user_db: -- add {$dst[F_NAME]} urls '$content';", 1); } unset($urls); # 4. build expression file $expr = $dst[F_EXPRESSIONS]; if (!empty($expr)) { $content = trim(str_replace("|", " ", $expr)); # delete first and last unnecessary '|' symbol $content = str_replace(" ", "|", $content); file_put_contents($path . '/expressions', $content); sg_addlog("sg_reconfigure_user_db: -- add {$dst[F_NAME]} expressions '$content';", 1); } unset($expr); } # 5. recursive set files access set_file_access($dbhome, OWNER_NAME, 0755); # 6. rebuild user db ('/var/db/squidGuard') sg_rebuild_db("_usrdb", $dbhome, $dst_list); } else sg_addlog("sg_reconfigure_user_db: Nothing. User destinations list empty.", 2); # 7. remove unused db entries sg_remove_unused_db_entries(); conf_mount_ro(); } # ------------------------------------------------------------------------------ # sg_remove_unused_db_entries # ------------------------------------------------------------------------------ function sg_remove_unused_db_entries() { global $squidguard_config; conf_mount_rw(); $db_entries = array(); $file_list = ''; $dbhome = $squidguard_config[F_DBHOME]; $workdir = $squidguard_config[F_WORKDIR]; # black list entries # * worked only with 'blacklist entries list file - else may be deleted black list entry if (file_exists($workdir . SQUIDGUARD_BLK_ENTRIES)) { $file_for_del = array(); # load blk entries $db_entries = explode("\n", file_get_contents($workdir . SQUIDGUARD_BLK_ENTRIES)); # $db_entries + add user entries $dests = $squidguard_config[F_DESTINATIONS]; if (!empty($dests)) { foreach($dests[F_ITEM] as $dst) $db_entries[] = $dst[F_NAME]; } # diff between file list and entries list $file_list = scan_dir($dbhome); if (is_array($file_list) and is_array($db_entries)) { $file_for_del = array_diff($file_list, $db_entries); } # delete if (is_array($file_for_del) and !empty($file_for_del)) { foreach($file_for_del as $fd) { $file_fd = "$dbhome/$fd"; if (!empty($fd) && ($fd != ".") && ($fd != "..")) { if (file_exists($file_fd)) { mwexec("rm -R $file_fd"); sg_addlog("sg_remove_unused_db_entries: Removed file '$file_fd'.", 1); } else sg_addlog("sg_remove_unused_db_entries: File'$file_fd' not found.", 2); } } } } conf_mount_ro(); } # ------------------------------------------------------------------------------ # sg_rebuild_db Rebuild squidGuard DB from list items # ------------------------------------------------------------------------------ # $shtag - rebuild SH script TAG # $rdb_dbhome - DB directory (default: '/var/db/squidGuard') # $rdb_itemslist - items list as ['dest_key']='dest_DB_path' # dest_DB_path - path without '$rdb_dbhome' # example: ['ads_ban']='ads/banners' -> '/var/db/squidGuard/ads/banners' # ------------------------------------------------------------------------------ function sg_rebuild_db($shtag, $rdb_dbhome, $rdb_itemslist) { global $squidguard_config; conf_mount_rw(); $conf = ''; $conf_path = ''; $logdir = $squidguard_config[F_LOGDIR]; $dbhome = $squidguard_config[F_DBHOME]; # current dbhome dir if (!empty($rdb_dbhome)) $dbhome = $rdb_dbhome; sg_addlog("sg_rebuild_db: Begin with path '$dbhome'.", 1); # define - where config will placed $conf_path = "/tmp/squidGuard_rebuild.conf" . $shtag; # make rebuild config; include all found dest items $conf = sg_create_simple_config($dbhome, $rdb_itemslist); file_put_contents($conf_path, $conf); set_file_access($conf_path, OWNER_NAME, 0750); sg_addlog("sg_rebuild_db: Create temporary config '$conf_path'.", 1); # *** SH script *** $sh_scr = Array(); $sh_scr[] = "#!/bin/sh"; $sh_scr[] = "cd $dbhome"; $sh_scr[] = $squidguard_config[F_BINPATH] . "/squidGuard -c $conf_path -C all"; $sh_scr[] = "wait"; # wait while SG rebuild DB # set DB owner and right access $sh_scr[] = "chown -R -v " . OWNER_NAME . " $dbhome"; # restart squid for changes to take effects $sh_scr[] = "/usr/local/sbin/squid -k reconfigure"; # store & exec sh $sh_scr = implode("\n", $sh_scr); $shfile = DB_REBUILD_SH . $shtag; file_put_contents($shfile, $sh_scr); set_file_access($shfile, OWNER_NAME, 0750); # ! not background exec ! mwexec($shfile); sg_addlog("sg_rebuild_db: Started SH script '$shfile'.", 1); conf_mount_ro(); } # ============================================================================== # Log # ------------------------------------------------------------------------------ # sg_addlog # ------------------------------------------------------------------------------ function sg_addlog($log, $level = 0) { global $squidguard_config; # log level if ($level < SQUIDGUARD_LOG_LEVEL) return; $logfile = ''; $logfile = SQUIDGUARD_LOGDIR_DEF . SQUIDGUARDCONF_LOGFILE; $log_content = array(); setlocale(LC_TIME, ''); $dt = date("d.m.Y H:i:s"); # define logfile if (!empty($squidguard_config)) { if (file_exists($squidguard_config[F_LOGDIR])) $logfile = $squidguard_config[F_LOGDIR] . SQUIDGUARDCONF_LOGFILE; } else $log_content[] = "$dt : " . "sg_addlog: Error: squidguard_config is empty"; $tmplog = ''; if (file_exists($logfile)) $tmplog = file_get_contents($logfile); $log_content = explode("\n", $tmplog); unset($tmplog); # shrink to MAXCOUNT log entries $log_content[] = "$dt : $log"; if (count($log_content) > SQUIDGUARD_LOG_MAXCOUNT) array_splice($log_content, 0, SQUIDGUARD_LOG_MAXCOUNT - count($log_content)); file_put_contents($logfile, implode("\n", $log_content)); } # ------------------------------------------------------------------------------ # sg_getlog # ------------------------------------------------------------------------------ function sg_getlog($last_entries_count) { global $squidguard_config; $log_content = ''; $logfile = SQUIDGUARD_LOGDIR_DEF . SQUIDGUARDCONF_LOGFILE; # define logfile if (!empty($squidguard_config) && file_exists($squidguard_config[F_LOGDIR])) $logfile = $squidguard_config[F_LOGDIR] . SQUIDGUARDCONF_LOGFILE; # get log last 100 entries if (file_exists($logfile)) { $log_content = explode("\n", file_get_contents($logfile)); if (count($log_content) > $last_entries_count) array_splice($log_content, 0, $last_entries_count - count($log_content)); # insert log file name on top $log_content[0] = $logfile; $log_content = implode("\n", $log_content); } return $log_content; } # ============================================================================== # make config # ============================================================================== # sg_create_config # ------------------------------------------------------------------------------ function sg_create_config() { global $squidguard_config; $sgconf = array(); $sg_tag = new TSgTag; $error_res = ''; $temp_str = ''; if(!is_array($squidguard_config) || empty($squidguard_config)) { sg_addlog("sg_create_config: Error squidguard config data.", 2); return sg_create_simple_config('', '', SG_ERR0 . " (sg_create_config: [1])."); } # check configuration data if (!sg_check_config_data(&$error_res)) { sg_addlog("sg_create_config: Error config data. It's all error_res: \n$error_res", 2); sg_addlog("sg_create_config: Terminated.", 2); return sg_create_simple_config('', '', SG_ERR0 . " (sg_create_config: [2])."); } # --- Header --- $sgconf[] = CONFIG_SG_HEADER; $sgconf[] = "logdir {$squidguard_config[F_LOGDIR]}"; $sgconf[] = "dbhome {$squidguard_config[F_DBHOME]}"; # --- Times --- if ($squidguard_config[F_TIMES]) { $temp_str = ''; foreach($squidguard_config[F_TIMES][F_ITEM] as $tm) { $sg_tag->clear(); $sg_tag->set("time", $tm[F_NAME], "", $tm[F_DESCRIPTION]); foreach($tm[F_ITEM] as $itm) { $dts = ($itm[F_TIMETYPE] === "weekly") ? $itm[F_TIMEDAYS] : $itm[F_DATERANGE]; $sg_tag->items[] = "{$itm[F_TIMETYPE]} $dts {$itm[F_TIMERANGE]}"; } $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # log $temp_str .= " {$tm[F_NAME]}"; } # log $temp_str = !empty($temp_str) ? $temp_str : "Nothing."; sg_addlog("sg_create_config: add times: \n $temp_str", 1); } # --- Sources --- if ($squidguard_config[F_SOURCES]) { $temp_str = ''; foreach($squidguard_config[F_SOURCES][F_ITEM] as $src) { $sg_tag->clear(); $sg_tag->set("src", $src[F_NAME], "", $src[F_DESCRIPTION]); # separate IP, domains, usernames $tsrc = explode(" ", trim($src[F_SOURCE])); foreach($tsrc as $sr) { $sr = trim($sr); if (empty($sr)) continue; if (is_ipaddr_valid($sr)) $sg_tag->items[] = "ip $sr"; elseif (is_domain_valid($sr)) $sg_tag->items[] = "domain $sr"; elseif (is_username($sr)) $sg_tag->items[] = "user " . str_replace("'", "", $sr); } if ($src[F_LOG]) $sg_tag->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # log $temp_str .= " " . $src[F_NAME]; } # log $temp_str = !empty($temp_str) ? $temp_str : "Nothing."; sg_addlog("sg_create_config: add sources: \n $temp_str", 1); } # --- Blacklist --- # Note! Blacklist must be added to config permanently. It's need for rebuild DB now $db_entries = sg_entries_blacklist(); if (($squidguard_config[F_BLACKLISTENABLED] === 'on') and $db_entries) { $log_entr_added = ''; $log_entr_ignored = ''; sg_addlog("sg_create_config: add blacklist entries", 1); foreach($db_entries as $key => $ent) { $ent_state = array(); $file_dms = "{$squidguard_config[F_DBHOME]}/$ent/domains"; $file_urls = "{$squidguard_config[F_DBHOME]}/$ent/urls"; $file_expr = "{$squidguard_config[F_DBHOME]}/$ent/expressions"; # check blacklist acl state if (file_exists($file_dms)) { $ent_state['exists'] = 'on'; $ent_state[F_DOMAINS] = 'on'; } if (file_exists($file_urls)) { $ent_state['exists'] = 'on'; $ent_state[F_URLS] = 'on'; } if (file_exists($file_expr)) { $ent_state['exists'] = 'on'; $ent_state[F_EXPRESSIONS] = 'on'; } # create config if blacklist item exists if ($ent_state['exists']) { $sg_tag->clear(); $sg_tag->set("dest", $ent, "", ""); if ($ent_state[F_DOMAINS]) $sg_tag->items[] = "domainlist $ent/domains"; if ($ent_state[F_EXPRESSIONS]) $sg_tag->items[] = "expressionlist $ent/expressions"; if ($ent_state[F_URLS]) $sg_tag->items[] = "urllist $ent/urls"; $sg_tag->items[] = "log ". SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # log $log_entr_added .= " $ent;"; } else { $sgconf[] = "\t# Config ERROR: Destination '$ent' not found in DB"; $log_entr_ignored .= " $ent;"; } } # log 'added' and 'ignored' if (!empty($log_entr_added)) sg_addlog("sg_create_config: added: \n $log_entr_added \n", 1); if (!empty($log_entr_ignored)) sg_addlog("sg_create_config: ignored: \n $log_entr_ignored \n", 2); } # --- Destinations --- if ($squidguard_config[F_DESTINATIONS]) { $temp_str = ''; foreach($squidguard_config[F_DESTINATIONS][F_ITEM] as $dst) { $dstname = $dst[F_NAME]; $sg_tag->clear(); $sg_tag->set("dest", $dst[F_NAME], "", $dst[F_DESCRIPTION]); if ($dst[F_DOMAINS]) $sg_tag->items[] = "domainlist $dstname/domains"; if ($dst[F_EXPRESSIONS]) $sg_tag->items[] = "expressionlist $dstname/expressions"; if ($dst[F_URLS]) $sg_tag->items[] = "urllist $dstname/urls"; if ($dst[F_RMOD] != RMOD_NONE) $sg_tag->items[] = "redirect " . sg_redirector_base_url($dst[F_REDIRECT], $dst[F_RMOD]); if ($dst[F_LOG]) $sg_tag->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # log $temp_str .= " $dstname;"; } # log $temp_str = !empty($temp_str) ? $temp_str : "Nothing."; sg_addlog("sg_create_config: add destinations: \n $temp_str", 1); } # --- Rewrites --- if ($squidguard_config[F_REWRITES]) { $temp_str = ''; $log_entr_added = ''; $log_entr_err = ''; foreach($squidguard_config[F_REWRITES][F_ITEM] as $rew) { $sg_tag->clear(); $sg_tag->set("rew", $rew[F_NAME], "", ""); if (is_array($rew[F_ITEM])) { foreach ($rew[F_ITEM] as $rw) $sg_tag->items[] = "s@{$rw[F_TARGETURL]}@{$rw[F_REPLACETO]}@{$rw[F_MODE]}"; if ($rew[F_LOG]) $sg_tag->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # log $log_entr_added .= " {$rew[F_NAME]};"; } else { $sgconf[] = ""; $sgconf[] = "# Rewrite {$rew[F_NAME]} error."; # log $log_entr_err .= " {$rew[F_NAME]};"; } } # log if (!empty($log_entr_added)) sg_addlog("sg_create_config: add rewrites: success $log_entr_added", 1); if (!empty($log_entr_err)) sg_addlog("sg_create_config: add rewrites: error $log_entr_err", 1); } # ---------------------------------------- $entry_blacklist = sg_entries_blacklist(); # --- ACL --- $sg_tag->clear(); $sg_tag->set("acl", "", "", ""); if ($squidguard_config[F_ACLS]) { $temp_str = ''; $log_entr_added = ''; foreach($squidguard_config[F_ACLS][F_ITEM] as $acl) { if (!$acl[F_DISABLED]) { $sg_acltag = new TSgTag; $sg_acltag->set($acl[F_NAME], "", $acl[F_TIMENAME], $acl[F_DESCRIPTION]); # delete blacklist entries from 'pass' if blacklist disabled if ($squidguard_config[F_BLACKLISTENABLED] !== 'on') { acl_remove_blacklist_items(&$acl[F_DESTINATIONNAME]); acl_remove_blacklist_items(&$acl[F_OVERDESTINATIONNAME]); } # not allowing IP in URL if ($acl[F_NOTALLOWINGIP]) { $acl[F_DESTINATIONNAME] = "!in-addr {$acl[F_DESTINATIONNAME]}"; $acl[F_OVERDESTINATIONNAME] = "!in-addr {$acl[F_OVERDESTINATIONNAME]}"; } # re-order acl pass (<allow><deny<all|none>) $acl[F_DESTINATIONNAME] = sg_aclpass_reorder($acl[F_DESTINATIONNAME]); $acl[F_OVERDESTINATIONNAME] = sg_aclpass_reorder($acl[F_OVERDESTINATIONNAME]); # ontime $sg_acltag->items[] = "pass {$acl[F_DESTINATIONNAME]}"; if ($acl[F_RMOD] != RMOD_NONE) $sg_acltag->items[] = "redirect " . sg_redirector_base_url($acl[F_REDIRECT], $acl[F_RMOD]); if ($acl[F_REWRITENAME]) $sg_acltag->items[] = "rewrite {$acl[F_REWRITENAME]}"; if ($acl[F_LOG]) $sg_acltag->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; # overtime if ($acl[F_TIMENAME]) { $sg_acltag->items[] = "} else {"; $sg_acltag->items[] = "pass {$acl[F_OVERDESTINATIONNAME]}"; if ($acl[F_REDIRECMODE] !== RMOD_NONE) $sg_acltag->items[] = "redirect " . sg_redirector_base_url($acl[F_OVERREDIRECT], $acl[F_RMOD]); if ($acl[F_OVERREWRITENAME]) $sg_acltag->items[] = "rewrite {$acl[F_OVERREWRITENAME]}"; if ($acl[F_LOG]) $sg_acltag->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; } $sg_tag->items[] = $sg_acltag; } $log_entr_added .= " {$acl[F_NAME]};"; } # log $log_entr_added = !empty($log_entr_added) ? $log_entr_added : "Nothing."; sg_addlog("sg_create_config: add ACL's: \n $log_entr_added", 1); } # --- Default --- $sg_tag_def = new TSgTag; $sg_tag_def->set("default", "", "", ""); $def = $squidguard_config[F_DEFAULT]; sg_addlog("sg_create_config: add Default", 1); if ($def) { $temp_str = ''; # delete blacklist entries from 'pass' if blacklist disabled if ($squidguard_config[F_BLACKLISTENABLED] !== 'on') acl_remove_blacklist_items(&$def[F_DESTINATIONNAME]); # not allowing IP in URL if ($def[F_NOTALLOWINGIP]) $def[F_DESTINATIONNAME] = "!in-addr " . $def[F_DESTINATIONNAME]; # re-order acl pass (<allow><deny<all|none>) $def[F_DESTINATIONNAME] = sg_aclpass_reorder($def[F_DESTINATIONNAME]); # ! 'Default' must use without times ! $sg_tag_def->items[] = "pass {$def[F_DESTINATIONNAME]}"; if ($def[F_RMOD] !== RMOD_NONE) $sg_tag_def->items[] = "redirect " . sg_redirector_base_url($def[F_REDIRECT], $def[F_RMOD]); if ($def[F_REWRITENAME]) $sg_tag_def->items[] = "rewrite {$def[F_REWRITENAME]}"; if ($def[F_LOG]) $sg_tag_def->items[] = "log " . SQUIDGUARD_ACCESSBLOCK_FILE; } # <- if def else { $msg = "Error: ACL 'default' is empty, will use default 'block all'"; $sg_tag_def->items[] = "# $msg"; $sg_tag_def->items[] = "pass none"; $sg_tag_def->items[] = "redirect " . sg_redirector_base_url('', RMOD_INT_ERRORPAGE); sg_addlog("sg_create_config: $msg.", 2); } # --- ACL end --- $sg_tag->items[] = $sg_tag_def; # add 'default' ACL object $sgconf[] = ""; $sgconf[] = $sg_tag->tag_text(); # delete "\n" chars before each string - SG bug (first string of config must be not empty) foreach ($sgconf as $key => $val) $sgconf[$key] = ltrim($sgconf[$key], "\n"); return implode("\n", $sgconf); } # ------------------------------------------------------------------------------ # sg_create_simple_config # Create config for DB rebuilding # Default rule - block all # Variables: # $blk_dbhome - temporary DB home dir, may be different with DBHOME # $blk_destlist - is array as [dst_name] = 'path', # where path - catalog without dbhome path # For example: dbhome is '/var/db/squidGuard/', # path can be 'usr/ads' or 'bl/poxy' # $redirect_to - redirector string # ------------------------------------------------------------------------------ function sg_create_simple_config($blk_dbhome, $blk_destlist, $redirect_to = "404") { global $squidguard_config; $sgconf = array(); $logdir = $squidguard_config[F_LOGDIR]; $dbhome = $squidguard_config[F_DBHOME]; # current dbhome dir if (!empty($blk_dbhome)) $dbhome = $blk_dbhome; sg_addlog("sg_create_simple_config: Begin with dbhome='$dbhome'.", 1); # header $sgconf[] = CONFIG_SG_HEADER; # init section $sgconf[] = "logdir $logdir"; $sgconf[] = "dbhome $dbhome"; $sgconf[] = ""; # destination section if (is_array($blk_destlist)) { foreach($blk_destlist as $dst => $dpath) { $tmp_s = array(); # check item elements if (file_exists("$dbhome/$dpath/domains")) $tmp_s[] = "\t domainlist $dpath/domains"; if (file_exists("$dbhome/$dpath/urls")) $tmp_s[] = "\t urllist $dpath/urls"; if (file_exists("$dbhome/$dpath/expressions")) $tmp_s[] = "\t expressionlist $dpath/expressions"; # create only valid items if (!empty($tmp_s)) { $tmp_s = implode("\n", $tmp_s); $sgconf[] = "dest $dst {\n $tmp_s \n}\n"; sg_addlog("sg_create_simple_config: -- added item '$dst' = '$dbhome/$dpath'."); } else sg_addlog("sg_create_simple_config: -- ignored empty item '$dst' = '$dbhome/$dpath'."); } } # acl section $sgconf[] = "acl {\n\t default {\n\t\t pass all "; $sgconf[] = "\t\t redirect " . sg_redirector_base_url($redirect_to, RMOD_INT_ERRORPAGE); # use sgerror only! $sgconf[] = "\t } \n}"; # delete "\n" chars before each string - SG bug (first string of config must be not empty) foreach ($sgconf as $key => $val) $sgconf[$key] = ltrim($sgconf[$key], "\n"); return implode("\n", $sgconf); } # ------------------------------------------------------------------------------------------------- # sg_redirector_base_url # $url - url where redirect to # $use_internal - ignore 'Redirect mode' option, use internal (for rebuild config, for example) # # ------------------------------------------------------------------------------------------------- function sg_redirector_base_url($rdr_info, $redirect_mode) { global $squidguard_config; $rdr_path = ''; # gui port, ip & proto $guiip = (!empty($squidguard_config[F_CURRENT_LAN_IP])) ? $squidguard_config[F_CURRENT_LAN_IP] : '127.0.0.1'; $guiport = (!empty($squidguard_config[F_CURRENT_GUI_PORT])) ? $squidguard_config[F_CURRENT_GUI_PORT] : '80'; $guiproto = ($squidguard_config[F_CURRENT_GUI_PROTO] === "https") ? "https" : "http"; $rdr_path = "$guiproto://$guiip:$guiport" . REDIRECT_BASE_URL; # check redirect $errmsg = ''; if (!sg_check_redirect($redirect_mode, $rdr_info, &$errmsg)) { $redirect_mode = RMOD_INT_ERRORPAGE; $rdr_info = "Redirect settings error. $errmsg Check you configuration."; sg_addlog("sg_redirector_base_url: ERROR: $errmsg"); } switch($redirect_mode) { case RMOD_EXT_ERR: $rdr_path = "$rdr_info" . REDIRECT_URL_ARGS; break; case RMOD_EXT_RDR: $rdr_path = "$rdr_info"; break; case RMOD_EXT_MOVED: $rdr_path = "301:$rdr_info"; break; case RMOD_EXT_FOUND: $rdr_path = "302:$rdr_info"; break; case RMOD_INT_BLANKPAGE: $rdr_path .= "?url=blank&msg=" . rawurlencode($rdr_info) . REDIRECT_URL_ARGS; break; case RMOD_INT_BLANKIMG: $rdr_path .= "?url=blank_img&msg=" . rawurlencode($rdr_info) . REDIRECT_URL_ARGS; break; case RMOD_INT_SIZELIMIT: $rdr_path .= "?url=maxlen_$rdr_info" . REDIRECT_URL_ARGS; break; case RMOD_INT_ERRORPAGE: default: $rdr_path .= "?url=" . rawurlencode("403 $rdr_info") . REDIRECT_URL_ARGS; break; } sg_addlog("sg_redirector_base_url: Select redirector base url ($rdr_path)"); return $rdr_path; } # ------------------------------------------------------------------------------------------------- # sg_aclpass_reorder # ------------------------------------------------------------------------------------------------- function sg_aclpass_reorder($pass) { $ar_pass = explode(" ", $pass); # 'pass' order: <allow> <deny> <all|none> if (is_array($ar_pass)) { $pass_end = ''; $pass_fst = array(); # whitelist - '^' prefix (will deleted) $pass_sec = array(); # blacklist - '!' prefix $pass_lst = array(); # allow foreach ($ar_pass as $val) { $tk = trim($val); if ($tk === 'all' or $tk === 'none') $pass_end = $val; elseif (strpos($tk, "^") !== false) # delete '^' prefix $pass_fst[] = str_replace('^', '', $val); elseif (strpos($tk, "!") !== false) $pass_sec[] = $val; else $pass_lst[] = $val; } $ar_pass = array_merge($pass_fst, $pass_sec, $pass_lst); $ar_pass[] = $pass_end; } return implode(" ", $ar_pass); } # ------------------------------------------------------------ # sg_check_config_data # ------------------------------------------------------------ function sg_check_config_data ($input_errors) { global $squidguard_config; $elog = array(); $times = sg_list_itemsfield($squidguard_config[F_TIMES], F_NAME); $sources = sg_list_itemsfield($squidguard_config[F_SOURCES], F_NAME); $destinations = sg_list_itemsfield($squidguard_config[F_DESTINATIONS], F_NAME); $rewrites = sg_list_itemsfield($squidguard_config[F_REWRITES], F_NAME); $acls = array(); # --- Times --- if ($squidguard_config[F_TIMES]) { $key_tm = array_count_values($times); foreach($squidguard_config[F_TIMES][F_ITEM] as $tm) { # check name as unique and name format $tm_name = $tm[F_NAME]; $err_s = ''; if (!check_name_format($tm_name, &$err_s)) $elog[] = "(T1) TIME '$tm_name' error: >>> $err_s"; if ($key_tm[$tm_name] > 1) $elog[] = "(T2) TIME '$tm_name' error: duplicate time name '$tm_name'"; # check time items format sg_check_time($tm, &$elog); } } # --- Sources --- if ($squidguard_config[F_SOURCES]) { $key_src = array_count_values($sources); foreach($squidguard_config[F_SOURCES][F_ITEM] as $src) { # check name as unique and name format $src_name = $src[F_NAME]; $err_s = ''; if (!check_name_format($src_name, &$err_s)) $elog[] = "(A1) ACL '$src_name'error: $err_s"; if ($key_src[$src_name] > 1) $elog[] = "(A2) ACL '$src_name' error: duplicate source name '$src_name'"; sg_check_src($src, $elog); } } # --- Destinations --- if ($squidguard_config[F_DESTINATIONS]) { $key_dst = array_count_values($destinations); foreach($squidguard_config[F_DESTINATIONS][F_ITEM] as $dst) { # check name as unique and name format $dst_name = $dst[F_NAME]; $err_s = ''; if (!check_name_format($dst_name, &$err_s)) $elog[] = "(D1) DEST '$dst_name' error: $err_s"; if ($key_dst[$dst_name] > 1) $elog[] = "(D2) DEST '$dst_name' error: duplicate destination name '$dst_name'"; # sg_check_dest($dst, &$elog); } } # --- Blacklist --- if ($squidguard_config[F_BLACKLISTENABLED]) { $blk_entries_file = $squidguard_config[F_WORKDIR] . SQUIDGUARD_BLK_ENTRIES; if (file_exists($blk_entries_file)) { $blk_entr = explode("\n", file_get_contents($blk_entries_file)); foreach($blk_entr as $entr) { if ($entr) { $destinations[] = $entr; # check entry for exists $dbfile = $squidguard_config[F_DBHOME] . "/$entr"; if (!file_exists($dbfile)) $elog[] = "(B1) BLACKLIST '$entr' error: file '$dbfile' not found"; } } } } # --- Rewrites --- if ($squidguard_config[F_REWRITES]) { $key_rw = array_count_values($rewrites); foreach($squidguard_config[F_REWRITES][F_ITEM] as $rw) { # check check name as unique and name format $rw_name = $rw[F_NAME]; $err_s = ''; if (!check_name_format($rw_name, &$err_s)) $elog[] = "(R1) REWRITE '$rw_name' error: $err_s"; if ($key_rw[$rw_name] > 1) $elog[] = "(R2) REWRITE '$rw_name' error: duplicate rewrite name '$rw_name'"; } } $key_times = array_count_values($times); $key_sources = array_count_values($sources); $key_destinations = array_count_values($destinations); $key_rewrites = array_count_values($rewrites); # --- ACLs --- if ($squidguard_config[F_ACLS]) { $acls = array(); foreach($squidguard_config[F_ACLS][F_ITEM] as $acl) { # skip disabled acl if ($acls[F_DISABLED]) continue; $acl_name = $acl[F_NAME]; # check acl name for unique and exists (as source items) if ($acl_name and !$key_sources[$acl_name]) $elog[] = "(A1) ACL '$acl_name' error: acl name '$acl_name' not found"; $acls[] = $acl_name; $key_acls = array_count_values($acls); if ($key_acls[$acl_name] > 1) $elog[] = "(A2) ACL '$acl_name' error: duplicate acl name '$acl_name'"; # check time $time = $acl[F_TIMENAME]; if ($time and !$key_times[$time]) # time name must exists $elog[] = "(A3) ACL '$acl_name' error: time name '$time' not found"; # check destinations if ($acl[F_DESTINATIONNAME]) { $acldest = $acl[F_DESTINATIONNAME]; $acldest = str_replace("!", "", $acldest); $acldest = str_replace("^", "", $acldest); $acldest = explode(" ", $acldest); $key_acldest = array_count_values($acldest); foreach($acldest as $adest) { # check duplicates destinations in acl if ($key_acldest[$adest] > 1) $elog[] = "(A4) ACL '$acl_name' error: duplicate destination name '$adest'. Any destination must included once."; # check destinations for exists if ($adest and ($adest != 'all') and ($adest != 'none') and !$key_destinations[$adest]) $elog[] = "(A5) ACL '$acl_name' error: destination name '$adest' not found"; } } else { $elog[] = "(A6) ACL '$acl_name' error: ontime pass list is empty. Added 'none'."; $acl[F_DESTINATIONNAME] = "none"; } # check overtime destinations if ($time) { if ($acl[F_OVERDESTINATIONNAME]) { $acloverdest = $acl[F_OVERDESTINATIONNAME]; $acloverdest = str_replace("!", "", $acloverdest); $acloverdest = str_replace("^", "", $acloverdest); $acloverdest = explode(" ", $acloverdest); $key_acloverdest = array_count_values($acloverdest); foreach($acloverdest as $adest) { # check duplicates destinations in acl if ($key_acloverdest[$adest] > 1) $elog[] = "(A7) ACL '$acl_name' error: duplicate overtime destination name '$adest'. Any destination must included once."; # check destinations for exists if ($adest and ($adest != 'all') and ($adest != 'none') and !$key_destinations[$adest]) $elog[] = "(A8) ACL '$acl_name' error: overtime destination name '$adest' not found"; } } else { $elog[] = "(A9) ACL '$acl_name' error: overtime pass list is empty. Added 'none'."; $acl[F_OVERDESTINATIONNAME] = "none"; } } # check rewrite $rew = $acl[F_REWRITENAME]; if ($rew and !$key_rewrites[$rew]) $elog[] = "(AA) ACL '$acl_name' error: rewrite name '$rew' not found"; # check overtime rewrite $overrew = $acl[F_OVERREWRITENAME]; if ($time and $overrew and !$key_rewrites[$overrew]) $elog[] = "(AB) ACL '$acl_name' error: overtime rewrite name '$overrew' not found"; # check redirect $redir = $acl[F_REDIRECT]; $overredir = $acl[F_OVERREDIRECT]; } } # --- Default --- if ($squidguard_config[F_ACLS]) { $def = $squidguard_config[F_DEFAULT]; # check time $time = $def[F_TIMENAME]; if ($time and !$key_times[$time]) # time name must exists $elog[] = "(DF1) ACL 'default' error: time name '$time' not found"; # check destinations if ($def[F_DESTINATIONNAME]) { $defdest = $def[F_DESTINATIONNAME]; $defdest = str_replace("!", "", $defdest); $defdest = str_replace("^", "", $defdest); $defdest = explode(" ", $defdest); $key_defdest = array_count_values($defdest); foreach($defdest as $adest) { # check duplicates destinations in acl if ($key_defdest[$adest] > 1) $elog[] = "(DF2) ACL 'default' error: duplicate destination name '$adest'. Any destination must included once."; # check destinations for exists if ($adest and ($adest != 'all') and ($adest != 'none') and !$key_destinations[$adest]) $elog[] = "(DF3) ACL 'default' error: destination name '$adest' not found"; } } else { $elog[] = "(DF4) ACL 'default' error: ontime pass list is empty. Added 'none'."; $def[F_DESTINATIONNAME] = "none"; } # check rewrite $rew = $def[F_REWRITENAME]; if ($rew and !$key_rewrites[$rew]) $elog[] = "(DF5) ACL 'default' error: rewrite name '$rew' not found"; # check overtime rewrite $overrew = $def[F_OVERREWRITENAME]; if ($time and $overrew and !$key_rewrites[$overrew]) $elog[] = "(DF6) ACL 'default' error: overtime rewrite name '$overrew' not found"; # check redirect $redir = $def[F_REDIRECT]; $overredir = $def[F_OVERREDIRECT]; } # update log if (!empty($elog)) { $input_errors = (is_array($input_errors)) ? array_merge($input_errors, $elog) : implode("\n", $elog); } return empty($elog); } # ============================================================================= # Blacklist # ============================================================================= # sg_reconfigure_blacklist($source_filename, $opt) # $source_filename - file name or url # $opt - option: # '' or 'local' - update from local file # 'url' - update from url # ----------------------------------------------------------------------------- function sg_reconfigure_blacklist($source_filename, $opt = '') { global $squidguard_config; $sf = trim($source_filename); $sf_contents = ''; sg_addlog("sg_reconfigure_blacklist: Begin with '$sf'.", 1); # 1. check system sg_check_system(); # 2. upload if ($sf[0] === "/") { # local file - example '/tmp/blacklists.tar' sg_addlog("sg_reconfigure_blacklist: Update from file '$sf'.", 1); if (file_exists($sf)) { $sf_contents = file_get_contents($sf); } else { sg_addlog("sg_reconfigure_blacklist: Error, file '$sf' not found.", 2); return; } } # from url else { sg_addlog("sg_reconfigure_blacklist: Upload from url '$sf'.", 1); $sf_contents = sg_uploadfile_from_url($sf, BLK_LOCALFILE, $opt); } # 3. update if (empty($sf_contents)) { sg_addlog("sg_reconfigure_blacklist: Error content from '$sf'.", 2); return; } # save black list archive content to local file conf_mount_rw(); file_put_contents(BLK_LOCALFILE, $sf_contents); conf_mount_ro(); # 4. update blacklist sg_update_blacklist(BLK_LOCALFILE); } # ------------------------------------------------------------------------------ # sg_update_blacklist - update blacklist from file # How it's work: # - unpack tar archive to temp dir # - copy subdir's tree to one-level temp DB # - copy unrebuilded temp db to work db (for user's can configure with new Blacklist) # - create Blacklist files listing and copy to values dir and temp DB dir # - background rebuild temp DB via sh script (longer proccess) and copy to work DB # ------------------------------------------------------------------------------ function sg_update_blacklist($from_file) { global $squidguard_config; conf_mount_rw(); $dbhome = SQUIDGUARD_DBHOME_DEF; $workdir = SQUIDGUARD_WORKDIR_DEF; $tmp_unpack_dir = SQUIDGUARD_TMP . SQUIDGUARD_BL_UNPACK; $arc_db_dir = SQUIDGUARD_VAR . SG_BLK_ARC; sg_addlog("sg_update_blacklist: Begin with '$from_file'.", 1); if (file_exists($from_file)) { # check work and DB dir's if (file_exists($squidguard_config[F_DBHOME])) $dbhome = $squidguard_config[F_DBHOME]; if (file_exists($squidguard_config[F_WORKDIR])) $workdir = $squidguard_config[F_WORKDIR]; # delete old tmp dir's if (file_exists($tmp_unpack_dir)) mwexec("rm -R . $tmp_unpack_dir"); if (file_exists($arc_db_dir)) mwexec("rm -R . $arc_db_dir"); # create new tmp/arc dir's mwexec("mkdir -p -m 0755 $tmp_unpack_dir"); mwexec("mkdir -p -m 0755 $arc_db_dir"); # 1. unpack archive mwexec("tar zxvf $from_file -C $tmp_unpack_dir"); set_file_access($tmp_unpack_dir, OWNER_NAME, 0755); sg_addlog("sg_update_blacklist: Unpack uploaded file '$from_file' -> '$tmp_unpack_dir'.", 1); # 2. copy blacklist to squidGuard base & create entries list if (file_exists($tmp_unpack_dir)) { $blk_items = array(); $blk_list = array(); # scan blacklist items scan_blacklist_cat($tmp_unpack_dir, "blk", & $blk_items); # move blacklist catalog structure to 'one level' (from tmp_DB to arch_DB) foreach ($blk_items as $key => $val) { $current_dbpath = "$arc_db_dir/$key"; if (count($val)) { # make blk_list for config file $blk_list[$key] = $key; # delete '$current_dbpath' for correct moving # need moving $val['path'] to $current_dbpath # if $current_dbpath exists, # then $val['path'] will created as subdir - !it's worng! if (file_exists($current_dbpath)) mwexec("rm -R $current_dbpath"); mwexec("mv -f {$val['path']}/ $current_dbpath"); sg_addlog("sg_update_blacklist: Move {$val['path']}/ -> $current_dbpath.", 1); } } set_file_access($arc_db_dir, OWNER_NAME, 0755); # -- DISABLED -- copy unrebuilded blacklist from arch_DB_to work DB & set access rights # mwexec("cp -R $arc_db_dir/ $dbhome"); # set_file_access($dbhome, OWNER_NAME, 0755); # create entries list if (count($blk_items)) { # save to temp DB $blklist_file = SQUIDGUARD_VAR . SQUIDGUARD_BLK_ENTRIES; file_put_contents($blklist_file, implode("\n", array_keys($blk_items))); set_file_access ($blklist_file, OWNER_NAME, 0755); # -- DISABLED -- save copy to squidGuard config dir # $blklist_file = "{$squidguard_config[F_WORKDIR]}/" . SQUIDGUARD_BLK_ENTRIES; # file_put_contents($blklist_file, implode("\n", array_keys($blk_items))); # set_file_access ($blklist_file, OWNER_NAME, 0755); sg_addlog("sg_update_blacklist: Create DB entries list '$blklist_file'.", 1); } # make rebuild config (included all found dest items) & save to work dir $conf_path = SQUIDGUARD_VAR . DB_REBUILD_BLK_CONF; # "/tmp/squidGuard_rebuild_blk.conf"; file_put_contents($conf_path, sg_create_simple_config($arc_db_dir, $blk_list)); set_file_access($conf_path, OWNER_NAME, 0755); sg_addlog("sg_update_blacklist: Create rebuild config '$conf_path'.", 1); # *** SH script *********************************************** $sh_scr = Array(); $sh_scr[] = "#!/bin/sh"; $sh_scr[] = "cd $arc_db_dir"; $sh_scr[] = $squidguard_config[F_BINPATH] . "/squidGuard -c $conf_path -C all"; $sh_scr[] = "wait"; # wait while SG rebuild DB $sh_scr[] = "chown -R -v " . OWNER_NAME . " $arc_db_dir"; $sh_scr[] = "chmod -R -v 0755 $arc_db_dir"; # copy temp db to '/var/db/squidGuard (-R - recursive; -p - copy access rights) # '$bl_temp_dbhome/' - slash in end of path - copy only dir content (not self dir) $sh_scr[] = "cp -R -p $arc_db_dir/ $dbhome"; $sh_scr[] = "cp -f -p $blklist_file " . SQUIDGUARD_WORKDIR_DEF; # set DB owner and right access $sh_scr[] = "chown -R -v " . OWNER_NAME . " $dbhome"; $sh_scr[] = "chmod -R -v 0755 $dbhome"; # if new blacklist some as already installed, then restart squid for changes to take effects $blk_items_old = ''; $blk_file_old = $squidguard_config[F_WORKDIR] . SQUIDGUARD_BLK_ENTRIES; if (file_exists($blk_items_old)) $blk_items_old = file_get_contents($blk_file_old); if (!empty($blk_items_old) && ($blk_items_old === implode("\n", array_keys($blk_items)))) { $sh_scr[] = "/usr/local/sbin/squid -k reconfigure"; $sh_scr[] = "wait"; # wait while process } unset($blk_file_old); unset($blk_items_old); # store & exec sh $sh_scr = implode("\n", $sh_scr); $shfile = DB_REBUILD_SH . "_blk"; file_put_contents($shfile, $sh_scr); set_file_access($shfile, OWNER_NAME, 0755); # 0755 - script will execute # kill exists rebuild processes # mwexec("kill `ps auxw | grep \"$shfile\" | grep -v \"grep\" | awk '{print $2}'`"); # sh script mwexec("kill `ps auxw | grep \"squidGuard_blk_rebuild\" | grep -v \"grep\" | awk '{print $2}'`"); # squidGuard process mwexec_bg("nice -n 5 $shfile"); sg_addlog("sg_update_blacklist: Started sh script '$shfile'.", 1); # clearing temp # mwexec("rm -R $bl_temp"); } } conf_mount_ro(); } # ----------------------------------------------------------------------------- # sg_blacklist_rebuild_DB - update blacklist from file # ----------------------------------------------------------------------------- function sg_entries_blacklist() { global $squidguard_config; $contents = ''; $fl = SQUIDGUARD_WORKDIR_DEF . SQUIDGUARD_BLK_ENTRIES; if (file_exists($squidguard_config[F_WORKDIR])) $fl = $squidguard_config[F_WORKDIR] . SQUIDGUARD_BLK_ENTRIES; if (file_exists($fl)) $contents = explode("\n", file_get_contents($fl)); return $contents; } # ----------------------------------------------------------------------------- # sg_blacklist_rebuild_db - rebuild current Blacklist DB (default: '/var/db/squidGuard') # ----------------------------------------------------------------------------- function sg_blacklist_rebuild_db() { global $squidguard_config; $dst_list = array(); $dbhome = $squidguard_config[F_DBHOME]; $workdir = $squidguard_config[F_WORKDIR]; # current dbhome and work dir's sg_addlog("sg_blacklist_rebuild_db: Start with path '$dbhome'.", 1); # make dest list $blklist_file = "$workdir/" . SQUIDGUARD_BLK_ENTRIES; if (file_exists($blklist_file)) { $blklist = explode("\n", file_get_contents($blklist_file)); if (is_array($blklist)) foreach($blklist as $bl) { $dst_list[$bl] = $bl; } } # rebuild user db ('/var/db/squidGuard') sg_rebuild_db("_blkdb", $dbhome, $dst_list); } # ========================== UTILS ============================================= # sg_uploadfile_from_url # upload file and put them to $destination_file # return = upload content # ------------------------------------------------------------------------------ function sg_uploadfile_from_url($url_file, $destination_file, $proxy = '') { conf_mount_rw(); # open destination file sg_addlog("sg_uploadfile_from_url: begin url'$url_file' proxy'$proxy'", 1); $result = ''; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_file); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if (!empty($proxy)) { $ip = ''; $login = ''; $s = trim($proxy); if (strpos($s, ' ')) { $ip = substr($s, 0, strpos($s, ' ')); $login = substr($s, strpos($s, ' ') + 1); } else $ip = $s; if($ip != '') { curl_setopt($ch, CURLOPT_PROXY, $ip); if($login != '') curl_setopt($ch, CURLOPT_PROXYUSERPWD, $login); } } $result=curl_exec ($ch); curl_close ($ch); if (!empty($destination_file)) file_put_contents($destination_file, $result); else sg_addlog("sg_uploadfile_from_url: Error upload file", 2); # for test file_put_contents(BLK_LOCALFILE, $result); conf_mount_rw(); return $result; } # ============================================================================== # self utils # ============================================================================== # Set file access # ------------------------------------------------------------------------------ function set_file_access($dir, $owner, $mod) { $mod = sprintf("%o", $mod); if (!file_exists($dir)) return; # recursive change access mwexec("chown -R -v $owner $dir"); mwexec("chgrp -R -v $owner $dir"); mwexec("chmod -R -v $mod $dir"); } # ------------------------------------------------------------------------------ # scan_dir - build files listing for $dir # ------------------------------------------------------------------------------ function scan_dir($dir) { $files = array(); if (file_exists($dir)) { $dh = opendir($dir); while (false !== ($filename = readdir($dh))) { # skip '.' and '..' names if (($filename !== '.') and ($filename !== '..')) $files[] = $filename; } sort($files); } return $files; } # ------------------------------------------------------------------------------ # restore_arc_blacklist - copy arc blacklist to db # ------------------------------------------------------------------------------ function restore_arc_blacklist() { global $squidguard_config; $dbhome = SQUIDGUARD_DBHOME_DEF; $blklist_file = SQUIDGUARD_WORKDIR_DEF . SQUIDGUARD_BLK_ENTRIES; $arc_db_dir = SQUIDGUARD_VAR . SG_BLK_ARC; $arc_blklist_file = SQUIDGUARD_VAR . SQUIDGUARD_BLK_ENTRIES; if (file_exists($arc_db_dir) and file_exists($arc_blklist_file)) { conf_mount_rw(); # copy arc blacklist to work DB with permissions mwexec("cp -R -p $arc_db_dir/ $dbhome"); set_file_access($dbhome, OWNER_NAME, 0755); sg_addlog("restore_arc_blacklist: Restore blacklist archive from '$arc_db_dir'.", 1); # copy black list file copy($arc_blklist_file, $blklist_file); set_file_access($blklist_file, OWNER_NAME, 0755); sg_addlog("restore_arc_blacklist: Restore black list file from '$arc_blklist_file' to '$blklist_file'.", 1); conf_mount_ro(); } else { sg_addlog("restore_arc_blacklist: Error, file '$arc_db_dir' or '$blklist_file' not found.", 2); } } # ------------------------------------------------------------------------------ # scan_blacklist_cat - scan all dirs and subdirs tree and make blk enrties list # $cur_dir - start directory # $key_name - current key name # ------------------------------------------------------------------------------ # blk entry[key]: # ["domains"] domains file path # ["urls"] urls file path # ["expressions"] expressions file path # ------------------------------------------------------------------------------ function scan_blacklist_cat($curdir, $key_name, $cat_array) { if (file_exists($curdir) and is_dir($curdir)) { $blk_entry = array(); $files = scan_dir($curdir); foreach($files as $fls) { $fls_file = "$curdir/$fls"; if (($fls != ".") and ($fls != "..")) { if (is_file($fls_file)) { # add files path switch(strtolower($fls)) { case "domains": $blk_entry["domains"] = $fls_file; $blk_entry["path"] = $curdir; break; case "urls": $blk_entry["urls"] = $fls_file; $blk_entry["path"] = $curdir; break; case "expressions": $blk_entry["expressions"] = $fls_file; $blk_entry["path"] = $curdir; break; } } elseif (is_dir($fls_file)) { $fls_key = $key_name . "_" . $fls; # recursive call scan_blacklist_cat($fls_file, $fls_key, & $cat_array); } } } if (count($blk_entry)) $cat_array[$key_name] = $blk_entry; } } # ****************************************************************************** # squidguard utils # ****************************************************************************** # sg_list_itemsfield - get items field list # ------------------------------------------------------------------------------ function sg_list_itemsfield($xml_items, $fld_name) { $ls = array(); if (is_array($xml_items[F_ITEM])) foreach($xml_items[F_ITEM] as $it) { $ls[] = $it[$fld_name]; } return $ls; } # ------------------------------------------------------------------------------ # is_url - check url an err_codes # ------------------------------------------------------------------------------ if(!function_exists("is_url")) { function is_url($url) { if (empty($url)) return false; if (eregi("^http://", $url)) return true; if (eregi("^https://", $url)) return true; if (strstr("blank", $url)) return true; if (strstr("blank_img", $url)) return true; if (eregi("^((30[1235]{1})|(40[0-9]{1})|(41[0-7]{1})|(50[0-5]{1}))", $url)) return true; # http error code 30x, 4xx, 50x. return false; } } # url as 'domain/path': 'mydomain.com/index.php' function is_dest_url($url) { $fmt = "[a-zA-Z0-9_-]"; if (empty($url)) return false; if (eregi("^(($fmt){1,}\.){1,}($fmt){2,}(/(.[^\*][^ ])*)", $url)) return true; return false; } # ------------------------------------------------------------------------------ # is_masksubnet - check ip/mask # ------------------------------------------------------------------------------ function is_masksubnet($subnet) { if (!is_string($subnet)) return false; list($ip,$msk) = explode('/', $subnet); if (!is_ipaddr($ip) || !is_ipaddr($msk)) return false; return true; } # ------------------------------------------------------------------------------ # is_iprange - check ip1-ip2 # ------------------------------------------------------------------------------ function is_iprange_sg($ip_range) { if (!is_string($ip_range)) return false; list($ip1,$ip2) = explode('-', $ip_range); if (!is_ipaddr($ip1) || !is_ipaddr($ip2)) return false; # ip2 < ip1 - wrong if (ipcmp(ip2, ip1) === -1) return false; return true; } # ------------------------------------------------------------------------------ # is_ipaddr_valid - validate IP, subnet, IP range # ------------------------------------------------------------------------------ function is_ipaddr_valid($val) { return is_string($val) && (is_ipaddr($val) || is_masksubnet($val) || is_subnet($val) || is_iprange_sg($val)); } # ------------------------------------------------------------------------------ # is_domain_valid - check domain format # ------------------------------------------------------------------------------ function is_domain_valid($domain) { $dm_fmt = "([a-z0-9\-]{1,})"; $dm_fmt = "^(($dm_fmt{1,}\.){1,}$dm_fmt{2,})+$"; # example: (my.)(super.)(domain.)com return is_string($domain) && eregi($dm_fmt, trim($domain)); } # ------------------------------------------------------------------------------ # is_username - check username # ------------------------------------------------------------------------------ function is_username($username) { $unm_fmt = "^\'[a-zA-Z_0-9\.\-]{1,}\'$"; return is_string($username) && eregi($unm_fmt, trim($username)); } # ------------------------------------------------------------------------------ # check name # ------------------------------------------------------------------------------ function check_name_format ($name, $input_errors) { $elog = array(); $val = trim($name); if ((strlen($val) < 2) || (strlen($val) > 16)) $elog[] = " Size of name '$val' must be between [2..16]."; # All symbols must be [a-zA-Z_0-9\-] First symbol = letter. if (!eregi("^([a-zA-Z]{1})([a-zA-Z_0-9\-]+)$", $val)) $elog[] = " Invalid name $name. Valid name symbols: ['a-Z', '_', '0-9', '-']. First symbol must be a letter."; # update log if (!empty($elog)) { $input_errors = (is_array($input_errors)) ? array_merge($input_errors, $elog) : implode("\n", $elog); } return empty($elog); } # ****************************************************************************** # squidguard check # ****************************************************************************** # check redirect # ------------------------------------------------------------------------------ function sg_check_redirect($rdr_mode, $rdr_info, $err_msg) { $res = true; switch($rdr_mode) { case RMOD_EXT_ERR: case RMOD_EXT_RDR: case RMOD_EXT_MOVED: case RMOD_EXT_FOUND: $res = is_url($rdr_info); if (!$res) $err_msg = "Valid URL expected, but '$rdr_info' found."; break; case RMOD_INT_SIZELIMIT: $res = is_numeric($rdr_path); if (!$res) $err_msg = "Valid number value expected, but '$rdr_info' found."; break; case RMOD_INT_BLANKPAGE: case RMOD_INT_BLANKIMG: case RMOD_INT_ERRORPAGE: default: $res = true; break; } return $res; } # ------------------------------------------------------------------------------ # sg_check_time # ------------------------------------------------------------------------------ function sg_check_time($sgtime, $input_errors) { $err = ''; $days = array("*", "mon", "tue", "wed", "thu", "fri", "sat", "sun"); $timetypes = array("weekly", "date"); if (is_array($sgtime[F_ITEM])) { # check date and time foreach ($sgtime[F_ITEM] as $item) { if (!in_array(trim($item[F_TIMETYPE]), $timetypes)) $err .= " Invalid type '{$item[F_TIMETYPE]}'."; if (!in_array(trim($item[F_TIMEDAYS]), $days)) $err .= " Invalid week day '{$item[F_TIMEDAYS]}'."; if (trim($item[F_DATERANGE])) $err .= check_date(trim($item[F_DATERANGE])); if (trim($item[F_TIMERANGE])) $err .= check_time(trim($item[F_TIMERANGE])); } } # errors update if (!empty($err)) $input_errors[] = "TIME '{$sgtime[F_NAME]}': $err"; return empty($err); } # ------------------------------------------------------------------------------ # sg_check_dest # ------------------------------------------------------------------------------ function sg_check_dest($sgx, $input_errors) { $elog = array(); $dm = explode(" ", $sgx[F_DOMAINS]); # $ex = explode(" ", $sgx[F_EXPRESSIONS]); $ur = explode(" ", $sgx[F_URLS]); array_packitems(&$dm); array_packitems(&$ur); # domain foreach ($dm as $d_it) if ($d_it && !is_domain_valid($d_it)) $elog[] = "Item '$d_it' is not a domain."; # url foreach ($ur as $u_it) if ($u_it && !is_dest_url($u_it)) $elog[] = "Item '$u_it' is not a url."; # check redirect sg_check_redirect($sgx[F_RMOD], $sgx[F_REDIRECT], &$elog); # update log if (!empty($elog)) { $elog = "DEST '{$sgx[F_NAME]}': " . implode(" ", $elog); if (is_array($input_errors)) $input_errors[] = $elog; else $input_errors = $elog; } return empty($elog); } # ------------------------------------------------------------------------------ # sg_check_src # ------------------------------------------------------------------------------ function sg_check_src($sgx, $input_errors) { $elog = array(); # source may be as one ('source') field or as two ('ip' and 'domain') fields $src = (isset($sgx[F_SOURCE])) ? $sgx[F_SOURCE] : $sgx[F_IP] . " " . $sgx[F_DOMAINS]; $src = explode(" ", $src); foreach ($src as $s_item) { if ($s_item) { if (!is_ipaddr_valid($s_item) and !is_domain_valid($s_item) and !is_username($s_item)) $elog[] = "SRC '{$sgx[F_NAME]}': Item '$s_item' is not a ip address or a domain or a 'username'."; } } # update log if (!empty($elog)) { $input_errors = (is_array($input_errors)) ? array_merge($input_errors, $elog) : implode("\n", $elog); } return empty($elog); } # ------------------------------------------------------------------------------ # check rebuild blacklist # ------------------------------------------------------------------------------ function is_blacklist_update_started() { return exec("ps auxw | grep \"[s]quidGuard_blk_rebuild\" | awk '{print $2}' | wc -l | awk '{ print $1 }'"); } # ------------------------------------------------------------------------------ # Strings # ------------------------------------------------------------------------------ # str_pack_spaces - replace two and more space to single # ------------------------------------------------------------------------------ function str_packspaces($str) { while(strpos($str, ' ')) $str = str_replace(' ', ' ', $str); } function array_packitems($arval) { if (is_array($arval)) { $arval = array_map("trim", $arval); # trim all items $arval = array_diff($arval, array(' ', '')); # exclude ' ' abd '' elements $arval = array_unique($arval); # unique items $arval = array_values($arval); # pack array } return $arval; } # ----------------------------------------------------------------------------- # check date # date or date range format: 'yyyy-mm-dd', 'yyyy-m-d', 'yyyy.mm.dd' 'yyyy.mm.dd-yyyy.mm.dd' # date mask format: '*-mm-dd', 'yyyy-*-dd', 'yyyy.mm.*' (but not for range) # ----------------------------------------------------------------------------- function check_date($date) { $err = ''; $val = trim($date); $dtfmt = "([0-9]{4})\.([0-9]{2})\.([0-9]{2})"; # check date range if (eregi("^{$dtfmt}-{$dtfmt}$", $val)) { $val = explode("-", str_replace(".", '', $val)); if (intval($val[0]) >= intval($val[1])) $err .= "Invalid date range, begin range must be less than the end. {$val[0]} - {$val[1]}"; } elseif (!eregi("^(([0-9]{4})|[*])\.(([0-9]{2})|[*])\.(([0-9]{2})|[*])$", $val)) { $err .= "Bad date format."; } if ($err) $err = " Invalid date '$date'. $err You mast use date or date range format: 'yyyy.mm.dd' and 'yyyy.mm.dd-yyyy.mm.dd'. Also possible use mask * (mean any). Example: '*-10-01', '1990-*-*'."; return $err; } # ----------------------------------------------------------------------------- # check time # ----------------------------------------------------------------------------- function check_time($time) { $err = ''; $time = trim($time); if (empty($time)) return ''; # time range format: 'HH:MM-HH:MM' if (!eregi("^([0-2][0-9])\:([0-5][0-9])-([0-2][0-9])\:([0-5][0-9])$", $time)) $err = "Invalid time range '$time'. You must use 'HH:MM-HH:MM' time range format. "; else { $tms = str_replace("-", "\n", $time); $tmsview = explode("\n", $tms); $tms = str_replace(":", "", $tms); $tms = explode("\n", $tms); if ($tms[0] >= 2400) $err .= "Invalid time range var1='{$tmsview[0]}' must be < '24:00'. "; if ($tms[1] > 2400) $err .= "Invalid time range var2='{$tmsview[1]}' must be <= '24:00'. "; if ($tms[0] >= $tms[1]) $err .= "Invalid time range var1='{$tmsview[0]}' must be < var2='{$tmsview[1]}'. "; } return $err; } # ----------------------------------------------------------------------------- # acl_remove_blacklist_items # ----------------------------------------------------------------------------- function acl_remove_blacklist_items($items) { # add !items and ^items $db_entries = sg_entries_blacklist(); if (!is_array($db_entries)) return; $tdb_entries = array(); foreach ($db_entries as $ent) { $tdb_entries[] = $ent; $tdb_entries[] = "!$ent"; $tdb_entries[] = "^$ent"; } $db_entries = $tdb_entries; unset($tdb_entries); # delete blacklist entries from 'pass' if blacklist disabled $items = explode(" ", $items); $items = implode(" ", array_diff($items, $db_entries)); return $items; } # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ # classes # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class TSgTag { var $tag; var $name; var $time; var $items; var $desc; function __construct() { $this->clear(); } function clear() { $this->tag = ''; $this->name = ''; $this->time = ''; $this->items = array(); $this->desc = ''; } function set($tag, $name, $time, $desc) { $this->tag = $tag; $this->name = $name; $this->time = $time; $this->desc = $desc; } function tag_text($offset = 0) { $str = array(); $off = str_repeat("\t", $offset); $str[] = $off . "# {$this->desc}"; if (empty($this->time)) $str[] = $off . "{$this->tag} {$this->name} {"; else $str[] = $off . "{$this->tag} {$this->name} within {$this->time} {"; # get items foreach($this->items as $it) { if (is_a($it, "TSgTag")) $str[] = $off . $it->tag_text($offset + 1); # sub tag else $str[] = $off . "\t{$it}"; # item } $str[] = $off . "}"; return implode("\n", $str); } } ?>