This commit is contained in:
Sean Whalen
2018-03-26 13:55:03 -04:00
parent 31c70a5554
commit 47c79a298c
9 changed files with 166 additions and 259 deletions
+4 -4
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Overview: module code &mdash; parsedmarc 2.1.2 documentation</title>
<title>Overview: module code &mdash; parsedmarc 3.0.0 documentation</title>
@@ -35,7 +35,7 @@
<link rel="index" title="Index"
href="../genindex.html"/>
<link rel="search" title="Search" href="../search.html"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="../index.html"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="../index.html"/>
<script src="../_static/js/modernizr.min.js"></script>
@@ -64,7 +64,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -187,7 +187,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+87 -207
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc &mdash; parsedmarc 2.1.2 documentation</title>
<title>parsedmarc &mdash; parsedmarc 3.0.0 documentation</title>
@@ -35,7 +35,7 @@
<link rel="index" title="Index"
href="../genindex.html"/>
<link rel="search" title="Search" href="../search.html"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="../index.html"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="../index.html"/>
<link rel="up" title="Module code" href="index.html"/>
@@ -65,7 +65,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -153,10 +153,9 @@
<div itemprop="articleBody">
<h1>Source code for parsedmarc</h1><div class="highlight"><pre>
<span></span><span class="ch">#!/usr/bin/env python3</span>
<span class="c1"># -*- coding: utf-8 -*-</span>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;A Python module and CLI for parsing DMARC reports&quot;&quot;&quot;</span>
<span class="sd">&quot;&quot;&quot;A Python module for parsing DMARC reports&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">os</span>
@@ -171,14 +170,12 @@
<span class="kn">from</span> <span class="nn">csv</span> <span class="k">import</span> <span class="n">DictWriter</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">from</span> <span class="nn">base64</span> <span class="k">import</span> <span class="n">b64decode</span>
<span class="kn">import</span> <span class="nn">binascii</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">argparse</span> <span class="k">import</span> <span class="n">ArgumentParser</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">email</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="k">import</span> <span class="n">sleep</span>
<span class="kn">from</span> <span class="nn">email.mime.application</span> <span class="k">import</span> <span class="n">MIMEApplication</span>
<span class="kn">from</span> <span class="nn">email.mime.multipart</span> <span class="k">import</span> <span class="n">MIMEMultipart</span>
<span class="kn">from</span> <span class="nn">email.mime.text</span> <span class="k">import</span> <span class="n">MIMEText</span>
@@ -199,14 +196,17 @@
<span class="kn">import</span> <span class="nn">dateparser</span>
<span class="kn">import</span> <span class="nn">mailparser</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;2.1.2&quot;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;3.0.0&quot;</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="n">feedback_report_regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;^([\w\-]+): (.+)$&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">MULTILINE</span><span class="p">)</span>
<span class="n">MAGIC_ZIP</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x50\x4B\x03\x04</span><span class="s2">&quot;</span>
<span class="n">MAGIC_GZIP</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x1F\x8B</span><span class="s2">&quot;</span>
<span class="n">MAGIC_XML</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x3c\x3f\x78\x6d\x6c\x20</span><span class="s2">&quot;</span>
<div class="viewcode-block" id="ParserError"><a class="viewcode-back" href="../index.html#parsedmarc.ParserError">[docs]</a><span class="k">class</span> <span class="nc">ParserError</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Raised whenever the parser fails for some reason&quot;&quot;&quot;</span></div>
@@ -281,6 +281,7 @@
<span class="sd"> domain (str): The domain or subdomain to query about</span>
<span class="sd"> record_type (str): The record type to query for</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -288,8 +289,9 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">resolver</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">Resolver</span><span class="p">()</span>
<span class="n">timeout</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
<span class="k">if</span> <span class="n">nameservers</span><span class="p">:</span>
<span class="n">resolver</span><span class="o">.</span><span class="n">nameservers</span> <span class="o">=</span> <span class="n">nameservers</span>
<span class="k">if</span> <span class="n">nameservers</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">nameservers</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;8.8.8.8&quot;</span><span class="p">,</span> <span class="s2">&quot;4.4.4.4&quot;</span><span class="p">]</span>
<span class="n">resolver</span><span class="o">.</span><span class="n">nameservers</span> <span class="o">=</span> <span class="n">nameservers</span>
<span class="n">resolver</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span>
<span class="n">resolver</span><span class="o">.</span><span class="n">lifetime</span> <span class="o">=</span> <span class="n">timeout</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span>
@@ -303,7 +305,8 @@
<span class="sd"> Args:</span>
<span class="sd"> ip_address (str): The IP address to resolve</span>
<span class="sd"> nameservers (list): A list of nameservers to query</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS query timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -327,7 +330,7 @@
<span class="sd"> Converts a UNIX/DMARC timestamp to a Python ``DateTime`` object</span>
<span class="sd"> Args:</span>
<span class="sd"> timestamp: The timestamp</span>
<span class="sd"> timestamp (int): The timestamp</span>
<span class="sd"> Returns:</span>
<span class="sd"> DateTime: The converted timestamp as a Python ``DateTime`` object</span>
@@ -374,7 +377,7 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">db_filename</span> <span class="o">=</span> <span class="s2">&quot;.GeoLite2-Country.mmdb&quot;</span>
<span class="k">def</span> <span class="nf">download_country_database</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="s2">&quot;GeoLite2-Country.mmdb&quot;</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">download_country_database</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="s2">&quot;.GeoLite2-Country.mmdb&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Downloads the MaxMind Geolite2 Country database</span>
<span class="sd"> Args:</span>
@@ -387,10 +390,8 @@
<span class="n">tar_dir</span> <span class="o">=</span> <span class="n">tar_file</span><span class="o">.</span><span class="n">getnames</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">tar_path</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">/</span><span class="si">{1}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">tar_dir</span><span class="p">,</span> <span class="n">original_filename</span><span class="p">)</span>
<span class="n">tar_file</span><span class="o">.</span><span class="n">extract</span><span class="p">(</span><span class="n">tar_path</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">tar_path</span><span class="p">,</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">tar_path</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">tar_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">location</span> <span class="o">!=</span> <span class="n">original_filename</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="s2">&quot;GeoLite2-Country.mmdb&quot;</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
<span class="n">system_paths</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;/usr/local/share/GeoIP/GeoLite2-Country.mmdb&quot;</span><span class="p">,</span>
<span class="s2">&quot;/usr/share/GeoIP/GeoLite2-Country.mmdb&quot;</span><span class="p">]</span>
@@ -408,7 +409,6 @@
<span class="n">db_age</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
<span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">db_filename</span><span class="p">)</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">)</span>
<span class="k">if</span> <span class="n">db_age</span> <span class="o">&gt;</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">60</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">db_path</span><span class="p">)</span>
<span class="n">download_country_database</span><span class="p">()</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="n">db_filename</span>
@@ -429,8 +429,9 @@
<span class="sd"> Returns reverse DNS and country information for the given IP address</span>
<span class="sd"> Args:</span>
<span class="sd"> ip_address: The IP address to check</span>
<span class="sd"> ip_address (str): The IP address to check</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -462,11 +463,14 @@
<span class="sd"> Args:</span>
<span class="sd"> record (OrderedDict): The record to convert</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
<span class="sd"> OrderedDict: The converted record</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">nameservers</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">nameservers</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;8.8.8.8&quot;</span><span class="p">,</span> <span class="s2">&quot;4.4.4.4&quot;</span><span class="p">]</span>
<span class="n">record</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">new_record</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span>
<span class="n">new_record</span><span class="p">[</span><span class="s2">&quot;source&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_ip_address_info</span><span class="p">(</span><span class="n">record</span><span class="p">[</span><span class="s2">&quot;row&quot;</span><span class="p">][</span><span class="s2">&quot;source_ip&quot;</span><span class="p">],</span>
@@ -553,6 +557,7 @@
<span class="sd"> Args:</span>
<span class="sd"> xml (str): A string of DMARC aggregate report XML</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -566,13 +571,18 @@
<span class="n">schema</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">&quot;version&quot;</span><span class="p">]</span>
<span class="n">new_report</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;xml_schema&quot;</span><span class="p">,</span> <span class="n">schema</span><span class="p">)])</span>
<span class="n">new_report_metadata</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;org_name&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">report_metadata</span><span class="p">[</span><span class="s2">&quot;org_name&quot;</span><span class="p">]</span>
<span class="n">org_name</span> <span class="o">=</span> <span class="n">_get_base_domain</span><span class="p">(</span><span class="n">report_metadata</span><span class="p">[</span><span class="s2">&quot;org_name&quot;</span><span class="p">])</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;org_name&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">org_name</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;org_email&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">report_metadata</span><span class="p">[</span><span class="s2">&quot;email&quot;</span><span class="p">]</span>
<span class="n">extra</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="s2">&quot;extra_contact_info&quot;</span> <span class="ow">in</span> <span class="n">report_metadata</span><span class="p">:</span>
<span class="n">extra</span> <span class="o">=</span> <span class="n">report_metadata</span><span class="p">[</span><span class="s2">&quot;extra_contact_info&quot;</span><span class="p">]</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;org_extra_contact_info&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">extra</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;report_id&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">report_metadata</span><span class="p">[</span><span class="s2">&quot;report_id&quot;</span><span class="p">]</span>
<span class="n">report_id</span> <span class="o">=</span> <span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;report_id&quot;</span><span class="p">]</span>
<span class="n">report_id</span> <span class="o">=</span> <span class="n">report_id</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;&lt;&quot;</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;@&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">new_report_metadata</span><span class="p">[</span><span class="s2">&quot;report_id&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">report_id</span>
<span class="n">date_range</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">&quot;report_metadata&quot;</span><span class="p">][</span><span class="s2">&quot;date_range&quot;</span><span class="p">]</span>
<span class="n">date_range</span><span class="p">[</span><span class="s2">&quot;begin&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_timestamp_to_human</span><span class="p">(</span><span class="n">date_range</span><span class="p">[</span><span class="s2">&quot;begin&quot;</span><span class="p">])</span>
<span class="n">date_range</span><span class="p">[</span><span class="s2">&quot;end&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_timestamp_to_human</span><span class="p">(</span><span class="n">date_range</span><span class="p">[</span><span class="s2">&quot;end&quot;</span><span class="p">])</span>
@@ -657,12 +667,12 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">header</span> <span class="o">=</span> <span class="n">file_object</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="n">file_object</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">if</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x50\x4B\x03\x04</span><span class="s2">&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_ZIP</span><span class="p">):</span>
<span class="n">_zip</span> <span class="o">=</span> <span class="n">zipfile</span><span class="o">.</span><span class="n">ZipFile</span><span class="p">(</span><span class="n">file_object</span><span class="p">)</span>
<span class="n">xml</span> <span class="o">=</span> <span class="n">_zip</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">_zip</span><span class="o">.</span><span class="n">namelist</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x1F\x8B</span><span class="s2">&quot;</span><span class="p">):</span>
<span class="k">elif</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_GZIP</span><span class="p">):</span>
<span class="n">xml</span> <span class="o">=</span> <span class="n">GzipFile</span><span class="p">(</span><span class="n">fileobj</span><span class="o">=</span><span class="n">file_object</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;</span><span class="se">\x3c\x3f\x78\x6d\x6c\x20</span><span class="s2">&quot;</span><span class="p">):</span>
<span class="k">elif</span> <span class="n">header</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_XML</span><span class="p">):</span>
<span class="n">xml</span> <span class="o">=</span> <span class="n">file_object</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">file_object</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
@@ -684,6 +694,7 @@
<span class="sd"> Args:</span>
<span class="sd"> _input: A path to a file, a file like object, or bytes</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -806,10 +817,11 @@
<span class="sd"> Converts a DMARC forensic report and sample to a ``OrderedDict``</span>
<span class="sd"> Args:</span>
<span class="sd"> feedback_report: A message&#39;s feedback report as a string</span>
<span class="sd"> sample: The RFC 822 headers or RFC 822 message sample</span>
<span class="sd"> feedback_report (str): A message&#39;s feedback report as a string</span>
<span class="sd"> sample (str): The RFC 822 headers or RFC 822 message sample</span>
<span class="sd"> sample_headers_only (bool): Set true if the sample is only headers</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -830,10 +842,10 @@
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Converts a message subject to a string that is safe for a filename</span>
<span class="sd"> Args:</span>
<span class="sd"> _subject: A message subject</span>
<span class="sd"> _subject (str): A message subject</span>
<span class="sd"> Returns:</span>
<span class="sd"> A string safe for a filename</span>
<span class="sd"> str: A string safe for a filename</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">invalid_filename_chars</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="s1">&#39;|&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span>
<span class="s1">&#39;</span><span class="se">\r</span><span class="s1">&#39;</span><span class="p">]</span>
@@ -924,7 +936,7 @@
<span class="n">parsed_sample</span><span class="p">[</span><span class="s2">&quot;delivered_to&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span>
<span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">convert_address</span><span class="p">(</span><span class="n">x</span><span class="p">),</span>
<span class="n">parsed_sample</span><span class="p">[</span><span class="s2">&quot;delivered_to&quot;</span><span class="p">])</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;attachments&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">parsed_sample</span><span class="p">:</span>
<span class="n">parsed_sample</span><span class="p">[</span><span class="s2">&quot;attachments&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
@@ -1070,8 +1082,7 @@
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span> <span class="o">==</span> <span class="nb">bytes</span><span class="p">:</span>
<span class="k">if</span> <span class="n">is_outlook_msg</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
<span class="n">input_</span> <span class="o">=</span> <span class="n">convert_outlook_msg</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">input_</span> <span class="o">=</span> <span class="n">input_</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s2">&quot;replace&quot;</span><span class="p">)</span>
<span class="n">input_</span> <span class="o">=</span> <span class="n">input_</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s2">&quot;replace&quot;</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span>
<span class="n">subject</span> <span class="o">=</span> <span class="kc">None</span>
@@ -1081,10 +1092,6 @@
<span class="k">if</span> <span class="s2">&quot;subject&quot;</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">:</span>
<span class="n">subject</span> <span class="o">=</span> <span class="n">decode_header</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="s2">&quot;subject&quot;</span><span class="p">])</span>
<span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">msg</span><span class="o">.</span><span class="n">walk</span><span class="p">():</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">get_filename</span><span class="p">()</span>
<span class="k">if</span> <span class="n">filename</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">filename</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">get_content_type</span><span class="p">()</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">get_payload</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span> <span class="o">==</span> <span class="nb">list</span><span class="p">:</span>
@@ -1106,15 +1113,21 @@
<span class="n">result</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;report_type&quot;</span><span class="p">,</span> <span class="s2">&quot;forensic&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;report&quot;</span><span class="p">,</span> <span class="n">forensic_report</span><span class="p">)])</span>
<span class="k">return</span> <span class="n">result</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b64decode</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="k">if</span> <span class="n">payload</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_ZIP</span><span class="p">)</span> <span class="ow">or</span> \
<span class="n">payload</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_GZIP</span><span class="p">)</span> <span class="ow">or</span> \
<span class="n">payload</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">MAGIC_XML</span><span class="p">):</span>
<span class="n">ns</span> <span class="o">=</span> <span class="n">nameservers</span>
<span class="n">aggregate_report</span> <span class="o">=</span> <span class="n">parse_aggregate_report_file</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="n">ns</span><span class="p">,</span>
<span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;report_type&quot;</span><span class="p">,</span> <span class="s2">&quot;aggregate&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;report&quot;</span><span class="p">,</span> <span class="n">aggregate_report</span><span class="p">)])</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">Error</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;.gz&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;.zip&quot;</span><span class="p">):</span>
<span class="n">ns</span> <span class="o">=</span> <span class="n">nameservers</span>
<span class="n">xml</span> <span class="o">=</span> <span class="n">b64decode</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">get_payload</span><span class="p">())</span>
<span class="n">aggregate_report</span> <span class="o">=</span> <span class="n">parse_aggregate_report_file</span><span class="p">(</span><span class="n">xml</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="n">ns</span><span class="p">,</span>
<span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;report_type&quot;</span><span class="p">,</span> <span class="s2">&quot;aggregate&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;report&quot;</span><span class="p">,</span> <span class="n">aggregate_report</span><span class="p">)])</span>
<span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">error</span> <span class="o">=</span> <span class="s1">&#39;Message with subject &quot;</span><span class="si">{0}</span><span class="s1">&quot; is &#39;</span> \
<span class="s1">&#39;not a valid DMARC report&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span>
@@ -1130,6 +1143,7 @@
<span class="sd"> Args:</span>
<span class="sd"> input_: A path to a file, a file like object, or bytes</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> timeout (float): Sets the DNS timeout in seconds</span>
<span class="sd"> Returns:</span>
@@ -1160,6 +1174,7 @@
<div class="viewcode-block" id="get_dmarc_reports_from_inbox"><a class="viewcode-back" href="../index.html#parsedmarc.get_dmarc_reports_from_inbox">[docs]</a><span class="k">def</span> <span class="nf">get_dmarc_reports_from_inbox</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span>
<span class="n">reports_folder</span><span class="o">=</span><span class="s2">&quot;INBOX&quot;</span><span class="p">,</span>
<span class="n">archive_folder</span><span class="o">=</span><span class="s2">&quot;Archive&quot;</span><span class="p">,</span>
<span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">test</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
@@ -1171,6 +1186,7 @@
<span class="sd"> host: The mail server hostname or IP address</span>
<span class="sd"> user: The mail server user</span>
<span class="sd"> password: The mail server password</span>
<span class="sd"> reports_folder: The IMAP folder where reports can be found</span>
<span class="sd"> archive_folder: The folder to move processed mail to</span>
<span class="sd"> delete (bool): Delete messages after processing them</span>
<span class="sd"> test (bool): Do not move or delete messages after processing them</span>
@@ -1180,6 +1196,12 @@
<span class="sd"> Returns:</span>
<span class="sd"> OrderedDict: Lists of ``aggregate_reports`` and ``forensic_reports``</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">chunks</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Yield successive n-sized chunks from l.&quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">),</span> <span class="n">n</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="n">n</span><span class="p">]</span>
<span class="k">if</span> <span class="n">delete</span> <span class="ow">and</span> <span class="n">test</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;delete and test options are mutually exclusive&quot;</span><span class="p">)</span>
@@ -1187,16 +1209,13 @@
<span class="n">forensic_reports</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">aggregate_report_msg_uids</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">forensic_report_msg_uids</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">aggregate_reports_folder</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">/Aggregate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">),</span>
<span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">forensic_reports_folder</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">/Forensic&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">),</span>
<span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">archive_folder</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">aggregate_reports_folder</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">/Aggregate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">)</span>
<span class="n">forensic_reports_folder</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">/Forensic&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">imapclient</span><span class="o">.</span><span class="n">IMAPClient</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">use_uid</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">select_folder</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;INBOX&#39;</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">select_folder</span><span class="p">(</span><span class="n">reports_folder</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">server</span><span class="o">.</span><span class="n">folder_exists</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">):</span>
<span class="n">server</span><span class="o">.</span><span class="n">create_folder</span><span class="p">(</span><span class="n">archive_folder</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">server</span><span class="o">.</span><span class="n">folder_exists</span><span class="p">(</span><span class="n">aggregate_reports_folder</span><span class="p">):</span>
@@ -1206,7 +1225,7 @@
<span class="n">messages</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">search</span><span class="p">()</span>
<span class="k">for</span> <span class="n">message_uid</span> <span class="ow">in</span> <span class="n">messages</span><span class="p">:</span>
<span class="n">raw_msg</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">message_uid</span><span class="p">,</span>
<span class="p">[</span><span class="sa">b</span><span class="s1">&#39;RFC822&#39;</span><span class="p">])[</span><span class="n">message_uid</span><span class="p">][</span><span class="sa">b</span><span class="s1">&#39;RFC822&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;RFC822&quot;</span><span class="p">])[</span><span class="n">message_uid</span><span class="p">][</span><span class="sa">b</span><span class="s2">&quot;RFC822&quot;</span><span class="p">]</span>
<span class="n">msg_content</span> <span class="o">=</span> <span class="n">raw_msg</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s2">&quot;replace&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
@@ -1230,11 +1249,13 @@
<span class="n">server</span><span class="o">.</span><span class="n">expunge</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">aggregate_report_msg_uids</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">server</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">aggregate_report_msg_uids</span><span class="p">,</span>
<span class="n">aggregate_reports_folder</span><span class="p">)</span>
<span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="n">chunks</span><span class="p">(</span><span class="n">aggregate_report_msg_uids</span><span class="p">,</span> <span class="mi">100</span><span class="p">):</span>
<span class="n">server</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">chunk</span><span class="p">,</span>
<span class="n">aggregate_reports_folder</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">forensic_report_msg_uids</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">server</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">forensic_report_msg_uids</span><span class="p">,</span>
<span class="n">forensic_reports_folder</span><span class="p">)</span>
<span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="n">chunks</span><span class="p">(</span><span class="n">forensic_report_msg_uids</span><span class="p">,</span> <span class="mi">100</span><span class="p">):</span>
<span class="n">server</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">chunk</span><span class="p">,</span>
<span class="n">forensic_reports_folder</span><span class="p">)</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;aggregate_reports&quot;</span><span class="p">,</span> <span class="n">aggregate_reports</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;forensic_reports&quot;</span><span class="p">,</span> <span class="n">forensic_reports</span><span class="p">)])</span>
@@ -1446,9 +1467,9 @@
<span class="k">raise</span> <span class="n">SMTPError</span><span class="p">(</span><span class="s2">&quot;Certificate error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()))</span></div>
<div class="viewcode-block" id="watch_inbox"><a class="viewcode-back" href="../index.html#parsedmarc.watch_inbox">[docs]</a><span class="k">def</span> <span class="nf">watch_inbox</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">archive_folder</span><span class="o">=</span><span class="s2">&quot;Archive&quot;</span><span class="p">,</span>
<span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">test</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">wait</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">nameservers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">dns_timeout</span><span class="o">=</span><span class="mf">6.0</span><span class="p">):</span>
<div class="viewcode-block" id="watch_inbox"><a class="viewcode-back" href="../index.html#parsedmarc.watch_inbox">[docs]</a><span class="k">def</span> <span class="nf">watch_inbox</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">reports_folder</span><span class="o">=</span><span class="s2">&quot;INBOX&quot;</span><span class="p">,</span>
<span class="n">archive_folder</span><span class="o">=</span><span class="s2">&quot;Archive&quot;</span><span class="p">,</span> <span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">test</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">wait</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">dns_timeout</span><span class="o">=</span><span class="mf">6.0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use an IDLE IMAP connection to parse incoming emails, and pass the results</span>
<span class="sd"> to a callback function</span>
@@ -1458,13 +1479,16 @@
<span class="sd"> username: The mail server username</span>
<span class="sd"> password: The mail server password</span>
<span class="sd"> callback: The callback function to receive the parsing results</span>
<span class="sd"> reports_folder: The IMAP folder where reports can be found</span>
<span class="sd"> archive_folder: The folder to move processed mail to</span>
<span class="sd"> delete (bool): Delete messages after processing them</span>
<span class="sd"> test (bool): Do not move or delete messages after processing them</span>
<span class="sd"> wait (int): Number of seconds to wait for a IMAP IDLE response</span>
<span class="sd"> nameservers (list): A list of DNS nameservers to query</span>
<span class="sd"> nameservers (list): A list of one or more nameservers to use</span>
<span class="sd"> (8.8.8.8 and 4.4.4.4 by default)</span>
<span class="sd"> dns_timeout (float): Set the DNS query timeout</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rf</span> <span class="o">=</span> <span class="n">reports_folder</span>
<span class="n">af</span> <span class="o">=</span> <span class="n">archive_folder</span>
<span class="n">ns</span> <span class="o">=</span> <span class="n">nameservers</span>
<span class="n">dt</span> <span class="o">=</span> <span class="n">dns_timeout</span>
@@ -1472,7 +1496,7 @@
<span class="n">server</span> <span class="o">=</span> <span class="n">imapclient</span><span class="o">.</span><span class="n">IMAPClient</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">select_folder</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;INBOX&#39;</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">select_folder</span><span class="p">(</span><span class="n">rf</span><span class="p">)</span>
<span class="c1"># Start IDLE mode</span>
<span class="n">server</span><span class="o">.</span><span class="n">idle</span><span class="p">()</span>
@@ -1485,12 +1509,14 @@
<span class="k">if</span> <span class="n">response</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;RECENT&#39;</span> <span class="ow">and</span> <span class="n">response</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">get_dmarc_reports_from_inbox</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span>
<span class="n">password</span><span class="p">,</span>
<span class="n">reports_folder</span><span class="o">=</span><span class="n">rf</span><span class="p">,</span>
<span class="n">archive_folder</span><span class="o">=</span><span class="n">af</span><span class="p">,</span>
<span class="n">delete</span><span class="o">=</span><span class="n">delete</span><span class="p">,</span>
<span class="n">test</span><span class="o">=</span><span class="n">test</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="n">ns</span><span class="p">,</span>
<span class="n">dns_timeout</span><span class="o">=</span><span class="n">dt</span><span class="p">)</span>
<span class="n">callback</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">except</span> <span class="n">imapclient</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">IMAPClientError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">error</span> <span class="o">=</span> <span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;b&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)</span>
@@ -1515,152 +1541,6 @@
<span class="n">server</span><span class="o">.</span><span class="n">idle_done</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">IDLE mode done&quot;</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">logout</span><span class="p">()</span></div>
<span class="k">def</span> <span class="nf">_main</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;Called when the module in executed&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">print_results</span><span class="p">(</span><span class="n">results_</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Print results in human readable format</span>
<span class="sd"> Args:</span>
<span class="sd"> results_ (OrderedDict): Parsing results</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="nb">print</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">results_</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span> <span class="o">=</span> <span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Parses DMARC reports&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;file_path&quot;</span><span class="p">,</span> <span class="n">nargs</span><span class="o">=</span><span class="s2">&quot;*&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;one or more paths of aggregate report &quot;</span>
<span class="s2">&quot;files (compressed or uncompressed)&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-o&quot;</span><span class="p">,</span> <span class="s2">&quot;--output&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Write output files to the given directory&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-n&quot;</span><span class="p">,</span> <span class="s2">&quot;--nameservers&quot;</span><span class="p">,</span> <span class="n">nargs</span><span class="o">=</span><span class="s2">&quot;+&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;nameservers to query&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-t&quot;</span><span class="p">,</span> <span class="s2">&quot;--timeout&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;number of seconds to wait for an answer &quot;</span>
<span class="s2">&quot;from DNS (default 6.0)&quot;</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="nb">float</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="mf">6.0</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-H&quot;</span><span class="p">,</span> <span class="s2">&quot;--host&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;IMAP hostname or IP address&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-u&quot;</span><span class="p">,</span> <span class="s2">&quot;--user&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;IMAP user&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-p&quot;</span><span class="p">,</span> <span class="s2">&quot;--password&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;IMAP password&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-a&quot;</span><span class="p">,</span> <span class="s2">&quot;--archive-folder&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Specifies the IMAP folder to move &quot;</span>
<span class="s2">&quot;messages to after processing them &quot;</span>
<span class="s2">&quot;(default: Archive)&quot;</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="s2">&quot;Archive&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-d&quot;</span><span class="p">,</span> <span class="s2">&quot;--delete&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Delete the reports after processing them&quot;</span><span class="p">,</span>
<span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-O&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-host&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this host&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-U&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-user&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this user&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-P&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-password&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this password&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-F&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-from&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this from address&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-T&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-to&quot;</span><span class="p">,</span> <span class="n">nargs</span><span class="o">=</span><span class="s2">&quot;+&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results to these addresses&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-S&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-subject&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this subject&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-A&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-attachment&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this filename&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-M&quot;</span><span class="p">,</span> <span class="s2">&quot;--outgoing-message&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Email the results using this message&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-i&quot;</span><span class="p">,</span> <span class="s2">&quot;--idle&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Use an IMAP IDLE connection to process &quot;</span>
<span class="s2">&quot;reports as they arrive in the inbox&quot;</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--test&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Do not move or delete IMAP messages&quot;</span><span class="p">,</span>
<span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-v&quot;</span><span class="p">,</span> <span class="s2">&quot;--version&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;version&quot;</span><span class="p">,</span>
<span class="n">version</span><span class="o">=</span><span class="n">__version__</span><span class="p">)</span>
<span class="n">aggregate_reports</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">forensic_reports</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">arg_parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
<span class="n">file_paths</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">file_path</span> <span class="ow">in</span> <span class="n">args</span><span class="o">.</span><span class="n">file_path</span><span class="p">:</span>
<span class="n">file_paths</span> <span class="o">+=</span> <span class="n">glob</span><span class="p">(</span><span class="n">file_path</span><span class="p">)</span>
<span class="n">file_paths</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">file_paths</span><span class="p">))</span>
<span class="k">for</span> <span class="n">file_path</span> <span class="ow">in</span> <span class="n">file_paths</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">file_results</span> <span class="o">=</span> <span class="n">parse_report_file</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span>
<span class="n">nameservers</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">nameservers</span><span class="p">,</span>
<span class="n">timeout</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
<span class="k">if</span> <span class="n">file_results</span><span class="p">[</span><span class="s2">&quot;report_type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;aggregate&quot;</span><span class="p">:</span>
<span class="n">aggregate_reports</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">file_results</span><span class="p">[</span><span class="s2">&quot;report&quot;</span><span class="p">])</span>
<span class="k">elif</span> <span class="n">file_results</span><span class="p">[</span><span class="s2">&quot;report_type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;forensic&quot;</span><span class="p">:</span>
<span class="n">forensic_reports</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">file_results</span><span class="p">[</span><span class="s2">&quot;report&quot;</span><span class="p">])</span>
<span class="k">except</span> <span class="n">ParserError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Failed to parse </span><span class="si">{0}</span><span class="s2"> - </span><span class="si">{1}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span>
<span class="n">error</span><span class="p">))</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">host</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">user</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;user and password must be specified if&quot;</span>
<span class="s2">&quot;host is specified&quot;</span><span class="p">)</span>
<span class="n">af</span> <span class="o">=</span> <span class="n">args</span><span class="o">.</span><span class="n">archive_folder</span>
<span class="n">reports</span> <span class="o">=</span> <span class="n">get_dmarc_reports_from_inbox</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
<span class="n">args</span><span class="o">.</span><span class="n">user</span><span class="p">,</span>
<span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">,</span>
<span class="n">archive_folder</span><span class="o">=</span><span class="n">af</span><span class="p">,</span>
<span class="n">delete</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">delete</span><span class="p">,</span>
<span class="n">test</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">test</span><span class="p">)</span>
<span class="n">aggregate_reports</span> <span class="o">+=</span> <span class="n">reports</span><span class="p">[</span><span class="s2">&quot;aggregate_reports&quot;</span><span class="p">]</span>
<span class="n">forensic_reports</span> <span class="o">+=</span> <span class="n">reports</span><span class="p">[</span><span class="s2">&quot;forensic_reports&quot;</span><span class="p">]</span>
<span class="k">except</span> <span class="n">IMAPError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;IMAP Error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()))</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">([(</span><span class="s2">&quot;aggregate_reports&quot;</span><span class="p">,</span> <span class="n">aggregate_reports</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;forensic_reports&quot;</span><span class="p">,</span> <span class="n">forensic_reports</span><span class="p">)])</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">output</span><span class="p">:</span>
<span class="n">save_output</span><span class="p">(</span><span class="n">results</span><span class="p">,</span> <span class="n">output_directory</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="n">print_results</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">outgoing_host</span><span class="p">:</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">outgoing_from</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">args</span><span class="o">.</span><span class="n">outgoing_to</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;--outgoing-from and --outgoing-to must &quot;</span>
<span class="s2">&quot;be provided if --outgoing-host is used&quot;</span><span class="p">)</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">email_results</span><span class="p">(</span><span class="n">results</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">outgoing_host</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">outgoing_from</span><span class="p">,</span>
<span class="n">args</span><span class="o">.</span><span class="n">outgoing_to</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">outgoing_user</span><span class="p">,</span>
<span class="n">password</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">outgoing_password</span><span class="p">,</span>
<span class="n">subject</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">outgoing_subject</span><span class="p">)</span>
<span class="k">except</span> <span class="n">SMTPError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;SMTP Error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()))</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">host</span> <span class="ow">and</span> <span class="n">args</span><span class="o">.</span><span class="n">idle</span><span class="p">:</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;The IMAP Connection is now in IDLE mode. &quot;</span>
<span class="s2">&quot;Send yourself an email, or quit with ^c&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">watch_inbox</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">print_results</span><span class="p">,</span>
<span class="n">archive_folder</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">archive_folder</span><span class="p">,</span> <span class="n">delete</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">delete</span><span class="p">,</span>
<span class="n">test</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">test</span><span class="p">,</span> <span class="n">nameservers</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">nameservers</span><span class="p">,</span>
<span class="n">dns_timeout</span><span class="o">=</span><span class="n">args</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
<span class="k">except</span> <span class="n">IMAPError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;IMAP Error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()))</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">_main</span><span class="p">()</span>
</pre></div>
</div>
@@ -1697,7 +1577,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+22 -12
View File
@@ -21,6 +21,7 @@ Features
* Consistent data structures
* Simple JSON and/or CSV output
* Optionally email the results
* Optionally send the results to Elasticsearch, for use with premade Kibana dashboards
CLI help
========
@@ -28,26 +29,28 @@ CLI help
::
usage: parsedmarc [-h] [-o OUTPUT] [-n NAMESERVERS [NAMESERVERS ...]]
[-t TIMEOUT] [-H HOST] [-u USER] [-p PASSWORD]
[-a ARCHIVE_FOLDER] [-d] [-O OUTGOING_HOST]
[-U OUTGOING_USER] [-P OUTGOING_PASSWORD]
[-F OUTGOING_FROM] [-T OUTGOING_TO [OUTGOING_TO ...]]
[-S OUTGOING_SUBJECT] [-A OUTGOING_ATTACHMENT]
[-M OUTGOING_MESSAGE] [-i] [--test] [-v]
[file_path [file_path ...]]
[-t TIMEOUT] [-H HOST] [-u USER] [-p PASSWORD]
[-r REPORTS_FOLDER] [-a ARCHIVE_FOLDER] [-d]
[-E [ELASTICSEARCH_HOST [ELASTICSEARCH_HOST ...]]]
[--save-aggregate] [--save-forensic] [-O OUTGOING_HOST]
[-U OUTGOING_USER] [-P OUTGOING_PASSWORD] [-F OUTGOING_FROM]
[-T OUTGOING_TO [OUTGOING_TO ...]] [-S OUTGOING_SUBJECT]
[-A OUTGOING_ATTACHMENT] [-M OUTGOING_MESSAGE] [-i] [--test]
[-v]
[file_path [file_path ...]]
Parses DMARC reports
positional arguments:
file_path one or more paths of aggregate report files
(compressed or uncompressed)
file_path one or more paths to aggregate or forensic report
files or emails
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Write output files to the given directory
-n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...]
nameservers to query
nameservers to query (Default 8.8.8.8 4.4.4.4)
-t TIMEOUT, --timeout TIMEOUT
number of seconds to wait for an answer from DNS
(default 6.0)
@@ -55,10 +58,17 @@ CLI help
-u USER, --user USER IMAP user
-p PASSWORD, --password PASSWORD
IMAP password
-r REPORTS_FOLDER, --reports-folder REPORTS_FOLDER
The IMAP folder containing the reports Default: INBOX
-a ARCHIVE_FOLDER, --archive-folder ARCHIVE_FOLDER
Specifies the IMAP folder to move messages to after
processing them (default: Archive)
processing them Default: Archive
-d, --delete Delete the reports after processing them
-E [ELASTICSEARCH_HOST [ELASTICSEARCH_HOST ...]], --elasticsearch-host [ELASTICSEARCH_HOST [ELASTICSEARCH_HOST ...]]
A list of one or more Elasticsearch hostnames or URLs
to use (Default localhost:9200)
--save-aggregate Save aggregate reports to Elasticsearch
--save-forensic Save forensic reports to Elasticsearch
-O OUTGOING_HOST, --outgoing-host OUTGOING_HOST
Email the results using this host
-U OUTGOING_USER, --outgoing-user OUTGOING_USER
@@ -188,7 +198,7 @@ https://github.com/domainaware/parsedmarc/issues
Installation
============
``parsedmarc`` works with Python 2 or 3, but Python 3 is preferred.
``parsedmarc`` works with Python 3 only.
On Debian or Ubuntu systems, run:
+4 -4
View File
@@ -9,7 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index &mdash; parsedmarc 2.1.2 documentation</title>
<title>Index &mdash; parsedmarc 3.0.0 documentation</title>
@@ -36,7 +36,7 @@
<link rel="index" title="Index"
href="#"/>
<link rel="search" title="Search" href="search.html"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="index.html"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="index.html"/>
<script src="_static/js/modernizr.min.js"></script>
@@ -65,7 +65,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -293,7 +293,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+39 -22
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to parsedmarcs documentation! &mdash; parsedmarc 2.1.2 documentation</title>
<title>Welcome to parsedmarcs documentation! &mdash; parsedmarc 3.0.0 documentation</title>
@@ -35,7 +35,7 @@
<link rel="index" title="Index"
href="genindex.html"/>
<link rel="search" title="Search" href="search.html"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="#"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="#"/>
<script src="_static/js/modernizr.min.js"></script>
@@ -64,7 +64,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -186,31 +186,34 @@
<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"><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">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">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">i</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">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="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">i</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">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">of</span> <span class="n">aggregate</span> <span class="n">report</span> <span class="n">files</span>
<span class="p">(</span><span class="n">compressed</span> <span class="ow">or</span> <span class="n">uncompressed</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="n">nameservers</span> <span class="n">to</span> <span class="n">query</span> <span class="p">(</span><span class="n">Default</span> <span class="mf">8.8</span><span class="o">.</span><span class="mf">8.8</span> <span class="mf">4.4</span><span class="o">.</span><span class="mf">4.4</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="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>
@@ -218,10 +221,17 @@
<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="p">(</span><span class="n">default</span><span class="p">:</span> <span class="n">Archive</span><span class="p">)</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>
@@ -343,7 +353,7 @@ forensic report that you can share publicly, please contact me!</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"><span class="pre">parsedmarc</span></code> works with Python 2 or 3, but Python 3 is preferred.</p>
<p><code class="docutils literal"><span class="pre">parsedmarc</span></code> works with Python 3 only.</p>
<p>On Debian or Ubuntu systems, run:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo apt-get install python3-pip
</pre></div>
@@ -377,7 +387,7 @@ above commands.</p>
</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 module and CLI for parsing DMARC reports</p>
<p>A Python module 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>
@@ -464,7 +474,7 @@ or bytes.</p>
<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>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>
<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" />
@@ -474,6 +484,7 @@ or bytes.</p>
<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>
@@ -540,6 +551,7 @@ aggregate DMARC report</p>
<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>and 4.4.4.4 by default</strong><strong>)</strong> (<em>(</em><em>8.8.8.8</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
@@ -565,6 +577,7 @@ aggregate DMARC report</p>
<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>and 4.4.4.4 by default</strong><strong>)</strong> (<em>(</em><em>8.8.8.8</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
@@ -588,10 +601,11 @@ aggregate DMARC report</p>
<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> A messages feedback report as a string</li>
<li><strong>sample</strong> The RFC 822 headers or RFC 822 message sample</li>
<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>and 4.4.4.4 by default</strong><strong>)</strong> (<em>(</em><em>8.8.8.8</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
@@ -647,6 +661,7 @@ file-like object. or bytes</p>
<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>and 4.4.4.4 by default</strong><strong>)</strong> (<em>(</em><em>8.8.8.8</em>) </li>
<li><strong>timeout</strong> (<em>float</em>) Sets the DNS timeout in seconds</li>
</ul>
</td>
@@ -719,7 +734,7 @@ headers</p>
<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>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>
<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">
@@ -731,11 +746,13 @@ to a callback function</p>
<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 DNS nameservers to query</li>
<li><strong>nameservers</strong> (<em>list</em>) A list of one or more nameservers to use</li>
<li><strong>and 4.4.4.4 by default</strong><strong>)</strong> (<em>(</em><em>8.8.8.8</em>) </li>
<li><strong>dns_timeout</strong> (<em>float</em>) Set the DNS query timeout</li>
</ul>
</td>
@@ -792,7 +809,7 @@ to a callback function</p>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+1 -1
View File
@@ -1,6 +1,6 @@
# Sphinx inventory version 2
# Project: parsedmarc
# Version: 2.1.2
# Version: 3.0.0
# The remainder of this file is compressed using zlib.
xÚ¥”KNÃ0†÷9…lSÑmw©‹HU‹ÄÒrIjÉ/Ù“’²â\Ç -‰¸ìFãÿûÇ3Ù2ç¡TÌqb÷3eÊF¹%B—ÐN¶¨äuÌå7$Ïì—x²(æËçŒ ´,
£Éô”<GôŽIQÎëÚAÍV`Ãdþ¾˜¯î.díOÅ—!t‰ý®‹§ÔbBR¾‘èV5šÿMµèGÚ*9š©iuÕÂ,<­œQTèi“L"N_…mÅ4E¡À#S–¢¡e·!1Ú£)vi¸F%ä¿=RÆ-ªÃZéCÙþí/CÓ».´íÃ3p¿Kõ9ë=ÙÆ³PÓ mÆÏí…!ߎÙÕtŸ!Ë™d$Ÿ’!ÛëÈ"„ÙQVD'ŠgÜt»‰†/ññöîI§mhd¡üUÖ}•¿”³û|8ˆ~EüecaÙö;sQ¼ŽçKVCö <eü
+4 -4
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Module Index &mdash; parsedmarc 2.1.2 documentation</title>
<title>Python Module Index &mdash; parsedmarc 3.0.0 documentation</title>
@@ -35,7 +35,7 @@
<link rel="index" title="Index"
href="genindex.html"/>
<link rel="search" title="Search" href="search.html"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="index.html"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="index.html"/>
<script type="text/javascript">
@@ -71,7 +71,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -209,7 +209,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+4 -4
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search &mdash; parsedmarc 2.1.2 documentation</title>
<title>Search &mdash; parsedmarc 3.0.0 documentation</title>
@@ -35,7 +35,7 @@
<link rel="index" title="Index"
href="genindex.html"/>
<link rel="search" title="Search" href="#"/>
<link rel="top" title="parsedmarc 2.1.2 documentation" href="index.html"/>
<link rel="top" title="parsedmarc 3.0.0 documentation" href="index.html"/>
<script src="_static/js/modernizr.min.js"></script>
@@ -64,7 +64,7 @@
<div class="version">
2.1.2
3.0.0
</div>
@@ -195,7 +195,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'2.1.2',
VERSION:'3.0.0',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
+1 -1
View File
@@ -1 +1 @@
Search.setIndex({docnames:["index"],envversion:53,filenames:["index.rst"],objects:{"":{parsedmarc:[0,0,0,"-"]},parsedmarc:{IMAPError:[0,1,1,""],InvalidAggregateReport:[0,1,1,""],InvalidDMARCReport:[0,1,1,""],InvalidForensicReport:[0,1,1,""],ParserError:[0,1,1,""],SMTPError:[0,1,1,""],email_results:[0,2,1,""],extract_xml:[0,2,1,""],get_dmarc_reports_from_inbox:[0,2,1,""],get_report_zip:[0,2,1,""],human_timestamp_to_datetime:[0,2,1,""],parse_aggregate_report_file:[0,2,1,""],parse_aggregate_report_xml:[0,2,1,""],parse_forensic_report:[0,2,1,""],parse_report_email:[0,2,1,""],parse_report_file:[0,2,1,""],parsed_aggregate_reports_to_csv:[0,2,1,""],parsed_forensic_reports_to_csv:[0,2,1,""],save_output:[0,2,1,""],watch_inbox:[0,2,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:exception","2":"py:function"},terms:{"byte":0,"default":0,"float":0,"function":0,"int":0,"null":0,"return":0,"true":0,DNS:0,OLE:0,The:0,Use:0,_input:0,abl:0,abov:0,acm:0,actual:0,address:0,adkim:0,administr:0,adsl:0,after:0,aggreg:[],aggregate_report:0,ani:[],answer:0,appendix:0,apt:0,archiv:0,archive_fold:0,argument:0,arriv:0,aspf:0,attach:0,attachment_filenam:0,auth_result:0,base_domain:0,begin_d:0,bellsouth:0,bodi:0,bool:0,callback:0,can:0,check:0,checkdmarc:0,com:0,command:0,compress:0,connect:0,consist:0,contact:0,content:[],context:0,convert:0,count:0,countri:0,creat:0,data:0,datetim:0,debian:0,delet:0,develop:0,directli:0,directori:0,disposit:0,dkim:0,dkim_align:0,dkim_domain:0,dkim_result:0,dkim_selector:0,dmarc:[],dns_timeout:0,domain:0,domainawar:0,don:0,download:0,draft:0,email:0,email_result:0,encount:0,end_dat:0,envelope_from:0,envelope_to:0,error:0,even:0,exampl:0,except:0,exit:0,extract:0,extract_xml:0,fail:0,fals:0,feedback:0,feedback_report:0,fetch:0,few:[],file:0,file_path:0,filenam:0,flat:0,folder:0,forensic_report:0,format:0,found:0,from:0,get:0,get_dmarc_reports_from_inbox:0,get_report_zip:0,git:0,github:0,given:0,gzip:0,handl:0,have:0,header:0,header_from:0,here:0,host:0,hostnam:0,http:0,human:0,human_timestamp:0,human_timestamp_to_datetim:0,identifi:0,idl:0,imap:0,imaperror:0,inbox:0,includ:0,incom:0,index:0,input:0,input_:0,invalid:0,invalidaggregatereport:0,invaliddmarcreport:0,invalidforensicreport:0,ip_address:0,issu:0,latest:0,libemail:0,like:0,linux:0,list:0,look:0,maco:0,mail:0,mail_from:0,mail_to:0,messag:0,mfrom:0,microsoft:0,modul:0,more:0,move:0,msg:0,msgconvert:0,nameserv:0,net:0,none:0,norepli:0,normal:0,number:0,object:0,occur:0,often:[],older:0,one:0,onli:0,option:[],ordereddict:0,org:0,org_email:0,org_extra_contact_info:0,org_nam:0,out:0,outgo:0,outgoing_attach:0,outgoing_from:0,outgoing_host:0,outgoing_messag:0,outgoing_password:0,outgoing_subject:0,outgoing_to:0,outgoing_us:0,outlook:0,output_directori:0,over:0,overrid:0,page:0,paramet:0,pars:0,parse_aggregate_report_fil:0,parse_aggregate_report_xml:0,parse_forensic_report:0,parse_report_email:0,parse_report_fil:0,parsed_aggregate_report_to_csv:[],parsed_aggregate_reports_to_csv:0,parsed_dmarc_forensic_reports_to_csv:[],parsed_forensic_reports_to_csv:0,parser:0,parsererror:0,pasedmarc:0,pass:0,password:0,patch:0,path:0,pct:0,perl:0,pip3:0,pip:0,place:0,plain:0,pleas:0,policy_evalu:0,policy_override_com:0,policy_override_reason:0,policy_publish:0,port:0,posit:0,prefer:0,print:[],privaci:0,process:0,produc:0,program:0,project:0,provid:[],publicli:0,python3:0,python:0,queri:0,rais:0,rather:[],readabl:0,reason:0,receiv:0,recipi:[],record:[],regardless:0,releas:0,report_id:0,report_metadata:0,report_typ:0,requir:0,respons:0,result:0,reverse_dn:0,rfc:0,run:0,sample_headers_onli:0,save:0,save_output:0,schema:0,scope:0,screen:[],search:0,second:0,selector:0,send:[],server:0,set:0,share:0,show:0,shv:0,simpl:0,simpli:0,sister:0,smtp:0,smtperror:0,some:0,sourc:0,source_base_domain:0,source_countri:0,source_ip_address:0,source_reverse_dn:0,specifi:0,spf:[],spf_align:0,spf_domain:0,spf_result:0,spf_scope:0,ssl:0,ssl_context:0,stabl:0,standard:0,start:0,starttl:0,still:0,str:0,string:0,structur:0,subject:0,substitut:0,sudo:0,support:0,system:0,test:0,text:0,than:[],thei:0,them:0,thi:0,those:[],timeout:0,timestamp:0,tracker:0,transpar:0,type:0,ubuntu:0,uncompress:0,upgrad:0,usag:0,use:0,use_ssl:0,user:0,usernam:0,using:0,util:0,valu:0,veri:[],version:0,wait:0,watch_inbox:0,when:0,whenev:0,who:[],wide:0,wiki:0,window:0,work:0,would:0,write:0,www:0,xml:0,xml_schema:0,you:0,yyyi:0,zip:0},titles:["Welcome to parsedmarc\u2019s documentation!"],titleterms:{about:[],aggreg:0,api:0,bug:0,cli:0,csv:0,depend:0,dmarc:0,document:0,featur:0,forens:0,help:0,indic:0,instal:0,json:0,option:0,output:0,parsedmarc:0,record:0,report:0,sampl:0,spf:0,tabl:0,valid:0,welcom:0,what:[]}})
Search.setIndex({docnames:["index"],envversion:53,filenames:["index.rst"],objects:{"":{parsedmarc:[0,0,0,"-"]},parsedmarc:{IMAPError:[0,1,1,""],InvalidAggregateReport:[0,1,1,""],InvalidDMARCReport:[0,1,1,""],InvalidForensicReport:[0,1,1,""],ParserError:[0,1,1,""],SMTPError:[0,1,1,""],email_results:[0,2,1,""],extract_xml:[0,2,1,""],get_dmarc_reports_from_inbox:[0,2,1,""],get_report_zip:[0,2,1,""],human_timestamp_to_datetime:[0,2,1,""],parse_aggregate_report_file:[0,2,1,""],parse_aggregate_report_xml:[0,2,1,""],parse_forensic_report:[0,2,1,""],parse_report_email:[0,2,1,""],parse_report_file:[0,2,1,""],parsed_aggregate_reports_to_csv:[0,2,1,""],parsed_forensic_reports_to_csv:[0,2,1,""],save_output:[0,2,1,""],watch_inbox:[0,2,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:exception","2":"py:function"},terms:{"byte":0,"default":0,"float":0,"function":0,"int":0,"null":0,"return":0,"true":0,DNS:0,OLE:0,The:0,Use:0,_input:0,abl:0,abov:0,acm:0,actual:0,address:0,adkim:0,administr:0,adsl:0,after:0,aggreg:[],aggregate_report:0,ani:[],answer:0,appendix:0,apt:0,archiv:0,archive_fold:0,argument:0,arriv:0,aspf:0,attach:0,attachment_filenam:0,auth_result:0,base_domain:0,begin_d:0,bellsouth:0,bodi:0,bool:0,callback:0,can:0,check:0,checkdmarc:0,com:0,command:0,compress:0,connect:0,consist:0,contact:0,contain:0,content:[],context:0,convert:0,count:0,countri:0,creat:0,dashboard:0,data:0,datetim:0,debian:0,delet:0,develop:0,directli:0,directori:0,disposit:0,dkim:0,dkim_align:0,dkim_domain:0,dkim_result:0,dkim_selector:0,dmarc:[],dns_timeout:0,domain:0,domainawar:0,don:0,download:0,draft:0,elasticsearch:0,elasticsearch_host:0,email:0,email_result:0,encount:0,end_dat:0,envelope_from:0,envelope_to:0,error:0,even:0,exampl:0,except:0,exit:0,extract:0,extract_xml:0,fail:0,fals:0,feedback:0,feedback_report:0,fetch:0,few:[],file:0,file_path:0,filenam:0,flat:0,folder:0,forensic_report:0,format:0,found:0,from:0,get:0,get_dmarc_reports_from_inbox:0,get_report_zip:0,git:0,github:0,given:0,gzip:0,handl:0,have:0,header:0,header_from:0,here:0,host:0,hostnam:0,http:0,human:0,human_timestamp:0,human_timestamp_to_datetim:0,identifi:0,idl:0,imap:0,imaperror:0,inbox:0,includ:0,incom:0,index:0,input:0,input_:0,invalid:0,invalidaggregatereport:0,invaliddmarcreport:0,invalidforensicreport:0,ip_address:0,issu:0,kibana:0,latest:0,libemail:0,like:0,linux:0,list:0,localhost:0,look:0,maco:0,mail:0,mail_from:0,mail_to:0,messag:0,mfrom:0,microsoft:0,modul:0,more:0,move:0,msg:0,msgconvert:0,nameserv:0,net:0,none:0,norepli:0,normal:0,number:0,object:0,occur:0,often:[],older:0,one:0,onli:0,option:[],ordereddict:0,org:0,org_email:0,org_extra_contact_info:0,org_nam:0,out:0,outgo:0,outgoing_attach:0,outgoing_from:0,outgoing_host:0,outgoing_messag:0,outgoing_password:0,outgoing_subject:0,outgoing_to:0,outgoing_us:0,outlook:0,output_directori:0,over:0,overrid:0,page:0,paramet:0,pars:0,parse_aggregate_report_fil:0,parse_aggregate_report_xml:0,parse_forensic_report:0,parse_report_email:0,parse_report_fil:0,parsed_aggregate_report_to_csv:[],parsed_aggregate_reports_to_csv:0,parsed_dmarc_forensic_reports_to_csv:[],parsed_forensic_reports_to_csv:0,parser:0,parsererror:0,pasedmarc:0,pass:0,password:0,patch:0,path:0,pct:0,perl:0,pip3:0,pip:0,place:0,plain:0,pleas:0,policy_evalu:0,policy_override_com:0,policy_override_reason:0,policy_publish:0,port:0,posit:0,prefer:[],premad:0,print:[],privaci:0,process:0,produc:0,program:0,project:0,provid:[],publicli:0,python3:0,python:0,queri:0,rais:0,rather:[],readabl:0,reason:0,receiv:0,recipi:[],record:[],regardless:0,releas:0,report_id:0,report_metadata:0,report_typ:0,reports_fold:0,requir:0,respons:0,result:0,reverse_dn:0,rfc:0,run:0,sample_headers_onli:0,save:0,save_output:0,schema:0,scope:0,screen:[],search:0,second:0,selector:0,send:0,server:0,set:0,share:0,show:0,shv:0,simpl:0,simpli:0,sister:0,smtp:0,smtperror:0,some:0,sourc:0,source_base_domain:0,source_countri:0,source_ip_address:0,source_reverse_dn:0,specifi:0,spf:[],spf_align:0,spf_domain:0,spf_result:0,spf_scope:0,ssl:0,ssl_context:0,stabl:0,standard:0,start:0,starttl:0,still:0,str:0,string:0,structur:0,subject:0,substitut:0,sudo:0,support:0,system:0,test:0,text:0,than:[],thei:0,them:0,thi:0,those:[],timeout:0,timestamp:0,tracker:0,transpar:0,type:0,ubuntu:0,uncompress:[],upgrad:0,url:0,usag:0,use:0,use_ssl:0,user:0,usernam:0,using:0,util:0,valu:0,veri:[],version:0,wait:0,watch_inbox:0,when:0,whenev:0,where:0,who:[],wide:0,wiki:0,window:0,work:0,would:0,write:0,www:0,xml:0,xml_schema:0,you:0,yyyi:0,zip:0},titles:["Welcome to parsedmarc\u2019s documentation!"],titleterms:{about:[],aggreg:0,api:0,bug:0,cli:0,csv:0,depend:0,dmarc:0,document:0,featur:0,forens:0,help:0,indic:0,instal:0,json:0,option:0,output:0,parsedmarc:0,record:0,report:0,sampl:0,spf:0,tabl:0,valid:0,welcom:0,what:[]}})