mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-05-05 03:25:26 +00:00
Update docs
This commit is contained in:
+2
-2
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Overview: module code — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Overview: module code — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
|
||||
+10
-10
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
@@ -1234,8 +1234,8 @@
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_as_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_as_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_aligned"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"alignment"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_aligned"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"alignment"</span><span class="p">][</span><span class="s2">"dkim"</span><span class="p">]</span>
|
||||
@@ -1331,8 +1331,8 @@
|
||||
<span class="s2">"source_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_type"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn_domain"</span><span class="p">,</span>
|
||||
<span class="s2">"source_as_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_as_domain"</span><span class="p">,</span>
|
||||
<span class="s2">"count"</span><span class="p">,</span>
|
||||
<span class="s2">"spf_aligned"</span><span class="p">,</span>
|
||||
<span class="s2">"dkim_aligned"</span><span class="p">,</span>
|
||||
@@ -1541,8 +1541,8 @@
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_asn_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_as_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_as_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"source_country"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"country"</span><span class="p">]</span>
|
||||
<span class="k">del</span> <span class="n">row</span><span class="p">[</span><span class="s2">"source"</span><span class="p">]</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"subject"</span><span class="p">]</span> <span class="o">=</span> <span class="n">report</span><span class="p">[</span><span class="s2">"parsed_sample"</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subject"</span><span class="p">)</span>
|
||||
@@ -1592,8 +1592,8 @@
|
||||
<span class="s2">"source_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_type"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_asn_domain"</span><span class="p">,</span>
|
||||
<span class="s2">"source_as_name"</span><span class="p">,</span>
|
||||
<span class="s2">"source_as_domain"</span><span class="p">,</span>
|
||||
<span class="s2">"delivery_result"</span><span class="p">,</span>
|
||||
<span class="s2">"auth_failure"</span><span class="p">,</span>
|
||||
<span class="s2">"reported_domain"</span><span class="p">,</span>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc.elastic — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc.elastic — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
@@ -165,8 +165,8 @@
|
||||
<span class="n">source_type</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
|
||||
<span class="n">source_asn_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">message_count</span> <span class="o">=</span> <span class="n">Integer</span>
|
||||
<span class="n">disposition</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">dkim_aligned</span> <span class="o">=</span> <span class="n">Boolean</span><span class="p">()</span>
|
||||
@@ -262,8 +262,8 @@
|
||||
<span class="n">source_country</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_reverse_dns</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
|
||||
<span class="n">source_asn_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_authentication_mechanisms</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_auth_failures</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">dkim_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
@@ -595,8 +595,8 @@
|
||||
<span class="n">source_type</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"type"</span><span class="p">],</span>
|
||||
<span class="n">source_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_domain</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_as_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">],</span>
|
||||
<span class="n">source_as_domain</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">],</span>
|
||||
<span class="n">message_count</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"count"</span><span class="p">],</span>
|
||||
<span class="n">disposition</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"policy_evaluated"</span><span class="p">][</span><span class="s2">"disposition"</span><span class="p">],</span>
|
||||
<span class="n">dkim_aligned</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"policy_evaluated"</span><span class="p">][</span><span class="s2">"dkim"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
||||
@@ -785,8 +785,8 @@
|
||||
<span class="n">source_reverse_dns</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"reverse_dns"</span><span class="p">],</span>
|
||||
<span class="n">source_base_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"base_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_asn</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_name</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_as_name</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">],</span>
|
||||
<span class="n">source_as_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">],</span>
|
||||
<span class="n">authentication_mechanisms</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"authentication_mechanisms"</span><span class="p">],</span>
|
||||
<span class="n">auth_failure</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"auth_failure"</span><span class="p">],</span>
|
||||
<span class="n">dkim_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"dkim_domain"</span><span class="p">],</span>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc.opensearch — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc.opensearch — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
@@ -168,8 +168,8 @@
|
||||
<span class="n">source_type</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
|
||||
<span class="n">source_asn_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">message_count</span> <span class="o">=</span> <span class="n">Integer</span>
|
||||
<span class="n">disposition</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">dkim_aligned</span> <span class="o">=</span> <span class="n">Boolean</span><span class="p">()</span>
|
||||
@@ -265,8 +265,8 @@
|
||||
<span class="n">source_country</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_reverse_dns</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">()</span>
|
||||
<span class="n">source_asn_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_asn_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_name</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_as_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_authentication_mechanisms</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">source_auth_failures</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
<span class="n">dkim_domain</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
|
||||
@@ -625,8 +625,8 @@
|
||||
<span class="n">source_type</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"type"</span><span class="p">],</span>
|
||||
<span class="n">source_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_domain</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_as_name</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">],</span>
|
||||
<span class="n">source_as_domain</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">],</span>
|
||||
<span class="n">message_count</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"count"</span><span class="p">],</span>
|
||||
<span class="n">disposition</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"policy_evaluated"</span><span class="p">][</span><span class="s2">"disposition"</span><span class="p">],</span>
|
||||
<span class="n">dkim_aligned</span><span class="o">=</span><span class="n">record</span><span class="p">[</span><span class="s2">"policy_evaluated"</span><span class="p">][</span><span class="s2">"dkim"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
||||
@@ -815,8 +815,8 @@
|
||||
<span class="n">source_reverse_dns</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"reverse_dns"</span><span class="p">],</span>
|
||||
<span class="n">source_base_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"base_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_asn</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_name</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">],</span>
|
||||
<span class="n">source_asn_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">],</span>
|
||||
<span class="n">source_as_name</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">],</span>
|
||||
<span class="n">source_as_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">],</span>
|
||||
<span class="n">authentication_mechanisms</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"authentication_mechanisms"</span><span class="p">],</span>
|
||||
<span class="n">auth_failure</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"auth_failure"</span><span class="p">],</span>
|
||||
<span class="n">dkim_domain</span><span class="o">=</span><span class="n">forensic_report</span><span class="p">[</span><span class="s2">"dkim_domain"</span><span class="p">],</span>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc.splunk — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc.splunk — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
@@ -194,8 +194,8 @@
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_asn"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_asn_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_name"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_asn_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"asn_domain"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_as_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_name"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"source_as_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"source"</span><span class="p">][</span><span class="s2">"as_domain"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"message_count"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"count"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"disposition"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"policy_evaluated"</span><span class="p">][</span><span class="s2">"disposition"</span><span class="p">]</span>
|
||||
<span class="n">new_report</span><span class="p">[</span><span class="s2">"spf_aligned"</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="p">[</span><span class="s2">"alignment"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">]</span>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc.types — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc.types — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
@@ -131,8 +131,8 @@
|
||||
<span class="n">name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="nb">type</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
||||
<span class="n">asn_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span></div>
|
||||
<span class="n">as_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">as_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span></div>
|
||||
|
||||
|
||||
|
||||
|
||||
+354
-67
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc.utils — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc.utils — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="../../_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="../../_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="../../_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
@@ -98,6 +98,7 @@
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">shutil</span>
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">subprocess</span>
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">tempfile</span>
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">time</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">datetime</span><span class="w"> </span><span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">TypedDict</span><span class="p">,</span> <span class="n">Union</span><span class="p">,</span> <span class="n">cast</span>
|
||||
|
||||
@@ -248,8 +249,8 @@
|
||||
<span class="n">name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="nb">type</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
||||
<span class="n">asn_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span></div>
|
||||
<span class="n">as_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">as_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span></div>
|
||||
|
||||
|
||||
|
||||
@@ -584,6 +585,328 @@
|
||||
|
||||
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">_IPDatabaseRecord</span><span class="p">(</span><span class="n">TypedDict</span><span class="p">):</span>
|
||||
<span class="n">country</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
||||
<span class="n">as_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">as_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="InvalidIPinfoAPIKey">
|
||||
<a class="viewcode-back" href="../../api.html#parsedmarc.utils.InvalidIPinfoAPIKey">[docs]</a>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">InvalidIPinfoAPIKey</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Raised when the IPinfo API rejects the configured token."""</span></div>
|
||||
|
||||
|
||||
|
||||
<span class="c1"># IPinfo Lite REST API. When ``_IPINFO_API_TOKEN`` is set, ``get_ip_address_db_record()``</span>
|
||||
<span class="c1"># queries the API first and falls through to the bundled/cached MMDB only on</span>
|
||||
<span class="c1"># rate-limit/quota/network errors. A 401/403 on any lookup propagates as</span>
|
||||
<span class="c1"># ``InvalidIPinfoAPIKey`` so the CLI exits fatally; callers of the library</span>
|
||||
<span class="c1"># should catch it.</span>
|
||||
<span class="n">_IPINFO_API_URL</span> <span class="o">=</span> <span class="s2">"https://api.ipinfo.io/lite"</span>
|
||||
<span class="c1"># Account-info / quota endpoint. Separate from the lookup URL because ``/me``</span>
|
||||
<span class="c1"># lives at the ipinfo.io root, not under ``/lite``. Hitting it at startup</span>
|
||||
<span class="c1"># both validates the token and surfaces plan/usage details; IPinfo documents</span>
|
||||
<span class="c1"># it as a quota-free meta endpoint.</span>
|
||||
<span class="n">_IPINFO_ACCOUNT_URL</span> <span class="o">=</span> <span class="s2">"https://ipinfo.io/me"</span>
|
||||
<span class="n">_IPINFO_API_TOKEN</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">_IPINFO_API_TIMEOUT</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">5.0</span>
|
||||
<span class="c1"># Default cooldowns when the API returns 429/402 without a ``Retry-After``</span>
|
||||
<span class="c1"># header. Rate limits are usually short; quota resets (402) are typically at a</span>
|
||||
<span class="c1"># day/month boundary, so we pick a longer default there.</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMIT_COOLDOWN_SECONDS</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">300.0</span>
|
||||
<span class="n">_IPINFO_API_QUOTA_COOLDOWN_SECONDS</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">3600.0</span>
|
||||
<span class="c1"># Unix timestamp before which lookups skip the API and go straight to the</span>
|
||||
<span class="c1"># MMDB. ``0`` means the API is currently available.</span>
|
||||
<span class="n">_IPINFO_API_COOLDOWN_UNTIL</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span>
|
||||
<span class="c1"># Latch for recovery logging: True while the API is in a rate-limited or</span>
|
||||
<span class="c1"># quota-exhausted state, so the next successful lookup can log "recovered"</span>
|
||||
<span class="c1"># exactly once per event.</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMITED</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="configure_ipinfo_api">
|
||||
<a class="viewcode-back" href="../../api.html#parsedmarc.utils.configure_ipinfo_api">[docs]</a>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">configure_ipinfo_api</span><span class="p">(</span>
|
||||
<span class="n">token</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span>
|
||||
<span class="o">*</span><span class="p">,</span>
|
||||
<span class="n">probe</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="sd">"""Configure the IPinfo Lite REST API as the primary source for IP lookups.</span>
|
||||
|
||||
<span class="sd"> When a token is configured, ``get_ip_address_db_record()`` hits the API</span>
|
||||
<span class="sd"> first for every lookup and falls back to the MMDB on rate-limit, quota, or</span>
|
||||
<span class="sd"> network errors. An invalid token raises ``InvalidIPinfoAPIKey`` — the CLI</span>
|
||||
<span class="sd"> catches that and exits fatally.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> token: IPinfo API token. ``None`` or empty disables the API.</span>
|
||||
<span class="sd"> probe: If ``True``, verify the token by hitting ``/me`` (and, if that</span>
|
||||
<span class="sd"> is unreachable, by looking up ``1.1.1.1``). A 401/403 raises</span>
|
||||
<span class="sd"> ``InvalidIPinfoAPIKey``; other errors are logged and the token is</span>
|
||||
<span class="sd"> still accepted so per-request fallback can take over.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">global</span> <span class="n">_IPINFO_API_TOKEN</span>
|
||||
<span class="k">global</span> <span class="n">_IPINFO_API_COOLDOWN_UNTIL</span><span class="p">,</span> <span class="n">_IPINFO_API_RATE_LIMITED</span>
|
||||
|
||||
<span class="n">_IPINFO_API_TOKEN</span> <span class="o">=</span> <span class="n">token</span> <span class="ow">or</span> <span class="kc">None</span>
|
||||
<span class="n">_IPINFO_API_COOLDOWN_UNTIL</span> <span class="o">=</span> <span class="mf">0.0</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMITED</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IPINFO_API_TOKEN</span><span class="p">:</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">probe</span><span class="p">:</span>
|
||||
<span class="c1"># Verify the token. Any network/quota failure here is non-fatal — we</span>
|
||||
<span class="c1"># still accept the token and let per-request fallback handle it — but</span>
|
||||
<span class="c1"># an invalid-key response must fail fast so operators notice</span>
|
||||
<span class="c1"># immediately instead of seeing silent MMDB-only lookups all day.</span>
|
||||
<span class="c1">#</span>
|
||||
<span class="c1"># The /me meta endpoint doubles as a free-of-quota token check and a</span>
|
||||
<span class="c1"># plan/usage lookup, so we try it first. If /me is unreachable, fall</span>
|
||||
<span class="c1"># back to a lookup of 1.1.1.1 to validate the token.</span>
|
||||
<span class="n">account</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">dict</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">account</span> <span class="o">=</span> <span class="n">_ipinfo_api_account_info</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="n">InvalidIPinfoAPIKey</span><span class="p">:</span>
|
||||
<span class="k">raise</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"IPinfo account info fetch failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">account</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">summary</span> <span class="o">=</span> <span class="n">_format_ipinfo_account_summary</span><span class="p">(</span><span class="n">account</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">summary</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="sa">f</span><span class="s2">"IPinfo API configured — </span><span class="si">{</span><span class="n">summary</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">else</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">"IPinfo API configured"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">_ipinfo_api_lookup</span><span class="p">(</span><span class="s2">"1.1.1.1"</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">InvalidIPinfoAPIKey</span><span class="p">:</span>
|
||||
<span class="k">raise</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</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="sa">f</span><span class="s2">"IPinfo API probe failed (will fall back per-request): </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">else</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">"IPinfo API configured"</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_ipinfo_api_account_info</span><span class="p">()</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="nb">dict</span><span class="p">]:</span>
|
||||
<span class="w"> </span><span class="sd">"""Fetch the IPinfo ``/me`` account endpoint.</span>
|
||||
|
||||
<span class="sd"> Returns the parsed JSON dict on success, or ``None`` when the endpoint is</span>
|
||||
<span class="sd"> unreachable (network error, non-JSON body, non-2xx other than 401/403).</span>
|
||||
<span class="sd"> A 401/403 raises ``InvalidIPinfoAPIKey`` — this endpoint is the best way</span>
|
||||
<span class="sd"> to validate a token since it doesn't consume a lookup-quota unit.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IPINFO_API_TOKEN</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"User-Agent"</span><span class="p">:</span> <span class="n">USER_AGENT</span><span class="p">,</span>
|
||||
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"Bearer </span><span class="si">{</span><span class="n">_IPINFO_API_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
|
||||
<span class="s2">"Accept"</span><span class="p">:</span> <span class="s2">"application/json"</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
<span class="n">_IPINFO_ACCOUNT_URL</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">_IPINFO_API_TIMEOUT</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">401</span><span class="p">,</span> <span class="mi">403</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">InvalidIPinfoAPIKey</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"IPinfo API rejected the configured token (HTTP </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">)"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">response</span><span class="o">.</span><span class="n">ok</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"IPinfo /me returned HTTP </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">payload</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="n">payload</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_format_ipinfo_account_summary</span><span class="p">(</span><span class="n">account</span><span class="p">:</span> <span class="nb">dict</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
|
||||
<span class="w"> </span><span class="sd">"""Render a short, log-friendly summary of the IPinfo /me response.</span>
|
||||
|
||||
<span class="sd"> Field names in /me have varied across IPinfo plan generations, so we</span>
|
||||
<span class="sd"> probe a few aliases rather than commit to one schema. If nothing</span>
|
||||
<span class="sd"> useful is present we return ``None`` and the caller falls back to a</span>
|
||||
<span class="sd"> generic "configured" message.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">plan</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"plan"</span><span class="p">)</span>
|
||||
<span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"tier"</span><span class="p">)</span>
|
||||
<span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"token_type"</span><span class="p">)</span>
|
||||
<span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"type"</span><span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">limit</span> <span class="o">=</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"limit"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"monthly_limit"</span><span class="p">)</span>
|
||||
<span class="n">remaining</span> <span class="o">=</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"remaining"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"requests_remaining"</span><span class="p">)</span>
|
||||
<span class="n">used</span> <span class="o">=</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"month"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"month_requests"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">account</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"used"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">parts</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">if</span> <span class="n">plan</span><span class="p">:</span>
|
||||
<span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"plan: </span><span class="si">{</span><span class="n">plan</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">used</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">limit</span><span class="p">:</span>
|
||||
<span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"usage: </span><span class="si">{</span><span class="n">used</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">limit</span><span class="si">}</span><span class="s2"> this month"</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">limit</span><span class="p">:</span>
|
||||
<span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"monthly limit: </span><span class="si">{</span><span class="n">limit</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">remaining</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">remaining</span><span class="si">}</span><span class="s2"> remaining"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span> <span class="k">if</span> <span class="n">parts</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_parse_retry_after</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">default_seconds</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="sd">"""Parse an HTTP ``Retry-After`` header as seconds.</span>
|
||||
|
||||
<span class="sd"> Supports the delta-seconds form. HTTP-date form is rare enough for an API</span>
|
||||
<span class="sd"> client to ignore; we just fall back to the default.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">raw</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"Retry-After"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">raw</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">raw</span><span class="o">.</span><span class="n">strip</span><span class="p">()),</span> <span class="mf">1.0</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="k">pass</span>
|
||||
<span class="k">return</span> <span class="n">default_seconds</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_ipinfo_api_lookup</span><span class="p">(</span><span class="n">ip_address</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">_IPDatabaseRecord</span><span class="p">]:</span>
|
||||
<span class="w"> </span><span class="sd">"""Look up an IP via the IPinfo Lite REST API.</span>
|
||||
|
||||
<span class="sd"> Returns the normalized record on success, or ``None`` when the API is</span>
|
||||
<span class="sd"> unavailable for any reason the caller should fall back from (network</span>
|
||||
<span class="sd"> error, 429 rate limit, 402 quota exhausted, malformed response).</span>
|
||||
|
||||
<span class="sd"> On 429/402 the API is put in a cooldown (using ``Retry-After`` when</span>
|
||||
<span class="sd"> present) so we stop hammering it, and we log once per event at warning</span>
|
||||
<span class="sd"> level. After the cooldown expires the next lookup retries transparently;</span>
|
||||
<span class="sd"> a successful retry logs "API recovered" once at info level so operators</span>
|
||||
<span class="sd"> can see service came back.</span>
|
||||
|
||||
<span class="sd"> Raises:</span>
|
||||
<span class="sd"> InvalidIPinfoAPIKey: on 401/403. Propagates to abort the run.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">global</span> <span class="n">_IPINFO_API_COOLDOWN_UNTIL</span><span class="p">,</span> <span class="n">_IPINFO_API_RATE_LIMITED</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IPINFO_API_TOKEN</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="n">_IPINFO_API_COOLDOWN_UNTIL</span> <span class="ow">and</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o"><</span> <span class="n">_IPINFO_API_COOLDOWN_UNTIL</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">_IPINFO_API_URL</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">ip_address</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"User-Agent"</span><span class="p">:</span> <span class="n">USER_AGENT</span><span class="p">,</span>
|
||||
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"Bearer </span><span class="si">{</span><span class="n">_IPINFO_API_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
|
||||
<span class="s2">"Accept"</span><span class="p">:</span> <span class="s2">"application/json"</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">_IPINFO_API_TIMEOUT</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">requests</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">RequestException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"IPinfo API request for </span><span class="si">{</span><span class="n">ip_address</span><span class="si">}</span><span class="s2"> failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">401</span><span class="p">,</span> <span class="mi">403</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">InvalidIPinfoAPIKey</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"IPinfo API rejected the configured token (HTTP </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">)"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">429</span><span class="p">:</span>
|
||||
<span class="n">cooldown</span> <span class="o">=</span> <span class="n">_parse_retry_after</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">_IPINFO_API_RATE_LIMIT_COOLDOWN_SECONDS</span><span class="p">)</span>
|
||||
<span class="n">_IPINFO_API_COOLDOWN_UNTIL</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">cooldown</span>
|
||||
<span class="c1"># First hit of a rate-limit event is visible at warning; subsequent</span>
|
||||
<span class="c1"># 429s after cooldown-and-retry cycles stay at debug so we don't spam</span>
|
||||
<span class="c1"># the log when a run spans a long quota reset.</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IPINFO_API_RATE_LIMITED</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">"IPinfo API rate limit hit; falling back to the local MMDB "</span>
|
||||
<span class="sa">f</span><span class="s2">"for </span><span class="si">{</span><span class="n">cooldown</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2">s before retrying"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMITED</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"IPinfo API still rate-limited; retry after </span><span class="si">{</span><span class="n">cooldown</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2">s"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">402</span><span class="p">:</span>
|
||||
<span class="n">cooldown</span> <span class="o">=</span> <span class="n">_parse_retry_after</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">_IPINFO_API_QUOTA_COOLDOWN_SECONDS</span><span class="p">)</span>
|
||||
<span class="n">_IPINFO_API_COOLDOWN_UNTIL</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">cooldown</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">_IPINFO_API_RATE_LIMITED</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">"IPinfo API quota exhausted; falling back to the local MMDB "</span>
|
||||
<span class="sa">f</span><span class="s2">"for </span><span class="si">{</span><span class="n">cooldown</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2">s before retrying"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMITED</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"IPinfo API quota still exhausted; retry after </span><span class="si">{</span><span class="n">cooldown</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2">s"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">response</span><span class="o">.</span><span class="n">ok</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"IPinfo API returned HTTP </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2"> for </span><span class="si">{</span><span class="n">ip_address</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">payload</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"IPinfo API returned non-JSON for </span><span class="si">{</span><span class="n">ip_address</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">_IPINFO_API_RATE_LIMITED</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">"IPinfo API recovered; resuming API lookups"</span><span class="p">)</span>
|
||||
<span class="n">_IPINFO_API_RATE_LIMITED</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">_IPINFO_API_COOLDOWN_UNTIL</span> <span class="o">=</span> <span class="mf">0.0</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">_normalize_ip_record</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_normalize_ip_record</span><span class="p">(</span><span class="n">record</span><span class="p">:</span> <span class="nb">dict</span><span class="p">)</span> <span class="o">-></span> <span class="n">_IPDatabaseRecord</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="sd">"""Normalize an IPinfo / MaxMind record to the internal shape.</span>
|
||||
|
||||
<span class="sd"> Shared between the API path and the MMDB path so both schemas produce the</span>
|
||||
<span class="sd"> same output: country as ISO code, ASN as plain int, as_name string,</span>
|
||||
<span class="sd"> as_domain lowercased.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">country</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">as_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">as_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"country_code"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">code</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">nested</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"country"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">nested</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">nested</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"iso_code"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">country</span> <span class="o">=</span> <span class="n">code</span>
|
||||
|
||||
<span class="n">raw_asn</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"asn"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_asn</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="n">raw_asn</span>
|
||||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_asn</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">raw_asn</span><span class="p">:</span>
|
||||
<span class="n">digits</span> <span class="o">=</span> <span class="n">raw_asn</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="s2">"AS"</span><span class="p">)</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="s2">"as"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">digits</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">digits</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">asn</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">mm_asn</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"autonomous_system_number"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">mm_asn</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="n">mm_asn</span>
|
||||
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"as_name"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"autonomous_system_organization"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">name</span><span class="p">:</span>
|
||||
<span class="n">as_name</span> <span class="o">=</span> <span class="n">name</span>
|
||||
<span class="n">domain</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"as_domain"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">domain</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">domain</span><span class="p">:</span>
|
||||
<span class="n">as_domain</span> <span class="o">=</span> <span class="n">domain</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"country"</span><span class="p">:</span> <span class="n">country</span><span class="p">,</span>
|
||||
<span class="s2">"asn"</span><span class="p">:</span> <span class="n">asn</span><span class="p">,</span>
|
||||
<span class="s2">"as_name"</span><span class="p">:</span> <span class="n">as_name</span><span class="p">,</span>
|
||||
<span class="s2">"as_domain"</span><span class="p">:</span> <span class="n">as_domain</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_get_ip_database_path</span><span class="p">(</span><span class="n">db_path</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">])</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="n">db_paths</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"ipinfo_lite.mmdb"</span><span class="p">,</span>
|
||||
@@ -629,73 +952,37 @@
|
||||
<span class="k">return</span> <span class="n">db_path</span>
|
||||
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">_IPDatabaseRecord</span><span class="p">(</span><span class="n">TypedDict</span><span class="p">):</span>
|
||||
<span class="n">country</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
||||
<span class="n">asn_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="n">asn_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="get_ip_address_db_record">
|
||||
<a class="viewcode-back" href="../../api.html#parsedmarc.utils.get_ip_address_db_record">[docs]</a>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">get_ip_address_db_record</span><span class="p">(</span>
|
||||
<span class="n">ip_address</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">db_path</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="n">_IPDatabaseRecord</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="sd">"""Look up an IP in the configured MMDB and return country + ASN fields.</span>
|
||||
<span class="w"> </span><span class="sd">"""Look up an IP and return country + ASN fields.</span>
|
||||
|
||||
<span class="sd"> If the IPinfo Lite API is configured via ``configure_ipinfo_api()``, the</span>
|
||||
<span class="sd"> API is queried first; any non-fatal failure (rate limit, quota, network)</span>
|
||||
<span class="sd"> falls through to the MMDB. An invalid API token raises</span>
|
||||
<span class="sd"> ``InvalidIPinfoAPIKey`` and is not caught here.</span>
|
||||
|
||||
<span class="sd"> IPinfo Lite carries ``country_code``, ``as_name``, and ``as_domain`` on</span>
|
||||
<span class="sd"> every record. MaxMind/DBIP country-only databases carry only country, so</span>
|
||||
<span class="sd"> ``asn_name`` / ``asn_domain`` come back None for those users.</span>
|
||||
<span class="sd"> ``as_name`` / ``as_domain`` come back None for those users.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">api_record</span> <span class="o">=</span> <span class="n">_ipinfo_api_lookup</span><span class="p">(</span><span class="n">ip_address</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">api_record</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">api_record</span>
|
||||
|
||||
<span class="n">resolved_path</span> <span class="o">=</span> <span class="n">_get_ip_database_path</span><span class="p">(</span><span class="n">db_path</span><span class="p">)</span>
|
||||
<span class="n">db_reader</span> <span class="o">=</span> <span class="n">maxminddb</span><span class="o">.</span><span class="n">open_database</span><span class="p">(</span><span class="n">resolved_path</span><span class="p">)</span>
|
||||
<span class="n">record</span> <span class="o">=</span> <span class="n">db_reader</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">ip_address</span><span class="p">)</span>
|
||||
|
||||
<span class="n">country</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">asn</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">asn_name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">asn_domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">record</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="c1"># Support both the IPinfo schema (flat top-level ``country_code``) and</span>
|
||||
<span class="c1"># the MaxMind/DBIP schema (nested ``country.iso_code``) so users</span>
|
||||
<span class="c1"># dropping in their own MMDB from any of these providers keeps working.</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"country_code"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">code</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">nested</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"country"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">nested</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">nested</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"iso_code"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">country</span> <span class="o">=</span> <span class="n">code</span>
|
||||
|
||||
<span class="c1"># Normalize ASN to a plain integer. IPinfo stores it as a string like</span>
|
||||
<span class="c1"># "AS15169"; MaxMind's ASN DB uses ``autonomous_system_number`` as an</span>
|
||||
<span class="c1"># int. Integer form lets consumers do range queries and sort</span>
|
||||
<span class="c1"># numerically; display-time formatting with an "AS" prefix is trivial.</span>
|
||||
<span class="n">raw_asn</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"asn"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_asn</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="n">raw_asn</span>
|
||||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">raw_asn</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">raw_asn</span><span class="p">:</span>
|
||||
<span class="n">digits</span> <span class="o">=</span> <span class="n">raw_asn</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="s2">"AS"</span><span class="p">)</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="s2">"as"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">digits</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">digits</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">asn</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">mm_asn</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"autonomous_system_number"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">mm_asn</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="n">asn</span> <span class="o">=</span> <span class="n">mm_asn</span>
|
||||
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"as_name"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"autonomous_system_organization"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">name</span><span class="p">:</span>
|
||||
<span class="n">asn_name</span> <span class="o">=</span> <span class="n">name</span>
|
||||
<span class="n">domain</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"as_domain"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">domain</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">domain</span><span class="p">:</span>
|
||||
<span class="n">asn_domain</span> <span class="o">=</span> <span class="n">domain</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"country"</span><span class="p">:</span> <span class="n">country</span><span class="p">,</span>
|
||||
<span class="s2">"asn"</span><span class="p">:</span> <span class="n">asn</span><span class="p">,</span>
|
||||
<span class="s2">"asn_name"</span><span class="p">:</span> <span class="n">asn_name</span><span class="p">,</span>
|
||||
<span class="s2">"asn_domain"</span><span class="p">:</span> <span class="n">asn_domain</span><span class="p">,</span>
|
||||
<span class="p">}</span></div>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">record</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"country"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"asn"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"as_name"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"as_domain"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="n">_normalize_ip_record</span><span class="p">(</span><span class="n">record</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
|
||||
@@ -919,8 +1206,8 @@
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"type"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"asn"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"asn_name"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"asn_domain"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"as_name"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"as_domain"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">if</span> <span class="n">offline</span><span class="p">:</span>
|
||||
<span class="n">reverse_dns</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
@@ -934,8 +1221,8 @@
|
||||
<span class="n">db_record</span> <span class="o">=</span> <span class="n">get_ip_address_db_record</span><span class="p">(</span><span class="n">ip_address</span><span class="p">,</span> <span class="n">db_path</span><span class="o">=</span><span class="n">ip_db_path</span><span class="p">)</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"country"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"country"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"asn"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"asn"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"asn_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"asn_name"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"asn_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"asn_domain"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"as_name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"as_name"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"as_domain"</span><span class="p">]</span> <span class="o">=</span> <span class="n">db_record</span><span class="p">[</span><span class="s2">"as_domain"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"reverse_dns"</span><span class="p">]</span> <span class="o">=</span> <span class="n">reverse_dns</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">reverse_dns</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
@@ -968,14 +1255,14 @@
|
||||
<span class="n">url</span><span class="o">=</span><span class="n">reverse_dns_map_url</span><span class="p">,</span>
|
||||
<span class="n">offline</span><span class="o">=</span><span class="n">offline</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"asn_domain"</span><span class="p">]</span> <span class="ow">and</span> <span class="n">info</span><span class="p">[</span><span class="s2">"asn_domain"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">map_value</span><span class="p">:</span>
|
||||
<span class="n">service</span> <span class="o">=</span> <span class="n">map_value</span><span class="p">[</span><span class="n">info</span><span class="p">[</span><span class="s2">"asn_domain"</span><span class="p">]]</span>
|
||||
<span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"as_domain"</span><span class="p">]</span> <span class="ow">and</span> <span class="n">info</span><span class="p">[</span><span class="s2">"as_domain"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">map_value</span><span class="p">:</span>
|
||||
<span class="n">service</span> <span class="o">=</span> <span class="n">map_value</span><span class="p">[</span><span class="n">info</span><span class="p">[</span><span class="s2">"as_domain"</span><span class="p">]]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">service</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">service</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span>
|
||||
<span class="k">elif</span> <span class="n">info</span><span class="p">[</span><span class="s2">"asn_name"</span><span class="p">]:</span>
|
||||
<span class="k">elif</span> <span class="n">info</span><span class="p">[</span><span class="s2">"as_name"</span><span class="p">]:</span>
|
||||
<span class="c1"># ASN-domain not in the map: surface the raw AS name with no</span>
|
||||
<span class="c1"># classification. Better than leaving the row unattributed.</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">"asn_name"</span><span class="p">]</span>
|
||||
<span class="n">info</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">"as_name"</span><span class="p">]</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">cache</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">cache</span><span class="p">[</span><span class="n">ip_address</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
|
||||
|
||||
@@ -46,8 +46,8 @@ of the report schema.
|
||||
"name": null,
|
||||
"type": null,
|
||||
"asn": 7018,
|
||||
"asn_name": "AT&T Services, Inc.",
|
||||
"asn_domain": "att.com"
|
||||
"as_name": "AT&T Services, Inc.",
|
||||
"as_domain": "att.com"
|
||||
},
|
||||
"count": 2,
|
||||
"alignment": {
|
||||
@@ -93,7 +93,7 @@ of the report schema.
|
||||
### CSV aggregate report
|
||||
|
||||
```text
|
||||
xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,normalized_timespan,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_asn_name,source_asn_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results
|
||||
xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,normalized_timespan,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_as_name,source_as_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results
|
||||
draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-28 00:00:00,2012-04-28 23:59:59,False,,example.com,r,r,none,none,100,0,72.150.241.94,US,,,,,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
|
||||
draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-28 00:00:00,2012-04-28 23:59:59,False,,example.com,r,r,none,none,100,0,72.150.241.94,US,,,,,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
|
||||
|
||||
@@ -130,8 +130,8 @@ Thanks to GitHub user [xennn](https://github.com/xennn) for the anonymized
|
||||
"name": null,
|
||||
"type": null,
|
||||
"asn": null,
|
||||
"asn_name": null,
|
||||
"asn_domain": null
|
||||
"as_name": null,
|
||||
"as_domain": null
|
||||
},
|
||||
"authentication_mechanisms": [],
|
||||
"original_envelope_id": null,
|
||||
@@ -201,7 +201,7 @@ Thanks to GitHub user [xennn](https://github.com/xennn) for the anonymized
|
||||
### CSV forensic report
|
||||
|
||||
```text
|
||||
feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_asn_name,source_asn_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only
|
||||
feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_as_name,source_as_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only
|
||||
auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False
|
||||
```
|
||||
|
||||
|
||||
+12
-2
@@ -134,8 +134,17 @@ The full set of configuration options are:
|
||||
JSON output file
|
||||
- `ip_db_path` - str: An optional custom path to a MMDB file
|
||||
from IPinfo, MaxMind, or DBIP
|
||||
- `ip_db_url` - str: Overrides the default download URL for the
|
||||
IP-to-country database (env var: `PARSEDMARC_GENERAL_IP_DB_URL`)
|
||||
- `ipinfo_url` - str: Overrides the default download URL for the
|
||||
bundled IPinfo Lite MMDB (env var:
|
||||
`PARSEDMARC_GENERAL_IPINFO_URL`). The pre-9.10 name `ip_db_url` is
|
||||
still accepted as a deprecated alias and logs a warning.
|
||||
- `ipinfo_api_token` - str: Optional [IPinfo Lite REST API] token. When
|
||||
set, IP lookups hit the API first for the freshest country/ASN data
|
||||
and fall back to the local MMDB on rate limit, quota exhaustion, or
|
||||
network errors. An invalid token exits the process with a fatal error.
|
||||
Ignored when `offline` is set. The Lite tier is free and has no
|
||||
documented monthly request cap; see the IPinfo Lite docs for current
|
||||
limits. (env var: `PARSEDMARC_GENERAL_IPINFO_API_TOKEN`)
|
||||
- `offline` - bool: Do not use online queries for geolocation
|
||||
or DNS. Also disables automatic downloading of the IP-to-country
|
||||
database and reverse DNS map.
|
||||
@@ -801,3 +810,4 @@ journalctl -u parsedmarc.service -r
|
||||
|
||||
[cloudflare's public resolvers]: https://1.1.1.1/
|
||||
[url encoded]: https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters
|
||||
[ipinfo lite rest api]: https://ipinfo.io/developers/lite-api
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const DOCUMENTATION_OPTIONS = {
|
||||
VERSION: '9.9.0',
|
||||
VERSION: '9.10.0',
|
||||
LANGUAGE: 'en',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>API reference — parsedmarc 9.9.0 documentation</title>
|
||||
<title>API reference — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
@@ -147,7 +147,9 @@
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.DownloadError"><code class="docutils literal notranslate"><span class="pre">DownloadError</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.EmailParserError"><code class="docutils literal notranslate"><span class="pre">EmailParserError</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.IPAddressInfo"><code class="docutils literal notranslate"><span class="pre">IPAddressInfo</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.InvalidIPinfoAPIKey"><code class="docutils literal notranslate"><span class="pre">InvalidIPinfoAPIKey</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.ReverseDNSService"><code class="docutils literal notranslate"><span class="pre">ReverseDNSService</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.configure_ipinfo_api"><code class="docutils literal notranslate"><span class="pre">configure_ipinfo_api()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.convert_outlook_msg"><code class="docutils literal notranslate"><span class="pre">convert_outlook_msg()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.decode_base64"><code class="docutils literal notranslate"><span class="pre">decode_base64()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#parsedmarc.utils.get_base_domain"><code class="docutils literal notranslate"><span class="pre">get_base_domain()</span></code></a></li>
|
||||
@@ -1187,11 +1189,38 @@ to save in Splunk</p>
|
||||
<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">IPAddressInfo</span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#IPAddressInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.IPAddressInfo" title="Link to this definition"></a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="parsedmarc.utils.InvalidIPinfoAPIKey">
|
||||
<em class="property"><span class="k"><span class="pre">exception</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">InvalidIPinfoAPIKey</span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#InvalidIPinfoAPIKey"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.InvalidIPinfoAPIKey" title="Link to this definition"></a></dt>
|
||||
<dd><p>Raised when the IPinfo API rejects the configured token.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="parsedmarc.utils.ReverseDNSService">
|
||||
<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">ReverseDNSService</span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#ReverseDNSService"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.ReverseDNSService" title="Link to this definition"></a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py" id="parsedmarc.utils.configure_ipinfo_api">
|
||||
<span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">configure_ipinfo_api</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">token</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">probe</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#configure_ipinfo_api"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.configure_ipinfo_api" title="Link to this definition"></a></dt>
|
||||
<dd><p>Configure the IPinfo Lite REST API as the primary source for IP lookups.</p>
|
||||
<p>When a token is configured, <code class="docutils literal notranslate"><span class="pre">get_ip_address_db_record()</span></code> hits the API
|
||||
first for every lookup and falls back to the MMDB on rate-limit, quota, or
|
||||
network errors. An invalid token raises <code class="docutils literal notranslate"><span class="pre">InvalidIPinfoAPIKey</span></code> — the CLI
|
||||
catches that and exits fatally.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>token</strong> – IPinfo API token. <code class="docutils literal notranslate"><span class="pre">None</span></code> or empty disables the API.</p></li>
|
||||
<li><p><strong>probe</strong> – If <code class="docutils literal notranslate"><span class="pre">True</span></code>, verify the token by hitting <code class="docutils literal notranslate"><span class="pre">/me</span></code> (and, if that
|
||||
is unreachable, by looking up <code class="docutils literal notranslate"><span class="pre">1.1.1.1</span></code>). A 401/403 raises
|
||||
<code class="docutils literal notranslate"><span class="pre">InvalidIPinfoAPIKey</span></code>; other errors are logged and the token is
|
||||
still accepted so per-request fallback can take over.</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py" id="parsedmarc.utils.convert_outlook_msg">
|
||||
<span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">convert_outlook_msg</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">msg_bytes</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bytes</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">bytes</span></span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#convert_outlook_msg"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.convert_outlook_msg" title="Link to this definition"></a></dt>
|
||||
@@ -1288,10 +1317,14 @@ with the given IPv4 or IPv6 address.</p>
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py" id="parsedmarc.utils.get_ip_address_db_record">
|
||||
<span class="sig-prename descclassname"><span class="pre">parsedmarc.utils.</span></span><span class="sig-name descname"><span class="pre">get_ip_address_db_record</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">ip_address</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">_IPDatabaseRecord</span></span></span><a class="reference internal" href="_modules/parsedmarc/utils.html#get_ip_address_db_record"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#parsedmarc.utils.get_ip_address_db_record" title="Link to this definition"></a></dt>
|
||||
<dd><p>Look up an IP in the configured MMDB and return country + ASN fields.</p>
|
||||
<dd><p>Look up an IP and return country + ASN fields.</p>
|
||||
<p>If the IPinfo Lite API is configured via <code class="docutils literal notranslate"><span class="pre">configure_ipinfo_api()</span></code>, the
|
||||
API is queried first; any non-fatal failure (rate limit, quota, network)
|
||||
falls through to the MMDB. An invalid API token raises
|
||||
<code class="docutils literal notranslate"><span class="pre">InvalidIPinfoAPIKey</span></code> and is not caught here.</p>
|
||||
<p>IPinfo Lite carries <code class="docutils literal notranslate"><span class="pre">country_code</span></code>, <code class="docutils literal notranslate"><span class="pre">as_name</span></code>, and <code class="docutils literal notranslate"><span class="pre">as_domain</span></code> on
|
||||
every record. MaxMind/DBIP country-only databases carry only country, so
|
||||
<code class="docutils literal notranslate"><span class="pre">asn_name</span></code> / <code class="docutils literal notranslate"><span class="pre">asn_domain</span></code> come back None for those users.</p>
|
||||
<code class="docutils literal notranslate"><span class="pre">as_name</span></code> / <code class="docutils literal notranslate"><span class="pre">as_domain</span></code> come back None for those users.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Contributing to parsedmarc — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Contributing to parsedmarc — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Accessing an inbox using OWA/EWS — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Accessing an inbox using OWA/EWS — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Understanding DMARC — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Understanding DMARC — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Elasticsearch and Kibana — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Elasticsearch and Kibana — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+8
-4
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Index — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Index — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
@@ -139,10 +139,12 @@
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="api.html#parsedmarc.splunk.HECClient.close">close() (parsedmarc.splunk.HECClient method)</a>
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.utils.convert_outlook_msg">convert_outlook_msg() (in module parsedmarc.utils)</a>
|
||||
<li><a href="api.html#parsedmarc.utils.configure_ipinfo_api">configure_ipinfo_api() (in module parsedmarc.utils)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="api.html#parsedmarc.utils.convert_outlook_msg">convert_outlook_msg() (in module parsedmarc.utils)</a>
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.elastic.create_indexes">create_indexes() (in module parsedmarc.elastic)</a>
|
||||
|
||||
<ul>
|
||||
@@ -249,10 +251,12 @@
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.InvalidForensicReport">InvalidForensicReport</a>
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.InvalidSMTPTLSReport">InvalidSMTPTLSReport</a>
|
||||
<li><a href="api.html#parsedmarc.utils.InvalidIPinfoAPIKey">InvalidIPinfoAPIKey</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="api.html#parsedmarc.InvalidSMTPTLSReport">InvalidSMTPTLSReport</a>
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.utils.IPAddressInfo">IPAddressInfo (class in parsedmarc.utils)</a>
|
||||
</li>
|
||||
<li><a href="api.html#parsedmarc.types.IPSourceInfo">IPSourceInfo (class in parsedmarc.types)</a>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 9.9.0 documentation</title>
|
||||
<title>parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Installation — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Installation — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Using the Kibana dashboards — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Using the Kibana dashboards — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>What about mailing lists? — parsedmarc 9.9.0 documentation</title>
|
||||
<title>What about mailing lists? — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
BIN
Binary file not shown.
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>OpenSearch and Grafana — parsedmarc 9.9.0 documentation</title>
|
||||
<title>OpenSearch and Grafana — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+8
-8
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sample outputs — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Sample outputs — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
@@ -139,8 +139,8 @@ of the report schema.</p>
|
||||
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn"</span><span class="p">:</span><span class="w"> </span><span class="mi">7018</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AT&T Services, Inc."</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn_domain"</span><span class="p">:</span><span class="w"> </span><span class="s2">"att.com"</span>
|
||||
<span class="w"> </span><span class="nt">"as_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AT&T Services, Inc."</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"as_domain"</span><span class="p">:</span><span class="w"> </span><span class="s2">"att.com"</span>
|
||||
<span class="w"> </span><span class="p">},</span>
|
||||
<span class="w"> </span><span class="nt">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"alignment"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
@@ -186,7 +186,7 @@ of the report schema.</p>
|
||||
</section>
|
||||
<section id="csv-aggregate-report">
|
||||
<h3>CSV aggregate report<a class="headerlink" href="#csv-aggregate-report" title="Link to this heading"></a></h3>
|
||||
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,normalized_timespan,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_asn_name,source_asn_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results
|
||||
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,normalized_timespan,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_as_name,source_as_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results
|
||||
draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-28 00:00:00,2012-04-28 23:59:59,False,,example.com,r,r,none,none,100,0,72.150.241.94,US,,,,,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
|
||||
draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-28 00:00:00,2012-04-28 23:59:59,False,,example.com,r,r,none,none,100,0,72.150.241.94,US,,,,,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
|
||||
</pre></div>
|
||||
@@ -222,8 +222,8 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391
|
||||
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn_name"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"asn_domain"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
|
||||
<span class="w"> </span><span class="nt">"as_name"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"as_domain"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span>
|
||||
<span class="w"> </span><span class="p">},</span>
|
||||
<span class="w"> </span><span class="nt">"authentication_mechanisms"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span>
|
||||
<span class="w"> </span><span class="nt">"original_envelope_id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||||
@@ -293,7 +293,7 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391
|
||||
</section>
|
||||
<section id="csv-forensic-report">
|
||||
<h3>CSV forensic report<a class="headerlink" href="#csv-forensic-report" title="Link to this heading"></a></h3>
|
||||
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_asn_name,source_asn_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only
|
||||
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,source_name,source_type,source_asn,source_as_name,source_as_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only
|
||||
auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False
|
||||
</pre></div>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -5,14 +5,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Python Module Index — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Python Module Index — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Search — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Search — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Splunk — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Splunk — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
|
||||
+13
-4
@@ -6,14 +6,14 @@
|
||||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Using parsedmarc — parsedmarc 9.9.0 documentation</title>
|
||||
<title>Using parsedmarc — parsedmarc 9.10.0 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
|
||||
|
||||
|
||||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||||
<script src="_static/documentation_options.js?v=428ec01f"></script>
|
||||
<script src="_static/documentation_options.js?v=3c16008f"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script src="_static/js/theme.js"></script>
|
||||
@@ -232,8 +232,17 @@ JSON output file</p></li>
|
||||
JSON output file</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">ip_db_path</span></code> - str: An optional custom path to a MMDB file
|
||||
from IPinfo, MaxMind, or DBIP</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">ip_db_url</span></code> - str: Overrides the default download URL for the
|
||||
IP-to-country database (env var: <code class="docutils literal notranslate"><span class="pre">PARSEDMARC_GENERAL_IP_DB_URL</span></code>)</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">ipinfo_url</span></code> - str: Overrides the default download URL for the
|
||||
bundled IPinfo Lite MMDB (env var:
|
||||
<code class="docutils literal notranslate"><span class="pre">PARSEDMARC_GENERAL_IPINFO_URL</span></code>). The pre-9.10 name <code class="docutils literal notranslate"><span class="pre">ip_db_url</span></code> is
|
||||
still accepted as a deprecated alias and logs a warning.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">ipinfo_api_token</span></code> - str: Optional <a class="reference external" href="https://ipinfo.io/developers/lite-api">IPinfo Lite REST API</a> token. When
|
||||
set, IP lookups hit the API first for the freshest country/ASN data
|
||||
and fall back to the local MMDB on rate limit, quota exhaustion, or
|
||||
network errors. An invalid token exits the process with a fatal error.
|
||||
Ignored when <code class="docutils literal notranslate"><span class="pre">offline</span></code> is set. The Lite tier is free and has no
|
||||
documented monthly request cap; see the IPinfo Lite docs for current
|
||||
limits. (env var: <code class="docutils literal notranslate"><span class="pre">PARSEDMARC_GENERAL_IPINFO_API_TOKEN</span></code>)</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">offline</span></code> - bool: Do not use online queries for geolocation
|
||||
or DNS. Also disables automatic downloading of the IP-to-country
|
||||
database and reverse DNS map.</p></li>
|
||||
|
||||
Reference in New Issue
Block a user