function start() { $sock = new sockets(); $unix = new unix(); if (!$GLOBALS["VERBOSE"]) { $pidtime = "/etc/artica-postfix/pids/exec.mimedefang.quarantine.php.start.time"; if ($unix->file_time_min($pidtime) < 5) { return; } @unlink($pidtime); @file_put_contents($pidtime, time()); } $postgres = new postgres_sql(); $postgres->SMTP_TABLES(); $storage_path = "/var/spool/MD-Quarantine"; $unix = new unix(); $pidpath = "/etc/artica-postfix/pids/" . basename(__FILE__) . "." . __FUNCTION__ . ".pid"; $pid = @file_get_contents($pidpath); if ($unix->process_exists($pid)) { system_admin_events("Already process {$pid} running.. Aborting", __FUNCTION__, __FILE__, __LINE__, "postfix"); return; } @file_put_contents($pidpath, getmypid()); $c = 0; $q = new postgres_sql(); $q->SMTP_TABLES(); if ($handle = opendir($storage_path)) { while (false !== ($file = readdir($handle))) { if ($file == "." && $file == "..") { continue; } if (substr($file, 0, 1) == '.') { continue; } if (!preg_match("#^qdir-#", $file)) { continue; } $path = "{$storage_path}/{$file}"; if (!is_file("{$path}/ENTIRE_MESSAGE")) { continue; } import_quarantine($path); } } CleanDatabase(); }
@mkdir("{$GLOBALS["ARTICALOGDIR"]}/smtp-connections", 0755, true); @mkdir("/etc/artica-postfix/cron.1", 0755, true); @mkdir("/etc/artica-postfix/cron.2", 0755, true); $users = null; $sock = null; $unix = null; events("Memory: " . round(memory_get_usage() / 1024 / 1000, 2) . " after all declarations " . __LINE__); @mkdir("/home/artica/postfix/realtime-events"); ini_set('display_errors', 1); ini_set("log_errors", 1); ini_set('error_reporting', E_ALL); ini_set('error_prepend_string', null); ini_set('error_append_string', null); ini_set("error_log", "{$GLOBALS["ARTICALOGDIR"]}/postfix-logger.debug"); $postgres = new postgres_sql(); $postgres->SMTP_TABLES(); $pipe = fopen("php://stdin", "r"); while (!feof($pipe)) { $buffer = fgets($pipe, 4096); Parseline($buffer); $buffer = null; } fclose($pipe); events("Shutdown..."); die; function Parseline($buffer) { if (is_file("/etc/artica-postfix/DO_NOT_DETECT_POSTFIX")) { return; } $buffer = trim($buffer);
function stats_total($nopid = false) { $TimeFile = "/etc/artica-postfix/pids/exec.pflogsumm.php.stats_total.time"; $pidfile = "/etc/artica-postfix/pids/exec.pflogsumm.php.stats_total.pid"; $unix = new unix(); if (!$nopid) { if (system_is_overloaded(basename(__FILE__))) { die; } $pid = $unix->get_pid_from_file($pidfile); if ($unix->process_exists($pid, basename(__FILE__))) { $timepid = $unix->PROCCESS_TIME_MIN($pid); if ($GLOBALS["VERBOSE"]) { echo "{$pid} already executed since {$timepid}Mn\n"; } if (!$GLOBALS["FORCE"]) { if ($timepid < 14) { return; } $kill = $unix->find_program("kill"); unix_system_kill_force($pid); } } @file_put_contents($pidfile, getmypid()); if (!$GLOBALS["FORCE"]) { if (!$GLOBALS["VERBOSE"]) { $time = $unix->file_time_min($TimeFile); if ($time < 5) { echo "Current {$time}Mn, require at least 5mn\n"; return; } } } } include_once dirname(__FILE__) . "/ressources/class.postgres.inc"; $q = new postgres_sql(); $q->SMTP_TABLES(); $sql = "SELECT COUNT(*) as tcount FROM (SELECT SUM(grey) as grey, SUM(black) AS black, SUM(cnx) as cnx,cdir FROM smtpcdir_day GROUP BY cdir) as t;"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_CDIR = $ligne["tcount"]; $sql = "SELECT COUNT(*) as tcount FROM smtprefused"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SMTP_REFUSED = $ligne["tcount"]; if ($GLOBALS["VERBOSE"]) { echo "{$GLOBALS["BASEDIR"]}/SMTP_REFUSED ->{$SMTP_REFUSED}\n"; } @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_REFUSED", $SMTP_REFUSED); $sql = "SELECT COUNT(*) as tcount FROM (SELECT SUM(grey) as grey, SUM(black) AS black, SUM(cnx) as cnx,domain FROM smtpstats_day GROUP BY domain) as t;"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_DOMAINS = $ligne["tcount"]; if ($GLOBALS["VERBOSE"]) { echo "{$GLOBALS["BASEDIR"]}/SMTP_SUM_CDIR ->{$SUM_CDIR}\n"; } @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_CDIR", $SUM_CDIR); if ($GLOBALS["VERBOSE"]) { echo "{$GLOBALS["BASEDIR"]}/SMTP_SUM_DOMAINS ->{$SUM_DOMAINS}\n"; } @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_DOMAINS", $SUM_DOMAINS); $sql = "SELECT COUNT(*) as tcount,SUM(size) as size FROM smtpstats"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_TRANSCATS = $ligne["tcount"]; $SUM_SIZE = $ligne["size"]; if ($GLOBALS["VERBOSE"]) { echo "{$GLOBALS["BASEDIR"]}/SUM_TRANSCATS ->{$SUM_TRANSCATS}\n"; } if ($GLOBALS["VERBOSE"]) { echo "{$GLOBALS["BASEDIR"]}/SUM_TRANSCATS_SIZE ->{$SUM_SIZE}\n"; } @file_put_contents("{$GLOBALS["BASEDIR"]}/SUM_TRANSCATS", $SUM_TRANSCATS); @file_put_contents("{$GLOBALS["BASEDIR"]}/SUM_TRANSCATS_SIZE", $SUM_SIZE); $sql = "SELECT COUNT(*) as tcount FROM smtprefused"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_REFUSED = $ligne["tcount"]; @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_REFUSED", $SUM_REFUSED); $sql = "SELECT COUNT(*) as tcount, SUM(size) as size FROM backupmsg"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_BACK = $ligne["tcount"]; $SUM_BACKSIZE = $ligne["size"]; @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_BACK", $SUM_BACK); @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_BACKSIZE", $SUM_BACKSIZE); $sql = "SELECT COUNT(*) as tcount, SUM(size) as size FROM quarmsg"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_BACK = $ligne["tcount"]; $SUM_BACKSIZE = $ligne["size"]; @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_QUAR", $SUM_BACK); @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_QUARSIZE", $SUM_BACKSIZE); $sql = "SELECT COUNT(*) as tcount, SUM(size) as size FROM attachstats"; $ligne = pg_fetch_array($q->QUERY_SQL($sql)); if (!$q->ok) { echo $q->mysql_error . "\n"; } $SUM_BACK = $ligne["tcount"]; $SUM_BACKSIZE = $ligne["size"]; @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_ATTACH", $SUM_BACK); @file_put_contents("{$GLOBALS["BASEDIR"]}/SMTP_SUM_ATTACHSIZE", $SUM_BACKSIZE); }
function xrun() { $unix = new unix(); if (!$GLOBALS["FORCE"]) { $pidfile = "/etc/artica-postfix/pids/" . basename(__FILE__) . "." . __FUNCTION__ . ".pid"; $TimeFile = "/etc/artica-postfix/pids/exec.mimedefangToPostGresql.php.xrun.time"; $me = basename(__FILE__); $pid = @file_get_contents($pidfile); if ($unix->process_exists($pid, $me)) { events("Already executed.. {$pid} aborting the process", __LINE__); if ($GLOBALS["VERBOSE"]) { echo " --> Already executed.. {$pid} aborting the process\n"; } return; } @file_put_contents($pidfile, getmypid()); $TimeExec = $unix->file_time_min($TimeFile); if ($TimeExec < 3) { events("{$TimeExec}mn, require 3mn", __LINE__); return; } } @unlink($TimeFile); @file_put_contents($TimeFile, time()); $q = new mysql(); $Countrows = $q->COUNT_ROWS("mimedefang_stats", "artica_backup"); events("mimedefang_stats = {$Countrows}", __LINE__); if ($Countrows == 0) { $q2 = new postgres_sql(); $q2->SMTP_TABLES(); return AttachStats(); } $q2 = new postgres_sql(); $q2->SMTP_TABLES(); $results = $q->QUERY_SQL("SELECT * FROM mimedefang_stats", "artica_backup"); $prefix = "INSERT INTO smtpstats (zmd5,zdate,mailfrom,domainfrom,mailto,domainto,subject,size,spamscore,spamreport,disclaimer,backuped,infected,filtered,whitelisted,compressed,stripped) VALUES "; $f = array(); while ($ligne = @mysql_fetch_array($results, MYSQL_ASSOC)) { $mailfrom = $ligne["mailfrom"]; $mailfrom = str_replace("<", "", $mailfrom); $mailfrom = str_replace(">", "", $mailfrom); $zdate = $ligne["zdate"]; $mailto = $ligne["mailto"]; $mailto = str_replace("<", "", $mailto); $mailto = str_replace(">", "", $mailto); $domainfrom = $ligne["domainfrom"]; $domainto = $ligne["domainto"]; $subject = trim($ligne["subject"]); $subject = str_replace("'", "`", $subject); $subject = str_replace("\"", "`", $subject); $subject = utf8_encode($subject); $size = intval($ligne["size"]); $spamscore = intval($ligne["spamscore"]); $disclaimer = intval($ligne["disclaimer"]); $backuped = intval($ligne["backuped"]); $infected = intval($ligne["infected"]); $filtered = intval($ligne["filtered"]); $whitelisted = intval($ligne["whitelisted"]); $compressed = intval($ligne["compressed"]); $stripped = intval($ligne["stripped"]); $spamreport = $ligne["spamreport"]; $zmd5 = md5(serialize($ligne)); $zdateFinale = $zdate; $f[] = "('{$zmd5}','{$zdate}','{$mailfrom}','{$domainfrom}','{$mailto}','{$domainto}','{$subject}','{$size}','{$spamscore}','{$spamreport}','{$disclaimer}','{$backuped}','{$infected}','{$filtered}','{$whitelisted}','{$compressed}','{$stripped}')"; if (count($f) > 500) { events("mimedefang_stats = Inserting " . count($f), __LINE__); $q2->QUERY_SQL($prefix . @implode(",", $f) . " ON CONFLICT DO NOTHING"); if (!$q2->ok) { events("{$q2->mysql_error}", __LINE__); echo $q2->mysql_error . "\n" . $prefix . @implode(",", $f) . " ON CONFLICT DO NOTHING\n"; AttachStats(); return; } $f = array(); } } if (count($f) > 0) { events("mimedefang_stats = Inserting " . count($f), __LINE__); $q2->QUERY_SQL($prefix . @implode(",", $f) . " ON CONFLICT DO NOTHING"); if (!$q2->ok) { events("{$q2->mysql_error}", __LINE__); AttachStats(); return; } } events("DELETE FROM mimedefang_stats WHERE zdate<='{$zdateFinale}'", __LINE__); $q->QUERY_SQL("DELETE FROM mimedefang_stats WHERE zdate<='{$zdateFinale}'", "artica_backup"); if (!$q->ok) { events("{$q->mysql_error}", __LINE__); echo $q->mysql_error . "\n"; } AttachStats(); }
function connect_from($logpath) { $unix = new unix(); smtpstats_day_migrate_to_postgres(); smtpcdir_day_migrate_to_postgres(); smtpsum_day_migrate_to_postgres(); smtpgraph_day_migrate_to_postgres(); smtpdeliver_day_migrate_to_postgres(); smtpsenders_day_migrate_to_postgres(); smtprecipients_day_migrate_to_postgres(); $q = new postgres_sql(); $q->SMTP_TABLES(); $grep = $unix->find_program("grep"); $tmpfile = $unix->FILE_TEMP(); shell_exec("{$grep} -e \"smtpd.*: connect from\" {$logpath} >{$tmpfile}"); $fp = @fopen($tmpfile, "r"); if (!$fp) { return false; } $t = array(); $fam = new familysite(); while (!feof($fp)) { $line = trim(fgets($fp, 4096)); $line = str_replace("\r\n", "", $line); $line = str_replace("\n", "", $line); $line = str_replace("\r", "", $line); $line = trim($line); if (!preg_match("#^(.+?)\\s+([0-9]+)\\s+([0-9:]+)\\s+.*?\\[[0-9]+\\]:\\s+connect from\\s+(.+?)\\[([0-9\\.]+)\\]#", $line, $re)) { continue; } $date = strtotime("{$re[1]} {$re[2]} {$re[3]}"); $ipaddr = $re[5]; $day = date("Y-m-d", $date); $NETZ = explode(".", $ipaddr); $network = "{$NETZ[0]}.{$NETZ[1]}.{$NETZ[2]}.0/24"; $hostname = $re[4]; $familysite = $fam->GetFamilySites($hostname); if (!isset($MAINNETS[$day][$network]["CNX"])) { $MAINNETS[$day][$network]["CNX"] = 1; } else { $MAINNETS[$day][$network]["CNX"] = $MAINNETS[$day][$network]["CNX"] + 1; } if (!isset($MAINNETS[$day][$network]["FAM"][$familysite])) { $MAINNETS[$day][$network]["FAM"][$familysite] = 1; } else { $MAINNETS[$day][$network]["FAM"][$familysite] = $MAINNETS[$day][$network]["FAM"][$familysite] + 1; } if (!isset($MAIN[$day][$familysite]["IPS"][$ipaddr])) { $MAIN[$day][$familysite]["IPS"][$ipaddr] = 1; } else { $MAIN[$day][$familysite]["IPS"][$ipaddr] = $MAIN[$day][$familysite]["IPS"][$ipaddr] + 1; } if (!isset($MAIN[$day][$familysite]["COUNT"])) { $MAIN[$day][$familysite]["COUNT"] = 1; } else { $MAIN[$day][$familysite]["COUNT"] = $MAIN[$day][$familysite]["COUNT"] + 1; } if (!isset($MAIN[$day][$familysite]["HOSTS"][$hostname])) { $MAIN[$day][$familysite]["HOSTS"][$hostname] = 1; } else { $MAIN[$day][$familysite]["HOSTS"][$hostname] = $MAIN[$day][$familysite]["HOSTS"][$hostname] + 1; } //echo date("Y-m-d")." $hostname $ipaddr\n"; } @fclose($fp); @unlink($tmpfile); shell_exec("{$grep} -e \"NOQUEUE: milter-reject: RCPT from\" {$logpath} >{$tmpfile}"); $fp = @fopen($tmpfile, "r"); if (!$fp) { return false; } while (!feof($fp)) { $line = trim(fgets($fp, 4096)); $line = str_replace("\r\n", "", $line); $line = str_replace("\n", "", $line); $line = str_replace("\r", "", $line); $line = trim($line); if (!preg_match("#^(.+?)\\s+([0-9]+)\\s+([0-9:]+)\\s+.*?\\[[0-9]+\\]:\\s+NOQUEUE: milter-reject: RCPT from\\s+(.*?)\\[([0-9\\.]+)\\]:\\s+([0-9]+)\\s+#", $line, $re)) { echo "NO MATCH {$line}\n"; continue; } $date = strtotime("{$re[1]} {$re[2]} {$re[3]}"); $hostname = $re[4]; $ipaddr = $re[5]; $CODE = $re[6]; $day = date("Y-m-d", $date); $familysite = $fam->GetFamilySites($hostname); $NETZ = explode(".", $ipaddr); $network = "{$NETZ[0]}.{$NETZ[1]}.{$NETZ[2]}.0/24"; if (!isset($MAINNETS[$day][$network]["FAM"][$familysite])) { $MAINNETS[$day][$network]["FAM"][$familysite] = 1; } else { $MAINNETS[$day][$network]["FAM"][$familysite] = $MAINNETS[$day][$network]["FAM"][$familysite] + 1; } if ($CODE == 451) { if (!isset($MAINNETS[$day][$network]["GREY"])) { $MAINNETS[$day][$network]["GREY"] = 1; } else { $MAINNETS[$day][$network]["GREY"] = $MAINNETS[$day][$network]["GREY"] + 1; } if (!isset($MAIN[$day][$familysite]["GREY"])) { $MAIN[$day][$familysite]["GREY"] = 1; } else { $MAIN[$day][$familysite]["GREY"] = $MAIN[$day][$familysite]["GREY"] + 1; } } if ($CODE == 551) { if (!isset($MAIN[$day][$familysite]["BLACK"])) { $MAIN[$day][$familysite]["BLACK"] = 1; } else { $MAIN[$day][$familysite]["BLACK"] = $MAIN[$day][$familysite]["BLACK"] + 1; } if (!isset($MAINNETS[$day][$network]["BLACK"])) { $MAINNETS[$day][$network]["BLACK"] = 1; } else { $MAINNETS[$day][$network]["BLACK"] = $MAINNETS[$day][$network]["BLACK"] + 1; } } } @fclose($fp); @unlink($tmpfile); shell_exec("{$grep} -e \"NOQUEUE: reject: RCPT from\" {$logpath} >{$tmpfile}"); $fp = @fopen($tmpfile, "r"); if (!$fp) { return false; } while (!feof($fp)) { $line = trim(fgets($fp, 4096)); $line = str_replace("\r\n", "", $line); $line = str_replace("\n", "", $line); $line = str_replace("\r", "", $line); $line = trim($line); if (!preg_match("#^(.+?)\\s+([0-9]+)\\s+([0-9:]+)\\s+.*?\\[[0-9]+\\]:\\s+NOQUEUE: reject: RCPT from\\s+(.*?)\\[([0-9\\.]+)\\]:\\s+([0-9]+)\\s+#", $line, $re)) { echo "NO MATCH {$line}\n"; continue; } $date = strtotime("{$re[1]} {$re[2]} {$re[3]}"); $hostname = $re[4]; $ipaddr = $re[5]; $CODE = $re[6]; $day = date("Y-m-d", $date); $familysite = $fam->GetFamilySites($hostname); $NETZ = explode(".", $ipaddr); $network = "{$NETZ[0]}.{$NETZ[1]}.{$NETZ[2]}.0/24"; if ($CODE == 551 or $CODE == 554) { if (!isset($MAIN[$day][$familysite]["BLACK"])) { $MAIN[$day][$familysite]["BLACK"] = 1; } else { $MAIN[$day][$familysite]["BLACK"] = $MAIN[$day][$familysite]["BLACK"] + 1; } if (!isset($MAINNETS[$day][$network]["BLACK"])) { $MAINNETS[$day][$network]["BLACK"] = 1; } else { $MAINNETS[$day][$network]["BLACK"] = $MAINNETS[$day][$network]["BLACK"] + 1; } } } @fclose($fp); @unlink($tmpfile); $prefix = "INSERT INTO smtpstats_day (zmd5,zdate,domain,grey,black,cnx,hosts,ips,infos) VALUES "; $q = new postgres_sql(); while (list($zDate, $ARRAY) = each($MAIN)) { while (list($domain, $INFOS) = each($ARRAY)) { $GREY = 0; if (!isset($INFOS["BLACK"])) { $INFOS["BLACK"] = 0; } if (!isset($INFOS["GREY"])) { $INFOS["GREY"] = 0; } $HOSTS = count($INFOS["HOSTS"]); $IPS = count($INFOS["IPS"]); $BLACK = intval($INFOS["BLACK"]); $CNX = intval($INFOS["COUNT"]); $INFO["IPS"] = $INFOS["IPS"]; $INFO["HOSTS"] = $INFOS["HOSTS"]; $infotext = mysql_escape_string2(serialize($INFO)); if ($GLOBALS["VERBOSE"]) { echo "{$zDate}: {$domain} hosts:{$HOSTS} ips:{$IPS} blacklisted:{$BLACK} greylisted:{$GREY} cnx:{$CNX} {$infotext}\n"; } $md5 = md5("{$zDate}{$domain}{$HOSTS}{$IPS}{$BLACK}{$GREY}{$CNX}{$infotext}"); $f[] = "('{$md5}','{$zDate}','{$domain}','{$GREY}','{$BLACK}','{$CNX}','{$HOSTS}','{$IPS}','{$infotext}')"; if (count($f) > 500) { $q->QUERY_SQL($prefix . @implode(",", $f) . " ON CONFLICT DO NOTHING"); if (!$q->ok) { echo $q->mysql_error . "\n"; return; } $f = array(); } } } if (count($f) > 0) { $q->QUERY_SQL($prefix . @implode(",", $f), "artica_events"); if (!$q->ok) { echo $q->mysql_error . "\n"; return; } $f = array(); } $prefix = "INSERT INTO smtpcdir_day (zmd5,zdate,cdir,grey,black,cnx,domains,infos) VALUES "; $q = new postgres_sql(); $q->SMTP_TABLES(); while (list($zDate, $ARRAY) = each($MAINNETS)) { while (list($CDIR, $INFOS) = each($ARRAY)) { if (!isset($INFOS["BLACK"])) { $INFOS["BLACK"] = 0; } if (!isset($INFOS["GREY"])) { $INFOS["GREY"] = 0; } $CNX = intval($INFOS["CNX"]); $GREY = intval($INFOS["GREY"]); $BLACK = intval($INFOS["BLACK"]); $DOMAINS = intval($INFOS["FAM"]); $infotext = mysql_escape_string2(serialize($INFOS["FAM"])); echo "{$zDate} {$CDIR} cnx:{$CNX} greylisted:{$GREY} blacklisted:{$BLACK} domains:{$DOMAINS}\n"; $md5 = md5("{$zDate}{$CDIR}{$DOMAINS}{$BLACK}{$GREY}{$CNX}{$infotext}"); $f[] = "('{$md5}','{$zDate}','{$CDIR}','{$GREY}','{$BLACK}','{$CNX}','{$DOMAINS}','{$infotext}')"; if (count($f) > 500) { $q->QUERY_SQL($prefix . @implode(",", $f) . " ON CONFLICT DO NOTHING"); if (!$q->ok) { echo $q->mysql_error . "\n"; return; } $f = array(); } } } if (count($f) > 0) { $q->QUERY_SQL($prefix . @implode(",", $f), "artica_events"); if (!$q->ok) { echo $q->mysql_error . "\n"; return; } $f = array(); } return true; //print_r($MAINNETS); }