configwizard: set [hostfingerprints] when necessary (bug 1277406); r?glob draft
authorGregory Szorc <gps@mozilla.com>
Wed, 01 Jun 2016 16:21:59 -0700
changeset 8505 99f1ba59c1111b25549d461344298ef8d320471d
parent 8504 4bd95e71c235df22c4299505a404292ad2277d14
child 8506 fa342d0d8b1de9a080f3d7bef69403648552f623
push id918
push userbmo:gps@mozilla.com
push dateThu, 09 Jun 2016 19:23:31 +0000
reviewersglob
bugs1277406
configwizard: set [hostfingerprints] when necessary (bug 1277406); r?glob Another basic port from upstream. At the end of this commit, config.py had no value, so it was deleted. MozReview-Commit-ID: 23bFwcYWuP2
hgext/configwizard/__init__.py
hgext/configwizard/hgsetup/config.py
hgext/configwizard/hgsetup/wizard.py
hgext/configwizard/tests/test-security.t
--- a/hgext/configwizard/__init__.py
+++ b/hgext/configwizard/__init__.py
@@ -18,16 +18,23 @@ from mercurial import (
 )
 from mercurial.i18n import _
 
 OUR_DIR = os.path.dirname(__file__)
 execfile(os.path.join(OUR_DIR, '..', 'bootstrap.py'))
 
 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',
+}
+
 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()
@@ -210,16 +217,17 @@ command = cmdutil.command(cmdtable)
 wizardsteps = {
     'hgversion',
     'username',
     'diff',
     'color',
     'historyediting',
     'fsmonitor',
     'wip',
+    'security',
     'firefoxtree',
     'codereview',
     'pushtotry',
     'configchange',
 }
 
 @command('configwizard', [
     ('s', 'statedir', '', _('directory to store state')),
@@ -259,16 +267,19 @@ def configwizard(ui, repo, statedir=None
         _checkhistoryediting(ui, cw)
 
     if 'fsmonitor' in runsteps:
         _checkfsmonitor(ui, cw, hgversion)
 
     if 'wip' in runsteps:
         _checkwip(ui, cw)
 
+    if 'security' in runsteps:
+        _checksecurity(ui, cw, hgversion)
+
     if 'firefoxtree' in runsteps:
         _promptvctextension(ui, cw, 'firefoxtree', FIREFOXTREE_INFO)
 
     if 'codereview' in runsteps:
         _checkcodereview(ui, cw)
 
     if 'pushtotry' in runsteps:
         _promptvctextension(ui, cw, 'push-to-try', PUSHTOTRY_INFO)
@@ -474,16 +485,40 @@ def _checkwip(ui, cw):
             '{label("log.bookmark", if(bookmarks," {bookmarks}"))}'
             '\\n'
             # first line of commit message
             '{label(ifcontains(rev, revset("."), "desc.here"),desc|firstline)}'
             "'"
         )
 
 
+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.
+    modernssl = hasattr(ssl, 'SSLContext')
+    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
+
+    # 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
+
+
 def _checkcodereview(ui, cw):
     # We don't check for bzexport if reviewboard is enabled because
     # bzexport is legacy.
     if ui.hasconfig('extensions', 'reviewboard'):
         return
 
     if ui.promptchoice('Will you be submitting commits to Mozilla (Yn)? $$ &Yes $$ &No'):
         return
deleted file mode 100644
--- a/hgext/configwizard/hgsetup/config.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this,
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-from __future__ import unicode_literals
-
-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',
-}
-
-
-class MercurialConfig(object):
-    """Interface for manipulating a Mercurial config file."""
-
-    def add_mozilla_host_fingerprints(self):
-        """Add host fingerprints so SSL connections don't warn."""
-        if 'hostfingerprints' not in self._c:
-            self._c['hostfingerprints'] = {}
-
-        for k, v in HOST_FINGERPRINTS.items():
-            self._c['hostfingerprints'][k] = v
-
-    def update_mozilla_host_fingerprints(self):
-        """Update host fingerprints if they are present."""
-        if 'hostfingerprints' not in self._c:
-            return
-
-        for k, v in HOST_FINGERPRINTS.items():
-            if k in self._c['hostfingerprints']:
-                self._c['hostfingerprints'][k] = v
-
-    def activate_extension(self, name, path=None):
-        """Activate an extension.
-
-        An extension is defined by its name (in the config) and a filesystem
-        path). For built-in extensions, an empty path is specified.
-        """
-        if not path:
-            path = ''
-
-        if 'extensions' not in self._c:
-            self._c['extensions'] = {}
-
-        self._c['extensions'][name] = path
--- a/hgext/configwizard/hgsetup/wizard.py
+++ b/hgext/configwizard/hgsetup/wizard.py
@@ -82,31 +82,16 @@ class MercurialSetupWizard(object):
         for ext in {'bzexport', 'qimportbz', 'mqext'}:
             path = os.path.join(self.ext_dir, ext)
             if os.path.exists(path):
                 if self._prompt_yn('Would you like to remove the old and no '
                     'longer referenced repository at %s' % path):
                     print('Cleaning up old repository: %s' % path)
                     shutil.rmtree(path)
 
-        # 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.
-        have_modern_ssl = hasattr(ssl, 'SSLContext')
-        if hg_version < LooseVersion('3.4') or not have_modern_ssl:
-            c.add_mozilla_host_fingerprints()
-
-        # 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.
-        c.update_mozilla_host_fingerprints()
-
         # References to multiple version-control-tools checkouts can confuse
         # version-control-tools, since various Mercurial extensions resolve
         # dependencies via __file__ and repos could reference another copy.
         seen_vct = set()
         for k, v in c.config.get('extensions', {}).items():
             if 'version-control-tools' not in v:
                 continue
 
new file mode 100644
--- /dev/null
+++ b/hgext/configwizard/tests/test-security.t
@@ -0,0 +1,65 @@
+  $ . $TESTDIR/hgext/configwizard/tests/helpers.sh
+
+[hostfingerprints] not added on modern hg
+
+  $ 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>
+
+#if !sslcontext
+
+  $ 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 @@
+  +[hostfingerprints]
+  +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
+
+  $ 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,4 @@
+   [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
+