- create squidGuard with specified config file # ------------------------------------------------------------------------------ # Directories: # work path - $workdir # log path - $workdir + $logdir # ------------------------------------------------------------------------------ # Functions: # sg_init($init_xml) # sg_load_configxml($filename) # sg_save_configxml($filename) # sg_reconfigure() # sg_reconfigure_blacklist($source_filename, $opt) # $source_filename - file name or url # $opt - option: # '' or 'local' - update from local file (example: '/tmp/blacklist.tar') # 'url' - update from url # ------------------------------------------------------------------------------ # Config XML structure: # ------------------------------------------------------------------------------ /* on ... on ... on ... ... ... ... ... */ 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'); # ------------------------------------------------------------------------------ define('FILES_DB_HEADER', ' # ------------------------------------------------------------------------------ # File created by squidGuard package GUI # (C)2006 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) # this may use '301:' or '302:' value (only) #define('REDIRECT_BASE_URL', '302:'); define('REDIRECT_BASE_URL', 'http://127.0.0.1/sgerror.php'); define('REDIRECT_TRANSPARENT_BASE_URL', '/sgerror.php'); # ------------------------------------------------------------------------------ # squidguard system defines # ------------------------------------------------------------------------------ # !check this! define('SQUID_CONFIGFILE', '/usr/local/etc/squid/squid.conf'); define('TMP_DIR', '/var/tmp'); # not need for check define('SQUIDGUARD_CONFIGFILE', '/squidGuard.conf'); define('SQUIDGUARDCONF_LOGFILE', '/sg_configurator.log'); define('SQUIDGUARD_ACCESSBLOCK_FILE', 'block.log'); define('SQUIDGUARD_BLK_ENTRIES', '/blacklist.files'); define('BLACKLIST_ARCHIVE', '/blacklists.tar'); # ? may be not used ? 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_DBHOME_DEF', '/var/db/squidGuard'); define('BLK_LOCALFILE', '/tmp/sg_blacklists.tar'); # ------------------------------------------------------------------------------ // debug options define('DEBUG_UPDATE_SQUID_CONF', 'true'); define('DEBUG_UPDATE_SQUIDGUARD_DB', 'true'); define('DEBUG_MAKE_SQUIDGUARD_CONFIG', 'true'); // options define('SQUIDGUARD_LOG_MAXCOUNT', 1000); // max log lines # ------------------------------------------------------------------------------ # define('FLT_DEFAULT_ALL', 'all'); # ------------------------------------------------------------------------------ # owner user name (squid system user - need for define rights access) # ------------------------------------------------------------------------------ define('OWNER_NAME', 'proxy'); # ------------------------------------------------------------------------------ # 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'); # ------------------------------------------------------------------------------ # std_blacklist_get_description - black list std names description # ------------------------------------------------------------------------------ function std_blacklist_get_description() { $dst_std = array(); $dst_std[FLT_AD] = 'Reclama & banners filter'; $dst_std[FLT_AGGRESSIVE] = 'Agressive content sites filter'; $dst_std[FLT_AUDIOVIDEO] = 'Audio and Video sites filter'; $dst_std[FLT_DRUGGS] = 'Druggs filter'; $dst_std[FLT_GAMBLING] = 'Games sites filter'; $dst_std[FLT_HACKING] = 'Hacking sites filter'; $dst_std[FLT_MAIL] = 'Mail sites filter'; $dst_std[FLT_PORN] = 'Porno sites filter'; $dst_std[FLT_PROXY] = 'Proxy sites filter'; $dst_std[FLT_VIOLENCE] = 'Violence content sites filter'; $dst_std[FLT_WAREZ] = 'Wares, soft, downloads sites filter'; return $dst_std; } # ============================================================================== # SquidGuard Configurator # ============================================================================== // squidGuard config array $squidguard_config = array(); // default init sg_init(); # ------------------------------------------------------------------------------ # squidguard system fields # ------------------------------------------------------------------------------ define('FLD_SQUIDGUARD', 'squidGuard'); define('FLD_LOGDIR', 'logdir'); define('FLD_DBHOME', 'dbhome'); define('FLD_WORKDIR', 'workdir'); define('FLD_BINPATH', 'binpath'); define('FLD_PROCCESSCOUNT', 'process_count'); define('FLD_SQUIDCONFIGFILE', 'squid_configfile'); define('FLD_ENABLED', 'enabled'); define('FLD_BLACKLISTENABLED', 'blacklist_enabled'); define('FLD_SGCONF_XML', 'sgxml_file'); // other fields define('FLD_ITEM', 'item'); define('FLD_TIMES', 'times'); define('FLD_SOURCES', 'sources'); define('FLD_DESTINATIONS', 'destinations'); define('FLD_REWRITES', 'rewrites'); define('FLD_ACLS', 'acls'); define('FLD_DEFAULT', 'default'); define('FLD_NAME', 'name'); define('FLD_DESCRIPTION', 'description'); define('FLD_IP', 'ip'); define('FLD_URLS', 'urls'); define('FLD_DOMAINS', 'domains'); define('FLD_EXPRESSIONS', 'expressions'); define('FLD_REDIRECT', 'redirect'); define('FLD_TARGETURL', 'targeturl'); define('FLD_REPLACETO', 'replaceto'); define('FLD_LOG', 'log'); define('FLD_ITEM', 'item'); define('FLD_DISABLED', 'disabled'); define('FLD_TIMENAME', 'timename'); define('FLD_DESTINATIONNAME', 'destname'); define('FLD_REDIRECT', 'redirect'); define('FLD_REWRITE', 'rewrite'); define('FLD_REWRITENAME', 'rewritename'); define('FLD_OVERDESTINATIONNAME', 'overdestname'); define('FLD_OVERREDIRECT', 'overredirect'); define('FLD_OVERREWRITE', 'overrewrite'); define('FLD_OVERREWRITENAME', 'overrewritename'); define('FLD_TIMETYPE', 'timetype'); define('FLD_TIMEDAYS', 'timedays'); define('FLD_DATRANGE', 'daterange'); define('FLD_TIMERANGE', 'sg_timerange'); // transparent mode define('FLD_SQUID_TRANSPARENT_MODE', 'squid_transparent_mode'); define('FLD_CURRENT_LAN_IP', 'current_lan_ip'); # ------------------------------------------------------------------------------ # 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[FLD_LOGDIR] = SQUIDGUARD_LOGDIR_DEF; $squidguard_config[FLD_DBHOME] = SQUIDGUARD_DBHOME_DEF; $squidguard_config[FLD_WORKDIR] = SQUIDGUARD_WORKDIR_DEF; $squidguard_config[FLD_BINPATH] = SQUIDGUARD_BINPATH_DEF; $squidguard_config[FLD_SQUIDCONFIGFILE] = SQUID_CONFIGFILE; $squidguard_config[FLD_PROCCESSCOUNT] = REDIRECTOR_PROCESS_COUNT; sg_addlog("sg_init: default initialization squidguard_config"); } else { $squidguard_config = $init; sg_addlog("sg_init: ext initialization squidguard_config"); } 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); sg_addlog("sg_load_configxml: load config from $filename"); if (!empty($xmlconf)) { $squidguard_config = $xmlconf[FLD_SQUIDGUARD]; sg_addlog("sg_load_configxml: update config success."); } else sg_addlog("sg_load_configxml: update config error."); } else sg_addlog("sg_load_configxml: error load config from $filename - file not exists."); } # ------------------------------------------------------------------------------ # sg_saveconfig_xml # ------------------------------------------------------------------------------ function sg_save_configxml($filename) { global $squidguard_config; $xmlconf = dump_xml_config($squidguard_config, FLD_SQUIDGUARD); file_put_contents($filename, $xmlconf); } # ------------------------------------------------------------------------------ # sg_reconfigure # - squidguard reconfiguration # ------------------------------------------------------------------------------ function sg_reconfigure() { global $squidguard_config; sg_addlog("sg_reconfigure: start."); // 1. check system sg_check_system(); // 2. reconfigure user db sg_reconfigure_user_db(); // 3. generate squidGuard config $conf_file = SQUIDGUARD_LOGDIR_DEF . SQUIDGUARD_CONFIGFILE; $conf = sg_build_config(); if ($conf) { $conf = implode("\n", $conf); if ($squidguard_config[FLD_WORKDIR]) $conf_file = $squidguard_config[FLD_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[FLD_WORKDIR], OWNER_NAME, 0755); sg_addlog("sg_reconfigure: generate squidGuard config and save to $conf_file."); } // 4. reconfigure squid squid_reconfigure(); sg_addlog("sg_reconfigure: end."); } // ------------------------------------------------------------ // 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 $squidguard_config; sg_addlog("squid_reconfigure: begin"); // 1. update squid config $opt = ''; $squid_conf_file = SQUID_CONFIGFILE; $redirector_path = $squidguard_config[FLD_BINPATH] . '/squidGuard'; $redirector_conf = $squidguard_config[FLD_WORKDIR] . SQUIDGUARD_CONFIGFILE; // update squid.conf file if (file_exists($squid_conf_file)) { sg_addlog("squid_reconfigure: config file '$squid_conf_file'"); $conf = file_get_contents($squid_conf_file); // remove old redirector options from 'squid.conf' sg_addlog("squid_reconfigure: remove old redirector options from 'squid.conf'"); $conf = explode("\n", $conf); for($i=0; $i SQUIDGUARD_LOG_MAXCOUNT) array_shift($log_content); $tlog = implode("\n", $log_content); file_put_contents($logfile, $tlog); # file_put_contents("/tmp/_sg.log", $tmp_log); } // ------------------------------------------------------------ // 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)) if (file_exists($squidguard_config[FLD_LOGDIR])) $logfile = $squidguard_config[FLD_LOGDIR] . SQUIDGUARDCONF_LOGFILE; // get log last 100 entries if (file_exists($logfile)) { $log_content = file_get_contents($logfile); $log_content = explode("\n", $log_content); while (count($log_content) > $last_entries_count) array_shift($log_content); // insert log file name on top $log_content[0] = $logfile; $log_content = implode("\n", $log_content); } return $log_content; } # ------------------------------------------------------------- # sg_build_default_config # default rule - block all # ------------------------------------------------------------- function sg_build_default_config() { global $squidguard_config; $sgconf = array(); $redirect_base_url = REDIRECT_BASE_URL; // TODO: need fix for transparentproxy // header $sgconf[] = CONFIG_SG_HEADER; // init section $sgconf[] = "logdir {$squidguard_config[FLD_LOGDIR]}"; $sgconf[] = "dbhome {$squidguard_config[FLD_DBHOME]}"; $sgconf[] = ""; // acl section $sgconf[] = "acl {"; $sgconf[] = "\t default {"; $sgconf[] = "\t\t pass none"; $sgconf[] = "\t\t redirect " . $redirect_base_url; $sgconf[] = "\t }"; $sgconf[] = "}"; sg_addlog("sg_build_default_config: Created default configuration. All content will blocked."); return $sgconf; } // ------------------------------------------------------------ // sg_build_config // ------------------------------------------------------------ function sg_build_config() { global $squidguard_config; $sgconf = array(); $redirect_base_url = REDIRECT_BASE_URL; sg_addlog("sg_build_config: create squidGuard config"); if(!is_array($squidguard_config)) { sg_addlog("sg_build_config: error configuration in squidguard_config"); return sg_build_default_config(); } // check configuration data sg_addlog("sg_build_config: check configuration data"); $s = sg_check_config_data(); if ($s) { sg_addlog("sg_build_config: error configuration data. It's all errors: \n$s"); sg_addlog("sg_build_config: terminated."); return sg_build_default_config(); } unset($s); // --- Header --- $sgconf[] = CONFIG_SG_HEADER; // Transparent redirector base url if (isset($squidguard_config[FLD_SQUID_TRANSPARENT_MODE]) and isset($squidguard_config[FLD_CURRENT_LAN_IP])) { $redirect_base_url = "http://" . $squidguard_config[FLD_CURRENT_LAN_IP] . REDIRECT_TRANSPARENT_BASE_URL; sg_addlog("sg_build_config: select LAN redirector base url ($redirect_base_url)"); } else sg_addlog("sg_build_config: select localhost redirector base url ($redirect_base_url)"); // init $sgconf[] = "logdir " . $squidguard_config[FLD_LOGDIR]; $sgconf[] = "dbhome " . $squidguard_config[FLD_DBHOME]; // --- Times --- if ($squidguard_config[FLD_TIMES]) { sg_addlog("sg_build_config: add times"); foreach($squidguard_config[FLD_TIMES][FLD_ITEM] as $tm) { $sgconf[] = ""; if ($tm[FLD_DESCRIPTION]) $sgconf[] = "# " . $tm[FLD_DESCRIPTION]; $sgconf[] = "time " . $tm[FLD_NAME] . " {"; foreach($tm[FLD_ITEM] as $itm) { switch ($itm[FLD_TIMETYPE]) { case "weekly": $sgconf[] = "\t weekly " . $itm[FLD_TIMEDAYS] . " " . $itm[FLD_TIMERANGE]; break; case "date": $sgconf[] = "\t date " . $itm[FLD_DATERANGE] . " " . $itm[FLD_TIMERANGE]; break; } } $sgconf[] = "}"; } } // --- Sources --- if ($squidguard_config[FLD_SOURCES]) { sg_addlog("sg_build_config: add sources"); foreach($squidguard_config[FLD_SOURCES][FLD_ITEM] as $src) { $sgconf[] = ""; if ($src[FLD_DESCRIPTION]) $sgconf[] = "# " . $src[FLD_DESCRIPTION]; $sgconf[] = "src " . $src[FLD_NAME] . " {"; // IP if ($src[FLD_IP]) { $s_ip = explode(" ", $src[FLD_IP]); foreach($s_ip as $ip) if (!empty($ip)) $sgconf[] = "\t ip " . $ip; } // domains if ($src[FLD_DOMAINS]) { $dms = explode(" ", $src[FLD_DOMAINS]); foreach($dms as $dm) if (!empty($dm)) $sgconf[] = "\t domain " . $dm; } if ($src[FLD_LOG]) $sgconf[] = "\t log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = "}"; } } // --- Blacklist --- # # Note! Blacklist must be added to config constantly. It's need for rebuild DB # $db_entries = sg_entries_blacklist(); if (($squidguard_config[FLD_BLACKLISTENABLED] === 'on') and $db_entries) { sg_addlog("sg_build_config: add blacklist entries"); foreach($db_entries as $key => $ent) { $ent_state = array(); $file_dms = $squidguard_config[FLD_DBHOME] . "/$ent/domains"; $file_urls = $squidguard_config[FLD_DBHOME] . "/$ent/urls"; $file_expr = $squidguard_config[FLD_DBHOME] . "/$ent/expressions"; // check blacklist acl state if (file_exists($file_dms)) { $ent_state['exists'] = 'on'; $ent_state[FLD_DOMAINS] = 'on'; } if (file_exists($file_urls)) { $ent_state['exists'] = 'on'; $ent_state[FLD_URLS] = 'on'; } if (file_exists($file_expr)) { $ent_state['exists'] = 'on'; $ent_state[FLD_EXPRESSIONS] = 'on'; } // create config $sgconf[] = ""; if ($ent_state['exists']) { $sgconf[] = "dest $ent {"; $dstname = $ent; if ($ent_state[FLD_DOMAINS]) $sgconf[] = "\t domainlist $ent/domains"; if ($ent_state[FLD_EXPRESSIONS]) $sgconf[] = "\t expressionlist $ent/expressions"; if ($ent_state[FLD_URLS]) $sgconf[] = "\t urllist $ent/urls"; $sgconf[] = "\t log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = "}"; sg_addlog("sg_build_config: -- add '$ent' entry"); } else { $sgconf[] = "\t# Config ERROR: Destination '$ent' not found in DB"; sg_addlog("sg_build_config: uncompleted or error '$ent' entry - disabled"); } } } // --- Destinations --- if ($squidguard_config[FLD_DESTINATIONS]) { sg_addlog("sg_build_config: add destinations"); $sgconf[] = ""; # $sgconf[] = "dest localhost { # fix localhost access problem on transparent proxy "; # $sgconf[] = "\t ip 127.0.0.1"; # $sgconf[] = "}"; foreach($squidguard_config[FLD_DESTINATIONS][FLD_ITEM] as $dst) { $dstname = $dst[FLD_NAME]; $sgconf[] = ""; if ($dst[FLD_DESCRIPTION]) $sgconf[] = "# " . $dst[FLD_DESCRIPTION]; $sgconf[] = "dest $dstname {"; if ($dst[FLD_DOMAINS]) $sgconf[] = "\t domainlist $dstname/domains"; if ($dst[FLD_EXPRESSIONS]) $sgconf[] = "\t expressionlist $dstname/expressions"; if ($dst[FLD_URLS]) $sgconf[] = "\t urllist $dstname/urls"; if ($dst[FLD_REDIRECT] && is_url($dst[FLD_REDIRECT])) $sgconf[] = "\t redirect " . $redirect_base_url . "?url={$dst[FLD_REDIRECT]}"; if ($dst[FLD_LOG]) $sgconf[] = "\t log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = "}"; } } // --- Rewrites --- if ($squidguard_config[FLD_REWRITES]) { sg_addlog("sg_build_config: add rewrites"); foreach($squidguard_config[FLD_REWRITES][FLD_ITEM] as $rew) { $sgconf[] = ""; $sgconf[] = "rew " . $rew[FLD_NAME] . " {"; foreach ($rew[FLD_ITEM] as $rw) $sgconf[] = "\t s@." . $rw[FLD_TARGETURL] . "@" . $rw[FLD_REPLACETO]."@"; if ($rew[FLD_LOG]) $sgconf[] = "\t log " . SQUIDGUARD_ACCESSBLOCK_FILE; $sgconf[] = "}"; } } # ---------------------------------------- $entry_blacklist = sg_entries_blacklist(); // --- ACL --- $sgconf[] = ""; $sgconf[] = "acl {"; if ($squidguard_config[FLD_ACLS]) { sg_addlog("sg_build_config: add ACL"); foreach($squidguard_config[FLD_ACLS][FLD_ITEM] as $acl) { // delete blacklist entries from 'pass' if blacklist disabled if ($squidguard_config[FLD_BLACKLISTENABLED] !== 'on') { $tarray = explode(" ", $acl[FLD_DESTINATIONNAME]); $varray = explode(" ", $acl[FLD_OVERDESTINATIONNAME]); foreach($entry_blacklist as $entry) { $tk = array_search($entry, $tarray); if ($tk !== false) unset ($tarray[$tk]); $tk = array_search("!$entry", $tarray); if ($tk !== false) unset($tarray[$tk]); $tk = array_search($entry, $varray); if ($tk !== false) unset ($varray[$tk]); $tk = array_search("!$entry", $varray); if ($tk !== false) unset ($varray[$tk]); } $acl[FLD_DESTINATIONNAME] = implode (" ", $tarray); $acl[FLD_OVERDESTINATIONNAME] = implode (" ", $varray); } if (!$acl[FLD_DISABLED]) { if ($acl[FLD_DESCRIPTION]) $sgconf[] = "\t # " . $acl[FLD_DESCRIPTION]; if ($acl[FLD_TIMENAME]) { // ontime $sgconf[] = "\t " . $acl[FLD_NAME] . " within " . $acl[FLD_TIMENAME] . " { "; $sgconf[] = "\t\t pass " . $acl[FLD_DESTINATIONNAME]; if ($acl[FLD_REDIRECT]) { if (is_url($acl[FLD_REDIRECT])) $sgconf[] = "\t\t redirect " . $redirect_user_url . "?url={$acl[FLD_REDIRECT]}"; else $sgconf[] = "\t\t redirect " . $redirect_user_url . "?msg=" . htmlspecialchars($acl[FLD_REDIRECT]); } if ($acl[FLD_REWRITENAME]) $sgconf[] = "\t\t rewrite " . $acl[FLD_REWRITENAME]; // overtime $sgconf[] = "\t } else {"; $sgconf[] = "\t\t pass " . $acl[FLD_OVERDESTINATIONNAME]; if ($acl[FLD_OVERREDIRECT] && is_url($acl[FLD_OVERREDIRECT])) $sgconf[] = "\t\t redirect " . $redirect_base_url . "?url={$acl[FLD_OVERREDIRECT]}"; if ($acl[FLD_OVERREWRITENAME]) $sgconf[] = "\t\t rewrite " . $acl[FLD_OVERREWRITENAME]; $sgconf[] = "\t }"; } else { $sgconf[] = "\t " . $acl[FLD_NAME] . " { "; $sgconf[] = "\t\t pass " . $acl[FLD_DESTINATIONNAME]; if ($acl[FLD_REDIRECT] && is_url($acl[FLD_REDIRECT])) $sgconf[] = "\t\t redirect " . $redirect_base_url . "?url={$acl[FLD_REDIRECT]}"; if ($acl[FLD_REWRITENAME]) $sgconf[] = "\t\t rewrite " . $acl[FLD_REWRITENAME]; $sgconf[] = "\t }"; } $sgconf[] = ""; } } } // --- Default --- $def = $squidguard_config[FLD_DEFAULT]; sg_addlog("sg_build_config: add Default"); if ($def) { // delete blacklist entries from 'pass' if blacklist disabled if ($squidguard_config[FLD_BLACKLISTENABLED] !== 'on') { $tarray = explode(" ", $def[FLD_DESTINATIONNAME]); $varray = explode(" ", $def[FLD_OVERDESTINATIONNAME]); foreach($entry_blacklist as $entry) { $tk = array_search($entry , $tarray); if ($tk !== false) unset ($tarray[$tk]); $tk = array_search("!$entry" , $tarray); if ($tk !== false) unset ($tarray[$tk]); $tk = array_search($entry , $varray); if ($tk !== false) unset ($varray[$tk]); $tk = array_search("!$entry" , $varray); if ($tk !== false) unset ($varray[$tk]); } $def[FLD_DESTINATIONNAME] = implode (" ", $tarray); $def[FLD_OVERDESTINATIONNAME] = implode (" ", $varray); } if ($def[FLD_TIMENAME]) { // ontime $sgconf[] = "\t default within " . $def[FLD_TIMENAME] . " { "; $sgconf[] = "\t\t pass " . $def[FLD_DESTINATIONNAME]; if ($def[FLD_REDIRECT] && is_url($def[FLD_REDIRECT])) $sgconf[] = "\t\t redirect " . $redirect_base_url . "?url={$def[FLD_REDIRECT]}"; else $sgconf[] = "\t\t redirect " . $redirect_base_url; // overtime $sgconf[] = "\t } else {"; $sgconf[] = "\t\t pass " . $def[FLD_OVERDESTINATIONNAME]; if ($def[FLD_OVERREDIRECT] && is_url($def[FLD_OVERREDIRECT])) { $sgconf[] = "\t\t redirect " . $redirect_base_url . "?url={$def[FLD_OVERREDIRECT]}"; } else $sgconf[] = "\t\t redirect " . $redirect_base_url; $sgconf[] = "\t }"; } else { // without time $sgconf[] = "\t default { "; $sgconf[] = "\t\t pass " . $def[FLD_DESTINATIONNAME]; if ($def[FLD_REDIRECT] && is_url($def[FLD_REDIRECT])) { $sgconf[] = "\t\t redirect " . $redirect_base_url . "?url={$def[FLD_REDIRECT]}"; } else $sgconf[] = "\t\t redirect " . $redirect_base_url; $sgconf[] = "\t }"; } } // if def else { sg_addlog("sg_build_config: error - ACL 'default' is empty, use as default 'block all'."); $sgconf[] = "\t default { "; $sgconf[] = "\t\t pass none"; $sgconf[] = "\t\t redirect " . $redirect_base_url; $sgconf[] = "\t }"; } // --- ACL end --- $sgconf[] = "}"; return $sgconf; } // ------------------------------------------------------------ // sg_check_config_data // ------------------------------------------------------------ function sg_check_config_data () { global $squidguard_config; $check_log = array(); $times = array(); $sources = array(); $destinations = array(); $rewrites = array(); $acls = array(); // --- Times --- if ($squidguard_config[FLD_TIMES]) { foreach($squidguard_config[FLD_TIMES][FLD_ITEM] as $tm) { // check name as unique and name format $tm_name = $tm[FLD_NAME]; $s = check_name($tm_name); if ($s) $check_log[] = "TIME '$tm_name' error: $s"; $times[] = $tm_name; $key_tm = array_count_values($times); if ($key_tm[$tm_name] > 1) $check_log[] = "TIME '$tm_name' error: duplicate time name '$tm_name'"; // check time items format } } // --- Sources --- if ($squidguard_config[FLD_SOURCES]) { foreach($squidguard_config[FLD_SOURCES][FLD_ITEM] as $src) { // check name as unique and name format $src_name = $src[FLD_NAME]; $s = check_name($src_name); if ($s) $check_log[] = "SOURCE '$src_name'error: $s"; $sources[] = $src_name; $key_src = array_count_values($sources); if ($key_src[$src_name] > 1) $check_log[] = "SOURCE '$src_name' error: duplicate source name '$src_name'"; // check IP's } } // --- Destinations --- if ($squidguard_config[FLD_DESTINATIONS]) { foreach($squidguard_config[FLD_DESTINATIONS][FLD_ITEM] as $dst) { // check name as unique and name format $dst_name = $dst[FLD_NAME]; $s = check_name($dst_name); if ($s) $check_log[] = "DESTINATION '$dst_name' error: $s"; $destinations[] = $dst_name; $key_dst = array_count_values($destinations); if ($key_dst[$dst_name] > 1) $check_log[] = "DESTINATION '$dst_name' error: duplicate destination name '$dst_name'"; // check urls // check domains // check expressions // check redirection url } } // --- Blacklist --- $blk_entries_file = $squidguard_config[FLD_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[FLD_DBHOME] . "/$entr"; if (!file_exists($dbfile)) $check_log[] = "BLACKLIST '$entr' error: file '$dbfile' not found"; } } } // --- Rewrites --- if ($squidguard_config[FLD_REWRITES]) { foreach($squidguard_config[FLD_REWRITES][FLD_ITEM] as $rw) { // check check name as unique and name format $rw_name = $rw[FLD_NAME]; $s = check_name($dst_name); if ($s) $check_log[] = "REWRITE '$rw_name' error: $s"; $rewrites[] = $rw_name; $key_rw = array_count_values($rewrites); if ($key_rw[$rw_name] > 1) $check_log[] = "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[FLD_ACLS]) { $acls = array(); foreach($squidguard_config[FLD_ACLS][FLD_ITEM] as $acl) { // skip disabled acl if ($acls[FLD_DISABLED]) continue; $acl_name = $acl[FLD_NAME]; // check acl name for unique and exists (as source items) if ($acl_name and !$key_sources[$acl_name]) $check_log[] = "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) $check_log[] = "ACL '$acl_name' error: duplicate acl name '$acl_name'"; // check time $time = $acl[FLD_TIMENAME]; if ($time and !$key_times[$time]) // time name must exists $check_log[] = "ACL '$acl_name' error: time name '$time' not found"; // check destinations if ($acl[FLD_DESTINATIONNAME]) { $acldest = str_replace("!", "", $acl[FLD_DESTINATIONNAME]); $acldest = explode(" ", $acldest); $key_acldest = array_count_values($acldest); foreach($acldest as $adest) { // check duplicates destinations in acl if ($key_acldest[$adest] > 1) $check_log[] = "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]) $check_log[] = "ACL '$acl_name' error: destination name '$adest' not found"; } } else { $check_log[] = "ACL '$acl_name' error: ontime pass list is empty."; } // check overtime destinations if ($time) { if ($acl[FLD_OVERDESTINATIONNAME]) { $acloverdest = str_replace("!", "", $acl[FLD_OVERDESTINATIONNAME]); $acloverdest = explode(" ", $acloverdest); $key_acloverdest = array_count_values($acloverdest); foreach($acloverdest as $adest) { // check duplicates destinations in acl if ($key_acloverdest[$adest] > 1) $check_log[] = "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]) $check_log[] = "ACL '$acl_name' error: overtime destination name '$adest' not found"; } } else { $check_log[] = "ACL '$acl_name' error: overtime pass list is empty."; } } // check rewrite $rew = $acl[FLD_REWRITENAME]; if ($rew and !$key_rewrites[$rew]) $check_log[] = "ACL '$acl_name' error: rewrite name '$rew' not found"; // check overtime rewrite $overrew = $acl[FLD_OVERREWRITENAME]; if ($time and $overrew and !$key_rewrites[$overrew]) $check_log[] = "ACL '$acl_name' error: overtime rewrite name '$overrew' not found"; // check redirect $redir = $acl[FLD_REDIRECT]; $overredir = $acl[FLD_OVERREDIRECT]; } } // --- Default --- if ($squidguard_config[FLD_ACLS]) { $def = $squidguard_config[FLD_DEFAULT]; // check time $time = $def[FLD_TIMENAME]; if ($time and !$key_times[$time]) // time name must exists $check_log[] = "ACL 'default' error: time name '$time' not found"; // check destinations if ($def[FLD_DESTINATIONNAME]) { $defdest = str_replace("!", "", $def[FLD_DESTINATIONNAME]); $defdest = explode(" ", $defdest); $key_defdest = array_count_values($defdest); foreach($defdest as $adest) { // check duplicates destinations in acl if ($key_defdest[$adest] > 1) $check_log[] = "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]) $check_log[] = "ACL 'default' error: destination name '$adest' not found"; } } else { $check_log[] = "ACL 'default' error: ontime pass list is empty."; } // check overtime destinations if ($time) { if ($def[FLD_OVERDESTINATIONNAME]) { $defoverdest = str_replace("!", "", $def[FLD_OVERDESTINATIONNAME]); $defoverdest = explode(" ", $defoverdest); $key_defoverdest = array_count_values($defoverdest); foreach($defoverdest as $adest) { // check duplicates destinations in acl if ($key_defoverdest[$adest] > 1) $check_log[] = "ACL 'default' 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]) $check_log[] = "ACL 'default' error: overtime destination name '$adest' not found"; } } else { $check_log[] = "ACL 'default' error: overtime pass list is empty."; } } // check rewrite $rew = $def[FLD_REWRITENAME]; if ($rew and !$key_rewrites[$rew]) $check_log[] = "ACL 'default' error: rewrite name '$rew' not found"; // check overtime rewrite $overrew = $def[FLD_OVERREWRITENAME]; if ($time and $overrew and !$key_rewrites[$overrew]) $check_log[] = "ACL 'default' error: overtime rewrite name '$overrew' not found"; // check redirect $redir = $def[FLD_REDIRECT]; $overredir = $def[FLD_OVERREDIRECT]; } return implode("\n", $check_log); } // ============================================================================= // 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: start "); // 1. check system sg_check_system(); // 2. upload sg_addlog("sg_reconfigure_blacklist: begin upload from '$sf'."); if ($sf[0] === "/") { // local file - example '/tmp/blacklists.tar' if (file_exists($sf)) { $sf_contents = file_get_contents($sf); sg_addlog("sg_reconfigure_blacklist: get file '$sf'."); } else { sg_addlog("sg_reconfigure_blacklist: error get file '$sf', file not found."); return; } } else {// url sg_addlog("sg_reconfigure_blacklist: get url '$sf'."); $sf_contents = sg_uploadfile_from_url($sf, BLK_LOCALFILE, $opt); } // 3. update if (empty($sf_contents)) { sg_addlog("sg_reconfigure_blacklist: error file content '$sf'."); return; } // manually content save to local file file_put_contents(BLK_LOCALFILE, $sf_contents); sg_update_blacklist(BLK_LOCALFILE); // 4. rebuild db sg_full_rebuild_db(); sg_addlog("sg_reconfigure_blacklist: end"); } // ----------------------------------------------------------------------------- // sg_update_blacklist - update blacklist from file // ----------------------------------------------------------------------------- function sg_update_blacklist($from_file) { global $squidguard_config; $dbhome = SQUIDGUARD_DBHOME_DEF; $workdir = SQUIDGUARD_WORKDIR_DEF; if (file_exists($squidguard_config[FLD_DBHOME])) $dbhome = $squidguard_config[FLD_DBHOME]; if (file_exists($squidguard_config[FLD_WORKDIR])) $workdir = $squidguard_config[FLD_WORKDIR]; sg_addlog("sg_update_blacklist: begin '$dbhome'"); if (file_exists($from_file)) { // 1. unpack blacklist file $bl_temp = '/var/tmp/blacklists'; mwexec('tar zxvf ' . $from_file . ' -C /var/tmp/'); sg_addlog("sg_update_blacklist: unpack uploaded file $from_file -> $bl_temp"); // 2. copy blacklist to squidGuard base if (file_exists($bl_temp)) { // - copy blacklist & create entries list sg_addlog("sg_update_blacklist: create entries"); $blk_files = scan_dir($bl_temp); $blk_entries = array(); foreach($blk_files as $bf) { if (($bf != '.') && ($bf != '..')) { $blk_entries[] = $bf; mwexec("cp -Rf $bl_temp/$bf $dbhome"); sg_addlog("sg_update_blacklist: $bf"); } } // create entries list if (count($blk_entries)) { file_put_contents($workdir . SQUIDGUARD_BLK_ENTRIES, implode("\n", $blk_entries)); set_file_access($workdir . SQUIDGUARD_BLK_ENTRIES, OWNER_NAME, 0755); sg_addlog("sg_update_blacklist: create entries " . $workdir . SQUIDGUARD_BLK_ENTRIES); } sg_remove_unused_db_entries(); // clearing temp mwexec("rm -R $bl_temp"); } set_file_access($squidguard_config[FLD_DBHOME], OWNER_NAME, 0755); # sg_full_rebuild_db(); } sg_addlog("sg_update_blacklist: end"); } // ----------------------------------------------------------------------------- // sg_entries_blacklist - update blacklist from file // ----------------------------------------------------------------------------- function sg_entries_blacklist() { global $squidguard_config; $contentS = ''; $fl = SQUIDGUARD_WORKDIR_DEF . SQUIDGUARD_BLK_ENTRIES; if (file_exists($squidguard_config[FLD_WORKDIR])) $fl = $squidguard_config[FLD_WORKDIR] . SQUIDGUARD_BLK_ENTRIES; if (file_exists($fl)) { $contents = file_get_contents($fl); $contents = explode("\n", $contents); } return $contents; } # -------------------------- 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'"); $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"); // for test file_put_contents(BLK_LOCALFILE, $result); sg_addlog("sg_uploadfile_from_url: end"); return $result; } // ----------------------------------------------------------------------------- // Set file access // ----------------------------------------------------------------------------- function set_file_access($dir, $owner, $mod) { if (!file_exists($dir)) return; chown($dir, $owner); chgrp($dir, $owner); chmod($dir, $mod); if (is_dir($dir)) { $hd = opendir($dir); while (($item = readdir($hd)) !== false) { if (($item != ".") && ($item != "..")) { $path = "$dir/$item"; if (is_dir($path)) set_file_access($path, $owner, $mod); else { chown($path, $owner); chgrp($path, $owner); chmod($path, $mod); } } } } } # ============================================================================== # self utils # ============================================================================== # 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))) $files[] = $filename; sort($files); } return $files; } # ------------------------------------------------------------------------------ # is_url - build files listing for $dir # ------------------------------------------------------------------------------ function is_url($url) { if (empty($url)) return false; if (eregi("^http://", $url)) return true; if (eregi("^https://", $url)) return true; if (eregi("^([0-9]{3})", $url)) return true; // http error code 403, 404, 410, 500, return false; } # ------------------------------------------------------------------------------ # check name # ------------------------------------------------------------------------------ function check_name ($name) { $err = ''; $val = trim($name); if ((strlen($val) < 2) || (strlen($val) > 16)) $err .= " Size of name 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)) $err .= " Invalid name $name. Valid name symbols: ['a-Z', '_', '0-9', '-']. First symbol must be a letter."; return $err; } ?>