From 9ce047980a991129de1bfc6b56a8bd133f798942 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 12 Jun 2014 11:40:17 -0400 Subject: [PATCH 1/4] Add .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..94c6f7089 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.* +*.orig From 9cd71642fb13688565a2b245eac06089eaad8dcb Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 12 Jun 2014 11:50:39 -0400 Subject: [PATCH 2/4] Fix italicization boundaries --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2f0a410a1..6717f8b72 100644 --- a/README.md +++ b/README.md @@ -109,19 +109,19 @@ Config-generator should attempt to fetch the configuration file daily and transf The _address-domains_ field maps from mail domains (the part of an address after the "@") onto a list of properties for that domain. Matching of mail domains is on an exact-match basis, not a subdomain basis. For instance, eff.org would be listed separately from lists.eff.org in the _address-domains_ section. -Currently the only property defined for _address-domains_ is _accept-mx-domains_, a list. If an MX lookup for a listed address domain returns a hostname that is not a subdomain of one of the domains listed in the _accept-mx-domains_ property, the MTA should fail delivery or log an advisory failure, as appropriate. Matching of MX hostnames against the _accept-mx-domains_ list is on a subdomain basis. For instance, if an MX record for yahoo.com lists mta7.am0.yahoodns.net, and the _accept-mx-domains_ property for yahoo.com is ["yahoodns.net"], that should be considered a match. All domains listed in any _accept-mx-domains _list must correspond to an exactly matching field in the _mx-domains_ config section. +Currently the only property defined for _address-domains_ is _accept-mx-domains_, a list. If an MX lookup for a listed address domain returns a hostname that is not a subdomain of one of the domains listed in the _accept-mx-domains_ property, the MTA should fail delivery or log an advisory failure, as appropriate. Matching of MX hostnames against the _accept-mx-domains_ list is on a subdomain basis. For instance, if an MX record for yahoo.com lists mta7.am0.yahoodns.net, and the _accept-mx-domains_ property for yahoo.com is ["yahoodns.net"], that should be considered a match. All domains listed in any _accept-mx-domains_ list must correspond to an exactly matching field in the _mx-domains_ config section. The _accept-mx-domains_ mechanism partially solves the problem of DNS MITM. It doesn't completely solve the problem, since an attacker might somehow control a different hostname under an acceptable domain, e.g. evil.yahoodns.net. But it strikes a balance between improving security and allowing mail operators to change configuration as needed. Some mail operators delegate their MX handling to a third-party provider (i.e. Google Apps for Your Domain). If those operators are included in STARTTLS Everywhere and wish to change providers, they will have to first send an update to their _accept-mx-domains_ to include their new provider. **mx-domains** -The keys of this section are MX domains as described above for the _accept-mx-domains_ property. Each _mx-domain_ entry must be an exact match with an entry in one of the _accept-mx-domains_ lists provided. No _mx-domain _can be a subdomain of any other _mx-domain _in the configuration file. Fields in this section specify minimum security requirements that should be applied when connecting to any MX hostname that is a subdomain of the specified _mx-domain_. +The keys of this section are MX domains as described above for the _accept-mx-domains_ property. Each _mx-domain_ entry must be an exact match with an entry in one of the _accept-mx-domains_ lists provided. No _mx-domain_can be a subdomain of any other _mx-domain_in the configuration file. Fields in this section specify minimum security requirements that should be applied when connecting to any MX hostname that is a subdomain of the specified _mx-domain_. Implicitly each _mx-domain_ listed has a property _require-tls: true_. MX domains that do not support TLS will not be listed. The only required property is _enforce-mode_, which must be either _log-only_ or _enforce_. If _enforce-mode_ is _log-only_, the generated configs will not stop mail delivery on policy failures, but will produce logging information. If the _min-tls-version_ property is present, sending mail to domains under this policy should fail if the sending MTA cannot negotiate a TLS version equal to or greater than the listed version. Valid values are _TLSv1, TLSv1.1, and TLSv1.2._ -_Require-valid-certificate _defaults to false. If the _require-valid-certificate_ property is 'true' for a given _mx-domain_ the certificate presented must be valid for a hostname that is subdomain of the _mx-domain_. Validity means all of these must be true: +_Require-valid-certificate_defaults to false. If the _require-valid-certificate_ property is 'true' for a given _mx-domain_ the certificate presented must be valid for a hostname that is subdomain of the _mx-domain_. Validity means all of these must be true: 1. The CN or a DNS entry under subjectAltName matches an appropriate hostname. 2. The certificate is unexpired. From 499f6c2fad62fe4d793cfee727576f399012a1b2 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 12 Jun 2014 11:53:02 -0400 Subject: [PATCH 3/4] Add comment to ProcessgoogleSTARTTLSDomains.py --- ProcessGoogleSTARTTLSDomains.py | 11 ++++++++++- config.json | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ProcessGoogleSTARTTLSDomains.py b/ProcessGoogleSTARTTLSDomains.py index 0a0201875..abb2b3495 100755 --- a/ProcessGoogleSTARTTLSDomains.py +++ b/ProcessGoogleSTARTTLSDomains.py @@ -1,4 +1,13 @@ #!/usr/bin/python +""" +Process Google's TLS delivery data from +https://www.google.com/transparencyreport/saferemail/data/?hl=en +to look for outbound domains that can negotiate an encrypted +connection >99% of the time. + +Usage: + ./ProcessGoogleSTARTTLSDomains.py google-starttls-domains.csv +""" import csv import codecs import sys @@ -14,5 +23,5 @@ for (address_suffix, hostname_suffix, direction, region, fraction_encrypted) in pass for address_suffix, fraction_encrypted in d.iteritems(): - if min(fraction_encrypted) >= 0.50: + if min(fraction_encrypted) >= 0.99: print min(fraction_encrypted), address_suffix diff --git a/config.json b/config.json index 8d38696ff..1a9034545 100644 --- a/config.json +++ b/config.json @@ -3,7 +3,7 @@ "timestamp": 1401093333, "author": "Electronic Frontier Foundation https://eff.org", "expires": 1404677353, "comment 2:": "epoch seconds", - "security-policies": { + "tls-policies": { "*.valid-example-recipient.com": { "min-tls-version": "TLSv1.1" } From 43d457aa771e663a7c15886fbc81db081947d9cf Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 12 Jun 2014 13:18:20 -0400 Subject: [PATCH 4/4] Typo cleanup in MTAConfigGenerator --- ConfigParser.py | 1 - MTAConfigGenerator.py | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ConfigParser.py b/ConfigParser.py index 8bc7e708f..206132293 100755 --- a/ConfigParser.py +++ b/ConfigParser.py @@ -36,7 +36,6 @@ class Config: f = open(cfg_file_name) self.cfg = json.loads(f.read()) for atr, val in self.cfg.items(): - #print atr,val # Verify each attribute of the structure if atr.startswith("comment"): continue diff --git a/MTAConfigGenerator.py b/MTAConfigGenerator.py index 3b69ba37a..d5ec334ec 100755 --- a/MTAConfigGenerator.py +++ b/MTAConfigGenerator.py @@ -3,12 +3,12 @@ import string import os.path -POSTFIX_DIR = "/etc/postfix" +POSTFIX_DIR = "postfix-copy" DEFAULT_POLICY_FILE = os.path.join(POSTFIX_DIR, "starttls_everywhere_policy") POLICY_CF_ENTRY="texthash:" + DEFAULT_POLICY_FILE def parse_line(line_data): - "return the and right hand sides of stripped, non-comment postfix config line" + "return the left and right hand sides of stripped, non-comment postfix config line" # lines are like: # smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache num,line = line_data @@ -17,8 +17,6 @@ def parse_line(line_data): return None return (num, left.strip(), right.strip()) -#def get_cf_values(lines, var): - class MTAConfigGenerator: def __init__(self, policy_config): self.policy_config = policy_config @@ -36,8 +34,8 @@ class PostfixConfigGenerator(MTAConfigGenerator): def ensure_cf_var(self, var, ideal, also_acceptable): """ Ensure that existing postfix config @var is in the list of @acceptable - values; if not, set it to the ideal value. """ - + values; if not, set it to the ideal value. + """ acceptable = [ideal] + also_acceptable l = [(num,line) for num,line in enumerate(self.cf) if line.startswith(var)]