$OpenBSD$ Index: spoofcheck.py --- spoofcheck.py.orig +++ spoofcheck.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import sys @@ -18,11 +18,9 @@ logging.basicConfig(level=logging.INFO) def check_spf_redirect_mechanisms(spf_record): redirect_domain = spf_record.get_redirect_domain() - if redirect_domain is not None: - output_info("Processing an SPF redirect domain: %s" % redirect_domain) - + if redirect_domain: + output_info(f"Processing an SPF redirect domain: {redirect_domain}") return is_spf_record_strong(redirect_domain) - else: return False @@ -31,8 +29,7 @@ def check_spf_include_mechanisms(spf_record): include_domain_list = spf_record.get_include_domains() for include_domain in include_domain_list: - output_info("Processing an SPF include domain: %s" % include_domain) - + output_info(f"Processing an SPF include domain: {include_domain}") strong_all_string = is_spf_record_strong(include_domain) if strong_all_string: @@ -42,8 +39,9 @@ def check_spf_include_mechanisms(spf_record): def is_spf_redirect_record_strong(spf_record): - output_info("Checking SPF redirect domian: %(domain)s" % {"domain": spf_record.get_redirect_domain}) + output_info(f"Checking SPF redirect domain: {spf_record.get_redirect_domain}") redirect_strong = spf_record._is_redirect_mechanism_strong() + if redirect_strong: output_bad("Redirect mechanism is strong.") else: @@ -55,6 +53,7 @@ def is_spf_redirect_record_strong(spf_record): def are_spf_include_mechanisms_strong(spf_record): output_info("Checking SPF include mechanisms") include_strong = spf_record._are_include_mechanisms_strong() + if include_strong: output_bad("Include mechanisms include a strong record") else: @@ -65,7 +64,8 @@ def are_spf_include_mechanisms_strong(spf_record): def check_spf_include_redirect(spf_record): other_records_strong = False - if spf_record.get_redirect_domain() is not None: + + if spf_record.get_redirect_domain(): other_records_strong = is_spf_redirect_record_strong(spf_record) if not other_records_strong: @@ -76,12 +76,15 @@ def check_spf_include_redirect(spf_record): def check_spf_all_string(spf_record): strong_spf_all_string = True - if spf_record.all_string is not None: + + if spf_record.all_string: + if spf_record.all_string == "~all" or spf_record.all_string == "-all": - output_indifferent("SPF record contains an All item: " + spf_record.all_string) + output_indifferent(f"SPF record contains an All item: {spf_record.all_string}") else: - output_good("SPF record All item is too weak: " + spf_record.all_string) + output_good(f"SPF record All item is too weak: {spf_record.all_string}") strong_spf_all_string = False + else: output_good("SPF record has no All string") strong_spf_all_string = False @@ -94,26 +97,24 @@ def check_spf_all_string(spf_record): def is_spf_record_strong(domain): strong_spf_record = True + spf_record = spflib.SpfRecord.from_domain(domain) - if spf_record is not None and spf_record.record is not None: + if spf_record and spf_record.record: output_info("Found SPF record:") output_info(str(spf_record.record)) strong_all_string = check_spf_all_string(spf_record) - if strong_all_string is False: + if not strong_all_string: redirect_strength = check_spf_redirect_mechanisms(spf_record) include_strength = check_spf_include_mechanisms(spf_record) strong_spf_record = False - if redirect_strength is True: + if redirect_strength or include_strength: strong_spf_record = True - - if include_strength is True: - strong_spf_record = True else: - output_good(domain + " has no SPF record!") + output_good(f"{domain} has no SPF record!") strong_spf_record = False return strong_spf_record @@ -121,7 +122,7 @@ def is_spf_record_strong(domain): def get_dmarc_record(domain): dmarc = dmarclib.DmarcRecord.from_domain(domain) - if dmarc is not None and dmarc.record is not None: + if dmarc and dmarc.record: output_info("Found DMARC record:") output_info(str(dmarc.record)) return dmarc @@ -129,31 +130,32 @@ def get_dmarc_record(domain): def get_dmarc_org_record(base_record): org_record = base_record.get_org_record() - if org_record is not None: + if org_record: output_info("Found DMARC Organizational record:") output_info(str(org_record.record)) return org_record def check_dmarc_extras(dmarc_record): - if dmarc_record.pct is not None and dmarc_record.pct != str(100): - output_indifferent("DMARC pct is set to " + dmarc_record.pct + "% - might be possible") + if dmarc_record.pct and dmarc_record.pct != str(100): + output_indifferent(f"DMARC pct is set to {dmarc_record.pct}% - might be possible") - if dmarc_record.rua is not None: - output_indifferent("Aggregate reports will be sent: " + dmarc_record.rua) + if dmarc_record.rua: + output_indifferent(f"Aggregate reports will be sent: {dmarc_record.rua}") - if dmarc_record.ruf is not None: - output_indifferent("Forensics reports will be sent: " + dmarc_record.ruf) + if dmarc_record.ruf: + output_indifferent(f"Forensics reports will be sent: {dmarc_record.ruf}") def check_dmarc_policy(dmarc_record): policy_strength = False - if dmarc_record.policy is not None: + + if dmarc_record.policy: if dmarc_record.policy == "reject" or dmarc_record.policy == "quarantine": policy_strength = True - output_bad("DMARC policy set to " + dmarc_record.policy) + output_bad(f"DMARC policy set to {dmarc_record.policy}") else: - output_good("DMARC policy set to " + dmarc_record.policy) + output_good(f"DMARC policy set to {dmarc_record.policy}") else: output_good("DMARC record has no Policy") @@ -165,18 +167,18 @@ def check_dmarc_org_policy(base_record): try: org_record = base_record.get_org_record() - if org_record is not None and org_record.record is not None: + if org_record and org_record.record: output_info("Found organizational DMARC record:") output_info(str(org_record.record)) - if org_record.subdomain_policy is not None: + if org_record.subdomain_policy: if org_record.subdomain_policy == "none": - output_good("Organizational subdomain policy set to %(sp)s" % {"sp": org_record.subdomain_policy}) + output_good(f"Organizational subdomain policy set to {org_record.subdomain_policy}") elif org_record.subdomain_policy == "quarantine" or org_record.subdomain_policy == "reject": - output_bad("Organizational subdomain policy explicitly set to %(sp)s" % {"sp": org_record.subdomain_policy}) + output_bad(f"Organizational subdomain policy explicitly set to {org_record.subdomain_policy}") policy_strong = True else: - output_info("No explicit organizational subdomain policy. Defaulting to organizational policy") + output_info("No explicit organizational subdomain policy. Defaulting to organizational policy.") policy_strong = check_dmarc_policy(org_record) else: output_good("No organizational DMARC record") @@ -195,15 +197,17 @@ def is_dmarc_record_strong(domain): dmarc = get_dmarc_record(domain) - if dmarc is not None and dmarc.record is not None: + if dmarc and dmarc.record: dmarc_record_strong = check_dmarc_policy(dmarc) check_dmarc_extras(dmarc) - elif dmarc.get_org_domain() is not None: - output_info("No DMARC record found. Looking for organizational record") + + elif dmarc.get_org_domain(): + output_info("No DMARC record found. Looking for organizational record.") dmarc_record_strong = check_dmarc_org_policy(dmarc) + else: - output_good(domain + " has no DMARC record!") + output_good(f"{domain} has no DMARC record!") return dmarc_record_strong @@ -215,18 +219,13 @@ if __name__ == "__main__": try: domain = sys.argv[1] - spf_record_strength = is_spf_record_strong(domain) + spf_record_strong = is_spf_record_strong(domain) + dmarc_record_strong = is_dmarc_record_strong(domain) - dmarc_record_strength = is_dmarc_record_strong(domain) - if dmarc_record_strength is False: - spoofable = True + if spf_record_strong and dmarc_record_strong: + output_bad(f"Spoofing not possible for {domain}") else: - spoofable = False + output_good(f"Spoofing possible for {domain}!") - if spoofable: - output_good("Spoofing possible for " + domain + "!") - else: - output_bad("Spoofing not possible for " + domain) - except IndexError: - output_error("Usage: " + sys.argv[0] + " [DOMAIN]") + output_error(f"Usage: {sys.argv[0]} [DOMAIN]")