configwizard: use [hostsecurity] section to pin fingerprints (bug 1304793); r?smacleod draft
authorGregory Szorc <gps@mozilla.com>
Wed, 21 Sep 2016 11:40:34 -0700
changeset 9627 74d7eeb876d8df05ac9113f60384119783107b28
parent 9626 2f6865eec56d2d81de1a633b39134b4fc6c27ce2
push id1251
push userbmo:gps@mozilla.com
push dateThu, 22 Sep 2016 17:26:54 +0000
reviewerssmacleod
bugs1304793
configwizard: use [hostsecurity] section to pin fingerprints (bug 1304793); r?smacleod Mercurial 3.9 supports a new [hostsecurity] section that is everything [hostfingerprints] was and more. We add code to detect when running on Mercurial 3.9+. If so, we set fingerprints in [hostsecurity]. Fingerprints are defined as SHA-256, since that is harder to create a hash collision for than SHA-1. If [hostfingerprints] is present, we port fingerprints to [hostsecurity] automatically. It's worth noting that we never delete pinned fingerprints. However, fresh runs on Mercurial 3.9+ with modern SSL won't pin the fingerprints. MozReview-Commit-ID: 3HRNy1Wbg5x
hgext/configwizard/__init__.py
hgext/configwizard/tests/test-security.t
--- a/hgext/configwizard/__init__.py
+++ b/hgext/configwizard/__init__.py
@@ -28,16 +28,22 @@ from configobj import ConfigObj
 
 
 HOST_FINGERPRINTS = {
     'bitbucket.org': '3f:d3:c5:17:23:3c:cd:f5:2d:17:76:06:93:7e:ee:97:42:21:14:aa',
     'bugzilla.mozilla.org': '7c:7a:c4:6c:91:3b:6b:89:cf:f2:8c:13:b8:02:c4:25:bd:1e:25:17',
     'hg.mozilla.org': 'af:27:b9:34:47:4e:e5:98:01:f6:83:2b:51:c9:aa:d8:df:fb:1a:27',
 }
 
+MODERN_FINGERPRINTS = {
+    'bitbucket.org': 'sha256:4e:65:3e:76:0f:81:59:85:5b:50:06:0c:c2:4d:3c:56:53:8b:83:3e:9b:fa:55:26:98:9a:ca:e2:25:03:92:47',
+    'bugzilla.mozilla.org': 'sha256:10:95:a8:c1:e1:c3:18:fa:e4:95:40:99:11:07:6d:e3:79:ab:e5:b0:29:50:ff:40:e8:e8:63:c4:fd:f3:9f:cb',
+    'hg.mozilla.org': 'sha256:81:3d:75:69:e3:76:f8:5b:31:1e:92:c9:cf:56:23:f6:4b:c2:82:77:e3:63:fb:7f:28:65:d0:9a:88:fb:be:b7',
+}
+
 INITIAL_MESSAGE = '''
 This wizard will guide you through configuring Mercurial for an optimal
 experience contributing to Mozilla projects.
 
 The wizard makes no changes without your permission.
 
 To begin, press the enter/return key.
 '''.lstrip()
@@ -721,29 +727,63 @@ def _checksecurity(ui, cw, hgversion):
     import ssl
 
     # Python + Mercurial didn't have terrific TLS handling until Python
     # 2.7.9 and Mercurial 3.4. For this reason, it was recommended to pin
     # certificates in Mercurial config files. In modern versions of
     # Mercurial, the system CA store is used and old, legacy TLS protocols
     # are disabled. The default connection/security setting should
     # be sufficient and pinning certificates is no longer needed.
+
+    hg39 = util.versiontuple(n=2) >= (3, 9)
     modernssl = hasattr(ssl, 'SSLContext')
+
+    def setfingerprints(porting=False):
+        # Need to process in sorted order for tests to be deterministic.
+        if hg39:
+            cw.c.setdefault('hostsecurity', {})
+            for k, v in sorted(MODERN_FINGERPRINTS.items()):
+                if porting and k not in cw.c.get('hostfingerprints', {}):
+                    continue
+
+                cw.c['hostsecurity']['%s:fingerprints' % k] = v
+        else:
+            cw.c.setdefault('hostfingerprints', {})
+            for k, v in sorted(HOST_FINGERPRINTS.items()):
+                if porting and k not in cw.c['hostfingerprints']:
+                    continue
+
+                cw.c['hostfingerprints'][k] = v
+
     if not modernssl:
-        cw.c.setdefault('hostfingerprints', {})
-        # Need to process in sorted order for tests to be deterministic.
-        for k, v in sorted(HOST_FINGERPRINTS.items()):
-            cw.c['hostfingerprints'][k] = v
+        setfingerprints()
 
     # We always update fingerprints if they are present. We /could/ offer to
     # remove fingerprints if running modern Python and Mercurial. But that
     # just adds more UI complexity and isn't worth it.
-    if 'hostfingerprints' in cw.c:
-        for k, v in sorted(HOST_FINGERPRINTS.items()):
-            cw.c['hostfingerprints'][k] = v
+    have_legacy = any(k in cw.c.get('hostfingerprints', {})
+                      for k in HOST_FINGERPRINTS)
+    have_modern = any('%s:fingerprints' % k in cw.c.get('hostsecurity', {})
+                      for k in MODERN_FINGERPRINTS)
+
+    if have_legacy or have_modern:
+        setfingerprints(porting=True)
+
+    # If we're using Mercurial 3.9, remove legacy fingerprints if they
+    # are present.
+    if have_legacy and hg39:
+        for k in HOST_FINGERPRINTS:
+            try:
+                del cw.c['hostfingerprints'][k]
+            except KeyError:
+                pass
+
+        # Delete empty config section.
+        if 'hostfingerprints' in cw.c and not cw.c['hostfingerprints']:
+            del cw.c['hostfingerprints']
 
 
 def _checkcodereview(ui, cw):
     # We don't check for bzexport if reviewboard is enabled because
     # bzexport is legacy.
     if ui.hasconfig('extensions', 'reviewboard'):
         return
 
--- a/hgext/configwizard/tests/test-security.t
+++ b/hgext/configwizard/tests/test-security.t
@@ -1,22 +1,25 @@
   $ . $TESTDIR/hgext/configwizard/tests/helpers.sh
 
-[hostfingerprints] not added on modern hg
+#if sslcontext hg39+
+Modern Mercurial doesn't need to pin fingerprints
 
   $ hg --config configwizard.steps=security,configchange configwizard
   This wizard will guide you through configuring Mercurial for an optimal
   experience contributing to Mozilla projects.
   
   The wizard makes no changes without your permission.
   
   To begin, press the enter/return key.
    <RETURN>
+#endif
 
-#if no-sslcontext
+#if no-sslcontext no-hg39+
+[hostfingerprints] get set on Mercurial <3.9 if modern SSL not supported
 
   $ hg --config configwizard.steps=security,configchange configwizard
   This wizard will guide you through configuring Mercurial for an optimal
   experience contributing to Mozilla projects.
 
   The wizard makes no changes without your permission.
 
   To begin, press the enter/return key.
@@ -30,17 +33,43 @@
   +hg.mozilla.org = af:27:b9:34:47:4e:e5:98:01:f6:83:2b:51:c9:aa:d8:df:fb:1a:27
   +bitbucket.org = 3f:d3:c5:17:23:3c:cd:f5:2d:17:76:06:93:7e:ee:97:42:21:14:aa
   +bugzilla.mozilla.org = 7c:7a:c4:6c:91:3b:6b:89:cf:f2:8c:13:b8:02:c4:25:bd:1e:25:17
 
   Write changes to hgrc file (Yn)?  y
 
 #endif
 
-fingerprints updated when they are already pinned
+#if no-sslcontext hg39+
+[hostsecurity] set on Mercurial 3.9+ when no modern SSL
+
+  $ hg --config configwizard.steps=security,configchange configwizard
+  This wizard will guide you through configuring Mercurial for an optimal
+  experience contributing to Mozilla projects.
+
+  The wizard makes no changes without your permission.
+
+  To begin, press the enter/return key.
+   <RETURN>
+  Your config file needs updating.
+  Would you like to see a diff of the changes first (Yn)?  y
+  --- hgrc.old
+  +++ hgrc.new
+  @@ -1,1 +1,4 @@
+  +[hostsecurity]
+  +hg.mozilla.org:fingerprints = sha256:81:3d:75:69:e3:76:f8:5b:31:1e:92:c9:cf:56:23:f6:4b:c2:82:77:e3:63:fb:7f:28:65:d0:9a:88:fb:be:b7
+  +bitbucket.org:fingerprints = sha256:4e:65:3e:76:0f:81:59:85:5b:50:06:0c:c2:4d:3c:56:53:8b:83:3e:9b:fa:55:26:98:9a:ca:e2:25:03:92:47
+  +bugzilla.mozilla.org:fingerprints = sha256:10:95:a8:c1:e1:c3:18:fa:e4:95:40:99:11:07:6d:e3:79:ab:e5:b0:29:50:ff:40:e8:e8:63:c4:fd:f3:9f:cb
+
+  Write changes to hgrc file (Yn)?  y
+
+#endif
+
+#if no-hg39+
+[hostfingerprints] updated on Mercurial <3.9 when they are already pinned
 
   $ cat > .hgrc << EOF
   > [hostfingerprints]
   > hg.mozilla.org = aa:bb:cc:dd
   > EOF
 
   $ hg --config configwizard.steps=security,configchange configwizard
   This wizard will guide you through configuring Mercurial for an optimal
@@ -49,17 +78,48 @@ fingerprints updated when they are alrea
   The wizard makes no changes without your permission.
   
   To begin, press the enter/return key.
    <RETURN>
   Your config file needs updating.
   Would you like to see a diff of the changes first (Yn)?  y
   --- hgrc.old
   +++ hgrc.new
-  @@ -1,2 +1,4 @@
+  @@ -1,2 +1,2 @@
    [hostfingerprints]
   -hg.mozilla.org = aa:bb:cc:dd
   +hg.mozilla.org = af:27:b9:34:47:4e:e5:98:01:f6:83:2b:51:c9:aa:d8:df:fb:1a:27
-  +bitbucket.org = 3f:d3:c5:17:23:3c:cd:f5:2d:17:76:06:93:7e:ee:97:42:21:14:aa
-  +bugzilla.mozilla.org = 7c:7a:c4:6c:91:3b:6b:89:cf:f2:8c:13:b8:02:c4:25:bd:1e:25:17
   
   Write changes to hgrc file (Yn)?  y
 
+#endif
+
+#if hg39+
+[hostfingerprints] deleted and converted to [hostsecurity]
+(Note: no new fingerprints are added)
+
+  $ cat > .hgrc << EOF
+  > [hostfingerprints]
+  > hg.mozilla.org = aa:bb:cc:dd
+  > EOF
+
+  $ hg --config configwizard.steps=security,configchange configwizard
+  This wizard will guide you through configuring Mercurial for an optimal
+  experience contributing to Mozilla projects.
+  
+  The wizard makes no changes without your permission.
+  
+  To begin, press the enter/return key.
+   <RETURN>
+  Your config file needs updating.
+  Would you like to see a diff of the changes first (Yn)?  y
+  --- hgrc.old
+  +++ hgrc.new
+  @@ -1,2 +1,2 @@
+  -[hostfingerprints]
+  -hg.mozilla.org = aa:bb:cc:dd
+  +[hostsecurity]
+  +hg.mozilla.org:fingerprints = sha256:81:3d:75:69:e3:76:f8:5b:31:1e:92:c9:cf:56:23:f6:4b:c2:82:77:e3:63:fb:7f:28:65:d0:9a:88:fb:be:b7
+  
+  Write changes to hgrc file (Yn)?  y
+
+
+#endif