diff --git a/_modules/index.html b/_modules/index.html index 529e604..8c7c103 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -5,14 +5,14 @@ - Overview: module code — parsedmarc 8.19.1 documentation + Overview: module code — parsedmarc 9.0.0 documentation - + diff --git a/_modules/parsedmarc.html b/_modules/parsedmarc.html index 7fb4966..4744dd6 100644 --- a/_modules/parsedmarc.html +++ b/_modules/parsedmarc.html @@ -5,14 +5,14 @@ - parsedmarc — parsedmarc 8.19.1 documentation + parsedmarc — parsedmarc 9.0.0 documentation - + @@ -83,6 +83,10 @@ """A Python package for parsing DMARC reports""" +from __future__ import annotations + +from typing import Dict, List, Any, Union, IO, Callable + import binascii import email import email.utils @@ -98,9 +102,8 @@ from base64 import b64decode from collections import OrderedDict from csv import DictWriter -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone, tzinfo from io import BytesIO, StringIO -from typing import Callable import mailparser import xmltodict @@ -175,15 +178,196 @@ +def _bucket_interval_by_day( + begin: datetime, + end: datetime, + total_count: int, +) -> List[Dict[Any]]: + """ + Split the interval [begin, end) into daily buckets and distribute + `total_count` proportionally across those buckets. + + The function: + 1. Identifies each calendar day touched by [begin, end) + 2. Computes how many seconds of the interval fall into each day + 3. Assigns counts in proportion to those overlaps + 4. Ensures the final counts sum exactly to total_count + + Args: + begin: timezone-aware datetime, inclusive start of interval + end: timezone-aware datetime, exclusive end of interval + total_count: number of messages to distribute + + Returns: + A list of dicts like: + { + "begin": datetime, + "end": datetime, + "count": int + } + """ + # --- Input validation ---------------------------------------------------- + if begin > end: + raise ValueError("begin must be earlier than end") + if begin.tzinfo is None or end.tzinfo is None: + raise ValueError("begin and end must be timezone-aware") + if begin.tzinfo is not end.tzinfo: + raise ValueError("begin and end must have the same tzinfo") + if total_count < 0: + raise ValueError("total_count must be non-negative") + + # --- Short-circuit trivial cases ----------------------------------------- + interval_seconds = (end - begin).total_seconds() + if interval_seconds <= 0 or total_count == 0: + return [] + + tz: tzinfo = begin.tzinfo + + # --- Step 1: Determine all calendar days touched by [begin, end) ---------- + # + # For example: + # begin = Jan 1 12:00 + # end = Jan 3 06:00 + # + # We need buckets for: + # Jan 1 12:00 → Jan 2 00:00 + # Jan 2 00:00 → Jan 3 00:00 + # Jan 3 00:00 → Jan 3 06:00 + # + + # Start at midnight on the day of `begin`. + day_cursor = datetime(begin.year, begin.month, begin.day, tzinfo=tz) + + # If `begin` is earlier on that day (e.g. 10:00), we want that midnight. + # If `begin` is past that midnight (e.g. 00:30), this is correct. + # If `begin` is BEFORE that midnight (rare unless tz shifts), adjust: + if day_cursor > begin: + day_cursor -= timedelta(days=1) + + day_buckets: List[Dict[str, Any]] = [] + + while day_cursor < end: + day_start = day_cursor + day_end = day_cursor + timedelta(days=1) + + # Overlap between [begin, end) and this day + overlap_start = max(begin, day_start) + overlap_end = min(end, day_end) + + overlap_seconds = (overlap_end - overlap_start).total_seconds() + + if overlap_seconds > 0: + day_buckets.append( + { + "begin": overlap_start, + "end": overlap_end, + "seconds": overlap_seconds, + } + ) + + day_cursor = day_end + + # --- Step 2: Pro-rate counts across buckets ------------------------------- + # + # Compute the exact fractional count for each bucket: + # bucket_fraction = bucket_seconds / interval_seconds + # bucket_exact = total_count * bucket_fraction + # + # Then apply a "largest remainder" rounding strategy to ensure the sum + # equals exactly total_count. + + exact_values: List[float] = [ + (b["seconds"] / interval_seconds) * total_count for b in day_buckets + ] + + floor_values: List[int] = [int(x) for x in exact_values] + fractional_parts: List[float] = [x - int(x) for x in exact_values] + + # How many counts do we still need to distribute after flooring? + remainder = total_count - sum(floor_values) + + # Sort buckets by descending fractional remainder + indices_by_fraction = sorted( + range(len(day_buckets)), + key=lambda i: fractional_parts[i], + reverse=True, + ) + + # Start with floor values + final_counts = floor_values[:] + + # Add +1 to the buckets with the largest fractional parts + for idx in indices_by_fraction[:remainder]: + final_counts[idx] += 1 + + # --- Step 3: Build the final per-day result list ------------------------- + results: List[Dict[str, Any]] = [] + for bucket, count in zip(day_buckets, final_counts): + if count > 0: + results.append( + { + "begin": bucket["begin"], + "end": bucket["end"], + "count": count, + } + ) + + return results + + +def _append_parsed_record( + parsed_record: Dict[str, Any], + records: List[Dict[str, Any]], + begin_dt: datetime, + end_dt: datetime, + normalize: bool, +) -> None: + """ + Append a parsed DMARC record either unchanged or normalized. + + Args: + parsed_record: The record returned by _parse_report_record(). + records: Accumulating list of output records. + begin_dt: Report-level begin datetime (UTC). + end_dt: Report-level end datetime (UTC). + normalize: Whether this report exceeded the allowed timespan + and should be normalized per-day. + """ + + if not normalize: + parsed_record["normalized_timespan"] = False + parsed_record["interval_begin"] = begin_dt.strftime("%Y-%m-%d %H:%M:%S") + parsed_record["interval_end"] = end_dt.strftime("%Y-%m-%d %H:%M:%S") + + records.append(parsed_record) + return + + # Normalization path: break record into daily buckets + total_count = int(parsed_record.get("count", 0)) + buckets = _bucket_interval_by_day(begin_dt, end_dt, total_count) + if not buckets: + return + + for part_index, bucket in enumerate(buckets): + new_rec = parsed_record.copy() + new_rec["count"] = bucket["count"] + new_rec["normalized_timespan"] = True + + new_rec["interval_begin"] = bucket["begin"].strftime("%Y-%m-%d %H:%M:%S") + new_rec["interval_end"] = bucket["end"].strftime("%Y-%m-%d %H:%M:%S") + + records.append(new_rec) + + def _parse_report_record( - record, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - nameservers=None, - dns_timeout=2.0, + record: dict, + ip_db_path: str = None, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + nameservers: list[str] = None, + dns_timeout: float = 2.0, ): """ Converts a record from a DMARC aggregate report into a more consistent @@ -338,7 +522,7 @@ return new_record -def _parse_smtp_tls_failure_details(failure_details): +def _parse_smtp_tls_failure_details(failure_details: dict): try: new_failure_details = OrderedDict( result_type=failure_details["result-type"], @@ -374,7 +558,7 @@ raise InvalidSMTPTLSReport(str(e)) -def _parse_smtp_tls_report_policy(policy): +def _parse_smtp_tls_report_policy(policy: dict): policy_types = ["tlsa", "sts", "no-policy-found"] try: policy_domain = policy["policy"]["policy-domain"] @@ -413,7 +597,7 @@
[docs] -def parse_smtp_tls_report_json(report): +def parse_smtp_tls_report_json(report: dict): """Parses and validates an SMTP TLS report""" required_fields = [ "organization-name", @@ -455,7 +639,7 @@
[docs] -def parsed_smtp_tls_reports_to_csv_rows(reports): +def parsed_smtp_tls_reports_to_csv_rows(reports: dict): """Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV""" if type(reports) is OrderedDict: @@ -493,7 +677,7 @@
[docs] -def parsed_smtp_tls_reports_to_csv(reports): +def parsed_smtp_tls_reports_to_csv(reports: dict): """ Converts one or more parsed SMTP TLS reports to flat CSV format, including headers @@ -542,15 +726,16 @@
[docs] def parse_aggregate_report_xml( - xml, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - nameservers=None, - timeout=2.0, - keep_alive=None, + xml: str, + ip_db_path: bool = None, + always_use_local_files: bool = False, + reverse_dns_map_path: bool = None, + reverse_dns_map_url: bool = None, + offline: bool = False, + nameservers: bool = None, + timeout: float = 2.0, + keep_alive: callable = None, + normalize_timespan_threshold_hours: float = 24.0, ): """Parses a DMARC XML report string and returns a consistent OrderedDict @@ -565,6 +750,7 @@ (Cloudflare's public DNS resolvers by default) timeout (float): Sets the DNS timeout in seconds keep_alive (callable): Keep alive function + normalize_timespan_threshold_hours (float): Normalize timespans beyond this Returns: OrderedDict: The parsed aggregate DMARC report @@ -629,13 +815,27 @@ report_id = report_id.replace("<", "").replace(">", "").split("@")[0] new_report_metadata["report_id"] = report_id date_range = report["report_metadata"]["date_range"] - if int(date_range["end"]) - int(date_range["begin"]) > 2 * 86400: - _error = "Time span > 24 hours - RFC 7489 section 7.2" - raise InvalidAggregateReport(_error) - date_range["begin"] = timestamp_to_human(date_range["begin"]) - date_range["end"] = timestamp_to_human(date_range["end"]) + + begin_ts = int(date_range["begin"]) + end_ts = int(date_range["end"]) + span_seconds = end_ts - begin_ts + + normalize_timespan = span_seconds > normalize_timespan_threshold_hours * 3600 + + date_range["begin"] = timestamp_to_human(begin_ts) + date_range["end"] = timestamp_to_human(end_ts) + new_report_metadata["begin_date"] = date_range["begin"] new_report_metadata["end_date"] = date_range["end"] + new_report_metadata["timespan_requires_normalization"] = normalize_timespan + new_report_metadata["original_timespan_seconds"] = span_seconds + begin_dt = human_timestamp_to_datetime( + new_report_metadata["begin_date"], to_utc=True + ) + end_dt = human_timestamp_to_datetime( + new_report_metadata["end_date"], to_utc=True + ) + if "error" in report["report_metadata"]: if not isinstance(report["report_metadata"]["error"], list): errors = [report["report_metadata"]["error"]] @@ -694,7 +894,13 @@ nameservers=nameservers, dns_timeout=timeout, ) - records.append(report_record) + _append_parsed_record( + parsed_record=report_record, + records=records, + begin_dt=begin_dt, + end_dt=end_dt, + normalize=normalize_timespan, + ) except Exception as e: logger.warning("Could not parse record: {0}".format(e)) @@ -709,7 +915,13 @@ nameservers=nameservers, dns_timeout=timeout, ) - records.append(report_record) + _append_parsed_record( + parsed_record=report_record, + records=records, + begin_dt=begin_dt, + end_dt=end_dt, + normalize=normalize_timespan, + ) new_report["records"] = records @@ -730,7 +942,7 @@
[docs] -def extract_report(content): +def extract_report(content: Union[bytes, str, IO[Any]]): """ Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes. @@ -800,15 +1012,16 @@
[docs] def parse_aggregate_report_file( - _input, - offline=False, - always_use_local_files=None, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - ip_db_path=None, - nameservers=None, - dns_timeout=2.0, - keep_alive=None, + _input: Union[str, bytes, IO[Any]], + offline: bool = False, + always_use_local_files: bool = None, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + ip_db_path: str = None, + nameservers: list[str] = None, + dns_timeout: float = 2.0, + keep_alive: Callable = None, + normalize_timespan_threshold_hours: float = 24.0, ): """Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report @@ -824,6 +1037,7 @@ (Cloudflare's public DNS resolvers by default) dns_timeout (float): Sets the DNS timeout in seconds keep_alive (callable): Keep alive function + normalize_timespan_threshold_hours (float): Normalize timespans beyond this Returns: OrderedDict: The parsed DMARC aggregate report @@ -844,13 +1058,14 @@ nameservers=nameservers, timeout=dns_timeout, keep_alive=keep_alive, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, )
[docs] -def parsed_aggregate_reports_to_csv_rows(reports): +def parsed_aggregate_reports_to_csv_rows(reports: list[dict]): """ Converts one or more parsed aggregate reports to list of dicts in flat CSV format @@ -879,6 +1094,9 @@ report_id = report["report_metadata"]["report_id"] begin_date = report["report_metadata"]["begin_date"] end_date = report["report_metadata"]["end_date"] + normalized_timespan = report["report_metadata"][ + "timespan_requires_normalization" + ] errors = "|".join(report["report_metadata"]["errors"]) domain = report["policy_published"]["domain"] adkim = report["policy_published"]["adkim"] @@ -896,6 +1114,7 @@ report_id=report_id, begin_date=begin_date, end_date=end_date, + normalized_timespan=normalized_timespan, errors=errors, domain=domain, adkim=adkim, @@ -908,6 +1127,8 @@ for record in report["records"]: row = report_dict.copy() + row["begin_date"] = record["interval_begin"] + row["end_date"] = record["interval_end"] row["source_ip_address"] = record["source"]["ip_address"] row["source_country"] = record["source"]["country"] row["source_reverse_dns"] = record["source"]["reverse_dns"] @@ -971,7 +1192,7 @@
[docs] -def parsed_aggregate_reports_to_csv(reports): +def parsed_aggregate_reports_to_csv(reports: list[OrderedDict]): """ Converts one or more parsed aggregate reports to flat CSV format, including headers @@ -991,6 +1212,7 @@ "report_id", "begin_date", "end_date", + "normalized_timespan", "errors", "domain", "adkim", @@ -1040,17 +1262,17 @@
[docs] def parse_forensic_report( - feedback_report, - sample, - msg_date, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - ip_db_path=None, - nameservers=None, - dns_timeout=2.0, - strip_attachment_payloads=False, + feedback_report: str, + sample: str, + msg_date: datetime, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + ip_db_path: str = None, + nameservers: list[str] = None, + dns_timeout: float = 2.0, + strip_attachment_payloads: bool = False, ): """ Converts a DMARC forensic report and sample to a ``OrderedDict`` @@ -1182,7 +1404,7 @@
[docs] -def parsed_forensic_reports_to_csv_rows(reports): +def parsed_forensic_reports_to_csv_rows(reports: list[OrderedDict]): """ Converts one or more parsed forensic reports to a list of dicts in flat CSV format @@ -1221,7 +1443,7 @@
[docs] -def parsed_forensic_reports_to_csv(reports): +def parsed_forensic_reports_to_csv(reports: list[dict]): """ Converts one or more parsed forensic reports to flat CSV format, including headers @@ -1277,16 +1499,17 @@
[docs] def parse_report_email( - input_, - offline=False, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - nameservers=None, - dns_timeout=2.0, - strip_attachment_payloads=False, - keep_alive=None, + input_: Union[bytes, str], + offline: bool = False, + ip_db_path: str = None, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + nameservers: list[str] = None, + dns_timeout: float = 2.0, + strip_attachment_payloads: bool = False, + keep_alive: callable = None, + normalize_timespan_threshold_hours: float = 24.0, ): """ Parses a DMARC report from an email @@ -1303,6 +1526,7 @@ strip_attachment_payloads (bool): Remove attachment payloads from forensic report results keep_alive (callable): keep alive function + normalize_timespan_threshold_hours (float): Normalize timespans beyond this Returns: OrderedDict: @@ -1415,6 +1639,7 @@ nameservers=nameservers, timeout=dns_timeout, keep_alive=keep_alive, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) result = OrderedDict( [("report_type", "aggregate"), ("report", aggregate_report)] @@ -1474,16 +1699,17 @@
[docs] def parse_report_file( - input_, - nameservers=None, - dns_timeout=2.0, - strip_attachment_payloads=False, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - keep_alive=None, + input_: Union[bytes, str, IO[Any]], + nameservers: list[str] = None, + dns_timeout: float = 2.0, + strip_attachment_payloads: bool = False, + ip_db_path: str = None, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + keep_alive: Callable = None, + normalize_timespan_threshold_hours: float = 24, ): """Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes @@ -1526,6 +1752,7 @@ nameservers=nameservers, dns_timeout=dns_timeout, keep_alive=keep_alive, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) results = OrderedDict([("report_type", "aggregate"), ("report", report)]) except InvalidAggregateReport: @@ -1546,6 +1773,7 @@ dns_timeout=dns_timeout, strip_attachment_payloads=sa, keep_alive=keep_alive, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) except InvalidDMARCReport: raise ParserError("Not a valid report") @@ -1556,15 +1784,16 @@
[docs] def get_dmarc_reports_from_mbox( - input_, - nameservers=None, - dns_timeout=2.0, - strip_attachment_payloads=False, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, + input_: str, + nameservers: list[str] = None, + dns_timeout: float = 2.0, + strip_attachment_payloads: bool = False, + ip_db_path: str = None, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + normalize_timespan_threshold_hours: float = 24.0, ): """Parses a mailbox in mbox format containing e-mails with attached DMARC reports @@ -1581,6 +1810,7 @@ reverse_dns_map_url (str): URL to a reverse DNS map file ip_db_path (str): Path to a MMDB file from MaxMind or DBIP offline (bool): Do not make online queries for geolocation or DNS + normalize_timespan_threshold_hours (float): Normalize timespans beyond this Returns: OrderedDict: Lists of ``aggregate_reports`` and ``forensic_reports`` @@ -1610,6 +1840,7 @@ nameservers=nameservers, dns_timeout=dns_timeout, strip_attachment_payloads=sa, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) if parsed_email["report_type"] == "aggregate": report_org = parsed_email["report"]["report_metadata"]["org_name"] @@ -1645,22 +1876,23 @@ [docs] def get_dmarc_reports_from_mailbox( connection: MailboxConnection, - reports_folder="INBOX", - archive_folder="Archive", - delete=False, - test=False, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - nameservers=None, - dns_timeout=6.0, - strip_attachment_payloads=False, - results=None, - batch_size=10, - since=None, - create_folders=True, + reports_folder: str = "INBOX", + archive_folder: str = "Archive", + delete: bool = False, + test: bool = False, + ip_db_path: str = None, + always_use_local_files: str = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + nameservers: list[str] = None, + dns_timeout: float = 6.0, + strip_attachment_payloads: bool = False, + results: dict = None, + batch_size: int = 10, + since: datetime = None, + create_folders: bool = True, + normalize_timespan_threshold_hours: float = 24, ): """ Fetches and parses DMARC reports from a mailbox @@ -1687,6 +1919,7 @@ (units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}) create_folders (bool): Whether to create the destination folders (not used in watch) + normalize_timespan_threshold_hours (float): Normalize timespans beyond this Returns: OrderedDict: Lists of ``aggregate_reports`` and ``forensic_reports`` @@ -1804,6 +2037,7 @@ offline=offline, strip_attachment_payloads=sa, keep_alive=connection.keepalive, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) if parsed_email["report_type"] == "aggregate": report_org = parsed_email["report"]["report_metadata"]["org_name"] @@ -1955,6 +2189,7 @@ reverse_dns_map_url=reverse_dns_map_url, offline=offline, since=current_time, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) return results
@@ -1966,20 +2201,21 @@ def watch_inbox( mailbox_connection: MailboxConnection, callback: Callable, - reports_folder="INBOX", - archive_folder="Archive", - delete=False, - test=False, - check_timeout=30, - ip_db_path=None, - always_use_local_files=False, - reverse_dns_map_path=None, - reverse_dns_map_url=None, - offline=False, - nameservers=None, - dns_timeout=6.0, - strip_attachment_payloads=False, - batch_size=None, + reports_folder: str = "INBOX", + archive_folder: str = "Archive", + delete: bool = False, + test: bool = False, + check_timeout: int = 30, + ip_db_path: str = None, + always_use_local_files: bool = False, + reverse_dns_map_path: str = None, + reverse_dns_map_url: str = None, + offline: bool = False, + nameservers: list[str] = None, + dns_timeout: float = 6.0, + strip_attachment_payloads: bool = False, + batch_size: int = None, + normalize_timespan_threshold_hours: float = 24, ): """ Watches the mailbox for new messages and @@ -2005,6 +2241,7 @@ strip_attachment_payloads (bool): Replace attachment payloads in forensic report samples with None batch_size (int): Number of messages to read and process before saving + normalize_timespan_threshold_hours (float): Normalize timespans beyond this """ def check_callback(connection): @@ -2025,6 +2262,7 @@ strip_attachment_payloads=sa, batch_size=batch_size, create_folders=False, + normalize_timespan_threshold_hours=normalize_timespan_threshold_hours, ) callback(res) @@ -2070,14 +2308,14 @@
[docs] def save_output( - results, - output_directory="output", - aggregate_json_filename="aggregate.json", - forensic_json_filename="forensic.json", - smtp_tls_json_filename="smtp_tls.json", - aggregate_csv_filename="aggregate.csv", - forensic_csv_filename="forensic.csv", - smtp_tls_csv_filename="smtp_tls.csv", + results: OrderedDict, + output_directory: str = "output", + aggregate_json_filename: str = "aggregate.json", + forensic_json_filename: str = "forensic.json", + smtp_tls_json_filename: str = "smtp_tls.json", + aggregate_csv_filename: str = "aggregate.csv", + forensic_csv_filename: str = "forensic.csv", + smtp_tls_csv_filename: str = "smtp_tls.csv", ): """ Save report data in the given directory @@ -2158,7 +2396,7 @@
[docs] -def get_report_zip(results): +def get_report_zip(results: OrderedDict): """ Creates a zip file of parsed report output diff --git a/_modules/parsedmarc/elastic.html b/_modules/parsedmarc/elastic.html index 8863b72..6843946 100644 --- a/_modules/parsedmarc/elastic.html +++ b/_modules/parsedmarc/elastic.html @@ -5,14 +5,14 @@ - parsedmarc.elastic — parsedmarc 8.19.1 documentation + parsedmarc.elastic — parsedmarc 9.0.0 documentation - + @@ -152,6 +152,8 @@ date_range = Date() date_begin = Date() date_end = Date() + normalized_timespan = Boolean() + original_timespan_seconds = Integer errors = Text() published_policy = Object(_PublishedPolicy) source_ip_address = Ip() @@ -492,52 +494,7 @@ org_name = metadata["org_name"] report_id = metadata["report_id"] domain = aggregate_report["policy_published"]["domain"] - begin_date = human_timestamp_to_datetime(metadata["begin_date"], to_utc=True) - end_date = human_timestamp_to_datetime(metadata["end_date"], to_utc=True) - begin_date_human = begin_date.strftime("%Y-%m-%d %H:%M:%SZ") - end_date_human = end_date.strftime("%Y-%m-%d %H:%M:%SZ") - if monthly_indexes: - index_date = begin_date.strftime("%Y-%m") - else: - index_date = begin_date.strftime("%Y-%m-%d") - aggregate_report["begin_date"] = begin_date - aggregate_report["end_date"] = end_date - date_range = [aggregate_report["begin_date"], aggregate_report["end_date"]] - org_name_query = Q(dict(match_phrase=dict(org_name=org_name))) - report_id_query = Q(dict(match_phrase=dict(report_id=report_id))) - domain_query = Q(dict(match_phrase={"published_policy.domain": domain})) - begin_date_query = Q(dict(match=dict(date_begin=begin_date))) - end_date_query = Q(dict(match=dict(date_end=end_date))) - - if index_suffix is not None: - search_index = "dmarc_aggregate_{0}*".format(index_suffix) - else: - search_index = "dmarc_aggregate*" - if index_prefix is not None: - search_index = "{0}{1}".format(index_prefix, search_index) - search = Search(index=search_index) - query = org_name_query & report_id_query & domain_query - query = query & begin_date_query & end_date_query - search.query = query - - try: - existing = search.execute() - except Exception as error_: - raise ElasticsearchError( - "Elasticsearch's search for existing report \ - error: {}".format(error_.__str__()) - ) - - if len(existing) > 0: - raise AlreadySaved( - "An aggregate report ID {0} from {1} about {2} " - "with a date range of {3} UTC to {4} UTC already " - "exists in " - "Elasticsearch".format( - report_id, org_name, domain, begin_date_human, end_date_human - ) - ) published_policy = _PublishedPolicy( domain=aggregate_report["policy_published"]["domain"], adkim=aggregate_report["policy_published"]["adkim"], @@ -549,6 +506,52 @@ ) for record in aggregate_report["records"]: + begin_date = human_timestamp_to_datetime(record["interval_begin"], to_utc=True) + end_date = human_timestamp_to_datetime(record["interval_end"], to_utc=True) + begin_date_human = begin_date.strftime("%Y-%m-%d %H:%M:%SZ") + end_date_human = end_date.strftime("%Y-%m-%d %H:%M:%SZ") + if monthly_indexes: + index_date = begin_date.strftime("%Y-%m") + else: + index_date = begin_date.strftime("%Y-%m-%d") + aggregate_report["begin_date"] = begin_date + aggregate_report["end_date"] = end_date + date_range = [aggregate_report["begin_date"], aggregate_report["end_date"]] + + org_name_query = Q(dict(match_phrase=dict(org_name=org_name))) + report_id_query = Q(dict(match_phrase=dict(report_id=report_id))) + domain_query = Q(dict(match_phrase={"published_policy.domain": domain})) + begin_date_query = Q(dict(match=dict(date_begin=begin_date))) + end_date_query = Q(dict(match=dict(date_end=end_date))) + + if index_suffix is not None: + search_index = "dmarc_aggregate_{0}*".format(index_suffix) + else: + search_index = "dmarc_aggregate*" + if index_prefix is not None: + search_index = "{0}{1}".format(index_prefix, search_index) + search = Search(index=search_index) + query = org_name_query & report_id_query & domain_query + query = query & begin_date_query & end_date_query + search.query = query + + try: + existing = search.execute() + except Exception as error_: + raise ElasticsearchError( + "Elasticsearch's search for existing report \ + error: {}".format(error_.__str__()) + ) + + if len(existing) > 0: + raise AlreadySaved( + "An aggregate report ID {0} from {1} about {2} " + "with a date range of {3} UTC to {4} UTC already " + "exists in " + "Elasticsearch".format( + report_id, org_name, domain, begin_date_human, end_date_human + ) + ) agg_doc = _AggregateReportDoc( xml_schema=aggregate_report["xml_schema"], org_name=metadata["org_name"], @@ -558,6 +561,7 @@ date_range=date_range, date_begin=aggregate_report["begin_date"], date_end=aggregate_report["end_date"], + normalized_timespan=record["normalized_timespan"], errors=metadata["errors"], published_policy=published_policy, source_ip_address=record["source"]["ip_address"], diff --git a/_modules/parsedmarc/opensearch.html b/_modules/parsedmarc/opensearch.html index 7474dba..796c90b 100644 --- a/_modules/parsedmarc/opensearch.html +++ b/_modules/parsedmarc/opensearch.html @@ -5,14 +5,14 @@ - parsedmarc.opensearch — parsedmarc 8.19.1 documentation + parsedmarc.opensearch — parsedmarc 9.0.0 documentation - + @@ -152,6 +152,8 @@ date_range = Date() date_begin = Date() date_end = Date() + normalized_timespan = Boolean() + original_timespan_seconds = Integer errors = Text() published_policy = Object(_PublishedPolicy) source_ip_address = Ip() @@ -492,52 +494,7 @@ org_name = metadata["org_name"] report_id = metadata["report_id"] domain = aggregate_report["policy_published"]["domain"] - begin_date = human_timestamp_to_datetime(metadata["begin_date"], to_utc=True) - end_date = human_timestamp_to_datetime(metadata["end_date"], to_utc=True) - begin_date_human = begin_date.strftime("%Y-%m-%d %H:%M:%SZ") - end_date_human = end_date.strftime("%Y-%m-%d %H:%M:%SZ") - if monthly_indexes: - index_date = begin_date.strftime("%Y-%m") - else: - index_date = begin_date.strftime("%Y-%m-%d") - aggregate_report["begin_date"] = begin_date - aggregate_report["end_date"] = end_date - date_range = [aggregate_report["begin_date"], aggregate_report["end_date"]] - org_name_query = Q(dict(match_phrase=dict(org_name=org_name))) - report_id_query = Q(dict(match_phrase=dict(report_id=report_id))) - domain_query = Q(dict(match_phrase={"published_policy.domain": domain})) - begin_date_query = Q(dict(match=dict(date_begin=begin_date))) - end_date_query = Q(dict(match=dict(date_end=end_date))) - - if index_suffix is not None: - search_index = "dmarc_aggregate_{0}*".format(index_suffix) - else: - search_index = "dmarc_aggregate*" - if index_prefix is not None: - search_index = "{0}{1}".format(index_prefix, search_index) - search = Search(index=search_index) - query = org_name_query & report_id_query & domain_query - query = query & begin_date_query & end_date_query - search.query = query - - try: - existing = search.execute() - except Exception as error_: - raise OpenSearchError( - "OpenSearch's search for existing report \ - error: {}".format(error_.__str__()) - ) - - if len(existing) > 0: - raise AlreadySaved( - "An aggregate report ID {0} from {1} about {2} " - "with a date range of {3} UTC to {4} UTC already " - "exists in " - "OpenSearch".format( - report_id, org_name, domain, begin_date_human, end_date_human - ) - ) published_policy = _PublishedPolicy( domain=aggregate_report["policy_published"]["domain"], adkim=aggregate_report["policy_published"]["adkim"], @@ -549,6 +506,52 @@ ) for record in aggregate_report["records"]: + begin_date = human_timestamp_to_datetime(record["interval_begin"], to_utc=True) + end_date = human_timestamp_to_datetime(record["interval_end"], to_utc=True) + begin_date_human = begin_date.strftime("%Y-%m-%d %H:%M:%SZ") + end_date_human = end_date.strftime("%Y-%m-%d %H:%M:%SZ") + if monthly_indexes: + index_date = begin_date.strftime("%Y-%m") + else: + index_date = begin_date.strftime("%Y-%m-%d") + aggregate_report["begin_date"] = begin_date + aggregate_report["end_date"] = end_date + date_range = [aggregate_report["begin_date"], aggregate_report["end_date"]] + + org_name_query = Q(dict(match_phrase=dict(org_name=org_name))) + report_id_query = Q(dict(match_phrase=dict(report_id=report_id))) + domain_query = Q(dict(match_phrase={"published_policy.domain": domain})) + begin_date_query = Q(dict(match=dict(date_begin=begin_date))) + end_date_query = Q(dict(match=dict(date_end=end_date))) + + if index_suffix is not None: + search_index = "dmarc_aggregate_{0}*".format(index_suffix) + else: + search_index = "dmarc_aggregate*" + if index_prefix is not None: + search_index = "{0}{1}".format(index_prefix, search_index) + search = Search(index=search_index) + query = org_name_query & report_id_query & domain_query + query = query & begin_date_query & end_date_query + search.query = query + + try: + existing = search.execute() + except Exception as error_: + raise OpenSearchError( + "OpenSearch's search for existing report \ + error: {}".format(error_.__str__()) + ) + + if len(existing) > 0: + raise AlreadySaved( + "An aggregate report ID {0} from {1} about {2} " + "with a date range of {3} UTC to {4} UTC already " + "exists in " + "OpenSearch".format( + report_id, org_name, domain, begin_date_human, end_date_human + ) + ) agg_doc = _AggregateReportDoc( xml_schema=aggregate_report["xml_schema"], org_name=metadata["org_name"], diff --git a/_modules/parsedmarc/splunk.html b/_modules/parsedmarc/splunk.html index 7add6e6..5f15088 100644 --- a/_modules/parsedmarc/splunk.html +++ b/_modules/parsedmarc/splunk.html @@ -5,14 +5,14 @@ - parsedmarc.splunk — parsedmarc 8.19.1 documentation + parsedmarc.splunk — parsedmarc 9.0.0 documentation - + @@ -167,6 +167,9 @@ new_report = dict() for metadata in report["report_metadata"]: new_report[metadata] = report["report_metadata"][metadata] + new_report["interval_begin"] = record["interval_begin"] + new_report["interval_end"] = record["interval_end"] + new_report["normalized_timespan"] = record["normalized_timespan"] new_report["published_policy"] = report["policy_published"] new_report["source_ip_address"] = record["source"]["ip_address"] new_report["source_country"] = record["source"]["country"] @@ -187,7 +190,9 @@ new_report["spf_results"] = record["auth_results"]["spf"] data["sourcetype"] = "dmarc:aggregate" - timestamp = human_timestamp_to_unix_timestamp(new_report["begin_date"]) + timestamp = human_timestamp_to_unix_timestamp( + new_report["interval_begin"] + ) data["time"] = timestamp data["event"] = new_report.copy() json_str += "{0}\n".format(json.dumps(data)) diff --git a/_modules/parsedmarc/utils.html b/_modules/parsedmarc/utils.html index 3edc71e..a66ef67 100644 --- a/_modules/parsedmarc/utils.html +++ b/_modules/parsedmarc/utils.html @@ -5,14 +5,14 @@ - parsedmarc.utils — parsedmarc 8.19.1 documentation + parsedmarc.utils — parsedmarc 9.0.0 documentation - + diff --git a/_sources/output.md.txt b/_sources/output.md.txt index 61b8273..a8d19e4 100644 --- a/_sources/output.md.txt +++ b/_sources/output.md.txt @@ -23,6 +23,8 @@ of the report schema. "report_id": "9391651994964116463", "begin_date": "2012-04-27 20:00:00", "end_date": "2012-04-28 19:59:59", + "timespan_requires_normalization": false, + "original_timespan_seconds": 86399, "errors": [] }, "policy_published": { @@ -39,8 +41,10 @@ of the report schema. "source": { "ip_address": "72.150.241.94", "country": "US", - "reverse_dns": "adsl-72-150-241-94.shv.bellsouth.net", - "base_domain": "bellsouth.net" + "reverse_dns": null, + "base_domain": null, + "name": null, + "type": null }, "count": 2, "alignment": { @@ -74,7 +78,10 @@ of the report schema. "result": "pass" } ] - } + }, + "normalized_timespan": false, + "interval_begin": "2012-04-28 00:00:00", + "interval_end": "2012-04-28 23:59:59" } ] } @@ -83,8 +90,10 @@ of the report schema. ### CSV aggregate report ```text -xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_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-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass +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,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 + ``` ## Sample forensic report output diff --git a/_sources/usage.md.txt b/_sources/usage.md.txt index 00d7e28..85eec61 100644 --- a/_sources/usage.md.txt +++ b/_sources/usage.md.txt @@ -4,47 +4,50 @@ ```text usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] - [--aggregate-json-filename AGGREGATE_JSON_FILENAME] - [--forensic-json-filename FORENSIC_JSON_FILENAME] - [--aggregate-csv-filename AGGREGATE_CSV_FILENAME] - [--forensic-csv-filename FORENSIC_CSV_FILENAME] - [-n NAMESERVERS [NAMESERVERS ...]] [-t DNS_TIMEOUT] [--offline] - [-s] [--verbose] [--debug] [--log-file LOG_FILE] [-v] - [file_path ...] + [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] + [--smtp-tls-json-filename SMTP_TLS_JSON_FILENAME] [--aggregate-csv-filename AGGREGATE_CSV_FILENAME] + [--forensic-csv-filename FORENSIC_CSV_FILENAME] [--smtp-tls-csv-filename SMTP_TLS_CSV_FILENAME] + [-n NAMESERVERS [NAMESERVERS ...]] [-t DNS_TIMEOUT] [--offline] [-s] [-w] [--verbose] [--debug] + [--log-file LOG_FILE] [--no-prettify-json] [-v] + [file_path ...] - Parses DMARC reports +Parses DMARC reports - positional arguments: - file_path one or more paths to aggregate or forensic report - files, emails, or mbox files' +positional arguments: + file_path one or more paths to aggregate or forensic report files, emails, or mbox files' - optional arguments: - -h, --help show this help message and exit - -c CONFIG_FILE, --config-file CONFIG_FILE - a path to a configuration file (--silent implied) - --strip-attachment-payloads - remove attachment payloads from forensic report output - -o OUTPUT, --output OUTPUT - write output files to the given directory - --aggregate-json-filename AGGREGATE_JSON_FILENAME - filename for the aggregate JSON output file - --forensic-json-filename FORENSIC_JSON_FILENAME - filename for the forensic JSON output file - --aggregate-csv-filename AGGREGATE_CSV_FILENAME - filename for the aggregate CSV output file - --forensic-csv-filename FORENSIC_CSV_FILENAME - filename for the forensic CSV output file - -n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...] - nameservers to query - -t DNS_TIMEOUT, --dns_timeout DNS_TIMEOUT - number of seconds to wait for an answer from DNS - (default: 2.0) - --offline do not make online queries for geolocation or DNS - -s, --silent only print errors and warnings - --verbose more verbose output - --debug print debugging information - --log-file LOG_FILE output logging to a file - -v, --version show program's version number and exit +options: + -h, --help show this help message and exit + -c CONFIG_FILE, --config-file CONFIG_FILE + a path to a configuration file (--silent implied) + --strip-attachment-payloads + remove attachment payloads from forensic report output + -o OUTPUT, --output OUTPUT + write output files to the given directory + --aggregate-json-filename AGGREGATE_JSON_FILENAME + filename for the aggregate JSON output file + --forensic-json-filename FORENSIC_JSON_FILENAME + filename for the forensic JSON output file + --smtp-tls-json-filename SMTP_TLS_JSON_FILENAME + filename for the SMTP TLS JSON output file + --aggregate-csv-filename AGGREGATE_CSV_FILENAME + filename for the aggregate CSV output file + --forensic-csv-filename FORENSIC_CSV_FILENAME + filename for the forensic CSV output file + --smtp-tls-csv-filename SMTP_TLS_CSV_FILENAME + filename for the SMTP TLS CSV output file + -n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...] + nameservers to query + -t DNS_TIMEOUT, --dns_timeout DNS_TIMEOUT + number of seconds to wait for an answer from DNS (default: 2.0) + --offline do not make online queries for geolocation or DNS + -s, --silent only print errors + -w, --warnings print warnings in addition to errors + --verbose more verbose output + --debug print debugging information + --log-file LOG_FILE output logging to a file + --no-prettify-json output JSON in a single line without indentation + -v, --version show program's version number and exit ``` :::{note} diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 0bc7fa0..0f0cd60 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,5 +1,5 @@ const DOCUMENTATION_OPTIONS = { - VERSION: '8.19.1', + VERSION: '9.0.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/api.html b/api.html index dd731e2..781033e 100644 --- a/api.html +++ b/api.html @@ -6,14 +6,14 @@ - API reference — parsedmarc 8.19.1 documentation + API reference — parsedmarc 9.0.0 documentation - + @@ -227,7 +227,7 @@
-parsedmarc.extract_report(content)[source]
+parsedmarc.extract_report(content: bytes | str | IO[Any])[source]

Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes.

@@ -254,7 +254,7 @@ file-like object, or bytes.

-parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source]
+parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder: str = 'INBOX', archive_folder: str = 'Archive', delete: bool = False, test: bool = False, ip_db_path: str = None, always_use_local_files: str = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, offline: bool = False, nameservers: list[str] = None, dns_timeout: float = 6.0, strip_attachment_payloads: bool = False, results: dict = None, batch_size: int = 10, since: datetime = None, create_folders: bool = True, normalize_timespan_threshold_hours: float = 24)[source]

Fetches and parses DMARC reports from a mailbox

Parameters:
@@ -280,6 +280,7 @@ forensic report results

(units - {“m”:”minutes”, “h”:”hours”, “d”:”days”, “w”:”weeks”})

  • create_folders (bool) – Whether to create the destination folders (not used in watch)

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • Returns:
    @@ -293,7 +294,7 @@ forensic report results

    -parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source]
    +parsedmarc.get_dmarc_reports_from_mbox(input_: str, nameservers: list[str] = None, dns_timeout: float = 2.0, strip_attachment_payloads: bool = False, ip_db_path: str = None, always_use_local_files: bool = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, offline: bool = False, normalize_timespan_threshold_hours: float = 24.0)[source]

    Parses a mailbox in mbox format containing e-mails with attached DMARC reports

    @@ -310,6 +311,7 @@ forensic report results

  • reverse_dns_map_url (str) – URL to a reverse DNS map file

  • ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP

  • offline (bool) – Do not make online queries for geolocation or DNS

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • Returns:
    @@ -323,7 +325,7 @@ forensic report results

    -parsedmarc.get_report_zip(results)[source]
    +parsedmarc.get_report_zip(results: OrderedDict)[source]

    Creates a zip file of parsed report output

    Parameters:
    @@ -340,7 +342,7 @@ forensic report results

    -parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source]
    +parsedmarc.parse_aggregate_report_file(_input: str | bytes | IO[Any], offline: bool = False, always_use_local_files: bool = None, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, ip_db_path: str = None, nameservers: list[str] = None, dns_timeout: float = 2.0, keep_alive: Callable = None, normalize_timespan_threshold_hours: float = 24.0)[source]

    Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report

    @@ -356,6 +358,7 @@ aggregate DMARC report

    (Cloudflare’s public DNS resolvers by default)

  • dns_timeout (float) – Sets the DNS timeout in seconds

  • keep_alive (callable) – Keep alive function

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • Returns:
    @@ -369,7 +372,7 @@ aggregate DMARC report

    -parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source]
    +parsedmarc.parse_aggregate_report_xml(xml: str, ip_db_path: bool = None, always_use_local_files: bool = False, reverse_dns_map_path: bool = None, reverse_dns_map_url: bool = None, offline: bool = False, nameservers: bool = None, timeout: float = 2.0, keep_alive: callable = None, normalize_timespan_threshold_hours: float = 24.0)[source]

    Parses a DMARC XML report string and returns a consistent OrderedDict

    Parameters:
    @@ -384,6 +387,7 @@ aggregate DMARC report

    (Cloudflare’s public DNS resolvers by default)

  • timeout (float) – Sets the DNS timeout in seconds

  • keep_alive (callable) – Keep alive function

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • Returns:
    @@ -397,7 +401,7 @@ aggregate DMARC report

    -parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source]
    +parsedmarc.parse_forensic_report(feedback_report: str, sample: str, msg_date: datetime, always_use_local_files: bool = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, offline: bool = False, ip_db_path: str = None, nameservers: list[str] = None, dns_timeout: float = 2.0, strip_attachment_payloads: bool = False)[source]

    Converts a DMARC forensic report and sample to a OrderedDict

    Parameters:
    @@ -428,7 +432,7 @@ forensic report results

    -parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source]
    +parsedmarc.parse_report_email(input_: bytes | str, offline: bool = False, ip_db_path: str = None, always_use_local_files: bool = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, nameservers: list[str] = None, dns_timeout: float = 2.0, strip_attachment_payloads: bool = False, keep_alive: callable = None, normalize_timespan_threshold_hours: float = 24.0)[source]

    Parses a DMARC report from an email

    Parameters:
    @@ -444,6 +448,7 @@ forensic report results

  • strip_attachment_payloads (bool) – Remove attachment payloads from forensic report results

  • keep_alive (callable) – keep alive function

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • Returns:
    @@ -461,7 +466,7 @@ forensic report results

    -parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source]
    +parsedmarc.parse_report_file(input_: bytes | str | IO[Any], nameservers: list[str] = None, dns_timeout: float = 2.0, strip_attachment_payloads: bool = False, ip_db_path: str = None, always_use_local_files: bool = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, offline: bool = False, keep_alive: Callable = None, normalize_timespan_threshold_hours: float = 24)[source]

    Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes

    @@ -492,13 +497,13 @@ forensic report results

    -parsedmarc.parse_smtp_tls_report_json(report)[source]
    +parsedmarc.parse_smtp_tls_report_json(report: dict)[source]

    Parses and validates an SMTP TLS report

    -parsedmarc.parsed_aggregate_reports_to_csv(reports)[source]
    +parsedmarc.parsed_aggregate_reports_to_csv(reports: list[OrderedDict])[source]

    Converts one or more parsed aggregate reports to flat CSV format, including headers

    @@ -516,7 +521,7 @@ headers

    -parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source]
    +parsedmarc.parsed_aggregate_reports_to_csv_rows(reports: list[dict])[source]

    Converts one or more parsed aggregate reports to list of dicts in flat CSV format

    @@ -535,7 +540,7 @@ format

    -parsedmarc.parsed_forensic_reports_to_csv(reports)[source]
    +parsedmarc.parsed_forensic_reports_to_csv(reports: list[dict])[source]

    Converts one or more parsed forensic reports to flat CSV format, including headers

    @@ -553,7 +558,7 @@ headers

    -parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source]
    +parsedmarc.parsed_forensic_reports_to_csv_rows(reports: list[OrderedDict])[source]

    Converts one or more parsed forensic reports to a list of dicts in flat CSV format

    @@ -571,7 +576,7 @@ format

    -parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source]
    +parsedmarc.parsed_smtp_tls_reports_to_csv(reports: dict)[source]

    Converts one or more parsed SMTP TLS reports to flat CSV format, including headers

    @@ -589,14 +594,14 @@ headers

    -parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source]
    +parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports: dict)[source]

    Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV

    -parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source]
    +parsedmarc.save_output(results: OrderedDict, output_directory: str = 'output', aggregate_json_filename: str = 'aggregate.json', forensic_json_filename: str = 'forensic.json', smtp_tls_json_filename: str = 'smtp_tls.json', aggregate_csv_filename: str = 'aggregate.csv', forensic_csv_filename: str = 'forensic.csv', smtp_tls_csv_filename: str = 'smtp_tls.csv')[source]

    Save report data in the given directory

    Parameters:
    @@ -616,7 +621,7 @@ layer OrderedDict objects suitable for use in a CSV

    -parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source]
    +parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder: str = 'INBOX', archive_folder: str = 'Archive', delete: bool = False, test: bool = False, check_timeout: int = 30, ip_db_path: str = None, always_use_local_files: bool = False, reverse_dns_map_path: str = None, reverse_dns_map_url: str = None, offline: bool = False, nameservers: list[str] = None, dns_timeout: float = 6.0, strip_attachment_payloads: bool = False, batch_size: int = None, normalize_timespan_threshold_hours: float = 24)[source]
    Watches the mailbox for new messages and

    sends the results to a callback function

    @@ -643,6 +648,7 @@ or the number of seconds until the next mail check

  • strip_attachment_payloads (bool) – Replace attachment payloads in forensic report samples with None

  • batch_size (int) – Number of messages to read and process before saving

  • +
  • normalize_timespan_threshold_hours (float) – Normalize timespans beyond this

  • diff --git a/contributing.html b/contributing.html index ea52424..b31de9c 100644 --- a/contributing.html +++ b/contributing.html @@ -6,14 +6,14 @@ - Contributing to parsedmarc — parsedmarc 8.19.1 documentation + Contributing to parsedmarc — parsedmarc 9.0.0 documentation - + diff --git a/davmail.html b/davmail.html index 79bf811..2e65bf3 100644 --- a/davmail.html +++ b/davmail.html @@ -6,14 +6,14 @@ - Accessing an inbox using OWA/EWS — parsedmarc 8.19.1 documentation + Accessing an inbox using OWA/EWS — parsedmarc 9.0.0 documentation - + diff --git a/dmarc.html b/dmarc.html index 84ba4a2..b759608 100644 --- a/dmarc.html +++ b/dmarc.html @@ -6,14 +6,14 @@ - Understanding DMARC — parsedmarc 8.19.1 documentation + Understanding DMARC — parsedmarc 9.0.0 documentation - + diff --git a/elasticsearch.html b/elasticsearch.html index 5a8667a..a74e574 100644 --- a/elasticsearch.html +++ b/elasticsearch.html @@ -6,14 +6,14 @@ - Elasticsearch and Kibana — parsedmarc 8.19.1 documentation + Elasticsearch and Kibana — parsedmarc 9.0.0 documentation - + diff --git a/genindex.html b/genindex.html index d01fd81..d58fe08 100644 --- a/genindex.html +++ b/genindex.html @@ -5,14 +5,14 @@ - Index — parsedmarc 8.19.1 documentation + Index — parsedmarc 9.0.0 documentation - + diff --git a/index.html b/index.html index 3714a6b..569764f 100644 --- a/index.html +++ b/index.html @@ -6,14 +6,14 @@ - parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.19.1 documentation + parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 9.0.0 documentation - + diff --git a/installation.html b/installation.html index 9d7c3f3..e4cf5c9 100644 --- a/installation.html +++ b/installation.html @@ -6,14 +6,14 @@ - Installation — parsedmarc 8.19.1 documentation + Installation — parsedmarc 9.0.0 documentation - + diff --git a/kibana.html b/kibana.html index 8b96322..4d15b44 100644 --- a/kibana.html +++ b/kibana.html @@ -6,14 +6,14 @@ - Using the Kibana dashboards — parsedmarc 8.19.1 documentation + Using the Kibana dashboards — parsedmarc 9.0.0 documentation - + diff --git a/mailing-lists.html b/mailing-lists.html index 897465d..d418eae 100644 --- a/mailing-lists.html +++ b/mailing-lists.html @@ -6,14 +6,14 @@ - What about mailing lists? — parsedmarc 8.19.1 documentation + What about mailing lists? — parsedmarc 9.0.0 documentation - + diff --git a/objects.inv b/objects.inv index d255a56..93d3160 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/opensearch.html b/opensearch.html index 718cc09..e3dfe3b 100644 --- a/opensearch.html +++ b/opensearch.html @@ -6,14 +6,14 @@ - OpenSearch and Grafana — parsedmarc 8.19.1 documentation + OpenSearch and Grafana — parsedmarc 9.0.0 documentation - + diff --git a/output.html b/output.html index 2ca6b4b..d9f2753 100644 --- a/output.html +++ b/output.html @@ -6,14 +6,14 @@ - Sample outputs — parsedmarc 8.19.1 documentation + Sample outputs — parsedmarc 9.0.0 documentation - + @@ -116,6 +116,8 @@ of the report schema.

    "report_id": "9391651994964116463", "begin_date": "2012-04-27 20:00:00", "end_date": "2012-04-28 19:59:59", + "timespan_requires_normalization": false, + "original_timespan_seconds": 86399, "errors": [] }, "policy_published": { @@ -132,8 +134,10 @@ of the report schema.

    "source": { "ip_address": "72.150.241.94", "country": "US", - "reverse_dns": "adsl-72-150-241-94.shv.bellsouth.net", - "base_domain": "bellsouth.net" + "reverse_dns": null, + "base_domain": null, + "name": null, + "type": null }, "count": 2, "alignment": { @@ -167,7 +171,10 @@ of the report schema.

    "result": "pass" } ] - } + }, + "normalized_timespan": false, + "interval_begin": "2012-04-28 00:00:00", + "interval_end": "2012-04-28 23:59:59" } ] } @@ -176,8 +183,9 @@ of the report schema.

    CSV aggregate report

    -
    xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_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-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
    +
    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,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
     
    diff --git a/py-modindex.html b/py-modindex.html index 664dc11..e81c5e1 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -5,14 +5,14 @@ - Python Module Index — parsedmarc 8.19.1 documentation + Python Module Index — parsedmarc 9.0.0 documentation - + diff --git a/search.html b/search.html index 784a51f..b0fe352 100644 --- a/search.html +++ b/search.html @@ -5,7 +5,7 @@ - Search — parsedmarc 8.19.1 documentation + Search — parsedmarc 9.0.0 documentation @@ -13,7 +13,7 @@ - + diff --git a/searchindex.js b/searchindex.js index 49aee70..24662a2 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"23":10,"2369":[3,8],"24":0,"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86399":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8,12],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"below":[3,8,12],"best":7,"between":[4,7],"beyond":0,"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"indent":12,"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"interval_begin":10,"interval_end":10,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":[0,12],"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8,12],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[0,10,12],"normalize_timespan_threshold_hour":0,"normalized_timespan":10,"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"original_timespan_second":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"prettifi":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":[0,12],"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":[0,12],"smtp_tls_json_filenam":[0,12],"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_nam":10,"source_reverse_dn":10,"source_typ":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[0,2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timespan":0,"timespan_requires_norm":10,"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8,12],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 500f26f..20c6231 100644 --- a/splunk.html +++ b/splunk.html @@ -6,14 +6,14 @@ - Splunk — parsedmarc 8.19.1 documentation + Splunk — parsedmarc 9.0.0 documentation - + diff --git a/usage.html b/usage.html index 5a1ecc0..1248b45 100644 --- a/usage.html +++ b/usage.html @@ -6,14 +6,14 @@ - Using parsedmarc — parsedmarc 8.19.1 documentation + Using parsedmarc — parsedmarc 9.0.0 documentation - + @@ -92,47 +92,50 @@

    CLI help

    usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT]
    -                   [--aggregate-json-filename AGGREGATE_JSON_FILENAME]
    -                   [--forensic-json-filename FORENSIC_JSON_FILENAME]
    -                   [--aggregate-csv-filename AGGREGATE_CSV_FILENAME]
    -                   [--forensic-csv-filename FORENSIC_CSV_FILENAME]
    -                   [-n NAMESERVERS [NAMESERVERS ...]] [-t DNS_TIMEOUT] [--offline]
    -                   [-s] [--verbose] [--debug] [--log-file LOG_FILE] [-v]
    -                   [file_path ...]
    +                  [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME]
    +                  [--smtp-tls-json-filename SMTP_TLS_JSON_FILENAME] [--aggregate-csv-filename AGGREGATE_CSV_FILENAME]
    +                  [--forensic-csv-filename FORENSIC_CSV_FILENAME] [--smtp-tls-csv-filename SMTP_TLS_CSV_FILENAME]
    +                  [-n NAMESERVERS [NAMESERVERS ...]] [-t DNS_TIMEOUT] [--offline] [-s] [-w] [--verbose] [--debug]
    +                  [--log-file LOG_FILE] [--no-prettify-json] [-v]
    +                  [file_path ...]
     
    - Parses DMARC reports
    +Parses DMARC reports
     
    - positional arguments:
    -   file_path             one or more paths to aggregate or forensic report
    -                         files, emails, or mbox files'
    +positional arguments:
    +  file_path             one or more paths to aggregate or forensic report files, emails, or mbox files'
     
    - optional arguments:
    -   -h, --help            show this help message and exit
    -   -c CONFIG_FILE, --config-file CONFIG_FILE
    -                         a path to a configuration file (--silent implied)
    -   --strip-attachment-payloads
    -                         remove attachment payloads from forensic report output
    -   -o OUTPUT, --output OUTPUT
    -                         write output files to the given directory
    -   --aggregate-json-filename AGGREGATE_JSON_FILENAME
    -                         filename for the aggregate JSON output file
    -   --forensic-json-filename FORENSIC_JSON_FILENAME
    -                         filename for the forensic JSON output file
    -   --aggregate-csv-filename AGGREGATE_CSV_FILENAME
    -                         filename for the aggregate CSV output file
    -   --forensic-csv-filename FORENSIC_CSV_FILENAME
    -                         filename for the forensic CSV output file
    -   -n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...]
    -                         nameservers to query
    -   -t DNS_TIMEOUT, --dns_timeout DNS_TIMEOUT
    -                         number of seconds to wait for an answer from DNS
    -                         (default: 2.0)
    -   --offline             do not make online queries for geolocation or DNS
    -   -s, --silent          only print errors and warnings
    -   --verbose             more verbose output
    -   --debug               print debugging information
    -   --log-file LOG_FILE   output logging to a file
    -   -v, --version         show program's version number and exit
    +options:
    +  -h, --help            show this help message and exit
    +  -c CONFIG_FILE, --config-file CONFIG_FILE
    +                        a path to a configuration file (--silent implied)
    +  --strip-attachment-payloads
    +                        remove attachment payloads from forensic report output
    +  -o OUTPUT, --output OUTPUT
    +                        write output files to the given directory
    +  --aggregate-json-filename AGGREGATE_JSON_FILENAME
    +                        filename for the aggregate JSON output file
    +  --forensic-json-filename FORENSIC_JSON_FILENAME
    +                        filename for the forensic JSON output file
    +  --smtp-tls-json-filename SMTP_TLS_JSON_FILENAME
    +                        filename for the SMTP TLS JSON output file
    +  --aggregate-csv-filename AGGREGATE_CSV_FILENAME
    +                        filename for the aggregate CSV output file
    +  --forensic-csv-filename FORENSIC_CSV_FILENAME
    +                        filename for the forensic CSV output file
    +  --smtp-tls-csv-filename SMTP_TLS_CSV_FILENAME
    +                        filename for the SMTP TLS CSV output file
    +  -n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...]
    +                        nameservers to query
    +  -t DNS_TIMEOUT, --dns_timeout DNS_TIMEOUT
    +                        number of seconds to wait for an answer from DNS (default: 2.0)
    +  --offline             do not make online queries for geolocation or DNS
    +  -s, --silent          only print errors
    +  -w, --warnings        print warnings in addition to errors
    +  --verbose             more verbose output
    +  --debug               print debugging information
    +  --log-file LOG_FILE   output logging to a file
    +  --no-prettify-json    output JSON in a single line without indentation
    +  -v, --version         show program's version number and exit