--- /dev/null
+#!/bin/sh
+# Create temporary directory
+tmpdir=$(mktemp -d)
+
+# Set trap to clean up on exit
+cleanup() {
+ rm -rf "$tmpdir"
+}
+trap cleanup EXIT
+
+# Read stdin and save as attachment
+cat > "$tmpdir/attachment"
+
+# Determine file type and extract accordingly
+filetype=$(file -b "$tmpdir/attachment")
+
+case "$filetype" in
+ *"Zip archive"*)
+ echo "Detected ZIP archive"
+ unzip -q "$tmpdir/attachment" -d "$tmpdir"
+ ;;
+ *"gzip compressed"*)
+ echo "Detected gzip compressed file"
+ gunzip -c "$tmpdir/attachment" > "$tmpdir/extracted.xml" 2>/dev/null
+ ;;
+ *"XML"*)
+ echo "Detected XML file"
+ cp "$tmpdir/attachment" "$tmpdir/extracted.xml"
+ ;;
+ *)
+ echo "Unknown file type: $filetype"
+ exit 1
+ ;;
+esac
+
+# List contents
+echo "Extracted contents:"
+ls -la "$tmpdir"
+
+# Find and display the XML file
+xml_file=$(find "$tmpdir" -name "*.xml" -type f | head -1)
+if [ -n "$xml_file" ] && [ -f "$xml_file" ]; then
+ echo -e "\n=== Generating HTML DMARC Report for $(basename "$xml_file") ==="
+
+ # Create colorful HTML XSL stylesheet
+ cat > "$tmpdir/dmarc-html.xsl" << 'EOF'
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="html" doctype-system="about:legacy-compat"/>
+<xsl:template match="/">
+<html>
+<head>
+ <title>DMARC Aggregate Report</title>
+ <style>
+ body { font-family: monospace; background: #0a0a0a; color: #e0e0e0; margin: 20px; }
+ h1 { color: #4fc3f7; border-bottom: 2px solid #4fc3f7; padding-bottom: 5px; }
+ h2 { color: #81c784; margin-top: 25px; }
+ .section { background: #1a1a1a; border: 1px solid #333; border-radius: 5px; padding: 15px; margin: 15px 0; }
+ .metadata { color: #bb86fc; }
+ .policy { color: #03dac6; }
+ .record { background: #252525; border-left: 4px solid #ff9800; padding: 10px; margin: 10px 0; }
+ .ip { color: #ff9800; font-weight: bold; }
+ .count { color: #f06292; }
+ .pass { color: #4caf50; }
+ .fail { color: #f44336; }
+ .neutral { color: #ffeb3b; }
+ .header { color: #64b5f6; }
+ table { border-collapse: collapse; width: 100%; margin: 10px 0; }
+ th { background: #333; color: #fff; padding: 8px; text-align: left; }
+ td { padding: 8px; border-bottom: 1px solid #444; }
+ tr:hover { background: #2a2a2a; }
+ .timestamp { color: #9e9e9e; font-size: 0.9em; }
+ </style>
+</head>
+<body>
+ <h1>📊 DMARC Aggregate Report</h1>
+
+ <div class="section">
+ <h2>📋 Report Metadata</h2>
+ <table>
+ <tr><th>Field</th><th>Value</th></tr>
+ <tr><td>Organization</td><td class="metadata"><xsl:value-of select="feedback/report_metadata/org_name"/></td></tr>
+ <tr><td>Report ID</td><td class="metadata"><xsl:value-of select="feedback/report_metadata/report_id"/></td></tr>
+ <tr><td>Date Range</td><td class="metadata">
+ <xsl:value-of select="feedback/report_metadata/date_range/begin"/> to
+ <xsl:value-of select="feedback/report_metadata/date_range/end"/>
+ </td></tr>
+ <tr><td>Contact Email</td><td class="metadata"><xsl:value-of select="feedback/report_metadata/email"/></td></tr>
+ </table>
+ </div>
+
+ <div class="section">
+ <h2>⚙️ Published DMARC Policy</h2>
+ <table>
+ <tr><th>Field</th><th>Value</th></tr>
+ <tr><td>Domain</td><td class="policy"><xsl:value-of select="feedback/policy_published/domain"/></td></tr>
+ <tr><td>DKIM Alignment</td><td class="policy"><xsl:value-of select="feedback/policy_published/adkim"/></td></tr>
+ <tr><td>SPF Alignment</td><td class="policy"><xsl:value-of select="feedback/policy_published/aspf"/></td></tr>
+ <tr><td>Policy</td><td class="policy"><xsl:value-of select="feedback/policy_published/p"/></td></tr>
+ <tr><td>Subdomain Policy</td><td class="policy"><xsl:value-of select="feedback/policy_published/sp"/></td></tr>
+ <tr><td>Percentage</td><td class="policy"><xsl:value-of select="feedback/policy_published/pct"/>%</td></tr>
+ </table>
+ </div>
+
+ <div class="section">
+ <h2>📨 Email Records</h2>
+ <xsl:for-each select="feedback/record">
+ <div class="record">
+ <h3>📧 Record <xsl:value-of select="position()"/></h3>
+ <table>
+ <tr><td><strong>Source IP:</strong></td><td class="ip"><xsl:value-of select="row/source_ip"/></td></tr>
+ <tr><td><strong>Message Count:</strong></td><td class="count"><xsl:value-of select="row/count"/></td></tr>
+ <tr><td><strong>Header From:</strong></td><td class="header"><xsl:value-of select="identifiers/header_from"/></td></tr>
+ </table>
+
+ <h4>Policy Evaluation:</h4>
+ <table>
+ <tr>
+ <th>Disposition</th>
+ <th>DKIM</th>
+ <th>SPF</th>
+ </tr>
+ <tr>
+ <td><span class="{row/policy_evaluated/disposition}"><xsl:value-of select="row/policy_evaluated/disposition"/></span></td>
+ <td><span class="{row/policy_evaluated/dkim}"><xsl:value-of select="row/policy_evaluated/dkim"/></span></td>
+ <td><span class="{row/policy_evaluated/spf}"><xsl:value-of select="row/policy_evaluated/spf"/></span></td>
+ </tr>
+ </table>
+
+ <h4>Authentication Results:</h4>
+ <table>
+ <tr>
+ <th>Type</th>
+ <th>Domain</th>
+ <th>Result</th>
+ <th>Selector</th>
+ </tr>
+ <tr>
+ <td>DKIM</td>
+ <td><xsl:value-of select="auth_results/dkim/domain"/></td>
+ <td><span class="{auth_results/dkim/result}"><xsl:value-of select="auth_results/dkim/result"/></span></td>
+ <td><xsl:value-of select="auth_results/dkim/selector"/></td>
+ </tr>
+ <tr>
+ <td>SPF</td>
+ <td><xsl:value-of select="auth_results/spf/domain"/></td>
+ <td><span class="{auth_results/spf/result}"><xsl:value-of select="auth_results/spf/result"/></span></td>
+ <td>—</td>
+ </tr>
+ </table>
+ </div>
+ </xsl:for-each>
+ </div>
+</body>
+</html>
+</xsl:template>
+</xsl:stylesheet>
+EOF
+
+ # Generate HTML using xsltproc (more reliable for HTML output)
+ if command -v xsltproc >/dev/null 2>&1; then
+ html_file="$tmpdir/dmarc-report.html"
+ if xsltproc -o "$html_file" "$tmpdir/dmarc-html.xsl" "$xml_file"; then
+ echo "HTML report generated: $html_file"
+
+ # Display with lynx if available
+ if command -v lynx >/dev/null 2>&1; then
+ echo -e "\n=== Displaying with lynx (press 'q' to quit) ==="
+ lynx "$html_file"
+ else
+ echo "lynx not found. HTML file saved to: $html_file"
+ echo "You can view it with: cat $html_file"
+ fi
+ else
+ echo "xsltproc failed, showing raw XML instead:" && cat "$xml_file"
+ fi
+ else
+ echo "xsltproc not found, showing raw XML:"
+ cat "$xml_file"
+ fi
+else
+ echo "No XML file found in extracted contents."
+fi
+
+# Sample XML:
+
+# <?xml version="1.0" encoding="UTF-8" ?>
+# <feedback>
+# <version>1.0</version>
+# <report_metadata>
+# <org_name>google.com</org_name>
+# <email>noreply-dmarc-support@google.com</email>
+# <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
+# <report_id>9340001457015044932</report_id>
+# <date_range>
+# <begin>1770768000</begin>
+# <end>1770854399</end>
+# </date_range>
+# </report_metadata>
+# <policy_published>
+# <domain>atxsra.org</domain>
+# <adkim>r</adkim>
+# <aspf>r</aspf>
+# <p>none</p>
+# <sp>none</sp>
+# <pct>100</pct>
+# <np>none</np>
+# </policy_published>
+# <record>
+# <row>
+# <source_ip>173.255.193.22</source_ip>
+# <count>16</count>
+# <policy_evaluated>
+# <disposition>none</disposition>
+# <dkim>pass</dkim>
+# <spf>pass</spf>
+# </policy_evaluated>
+# </row>
+# <identifiers>
+# <header_from>atxsra.org</header_from>
+# </identifiers>
+# <auth_results>
+# <dkim>
+# <domain>atxsra.org</domain>
+# <result>pass</result>
+# <selector>lin</selector>
+# </dkim>
+# <spf>
+# <domain>atxsra.org</domain>
+# <result>pass</result>
+# </spf>
+# </auth_results>
+# </record>
+# <record>
+# <row>
+# <source_ip>2600:3c00::f03c:95ff:fee2:e488</source_ip>
+# <count>23</count>
+# <policy_evaluated>
+# <disposition>none</disposition>
+# <dkim>pass</dkim>
+# <spf>pass</spf>
+# </policy_evaluated>
+# </row>
+# <identifiers>
+# <header_from>atxsra.org</header_from>
+# </identifiers>
+# <auth_results>
+# <dkim>
+# <domain>atxsra.org</domain>
+# <result>pass</result>
+# <selector>lin</selector>
+# </dkim>
+# <spf>
+# <domain>atxsra.org</domain>
+# <result>pass</result>
+# </spf>
+# </auth_results>
+# </record>
+# <record>
+# <row>
+# <source_ip>209.85.220.41</source_ip>
+# <count>3</count>
+# <policy_evaluated>
+# <disposition>none</disposition>
+# <dkim>pass</dkim>
+# <spf>fail</spf>
+# </policy_evaluated>
+# </row>
+# <identifiers>
+# <header_from>atxsra.org</header_from>
+# </identifiers>
+# <auth_results>
+# <dkim>
+# <domain>atxsra.org</domain>
+# <result>pass</result>
+# <selector>lin</selector>
+# </dkim>
+# <spf>
+# <domain>gmail.com</domain>
+# <result>pass</result>
+# </spf>
+# </auth_results>
+# </record>
+# </feedback>