]> git.rmz.io Git - dotfiles.git/commitdiff
mutt: convert dmarc reports to html and display in browser
authorSamir Benmendil <me@rmz.io>
Sat, 8 Aug 2020 11:54:12 +0000 (12:54 +0100)
committerSamir Benmendil <me@rmz.io>
Sat, 8 Aug 2020 11:54:12 +0000 (12:54 +0100)
Currently only supports doing this from the attachement view. This is ok
for now.

mutt/dmarc.xsl [new file with mode: 0644]
mutt/mailcap

diff --git a/mutt/dmarc.xsl b/mutt/dmarc.xsl
new file mode 100644 (file)
index 0000000..4c16c50
--- /dev/null
@@ -0,0 +1,327 @@
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:date="http://exslt.org/dates-and-times"
+       xmlns="http://www.w3.org/1999/xhtml">
+       <xsl:output
+               omit-xml-declaration = "yes"
+               doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
+               doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
+       <xsl:param name="source_ip_href">
+               <!-- customize this -->
+               <!-- <xsl:text>http://www.tana.it/lookup.php?host=</xsl:text> -->
+               <xsl:text>http://network-tools.com/default.asp?prog=lookup&amp;host=</xsl:text>
+               <!-- alternative examples:
+               <xsl:text>http://www.ip-adress.com/reverse_ip/</xsl:text>
+               -->
+       </xsl:param>
+       <xsl:template match="feedback">
+               <html xmlns="http://www.w3.org/1999/xhtml">
+                       <xsl:variable name="title">
+                               Feedback from
+                               <xsl:value-of select="report_metadata/org_name"/>
+                       </xsl:variable>
+                       <head>
+                               <title>
+                                       <xsl:value-of select="$title"/>
+                               </title>
+                               <style type="text/css" id="internal-style">
+                                       body {
+                                               font-family: Arial, Helvetica, sans-serif;
+                                               color: #003300;
+                                               background-color: #ffcc66;
+                                       }
+                                       table, p {
+                                               margin: 1em;
+                                               padding: 4pt;
+                                               background-color: #ffeeaa;
+                                               border: 3pt solid #776633; 
+                                       }
+                                       td, th {
+                                               margin: 2pt;
+                                               padding: 2pt;
+                                               border: 1pt solid #776633; 
+                                       }
+                                       .pass {
+                                               background-color: #11bb00;
+                                       }
+                                       .fail {
+                                               background-color: #cc0000;
+                                       }
+                                       .dkimpolicy {
+                                               background-color: #ffff66;
+                                       }
+                                       .error {
+                                               background-color: #bbaaaa;
+                                               font-weight: bold;
+                                       }
+                                       .softfail {
+                                               background-color: #ff8866;
+                                       }
+                                       .reject {
+                                               background-color: #cc0000;
+                                       }
+                                       .quarantine {
+                                               background-color: #ff8866;
+                                       }
+                                       .normal {
+                                       }
+                                       .field {
+                                               font-weight: bold;
+                                       }
+                               </style>
+                       </head>
+                       <body>
+                               <h1>
+                                       <xsl:value-of select="$title"/>
+                               </h1>
+                               <p>
+                                       <xsl:apply-templates select="report_metadata"/>
+                                       <br/>
+                                       <xsl:apply-templates select="policy_published"/>
+                               </p>
+                               <table>
+                                       <tr>
+                                               <th>
+                                                       Relaying IP
+                                               </th>
+                                               <th>
+                                                       message count
+                                               </th>
+                                               <th>
+                                                       reason and disposition
+                                               </th>
+                                               <th>
+                                                       From header
+                                                       <br/>
+                                                       (opt. envelope)
+                                               </th>
+                                               <th>
+                                                       SPF
+                                               </th>
+                                               <xsl:variable name="signatures">
+                                                       <xsl:for-each select="record/auth_results">
+                                                               <xsl:sort select="count(dkim)"
+                                                                       data-type="number" order="descending"/>
+                                                               <xsl:if test="position()=1">
+                                                                       <xsl:value-of select="count(dkim)"/>
+                                                               </xsl:if>
+                                                       </xsl:for-each>
+                                               </xsl:variable>
+                                               <xsl:if test="$signatures > 0">
+                                                       <th>
+                                                               DKIM
+                                                       </th>
+                                                       <xsl:if test="$signatures > 1">
+                                                               <th>
+                                                                       2nd DKIM
+                                                               </th>
+                                                               <xsl:if test="$signatures > 2">
+                                                                       <th>
+                                                                               3rd DKIM
+                                                                       </th>
+                                                               </xsl:if>
+                                                       </xsl:if>
+                                               </xsl:if>
+                                       </tr>
+                                       <xsl:text>
+                                       </xsl:text>
+                                       <xsl:apply-templates select="record"/>
+                               </table>
+                               <p>
+                                       <b><u>Legend</u><br/>
+                                       disposition: </b>
+                                       <span class="quarantine">quarantine</span>,
+                                       <span class="reject">reject</span>.<br/>
+                                       <b>spf: </b>
+                                       <span class="pass">pass</span>,
+                                       <span class="fail">fail</span>,
+                                       <span class="softfail">softfail</span>,
+                                       <span class="error">temperror or permerror</span>.<br/>
+                                       <b>dkim: </b>
+                                       <span class="pass">pass</span>,
+                                       <span class="fail">fail</span>,
+                                       <span class="dkimpolicy">policy</span>.
+                               </p>
+                       </body>
+               </html>
+       </xsl:template>
+       <xsl:template match="policy_published">
+               <span class="field">Domain: </span>
+               <xsl:value-of select="domain"/>
+               <xsl:text>; </xsl:text>
+               <span class="field">DKIM: </span>
+               <xsl:apply-templates select="adkim"/>
+               <xsl:text>; </xsl:text>
+               <span class="field">SPF: </span>
+               <xsl:apply-templates select="aspf"/>
+               <xsl:text>; </xsl:text>
+               <span class="field">policy published: </span>
+               <xsl:value-of select="p"/>
+               <xsl:text> </xsl:text>
+               <xsl:value-of select="sp"/>
+               <xsl:text> </xsl:text>
+               <xsl:value-of select="pct"/>
+       </xsl:template>
+       <xsl:template match="adkim|aspf">
+               <xsl:variable name="alignment">
+                       <xsl:value-of select="."/>
+               </xsl:variable>
+               <xsl:choose>
+                       <xsl:when test="$alignment='r'">
+                               <xsl:text>relaxed</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="$alignment='s'">
+                               <xsl:text>strict</xsl:text>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:text>{$alignment}</xsl:text>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+       <xsl:template match="report_metadata">
+               <span class="field">Id: </span>
+               <xsl:value-of select="report_id"/>
+               <xsl:text>; </xsl:text>
+               <span class="field">begin: </span>
+               <xsl:call-template name="date-range">
+                       <xsl:with-param name="utime" select="date_range/begin"/>
+               </xsl:call-template>
+               <xsl:text>; </xsl:text>
+               <span class="field">end: </span>
+               <xsl:call-template name="date-range">
+                       <xsl:with-param name="utime" select="date_range/end"/>
+               </xsl:call-template>
+               <xsl:for-each select="error">
+                       <xsl:if test="position()=1">
+                               <br/>
+                               <span class="field">Error: </span>
+                       </xsl:if>
+                       <span class="error">
+                               <xsl:value-of select="."/>
+                       </span>
+                       <xsl:if test="not(position()=last())">
+                               <br/>
+                       </xsl:if>
+               </xsl:for-each>
+       </xsl:template>
+       <xsl:template name="date-range">
+               <xsl:param name="utime" select="0"/>
+               <xsl:choose>
+                       <xsl:when test="function-available('date:add')">
+                               <xsl:value-of
+                                       select="date:add('1970-01-01T00:00:00', date:duration($utime))"/>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="$utime"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+       <xsl:template match="record">
+               <tr>
+                       <xsl:apply-templates select="row"/>
+                       <xsl:apply-templates select="identifiers|identities"/>
+                       <xsl:apply-templates select="auth_results"/>
+               </tr>
+               <xsl:text>
+               </xsl:text>
+       </xsl:template>
+       <xsl:template match="row">
+               <td>
+                       <a>
+                               <xsl:attribute name="href">
+                                       <xsl:value-of select="$source_ip_href"/>
+                                       <xsl:value-of select="source_ip"/>
+                               </xsl:attribute>
+                               <xsl:value-of select="source_ip"/>
+                       </a>
+               </td>
+               <td align="right">
+                       <xsl:value-of select="count"/>
+               </td>
+               <td>
+                       <xsl:attribute name="class">
+                               <xsl:variable name="disposition">
+                                       <xsl:value-of select="policy_evaluated/disposition"/>
+                               </xsl:variable>
+                               <xsl:choose>
+                                       <xsl:when test="$disposition='reject'">
+                                               <xsl:text>reject</xsl:text>
+                                       </xsl:when>
+                                       <xsl:when test="$disposition='quarantine'">
+                                               <xsl:text>quarantine</xsl:text>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:text>normal</xsl:text>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:attribute>
+                       <xsl:for-each select="policy_evaluated/reason">
+                               <xsl:value-of select="type"/>
+                               <xsl:text> </xsl:text>
+                               <xsl:value-of select="comment"/>
+                               <br/>
+                       </xsl:for-each>
+               </td>
+       </xsl:template>
+       <xsl:template match="identifiers|identities">
+               <td>
+                       <xsl:value-of select="header_from"/>
+                       <xsl:if test="count(envelope_to) &gt; 0">
+                               <br/>
+                               <xsl:value-of select="envelope_to"/>
+                       </xsl:if>
+               </td>
+       </xsl:template>
+       <xsl:template match="auth_results">
+               <xsl:apply-templates select="spf"/><!-- one -->
+               <xsl:apply-templates select="dkim"/><!-- zero or more -->
+       </xsl:template>
+       <xsl:template name="class_attribute">
+               <xsl:attribute name="class">
+                       <xsl:variable name="result">
+                               <xsl:value-of select="result"/>
+                       </xsl:variable>
+                       <xsl:choose>
+                               <xsl:when test="$result='pass'">
+                                       <xsl:text>pass</xsl:text>
+                               </xsl:when>
+                               <xsl:when test="$result='fail' or $result='hardfail'">
+                                       <xsl:text>fail</xsl:text>
+                               </xsl:when>
+                               <xsl:when test="$result='temperror' or $result='permerror'">
+                                       <xsl:text>error</xsl:text>
+                               </xsl:when>
+                               <xsl:when test="$result='policy'">
+                                       <xsl:text>dkimpolicy</xsl:text>
+                               </xsl:when>
+                               <xsl:when test="$result='softfail'">
+                                       <xsl:text>softfail</xsl:text>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:text>normal</xsl:text>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:attribute>
+       </xsl:template>
+       <xsl:template match="spf">
+               <td>
+                       <xsl:call-template name="class_attribute" />
+                       <xsl:value-of select="domain"/>
+                       <br/>
+                       <xsl:value-of select="scope"/>
+                       <br/>
+                       <xsl:value-of select="human_result"/>
+               </td>
+       </xsl:template>
+       <xsl:template match="dkim">
+               <td>
+                       <xsl:call-template name="class_attribute" />
+                       <xsl:value-of select="domain"/>
+                       <br/>
+                       <xsl:value-of select="selector"/>
+                       <br/>
+                       <xsl:value-of select="human_result"/>
+               </td>
+       </xsl:template>
+</xsl:stylesheet>
+
index 6eb73912acfd7842625eea082c0a4b330947e89d..57f82474e02f13273c8ac4305d5d03c2c497f095 100644 (file)
@@ -1,5 +1,12 @@
 text/html;       $XDG_CONFIG_HOME/mutt/mutt_bgrun qutebrowser %s; test=test -n "$DISPLAY"; nametemplate=%s.html
 text/html;       w3m -I %{charset} -dump %s -T text/html -cols "$COLUMNS" -o display_link_number=1; copiousoutput; nametemplate=%s.html
 text/calendar;   $XDG_CONFIG_HOME/mutt/ical2txt; copiousoutput
+# generate html from dmarc report, testing against *rmz.io* because all other tests were to difficult
+application/gzip; zcat  | xsltproc $XDG_CONFIG_HOME/mutt/dmarc.xsl - > /tmp/dmarc.html && qutebrowser /tmp/dmarc.html ;\
+    test=[[ '%s' == *rmz.io* ]]
+application/zip; funzip | xsltproc $XDG_CONFIG_HOME/mutt/dmarc.xsl - > /tmp/dmarc.html && qutebrowser /tmp/dmarc.html ;\
+    test=[[ '%s' == *rmz.io* ]]
+application/gzip; zcat  | xmllint --format - ; copiousoutput ; test=[[ '%s' == *rmz.io* ]]
+application/zip; funzip | xmllint --format - ; copiousoutput ; test=[[ '%s' == *rmz.io* ]]
 application/*;   $XDG_CONFIG_HOME/mutt/mutt_bgrun rifle -f F %s;
 image/*;         rifle -f F %s;