- 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', '32M'); # ------------------------------------------------------------------------------ # 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', '/tmp/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 ; 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; file_put_contents($filename, dump_xml_config($squidguard_config, F_SQUIDGUARD)); } # ------------------------------------------------------------------------------ # 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) { 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); 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; # 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); } # ============================================================================== # squidGuard DB # ============================================================================== # sg_reconfigure_user_db - reconfigure(update) db user entries # ------------------------------------------------------------------------------ function sg_reconfigure_user_db() { global $squidguard_config; $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(); } # ------------------------------------------------------------------------------ # sg_remove_unused_db_entries # ------------------------------------------------------------------------------ function sg_remove_unused_db_entries() { global $squidguard_config; $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); } } } } } # ------------------------------------------------------------------------------ # 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 = ''; $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); } # ============================================================================== # 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 sg_addlog("sg_create_config: add rewrites: \n success $log_entr_added \n 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 () $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 () $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: 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 --- $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 file_put_contents(BLK_LOCALFILE, $sf_contents); # 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; $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"); } } } # ----------------------------------------------------------------------------- # 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 = '') { # 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); 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)) { # 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); } 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 # ------------------------------------------------------------------------------ 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($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($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(); $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); } } ?>