.
//
//####################################################################
//### 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[] = "
";
$reportdata[] = "
";
} else {
return "Unknown report number!";
}
$reportdata[] = "";
$reportdata[] = $row['raw_xml'];
$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[] = " IP | ";
$reportdata[] = " Host Name | ";
$reportdata[] = " Message Count | ";
$reportdata[] = " Disposition | ";
$reportdata[] = " Reason | ";
$reportdata[] = " DKIM Domain | ";
$reportdata[] = " DKIM Auth | ";
$reportdata[] = " SPF Domain | ";
$reportdata[] = " SPF Auth | ";
$reportdata[] = " DKIM Align | ";
$reportdata[] = " SPF Align | ";
$reportdata[] = " DMARC | ";
$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[] = " ". $ip. " | ";
if ( $host_lookup ) {
$reportdata[] = " ". gethostbyaddr($ip). " | ";
} else {
$reportdata[] = " #off# | ";
}
$reportdata[] = " ". $row['rcount']. " | ";
$reportdata[] = " ". $row['disposition']. " | ";
$reportdata[] = " ". $row['reason']. " | ";
$reportdata[] = " ". $row['dkimdomain']. " | ";
$reportdata[] = " ". $row['dkimresult']. " | ";
$reportdata[] = " ". $row['spfdomain']. " | ";
$reportdata[] = " ". $row['spfresult']. " | ";
$reportdata[] = " ". $row['dkim_align']. " | ";
$reportdata[] = " ". $row['spf_align']. " | ";
$reportdata[] = " " . get_dmarc_result($row)['result'] . " | ";
$reportdata[] = "
";
$reportsum += $row['rcount'];
}
$reportdata[] = " ";
$reportdata[] = " | Sum: | $reportsum | |
";
$reportdata[] = "
";
$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 .= "";
}
// 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 );
?>