Files
parsedmarc/docs/_build/html/index.html
Sean Whalen 713ce48b85 3.5.0
2018-06-10 12:30:27 -04:00

1085 lines
83 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to parsedmarcs documentation! &mdash; parsedmarc 3.5.0 documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<script src="_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="#" class="icon icon-home"> parsedmarc
</a>
<div class="version">
3.5.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"><ul>
<li><a class="reference internal" href="#">Welcome to parsedmarcs documentation!</a><ul>
<li><a class="reference internal" href="#features">Features</a></li>
<li><a class="reference internal" href="#cli-help">CLI help</a></li>
<li><a class="reference internal" href="#spf-and-dmarc-record-validation">SPF and DMARC record validation</a></li>
<li><a class="reference internal" href="#sample-aggregate-report-output">Sample aggregate report output</a><ul>
<li><a class="reference internal" href="#json">JSON</a></li>
<li><a class="reference internal" href="#csv">CSV</a></li>
</ul>
</li>
<li><a class="reference internal" href="#sample-forensic-report-output">Sample forensic report output</a></li>
<li><a class="reference internal" href="#bug-reports">Bug reports</a></li>
<li><a class="reference internal" href="#installation">Installation</a><ul>
<li><a class="reference internal" href="#optional-dependencies">Optional dependencies</a></li>
<li><a class="reference internal" href="#elasticsearch-and-kibana">Elasticsearch and Kibana</a></li>
<li><a class="reference internal" href="#running-parsedmarc-as-a-systemd-service">Running parsedmarc as a systemd service</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-parsedmarc">API</a><ul>
<li><a class="reference internal" href="#module-parsedmarc.elastic">parsedmarc.elastic</a></li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="#">parsedmarc</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="#">Docs</a> &raquo;</li>
<li>Welcome to parsedmarcs documentation!</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/index.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="welcome-to-parsedmarc-s-documentation">
<h1>Welcome to parsedmarcs documentation!<a class="headerlink" href="#welcome-to-parsedmarc-s-documentation" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="https://travis-ci.org/domainaware/parsedmarc"><img alt="Build Status" src="https://travis-ci.org/domainaware/parsedmarc.svg?branch=master" /></a></p>
<a class="reference external image-reference" href="_static/screenshots/dmarc-summary-charts.png"><img alt="A screenshot of DMARC summary charts in Kibana" class="align-center" src="_images/dmarc-summary-charts.png" style="width: 597.0px; height: 381.0px;" /></a>
<p><code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> is a Python module and CLI utility for parsing DMARC reports.</p>
<div class="section" id="features">
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Parses draft and 1.0 standard aggregate reports</li>
<li>Parses forensic reports</li>
<li>Can parse reports from an inbox over IMAP</li>
<li>Transparently handles gzip or zip compressed reports</li>
<li>Consistent data structures</li>
<li>Simple JSON and/or CSV output</li>
<li>Optionally email the results</li>
<li>Optionally send the results to Elasticsearch, for use with premade Kibana dashboards</li>
</ul>
</div>
<div class="section" id="cli-help">
<h2>CLI help<a class="headerlink" href="#cli-help" title="Permalink to this headline"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">usage</span><span class="p">:</span> <span class="n">parsedmarc</span> <span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">o</span> <span class="n">OUTPUT</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">n</span> <span class="n">NAMESERVERS</span> <span class="p">[</span><span class="n">NAMESERVERS</span> <span class="o">...</span><span class="p">]]</span>
<span class="p">[</span><span class="o">-</span><span class="n">t</span> <span class="n">TIMEOUT</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">H</span> <span class="n">HOST</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">u</span> <span class="n">USER</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">p</span> <span class="n">PASSWORD</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">r</span> <span class="n">REPORTS_FOLDER</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">a</span> <span class="n">ARCHIVE_FOLDER</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">d</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">E</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="o">...</span><span class="p">]]]</span>
<span class="p">[</span><span class="o">--</span><span class="n">save</span><span class="o">-</span><span class="n">aggregate</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="n">save</span><span class="o">-</span><span class="n">forensic</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">O</span> <span class="n">OUTGOING_HOST</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">U</span> <span class="n">OUTGOING_USER</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">P</span> <span class="n">OUTGOING_PASSWORD</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">F</span> <span class="n">OUTGOING_FROM</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">T</span> <span class="n">OUTGOING_TO</span> <span class="p">[</span><span class="n">OUTGOING_TO</span> <span class="o">...</span><span class="p">]]</span> <span class="p">[</span><span class="o">-</span><span class="n">S</span> <span class="n">OUTGOING_SUBJECT</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">A</span> <span class="n">OUTGOING_ATTACHMENT</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">M</span> <span class="n">OUTGOING_MESSAGE</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">w</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="n">test</span><span class="p">]</span>
<span class="p">[</span><span class="o">-</span><span class="n">s</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="n">debug</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">v</span><span class="p">]</span>
<span class="p">[</span><span class="n">file_path</span> <span class="p">[</span><span class="n">file_path</span> <span class="o">...</span><span class="p">]]</span>
<span class="n">Parses</span> <span class="n">DMARC</span> <span class="n">reports</span>
<span class="n">positional</span> <span class="n">arguments</span><span class="p">:</span>
<span class="n">file_path</span> <span class="n">one</span> <span class="ow">or</span> <span class="n">more</span> <span class="n">paths</span> <span class="n">to</span> <span class="n">aggregate</span> <span class="ow">or</span> <span class="n">forensic</span> <span class="n">report</span>
<span class="n">files</span> <span class="ow">or</span> <span class="n">emails</span>
<span class="n">optional</span> <span class="n">arguments</span><span class="p">:</span>
<span class="o">-</span><span class="n">h</span><span class="p">,</span> <span class="o">--</span><span class="n">help</span> <span class="n">show</span> <span class="n">this</span> <span class="n">help</span> <span class="n">message</span> <span class="ow">and</span> <span class="n">exit</span>
<span class="o">-</span><span class="n">o</span> <span class="n">OUTPUT</span><span class="p">,</span> <span class="o">--</span><span class="n">output</span> <span class="n">OUTPUT</span>
<span class="n">Write</span> <span class="n">output</span> <span class="n">files</span> <span class="n">to</span> <span class="n">the</span> <span class="n">given</span> <span class="n">directory</span>
<span class="o">-</span><span class="n">n</span> <span class="n">NAMESERVERS</span> <span class="p">[</span><span class="n">NAMESERVERS</span> <span class="o">...</span><span class="p">],</span> <span class="o">--</span><span class="n">nameservers</span> <span class="n">NAMESERVERS</span> <span class="p">[</span><span class="n">NAMESERVERS</span> <span class="o">...</span><span class="p">]</span>
<span class="n">nameservers</span> <span class="n">to</span> <span class="n">query</span> <span class="p">((</span><span class="n">Default</span> <span class="ow">is</span> <span class="n">Cloudflare</span><span class="s1">&#39;s))</span>
<span class="o">-</span><span class="n">t</span> <span class="n">TIMEOUT</span><span class="p">,</span> <span class="o">--</span><span class="n">timeout</span> <span class="n">TIMEOUT</span>
<span class="n">number</span> <span class="n">of</span> <span class="n">seconds</span> <span class="n">to</span> <span class="n">wait</span> <span class="k">for</span> <span class="n">an</span> <span class="n">answer</span> <span class="kn">from</span> <span class="nn">DNS</span>
<span class="p">(</span><span class="n">default</span> <span class="mf">6.0</span><span class="p">)</span>
<span class="o">-</span><span class="n">H</span> <span class="n">HOST</span><span class="p">,</span> <span class="o">--</span><span class="n">host</span> <span class="n">HOST</span> <span class="n">IMAP</span> <span class="n">hostname</span> <span class="ow">or</span> <span class="n">IP</span> <span class="n">address</span>
<span class="o">-</span><span class="n">u</span> <span class="n">USER</span><span class="p">,</span> <span class="o">--</span><span class="n">user</span> <span class="n">USER</span> <span class="n">IMAP</span> <span class="n">user</span>
<span class="o">-</span><span class="n">p</span> <span class="n">PASSWORD</span><span class="p">,</span> <span class="o">--</span><span class="n">password</span> <span class="n">PASSWORD</span>
<span class="n">IMAP</span> <span class="n">password</span>
<span class="o">-</span><span class="n">r</span> <span class="n">REPORTS_FOLDER</span><span class="p">,</span> <span class="o">--</span><span class="n">reports</span><span class="o">-</span><span class="n">folder</span> <span class="n">REPORTS_FOLDER</span>
<span class="n">The</span> <span class="n">IMAP</span> <span class="n">folder</span> <span class="n">containing</span> <span class="n">the</span> <span class="n">reports</span> <span class="n">Default</span><span class="p">:</span> <span class="n">INBOX</span>
<span class="o">-</span><span class="n">a</span> <span class="n">ARCHIVE_FOLDER</span><span class="p">,</span> <span class="o">--</span><span class="n">archive</span><span class="o">-</span><span class="n">folder</span> <span class="n">ARCHIVE_FOLDER</span>
<span class="n">Specifies</span> <span class="n">the</span> <span class="n">IMAP</span> <span class="n">folder</span> <span class="n">to</span> <span class="n">move</span> <span class="n">messages</span> <span class="n">to</span> <span class="n">after</span>
<span class="n">processing</span> <span class="n">them</span> <span class="n">Default</span><span class="p">:</span> <span class="n">Archive</span>
<span class="o">-</span><span class="n">d</span><span class="p">,</span> <span class="o">--</span><span class="n">delete</span> <span class="n">Delete</span> <span class="n">the</span> <span class="n">reports</span> <span class="n">after</span> <span class="n">processing</span> <span class="n">them</span>
<span class="o">-</span><span class="n">E</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="o">...</span><span class="p">]],</span> <span class="o">--</span><span class="n">elasticsearch</span><span class="o">-</span><span class="n">host</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="p">[</span><span class="n">ELASTICSEARCH_HOST</span> <span class="o">...</span><span class="p">]]</span>
<span class="n">A</span> <span class="nb">list</span> <span class="n">of</span> <span class="n">one</span> <span class="ow">or</span> <span class="n">more</span> <span class="n">Elasticsearch</span> <span class="n">hostnames</span> <span class="ow">or</span> <span class="n">URLs</span>
<span class="n">to</span> <span class="n">use</span> <span class="p">(</span><span class="n">Default</span> <span class="n">localhost</span><span class="p">:</span><span class="mi">9200</span><span class="p">)</span>
<span class="o">--</span><span class="n">save</span><span class="o">-</span><span class="n">aggregate</span> <span class="n">Save</span> <span class="n">aggregate</span> <span class="n">reports</span> <span class="n">to</span> <span class="n">Elasticsearch</span>
<span class="o">--</span><span class="n">save</span><span class="o">-</span><span class="n">forensic</span> <span class="n">Save</span> <span class="n">forensic</span> <span class="n">reports</span> <span class="n">to</span> <span class="n">Elasticsearch</span>
<span class="o">-</span><span class="n">O</span> <span class="n">OUTGOING_HOST</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">host</span> <span class="n">OUTGOING_HOST</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">host</span>
<span class="o">-</span><span class="n">U</span> <span class="n">OUTGOING_USER</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">user</span> <span class="n">OUTGOING_USER</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">user</span>
<span class="o">-</span><span class="n">P</span> <span class="n">OUTGOING_PASSWORD</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">password</span> <span class="n">OUTGOING_PASSWORD</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">password</span>
<span class="o">-</span><span class="n">F</span> <span class="n">OUTGOING_FROM</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="kn">from</span> <span class="nn">OUTGOING_FROM</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="kn">from</span> <span class="nn">address</span>
<span class="o">-</span><span class="n">T</span> <span class="n">OUTGOING_TO</span> <span class="p">[</span><span class="n">OUTGOING_TO</span> <span class="o">...</span><span class="p">],</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">to</span> <span class="n">OUTGOING_TO</span> <span class="p">[</span><span class="n">OUTGOING_TO</span> <span class="o">...</span><span class="p">]</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">to</span> <span class="n">these</span> <span class="n">addresses</span>
<span class="o">-</span><span class="n">S</span> <span class="n">OUTGOING_SUBJECT</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">subject</span> <span class="n">OUTGOING_SUBJECT</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">subject</span>
<span class="o">-</span><span class="n">A</span> <span class="n">OUTGOING_ATTACHMENT</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">attachment</span> <span class="n">OUTGOING_ATTACHMENT</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">filename</span>
<span class="o">-</span><span class="n">M</span> <span class="n">OUTGOING_MESSAGE</span><span class="p">,</span> <span class="o">--</span><span class="n">outgoing</span><span class="o">-</span><span class="n">message</span> <span class="n">OUTGOING_MESSAGE</span>
<span class="n">Email</span> <span class="n">the</span> <span class="n">results</span> <span class="n">using</span> <span class="n">this</span> <span class="n">message</span>
<span class="o">-</span><span class="n">w</span><span class="p">,</span> <span class="o">--</span><span class="n">watch</span> <span class="n">Use</span> <span class="n">an</span> <span class="n">IMAP</span> <span class="n">IDLE</span> <span class="n">connection</span> <span class="n">to</span> <span class="n">process</span> <span class="n">reports</span> <span class="k">as</span> <span class="n">they</span>
<span class="n">arrive</span> <span class="ow">in</span> <span class="n">the</span> <span class="n">inbox</span>
<span class="o">--</span><span class="n">test</span> <span class="n">Do</span> <span class="ow">not</span> <span class="n">move</span> <span class="ow">or</span> <span class="n">delete</span> <span class="n">IMAP</span> <span class="n">messages</span>
<span class="o">-</span><span class="n">s</span><span class="p">,</span> <span class="o">--</span><span class="n">silent</span> <span class="n">Only</span> <span class="nb">print</span> <span class="n">errors</span>
<span class="o">--</span><span class="n">debug</span> <span class="n">Print</span> <span class="n">debugging</span> <span class="n">information</span>
<span class="o">-</span><span class="n">v</span><span class="p">,</span> <span class="o">--</span><span class="n">version</span> <span class="n">show</span> <span class="n">program</span><span class="s1">&#39;s version number and exit</span>
</pre></div>
</div>
</div>
<div class="section" id="spf-and-dmarc-record-validation">
<h2>SPF and DMARC record validation<a class="headerlink" href="#spf-and-dmarc-record-validation" title="Permalink to this headline"></a></h2>
<p>If you are looking for SPF and DMARC record validation and parsing,
check out the sister project, <a class="reference external" href="https://domainaware.github.io/checkdmarc/">checkdmarc</a>.</p>
</div>
<div class="section" id="sample-aggregate-report-output">
<h2>Sample aggregate report output<a class="headerlink" href="#sample-aggregate-report-output" title="Permalink to this headline"></a></h2>
<p>Here are the results from parsing the <a class="reference external" href="https://dmarc.org/wiki/FAQ#I_need_to_implement_aggregate_reports.2C_what_do_they_look_like.3F">example</a>
report from the dmarc.org wiki. Its actually an older draft of the the 1.0
report schema standardized in
<a class="reference external" href="https://tools.ietf.org/html/rfc7489#appendix-C">RFC 7480 Appendix C</a>.
This draft schema is still in wide use.</p>
<p><code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> produces consistent, normalized output, regardless of the report
schema.</p>
<div class="section" id="json">
<h3>JSON<a class="headerlink" href="#json" title="Permalink to this headline"></a></h3>
<div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="nt">&quot;xml_schema&quot;</span><span class="p">:</span> <span class="s2">&quot;draft&quot;</span><span class="p">,</span>
<span class="nt">&quot;report_metadata&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;org_name&quot;</span><span class="p">:</span> <span class="s2">&quot;acme.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;org_email&quot;</span><span class="p">:</span> <span class="s2">&quot;noreply-dmarc-support@acme.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;org_extra_contact_info&quot;</span><span class="p">:</span> <span class="s2">&quot;http://acme.com/dmarc/support&quot;</span><span class="p">,</span>
<span class="nt">&quot;report_id&quot;</span><span class="p">:</span> <span class="s2">&quot;9391651994964116463&quot;</span><span class="p">,</span>
<span class="nt">&quot;begin_date&quot;</span><span class="p">:</span> <span class="s2">&quot;2012-04-27 20:00:00&quot;</span><span class="p">,</span>
<span class="nt">&quot;end_date&quot;</span><span class="p">:</span> <span class="s2">&quot;2012-04-28 19:59:59&quot;</span><span class="p">,</span>
<span class="nt">&quot;errors&quot;</span><span class="p">:</span> <span class="p">[]</span>
<span class="p">},</span>
<span class="nt">&quot;policy_published&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;domain&quot;</span><span class="p">:</span> <span class="s2">&quot;example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;adkim&quot;</span><span class="p">:</span> <span class="s2">&quot;r&quot;</span><span class="p">,</span>
<span class="nt">&quot;aspf&quot;</span><span class="p">:</span> <span class="s2">&quot;r&quot;</span><span class="p">,</span>
<span class="nt">&quot;p&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
<span class="nt">&quot;sp&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
<span class="nt">&quot;pct&quot;</span><span class="p">:</span> <span class="s2">&quot;100&quot;</span><span class="p">,</span>
<span class="nt">&quot;fo&quot;</span><span class="p">:</span> <span class="s2">&quot;0&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;records&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nt">&quot;source&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;ip_address&quot;</span><span class="p">:</span> <span class="s2">&quot;72.150.241.94&quot;</span><span class="p">,</span>
<span class="nt">&quot;country&quot;</span><span class="p">:</span> <span class="s2">&quot;US&quot;</span><span class="p">,</span>
<span class="nt">&quot;reverse_dns&quot;</span><span class="p">:</span> <span class="s2">&quot;adsl-72-150-241-94.shv.bellsouth.net&quot;</span><span class="p">,</span>
<span class="nt">&quot;base_domain&quot;</span><span class="p">:</span> <span class="s2">&quot;bellsouth.net&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;count&quot;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
<span class="nt">&quot;policy_evaluated&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;disposition&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
<span class="nt">&quot;dkim&quot;</span><span class="p">:</span> <span class="s2">&quot;fail&quot;</span><span class="p">,</span>
<span class="nt">&quot;spf&quot;</span><span class="p">:</span> <span class="s2">&quot;pass&quot;</span><span class="p">,</span>
<span class="nt">&quot;policy_override_reasons&quot;</span><span class="p">:</span> <span class="p">[]</span>
<span class="p">},</span>
<span class="nt">&quot;identifiers&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;header_from&quot;</span><span class="p">:</span> <span class="s2">&quot;example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;envelope_from&quot;</span><span class="p">:</span> <span class="s2">&quot;example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;envelope_to&quot;</span><span class="p">:</span> <span class="kc">null</span>
<span class="p">},</span>
<span class="nt">&quot;auth_results&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;dkim&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nt">&quot;domain&quot;</span><span class="p">:</span> <span class="s2">&quot;example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;selector&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
<span class="nt">&quot;result&quot;</span><span class="p">:</span> <span class="s2">&quot;fail&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;spf&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nt">&quot;domain&quot;</span><span class="p">:</span> <span class="s2">&quot;example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;scope&quot;</span><span class="p">:</span> <span class="s2">&quot;mfrom&quot;</span><span class="p">,</span>
<span class="nt">&quot;result&quot;</span><span class="p">:</span> <span class="s2">&quot;pass&quot;</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="csv">
<h3>CSV<a class="headerlink" href="#csv" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">xml_schema</span><span class="p">,</span><span class="n">org_name</span><span class="p">,</span><span class="n">org_email</span><span class="p">,</span><span class="n">org_extra_contact_info</span><span class="p">,</span><span class="n">report_id</span><span class="p">,</span><span class="n">begin_date</span><span class="p">,</span><span class="n">end_date</span><span class="p">,</span><span class="n">errors</span><span class="p">,</span><span class="n">domain</span><span class="p">,</span><span class="n">adkim</span><span class="p">,</span><span class="n">aspf</span><span class="p">,</span><span class="n">p</span><span class="p">,</span><span class="n">sp</span><span class="p">,</span><span class="n">pct</span><span class="p">,</span><span class="n">fo</span><span class="p">,</span><span class="n">source_ip_address</span><span class="p">,</span><span class="n">source_country</span><span class="p">,</span><span class="n">source_reverse_dns</span><span class="p">,</span><span class="n">source_base_domain</span><span class="p">,</span><span class="n">count</span><span class="p">,</span><span class="n">disposition</span><span class="p">,</span><span class="n">dkim_alignment</span><span class="p">,</span><span class="n">spf_alignment</span><span class="p">,</span><span class="n">policy_override_reasons</span><span class="p">,</span><span class="n">policy_override_comments</span><span class="p">,</span><span class="n">envelope_from</span><span class="p">,</span><span class="n">header_from</span><span class="p">,</span><span class="n">envelope_to</span><span class="p">,</span><span class="n">dkim_domains</span><span class="p">,</span><span class="n">dkim_selectors</span><span class="p">,</span><span class="n">dkim_results</span><span class="p">,</span><span class="n">spf_domains</span><span class="p">,</span><span class="n">spf_scopes</span><span class="p">,</span><span class="n">spf_results</span>
<span class="n">draft</span><span class="p">,</span><span class="n">acme</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">noreply</span><span class="o">-</span><span class="n">dmarc</span><span class="o">-</span><span class="n">support</span><span class="nd">@acme</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">acme</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">dmarc</span><span class="o">/</span><span class="n">support</span><span class="p">,</span><span class="mi">9391651994964116463</span><span class="p">,</span><span class="mi">2012</span><span class="o">-</span><span class="mi">04</span><span class="o">-</span><span class="mi">27</span> <span class="mi">20</span><span class="p">:</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="p">,</span><span class="mi">2012</span><span class="o">-</span><span class="mi">04</span><span class="o">-</span><span class="mi">28</span> <span class="mi">19</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">59</span><span class="p">,,</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">none</span><span class="p">,</span><span class="n">none</span><span class="p">,</span><span class="mi">100</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mf">72.150</span><span class="o">.</span><span class="mf">241.94</span><span class="p">,</span><span class="n">US</span><span class="p">,</span><span class="n">adsl</span><span class="o">-</span><span class="mi">72</span><span class="o">-</span><span class="mi">150</span><span class="o">-</span><span class="mi">241</span><span class="o">-</span><span class="mf">94.</span><span class="n">shv</span><span class="o">.</span><span class="n">bellsouth</span><span class="o">.</span><span class="n">net</span><span class="p">,</span><span class="n">bellsouth</span><span class="o">.</span><span class="n">net</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="n">none</span><span class="p">,</span><span class="n">fail</span><span class="p">,</span><span class="k">pass</span><span class="p">,,,</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,,</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">none</span><span class="p">,</span><span class="n">fail</span><span class="p">,</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,</span><span class="n">mfrom</span><span class="p">,</span><span class="k">pass</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="sample-forensic-report-output">
<h2>Sample forensic report output<a class="headerlink" href="#sample-forensic-report-output" title="Permalink to this headline"></a></h2>
<p>I dont have a sample I can share for privacy reasons. If you have a sample
forensic report that you can share publicly, please contact me!</p>
</div>
<div class="section" id="bug-reports">
<h2>Bug reports<a class="headerlink" href="#bug-reports" title="Permalink to this headline"></a></h2>
<p>Please report bugs on the GitHub issue tracker</p>
<p><a class="reference external" href="https://github.com/domainaware/parsedmarc/issues">https://github.com/domainaware/parsedmarc/issues</a></p>
</div>
<div class="section" id="installation">
<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline"></a></h2>
<p><code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> works with Python 3 only.</p>
<p>On Debian or Ubuntu systems, run:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ sudo apt-get install python3-pip
</pre></div>
</div>
<p>Python 3 installers for Windows and macOS can be found at
<a class="reference external" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></p>
<p>To install or upgrade to the latest stable release of <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> on
macOS or Linux, run</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ sudo -H pip3 install -U parsedmarc
</pre></div>
</div>
<p>Or, install the latest development release directly from GitHub:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ sudo -H pip3 install -U git+https://github.com/domainaware/parsedmarc.git
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">On Windows, <code class="docutils literal notranslate"><span class="pre">pip3</span></code> is <code class="docutils literal notranslate"><span class="pre">pip</span></code>, even with Python 3. So on Windows, simply
substitute <code class="docutils literal notranslate"><span class="pre">pip</span></code> as an administrator in place of <code class="docutils literal notranslate"><span class="pre">sudo</span> <span class="pre">pip3</span></code>, in the
above commands.</p>
</div>
<div class="section" id="optional-dependencies">
<h3>Optional dependencies<a class="headerlink" href="#optional-dependencies" title="Permalink to this headline"></a></h3>
<p>If you would like to be able to parse emails saved from Microsoft Outlook
(i.e. OLE .msg files), install <code class="docutils literal notranslate"><span class="pre">msgconvert</span></code>:</p>
<p>On Debian or Ubuntu systems, run:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ sudo apt-get install libemail-outlook-message-perl
</pre></div>
</div>
</div>
<div class="section" id="elasticsearch-and-kibana">
<h3>Elasticsearch and Kibana<a class="headerlink" href="#elasticsearch-and-kibana" title="Permalink to this headline"></a></h3>
<p>To set up visual dashboards of DMARC data, install Elasticsearch and Kibana.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo apt-get install -y openjdk-8-jre apt-transport-https
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch <span class="p">|</span> sudo apt-key add -
<span class="nb">echo</span> <span class="s2">&quot;deb https://artifacts.elastic.co/packages/6.x/apt stable main&quot;</span> <span class="p">|</span> sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list
sudo apt-get update
sudo apt-get install -y elasticsearch kibana
sudo systemctl daemon-reload
sudo systemctl <span class="nb">enable</span> elasticsearch.service
sudo systemctl <span class="nb">enable</span> kibana.service
sudo service start elasticsearch
sudo service start kibana
</pre></div>
</div>
<p>Without the commercial <a class="reference external" href="https://www.elastic.co/products/x-pack">X-Pack</a>, Kibana does not have any authentication
mechanism of its own. You can use nginx as a reverse proxy that provides basic
authentication.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo apt-get install -y nginx apache2-utils
</pre></div>
</div>
<p>Create a directory to store the certificates and keys:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>mkdir ~/ssl
<span class="nb">cd</span> ~/ssl
</pre></div>
</div>
<p>To create a self-signed certificate, run:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>openssl req -x509 -nodes -days <span class="m">365</span> -newkey rsa:4096 -keyout kibana.key -out kibana.crt
</pre></div>
</div>
<p>Or, to create a Certificate Signing Request (CSR) for a CA, run:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>openssl req -newkey rsa:4096-nodes -keyout kibana.key -out kibana.csr
</pre></div>
</div>
<p>Fill in the prompts. Watch out for Common Name (e.g. server FQDN or YOUR
domain name), which is the IP address or domain name that you will be hosting
Kibana on. it is the most important field.</p>
<p>If you generated a CSR, remove the CSR after you have your certs</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>rm -f kibana.csr
</pre></div>
</div>
<p>Move the keys into place and secure them:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nb">cd</span>
sudo mv ssl /etc/nginx
sudo chown -R root:www-data /etc/nginx/ssl
sudo chmod -R <span class="nv">u</span><span class="o">=</span>rX,g<span class="o">=</span>rX,o<span class="o">=</span> /etc/nginx/ssl
</pre></div>
</div>
<p>Disable the default nginx configuration:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo rm /etc/nginx/sites-enabled/default
</pre></div>
</div>
<p>Create the web server configuration</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo nano /etc/nginx/sites-available/kibana
</pre></div>
</div>
<div class="highlight-nginx notranslate"><div class="highlight"><pre><span></span><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
<span class="kn">ssl_certificate</span> <span class="s">/etc/nginx/ssl/kibana.crt</span><span class="p">;</span>
<span class="kn">ssl_certificate_key</span> <span class="s">/etc/nginx/ssl/kibana.key</span><span class="p">;</span>
<span class="kn">ssl_dhparam</span> <span class="s">/etc/nginx/ssl/dhparam.pem</span><span class="p">;</span>
<span class="kn">ssl_session_timeout</span> <span class="s">1d</span><span class="p">;</span>
<span class="kn">ssl_session_cache</span> <span class="s">shared:SSL:50m</span><span class="p">;</span>
<span class="kn">ssl_session_tickets</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">ssl_protocols</span> <span class="s">TLSv1.2</span><span class="p">;</span>
<span class="kn">ssl_ciphers</span> <span class="s">&#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHAC</span> <span class="s">ssl_prefer_server_ciphers</span> <span class="no">on</span><span class="p">;</span>
<span class="c1"># Uncomment this next line if you are using a signed, trusted cert</span>
<span class="c1">#add_header Strict-Transport-Security &quot;max-age=63072000; includeSubdomains; preload&quot;;</span>
<span class="kn">add_header</span> <span class="s">X-Frame-Options</span> <span class="s">SAMEORIGIN</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">X-Content-Type-Options</span> <span class="s">nosniff</span><span class="p">;</span>
<span class="kn">auth_basic</span> <span class="s">&quot;Login</span> <span class="s">required&quot;</span><span class="p">;</span>
<span class="kn">auth_basic_user_file</span> <span class="s">/etc/nginx/htpasswd</span><span class="p">;</span>
<span class="kn">location</span> <span class="s">/</span> <span class="p">{</span>
<span class="kn">proxy_pass</span> <span class="s">http://127.0.0.1:5601</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">X-Real-IP</span> <span class="nv">$remote_addr</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$server_name$request_uri</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Enable the nginx configuration for Kibana:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo ln -s /etc/nginx/sites-available/kibana /etc/nginx/sites-enabled/kibana
</pre></div>
</div>
<p>Add a user to basic authentication:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo htpasswd -c /etc/nginx/htpasswd exampleuser
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">exampleuser</span></code> is the name of the user you want to add.</p>
<p>Secure the permissions of the httpasswd file:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo chown root:www-data /etc/nginx/htpasswd
sudo chmod <span class="nv">u</span><span class="o">=</span>rw,g<span class="o">=</span>r,o<span class="o">=</span> /etc/nginx/htpasswd
</pre></div>
</div>
<p>Restart nginx:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo service nginx restart
</pre></div>
</div>
<p>Now that Elasticsearch is up and running, use <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> to send data to
it.</p>
<p>Om the same system as Elasticsearch, pass <code class="docutils literal notranslate"><span class="pre">--save-aggregate</span></code> and/or
<code class="docutils literal notranslate"><span class="pre">--save-forensic</span></code> to <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> save the results in Elasticsearch.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p><code class="docutils literal notranslate"><span class="pre">--save-aggregate</span></code> and <code class="docutils literal notranslate"><span class="pre">--save-forensic</span></code> are separate options because
you may not want to save forensic reports to your Elasticsearch instance,
particularly if you are in a highly-regulated industry that handles
sensitive data, such as healthcare or finance. If your legitimate outgoing
email fails DMARC, it is possible that email may appear later in a
forensic report.</p>
<p>Forensic reports contain the original headers of an email that failed a
DMARC check, and sometimes may also include the full message body,
depending on the policy of the reporting organisation.</p>
<p class="last">Most reporting organisations do not send forensic reports of any kind for
privacy reasons. While aggregate DMARC reports are sent at least daily,
it is normal to receive very few forensic reports.</p>
</div>
<p>When you first visit Kibana, it will prompt you to create an index pattern.
Start by creating the index pattern <code class="docutils literal notranslate"><span class="pre">dmarc_aggregate</span></code> (without an <code class="docutils literal notranslate"><span class="pre">*</span></code>),
and select <code class="docutils literal notranslate"><span class="pre">date_range</span></code> as the time field. Once the <code class="docutils literal notranslate"><span class="pre">dmarc_aggregate</span></code>
index pattern <code class="docutils literal notranslate"><span class="pre">dmarc_aggregate</span></code> has been saved, create a <code class="docutils literal notranslate"><span class="pre">dmarc_forensic</span></code>
index pattern, with <code class="docutils literal notranslate"><span class="pre">arrival_date</span></code> as the time field.</p>
<a class="reference external image-reference" href="_static/screenshots/define-dmarc-aggregate.png"><img alt="A screenshot of defining the dmarc_aggregate index pattern" class="align-center" src="_images/define-dmarc-aggregate.png" /></a>
<a class="reference external image-reference" href="_static/screenshots/dmarc-aggregate-time-field.png"><img alt="A screenshot of setting the time field for the dmarc_aggregate index pattern" class="align-center" src="_images/dmarc-aggregate-time-field.png" /></a>
<a class="reference external image-reference" href="_static/screenshots/define-dmarc-forensic.png"><img alt="A screenshot of defining the dmarc_forensic index pattern" class="align-center" src="_images/define-dmarc-forensic.png" /></a>
<a class="reference external image-reference" href="_static/screenshots/dmarc-forensic-time-field.png"><img alt="A screenshot of setting the time field for the dmarc_forensic index pattern" class="align-center" src="_images/dmarc-forensic-time-field.png" /></a>
<p>Once the index patterns have been created, you can import the dashboards.</p>
<p>Download (right click the link and click save as) <a class="reference external" href="https://raw.githubusercontent.com/domainaware/parsedmarc/master/kibana/kibana_saved_objects.json">kibana_saved_objects.json</a>.</p>
<p>Import <code class="docutils literal notranslate"><span class="pre">kibana_saved_objects.json</span></code> the Saved Objects tab of the management
page of Kibana.</p>
<p>It will give you the option to overwrite existing saved dashboards or
visualizations, which could be used to restore them if you or someone else
breaks them, as there are no permissions/access controls in Kibana without
the commercial <a class="reference external" href="https://www.elastic.co/products/x-pack">X-Pack</a>.</p>
<a class="reference external image-reference" href="_static/screenshots/saved-objects.png"><img alt="A screenshot of setting the Saved Objects management UI in Kibana" class="align-center" src="_images/saved-objects.png" /></a>
<a class="reference external image-reference" href="_static/screenshots/confirm-overwrite.png"><img alt="A screenshot of the overwrite conformation prompt" class="align-center" src="_images/confirm-overwrite.png" /></a>
<p>Kibana will then ask you to match the newly imported objects to your index
patterns. Select <code class="docutils literal notranslate"><span class="pre">dmarc_forensic</span></code> for the set of forensic objects, and
select <code class="docutils literal notranslate"><span class="pre">dmarc_aggregate</span></code> for the other saved objects, as shown below.</p>
<a class="reference external image-reference" href="_static/screenshots/index-pattern-conflicts.png"><img alt="A screenshot showing how to resolve index pattern conflicts after importing saved objects" class="align-center" src="_images/index-pattern-conflicts.png" /></a>
</div>
<div class="section" id="running-parsedmarc-as-a-systemd-service">
<h3>Running parsedmarc as a systemd service<a class="headerlink" href="#running-parsedmarc-as-a-systemd-service" title="Permalink to this headline"></a></h3>
<p>Use systemd to run <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> as a service and process reports as they
arrive.</p>
<p>Create the service configuration file</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo nano /etc/systemd/system/parsedmarc.service
</pre></div>
</div>
<p>Edit the command line options of <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> in the services <code class="docutils literal notranslate"><span class="pre">ExecStart</span></code>
setting to suit your needs.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Always pass the <code class="docutils literal notranslate"><span class="pre">--watch</span></code> option to <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> when running it as a
service. Use <code class="docutils literal notranslate"><span class="pre">--silent</span></code> to only log errors.</p>
</div>
<div class="highlight-ini notranslate"><div class="highlight"><pre><span></span><span class="k">[Unit]</span>
<span class="na">Description</span><span class="o">=</span><span class="s">parsedmarc mailbox watcher</span>
<span class="na">Documentation</span><span class="o">=</span><span class="s">https://domainaware.github.io/parsedmarc/</span>
<span class="k">[Service]</span>
<span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/local/bin/parsedmarc --watch --silent --save-aggregate --save-forensic -H &quot;outlook.office365.com&quot; -u &quot;dmarc@example.com&quot; -p &quot;FooBar!&quot;</span>
<span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
<span class="na">RestartSec</span><span class="o">=</span><span class="s">5m</span>
<span class="k">[Install]</span>
<span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</pre></div>
</div>
<p>Then, enable the service</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo systemctl daemon-reload
sudo systemctl <span class="nb">enable</span> parsedmarc.service
sudo service parsedmarc restart
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You must also run the above commands whenever you edit
<code class="docutils literal notranslate"><span class="pre">parsedmarc.service</span></code>.</p>
</div>
</div>
</div>
<div class="section" id="module-parsedmarc">
<span id="api"></span><h2>API<a class="headerlink" href="#module-parsedmarc" title="Permalink to this headline"></a></h2>
<p>A Python package for parsing DMARC reports</p>
<dl class="exception">
<dt id="parsedmarc.IMAPError">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">IMAPError</code><a class="reference internal" href="_modules/parsedmarc.html#IMAPError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.IMAPError" title="Permalink to this definition"></a></dt>
<dd><p>Raised when an IMAP error occurs</p>
</dd></dl>
<dl class="exception">
<dt id="parsedmarc.InvalidAggregateReport">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">InvalidAggregateReport</code><a class="reference internal" href="_modules/parsedmarc.html#InvalidAggregateReport"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.InvalidAggregateReport" title="Permalink to this definition"></a></dt>
<dd><p>Raised when an invalid DMARC aggregate report is encountered</p>
</dd></dl>
<dl class="exception">
<dt id="parsedmarc.InvalidDMARCReport">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">InvalidDMARCReport</code><a class="reference internal" href="_modules/parsedmarc.html#InvalidDMARCReport"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.InvalidDMARCReport" title="Permalink to this definition"></a></dt>
<dd><p>Raised when an invalid DMARC report is encountered</p>
</dd></dl>
<dl class="exception">
<dt id="parsedmarc.InvalidForensicReport">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">InvalidForensicReport</code><a class="reference internal" href="_modules/parsedmarc.html#InvalidForensicReport"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.InvalidForensicReport" title="Permalink to this definition"></a></dt>
<dd><p>Raised when an invalid DMARC forensic report is encountered</p>
</dd></dl>
<dl class="exception">
<dt id="parsedmarc.ParserError">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">ParserError</code><a class="reference internal" href="_modules/parsedmarc.html#ParserError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.ParserError" title="Permalink to this definition"></a></dt>
<dd><p>Raised whenever the parser fails for some reason</p>
</dd></dl>
<dl class="exception">
<dt id="parsedmarc.SMTPError">
<em class="property">exception </em><code class="descclassname">parsedmarc.</code><code class="descname">SMTPError</code><a class="reference internal" href="_modules/parsedmarc.html#SMTPError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.SMTPError" title="Permalink to this definition"></a></dt>
<dd><p>Raised when a SMTP error occurs</p>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.email_results">
<code class="descclassname">parsedmarc.</code><code class="descname">email_results</code><span class="sig-paren">(</span><em>results</em>, <em>host</em>, <em>mail_from</em>, <em>mail_to</em>, <em>port=0</em>, <em>starttls=True</em>, <em>use_ssl=False</em>, <em>user=None</em>, <em>password=None</em>, <em>subject=None</em>, <em>attachment_filename=None</em>, <em>message=None</em>, <em>ssl_context=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#email_results"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.email_results" title="Permalink to this definition"></a></dt>
<dd><p>Emails parsing results as a zip file</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>results</strong> (<em>OrderedDict</em>) Parsing results</li>
<li><strong>host</strong> Mail server hostname or IP address</li>
<li><strong>mail_from</strong> The value of the message from header</li>
<li><strong>mail_to</strong> A list of addresses to mail to</li>
<li><strong>port</strong> (<em>int</em>) Port to use</li>
<li><strong>starttls</strong> (<em>bool</em>) use STARTTLS</li>
<li><strong>use_ssl</strong> (<em>bool</em>) Require a SSL connection from the start</li>
<li><strong>user</strong> An optional username</li>
<li><strong>password</strong> An optional password</li>
<li><strong>subject</strong> Overrides the default message subject</li>
<li><strong>attachment_filename</strong> Override the default attachment filename</li>
<li><strong>message</strong> Override the default plain text body</li>
<li><strong>ssl_context</strong> SSL context options</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.extract_xml">
<code class="descclassname">parsedmarc.</code><code class="descname">extract_xml</code><span class="sig-paren">(</span><em>input_</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#extract_xml"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.extract_xml" title="Permalink to this definition"></a></dt>
<dd><p>Extracts xml from a zip or gzip file at the given path, file-like object,
or bytes.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>input</strong> A path to a file, a file like object, or bytes</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The extracted XML</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.get_dmarc_reports_from_inbox">
<code class="descclassname">parsedmarc.</code><code class="descname">get_dmarc_reports_from_inbox</code><span class="sig-paren">(</span><em>host</em>, <em>user</em>, <em>password</em>, <em>reports_folder='INBOX'</em>, <em>archive_folder='Archive'</em>, <em>delete=False</em>, <em>test=False</em>, <em>nameservers=None</em>, <em>dns_timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#get_dmarc_reports_from_inbox"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.get_dmarc_reports_from_inbox" title="Permalink to this definition"></a></dt>
<dd><p>Fetches and parses DMARC reports from sn inbox</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>host</strong> The mail server hostname or IP address</li>
<li><strong>user</strong> The mail server user</li>
<li><strong>password</strong> The mail server password</li>
<li><strong>reports_folder</strong> The IMAP folder where reports can be found</li>
<li><strong>archive_folder</strong> The folder to move processed mail to</li>
<li><strong>delete</strong> (<em>bool</em>) Delete messages after processing them</li>
<li><strong>test</strong> (<em>bool</em>) Do not move or delete messages after processing them</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of DNS nameservers to query</li>
<li><strong>dns_timeout</strong> (<em>float</em>) Set the DNS query timeout</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">Lists of <code class="docutils literal notranslate"><span class="pre">aggregate_reports</span></code> and <code class="docutils literal notranslate"><span class="pre">forensic_reports</span></code></p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.get_report_zip">
<code class="descclassname">parsedmarc.</code><code class="descname">get_report_zip</code><span class="sig-paren">(</span><em>results</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#get_report_zip"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.get_report_zip" title="Permalink to this definition"></a></dt>
<dd><p>Creates a zip file of parsed report output</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>results</strong> (<em>OrderedDict</em>) The parsed results</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">zip file bytes</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">bytes</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.human_timestamp_to_datetime">
<code class="descclassname">parsedmarc.</code><code class="descname">human_timestamp_to_datetime</code><span class="sig-paren">(</span><em>human_timestamp</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#human_timestamp_to_datetime"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.human_timestamp_to_datetime" title="Permalink to this definition"></a></dt>
<dd><p>Converts a human-readable timestamp into a Python <code class="docutils literal notranslate"><span class="pre">DateTime</span></code> object</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>human_timestamp</strong> (<em>str</em>) A timestamp in <cite>YYYY-MM-DD HH:MM:SS`</cite> format</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The converted timestamp</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">DateTime</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parse_aggregate_report_file">
<code class="descclassname">parsedmarc.</code><code class="descname">parse_aggregate_report_file</code><span class="sig-paren">(</span><em>_input</em>, <em>nameservers=None</em>, <em>timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parse_aggregate_report_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parse_aggregate_report_file" title="Permalink to this definition"></a></dt>
<dd><p>Parses a file at the given path, a file-like object. or bytes as a
aggregate DMARC report</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>_input</strong> A path to a file, a file like object, or bytes</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>public DNS resolvers by default</strong><strong>)</strong> (<em>(</em><em>Cloudflare's</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The parsed DMARC aggregate report</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parse_aggregate_report_xml">
<code class="descclassname">parsedmarc.</code><code class="descname">parse_aggregate_report_xml</code><span class="sig-paren">(</span><em>xml</em>, <em>nameservers=None</em>, <em>timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parse_aggregate_report_xml"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parse_aggregate_report_xml" title="Permalink to this definition"></a></dt>
<dd><p>Parses a DMARC XML report string and returns a consistent OrderedDict</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>xml</strong> (<em>str</em>) A string of DMARC aggregate report XML</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>public DNS resolvers by default</strong><strong>)</strong> (<em>(</em><em>Cloudflare's</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The parsed aggregate DMARC report</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parse_forensic_report">
<code class="descclassname">parsedmarc.</code><code class="descname">parse_forensic_report</code><span class="sig-paren">(</span><em>feedback_report</em>, <em>sample</em>, <em>sample_headers_only</em>, <em>nameservers=None</em>, <em>timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parse_forensic_report"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parse_forensic_report" title="Permalink to this definition"></a></dt>
<dd><p>Converts a DMARC forensic report and sample to a <code class="docutils literal notranslate"><span class="pre">OrderedDict</span></code></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>feedback_report</strong> (<em>str</em>) A messages feedback report as a string</li>
<li><strong>sample</strong> (<em>str</em>) The RFC 822 headers or RFC 822 message sample</li>
<li><strong>sample_headers_only</strong> (<em>bool</em>) Set true if the sample is only headers</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>public DNS resolvers by default</strong><strong>)</strong> (<em>(</em><em>Cloudflare's</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">An parsed report and sample</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parse_report_email">
<code class="descclassname">parsedmarc.</code><code class="descname">parse_report_email</code><span class="sig-paren">(</span><em>input_</em>, <em>nameservers=None</em>, <em>timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parse_report_email"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parse_report_email" title="Permalink to this definition"></a></dt>
<dd><p>Parses a DMARC report from an email</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>input</strong> An emailed DMARC report in RFC 822 format, as bytes or a string</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first"><ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">report_type</span></code>: <code class="docutils literal notranslate"><span class="pre">aggregate</span></code> or <code class="docutils literal notranslate"><span class="pre">forensic</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">report</span></code>: The parsed report</li>
</ul>
</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parse_report_file">
<code class="descclassname">parsedmarc.</code><code class="descname">parse_report_file</code><span class="sig-paren">(</span><em>input_</em>, <em>nameservers=None</em>, <em>timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parse_report_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parse_report_file" title="Permalink to this definition"></a></dt>
<dd><p>Parses a DMARC aggregate or forensic file at the given path, a
file-like object. or bytes</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>input</strong> A path to a file, a file like object, or bytes</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>public DNS resolvers by default</strong><strong>)</strong> (<em>(</em><em>Cloudflare's</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The parsed DMARC report</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">OrderedDict</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parsed_aggregate_reports_to_csv">
<code class="descclassname">parsedmarc.</code><code class="descname">parsed_aggregate_reports_to_csv</code><span class="sig-paren">(</span><em>reports</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parsed_aggregate_reports_to_csv"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parsed_aggregate_reports_to_csv" title="Permalink to this definition"></a></dt>
<dd><p>Converts one or more parsed aggregate reports to flat CSV format, including
headers</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>reports</strong> A parsed aggregate report or list of parsed aggregate reports</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Parsed aggregate report data in flat CSV format, including headers</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.parsed_forensic_reports_to_csv">
<code class="descclassname">parsedmarc.</code><code class="descname">parsed_forensic_reports_to_csv</code><span class="sig-paren">(</span><em>reports</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#parsed_forensic_reports_to_csv"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.parsed_forensic_reports_to_csv" title="Permalink to this definition"></a></dt>
<dd><p>Converts one or more parsed forensic reports to flat CSV format, including
headers</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>reports</strong> A parsed forensic report or list of parsed forensic reports</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Parsed forensic report data in flat CSV format, including headers</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.save_output">
<code class="descclassname">parsedmarc.</code><code class="descname">save_output</code><span class="sig-paren">(</span><em>results</em>, <em>output_directory='output'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#save_output"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.save_output" title="Permalink to this definition"></a></dt>
<dd><p>Save report data in the given directory</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>results</strong> (<em>OrderedDict</em>) Parsing results</li>
<li><strong>output_directory</strong> The patch to the directory to save in</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.watch_inbox">
<code class="descclassname">parsedmarc.</code><code class="descname">watch_inbox</code><span class="sig-paren">(</span><em>host</em>, <em>username</em>, <em>password</em>, <em>callback</em>, <em>reports_folder='INBOX'</em>, <em>archive_folder='Archive'</em>, <em>delete=False</em>, <em>test=False</em>, <em>wait=30</em>, <em>nameservers=None</em>, <em>dns_timeout=6.0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc.html#watch_inbox"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.watch_inbox" title="Permalink to this definition"></a></dt>
<dd><p>Use an IDLE IMAP connection to parse incoming emails, and pass the results
to a callback function</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>host</strong> The mail server hostname or IP address</li>
<li><strong>username</strong> The mail server username</li>
<li><strong>password</strong> The mail server password</li>
<li><strong>callback</strong> The callback function to receive the parsing results</li>
<li><strong>reports_folder</strong> The IMAP folder where reports can be found</li>
<li><strong>archive_folder</strong> The folder to move processed mail to</li>
<li><strong>delete</strong> (<em>bool</em>) Delete messages after processing them</li>
<li><strong>test</strong> (<em>bool</em>) Do not move or delete messages after processing them</li>
<li><strong>wait</strong> (<em>int</em>) Number of seconds to wait for a IMAP IDLE response</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>public DNS resolvers by default</strong><strong>)</strong> (<em>(</em><em>Cloudflare's</em>) </li>
<li><strong>dns_timeout</strong> (<em>float</em>) Set the DNS query timeout</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<div class="section" id="module-parsedmarc.elastic">
<span id="parsedmarc-elastic"></span><h3>parsedmarc.elastic<a class="headerlink" href="#module-parsedmarc.elastic" title="Permalink to this headline"></a></h3>
<dl class="exception">
<dt id="parsedmarc.elastic.AlreadySaved">
<em class="property">exception </em><code class="descclassname">parsedmarc.elastic.</code><code class="descname">AlreadySaved</code><a class="reference internal" href="_modules/parsedmarc/elastic.html#AlreadySaved"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.elastic.AlreadySaved" title="Permalink to this definition"></a></dt>
<dd><p>Raised when a report to be saved matches an existing report</p>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.elastic.create_indexes">
<code class="descclassname">parsedmarc.elastic.</code><code class="descname">create_indexes</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc/elastic.html#create_indexes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.elastic.create_indexes" title="Permalink to this definition"></a></dt>
<dd><p>Creates the required indexes</p>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.elastic.save_aggregate_report_to_elasticsearch">
<code class="descclassname">parsedmarc.elastic.</code><code class="descname">save_aggregate_report_to_elasticsearch</code><span class="sig-paren">(</span><em>aggregate_report</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc/elastic.html#save_aggregate_report_to_elasticsearch"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.elastic.save_aggregate_report_to_elasticsearch" title="Permalink to this definition"></a></dt>
<dd><p>Saves a parsed DMARC aggregate report to ElasticSearch</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>aggregate_report</strong> (<em>OrderedDict</em>) A parsed forensic report</td>
</tr>
<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><a class="reference internal" href="#parsedmarc.elastic.AlreadySaved" title="parsedmarc.elastic.AlreadySaved"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AlreadySaved</span></code></a></td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.elastic.save_forensic_report_to_elasticsearch">
<code class="descclassname">parsedmarc.elastic.</code><code class="descname">save_forensic_report_to_elasticsearch</code><span class="sig-paren">(</span><em>forensic_report</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc/elastic.html#save_forensic_report_to_elasticsearch"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.elastic.save_forensic_report_to_elasticsearch" title="Permalink to this definition"></a></dt>
<dd><p>Saves a parsed DMARC forensic report to ElasticSearch</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>forensic_report</strong> (<em>OrderedDict</em>) A parsed forensic report</td>
</tr>
<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><a class="reference internal" href="#parsedmarc.elastic.AlreadySaved" title="parsedmarc.elastic.AlreadySaved"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AlreadySaved</span></code></a></td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="function">
<dt id="parsedmarc.elastic.set_hosts">
<code class="descclassname">parsedmarc.elastic.</code><code class="descname">set_hosts</code><span class="sig-paren">(</span><em>hosts</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/parsedmarc/elastic.html#set_hosts"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#parsedmarc.elastic.set_hosts" title="Permalink to this definition"></a></dt>
<dd><p>Sets the Elasticsearch hosts to use</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>hosts</strong> A single hostname or URL, or list of hostnames or URLs</td>
</tr>
</tbody>
</table>
</dd></dl>
<div class="toctree-wrapper compound">
</div>
</div>
</div>
<div class="section" id="indices-and-tables">
<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
</ul>
</div>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Sean Whalen.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'3.5.0',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>