. // //#################################################################### //### configuration ################################################## //#################################################################### // Copy dmarcts-report-viewer-config.php.sample to // dmarcts-report-viewer-config.php and edit with the appropriate info // for your database authentication and location. // // Edit the configuration variables in dmarcts-report-viewer.js with your preferences. // // //#################################################################### //### functions ###################################################### //#################################################################### function tmpl_reportData($reportnumber, $reports, $host_lookup = 1) { global $dmarc_where; global $cookie_options; $title_message = "Click to toggle sort direction by this column"; if (!$reportnumber) { return ""; } $reportdata[] = ""; $reportdata[] = ""; $reportdata[] = ""; $reportsum = 0; if (isset($reports[$reportnumber])) { $row = $reports[$reportnumber]; $row['raw_xml'] = formatXML($row['raw_xml'], $reportnumber); $reportdata[] = "
"; $reportdata[] = "
Report from ".$row['org']." for ".$row['domain']."
". format_date($row['mindate'], $cookie_options['date_format']). " to ".format_date($row['maxdate'], $cookie_options['date_format'])."
Policies: adkim=" . $row['policy_adkim'] . ", aspf=" . $row['policy_aspf'] . ", p=" . $row['policy_p'] . ", sp=" . $row['policy_sp'] . ", pct=" . $row['policy_pct'] . "
"; $reportdata[] = "
Show Raw Report XML
"; $reportdata[] = "
"; } else { return "Unknown report number!"; } $reportdata[] = ""; $reportdata[] = "
"; if ( $cookie_options['dmarc_results_matching_only'] ) { $reportdata[] = "\"Show Only Matching Report Data records\" option is \"On\".
Some report records may not be displayed."; } $reportdata[] = ""; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; global $dbtype; global $dbh; $sql = " SELECT *, (CASE WHEN dkim_align = 'fail' THEN 0 WHEN dkim_align = 'pass' THEN 1 ELSE 3 END) + (CASE WHEN spf_align = 'fail' THEN 0 WHEN spf_align = 'pass' THEN 1 ELSE 3 END) AS dmarc_result_min, (CASE WHEN dkim_align = 'fail' THEN 0 WHEN dkim_align = 'pass' THEN 1 ELSE 3 END) + (CASE WHEN spf_align = 'fail' THEN 0 WHEN spf_align = 'pass' THEN 1 ELSE 3 END) AS dmarc_result_max FROM rptrecord WHERE serial = " . $reportnumber . ( $dmarc_where ? " AND $dmarc_where" : "" ) . " ORDER BY ip ASC "; $query = $dbh->query($sql); foreach($query as $row) { if ( $row['ip'] ) { $ip = long2ip($row['ip']); } elseif ( $row['ip6'] ) { if ( $dbtype == 'pgsql') { $row['ip6'] = stream_get_contents($row['ip6']); } $ip = inet_ntop($row['ip6']); } else { $ip = "-"; } /* escape html characters after exploring binary values, which will be messed up */ $row = array_map('html_escape', $row); $reportdata[] = " "; $reportdata[] = " "; if ( $host_lookup ) { $reportdata[] = " "; } else { $reportdata[] = " "; } $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportdata[] = " "; $reportsum += $row['rcount']; } $reportdata[] = " "; $reportdata[] = ""; $reportdata[] = "
IPHost
Name
Message
Count
DispositionReasonDKIM
Domain
DKIM
Auth
SPF
Domain
SPF
Auth
DKIM
Align
SPF
Align
DMARC
". $ip. "". gethostbyaddr($ip). "#off#". $row['rcount']. "". $row['disposition']. "". $row['reason']. "". $row['dkimdomain']. "". $row['dkimresult']. "". $row['spfdomain']. "". $row['spfresult']. "". $row['dkim_align']. "". $row['spf_align']. "" . get_dmarc_result($row)['result'] . "
Sum:$reportsum
"; $reportdata[] = "
"; $reportdata[] = ""; #indent generated html by 2 extra spaces return implode("\n ",$reportdata); } function formatXML($raw_xml, $reportnumber) { global $dbh; $out = ""; $html = ""; $sql = " SELECT MIN(id) AS id_min, MAX(id) AS id_max FROM rptrecord WHERE serial = $reportnumber; "; $query = $dbh->query($sql); foreach($query as $row) { $id_min = $row['id_min']; $id_max = $row['id_max']; } $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($raw_xml); // Extract and print from raw_xml, if it matches the regex pattern. if (preg_match("/<\?xml([^?>]*)\?>/", $raw_xml, $matches)) { $html .= "
" . htmlspecialchars($matches[0]) . "
"; } // Extract and print root from raw_xml. $root = $dom->firstChild; if (preg_match("/<". $root->localName ."([^>]*)>/", $raw_xml, $matches)) { $html .= "
" . htmlspecialchars($matches[0]) . "
"; } // Print all child nodes foreach ($root->childNodes as $element) { $out = $dom->saveXML($element); $out = htmlspecialchars($out); $elementName = $element->localName; // If element is a 'record', append database id to unique HTML id if ($elementName === "record") { $elementName .= $id_min; $id_min++; } $html .= "
" . $out . "
"; } // Extract closing
from raw_xml. if (preg_match("/<\/". $root->localName .">/", $raw_xml, $matches)) { $html .= "
" . htmlspecialchars($matches[0]) . "
"; } return $html; } //#################################################################### //### main ########################################################### //#################################################################### // These files are expected to be in the same folder as this script, and must exist. include "dmarcts-report-viewer-config.php"; include "dmarcts-report-viewer-common.php"; // Get all configuration options // -------------------------------------------------------------------------- configure(); // Parameters of GET // -------------------------------------------------------------------------- if(isset($_GET['report']) && is_numeric($_GET['report'])){ $reportid=$_GET['report']+0; }elseif(!isset($_GET['report'])){ $reportid=false; }else{ die('Invalid Report ID'); } if(isset($_GET['hostlookup']) && is_numeric($_GET['hostlookup'])){ $hostlookup=$_GET['hostlookup']+0; }elseif(!isset($_GET['hostlookup'])){ $hostlookup= isset( $default_lookup ) ? $default_lookup : 1; }else{ die('Invalid hostlookup flag'); } if(isset($_GET['sortorder']) && is_numeric($_GET['sortorder'])){ $sortorder=$_GET['sortorder']+0; }elseif(!isset($_GET['sortorder'])){ $sortorder= isset( $default_sort ) ? $default_sort : 1; }else{ die('Invalid sortorder flag'); } if( $cookie_options['dmarc_results_matching_only'] && isset($_GET['dmarc']) ) { $dmarc_select=$_GET['dmarc']; }else{ $dmarc_select= ''; } if( $dmarc_select == "all" ) { $dmarc_select= ''; } // Debug //echo "
D=$dom_select
O=$org_select
"; // Make a DB Connection // -------------------------------------------------------------------------- $dbh = connect_db($dbtype, $dbhost, $dbport, $dbname, $dbuser, $dbpass); // // Get allowed reports and cache them - using serial as key // -------------------------------------------------------------------------- $reports = array(); // set sort direction // -------------------------------------------------------------------------- $sort = ''; if( $sortorder ) { $sort = "ASC"; } else { $sort = "DESC"; } // DMARC // dkimresult spfresult // -------------------------------------------------------------------------- switch ($dmarc_select) { case "DMARC_PASS": // DKIM and SPF Pass: Green $dmarc_where = "(rptrecord.dkimresult='pass' AND rptrecord.spfresult='pass')"; break; case "DMARC_PASS_AND_FAIL": // DKIM or SPF Fail: Orange $dmarc_where = "(rptrecord.dkimresult='fail' OR rptrecord.spfresult='fail')"; break; case "DMARC_FAIL": // DKIM and SPF Fail: Red $dmarc_where = "(rptrecord.dkimresult='fail' AND rptrecord.spfresult='fail')"; break; case "DMARC_OTHER_CONDITION": // Other condition: Yellow $dmarc_where = "NOT ((rptrecord.dkimresult='pass' AND rptrecord.spfresult='pass') OR (rptrecord.dkimresult='fail' OR rptrecord.spfresult='fail') OR (rptrecord.dkimresult='fail' AND rptrecord.spfresult='fail'))"; // In other words, "NOT" all three other conditions break; default: break; } // Include the rcount via left join, so we do not have to make an sql query // for every single report. // -------------------------------------------------------------------------- $sql = " SELECT * FROM report WHERE serial = " . $dbh->quote($reportid) ; // Debug // echo "
Data Report sql: $sql
"; $query = $dbh->query($sql); foreach($query as $row) { if (true) { //add data by serial $reports[$row['serial']] = $row; } } // Generate Page with report list and report data (if a report is selected). // -------------------------------------------------------------------------- echo tmpl_reportData($reportid, $reports, $hostlookup ); ?>