From 1fbf6db1276c5bca41c4cfbcc90818d9605c1938 Mon Sep 17 00:00:00 2001
From: Tomas Touceda <chiiph@leap.se>
Date: Fri, 12 Apr 2013 14:07:15 -0300
Subject: Add --danger option to not validate the first hop of certificates

This is intended to be used while testing, not in production
---
 src/leap/app.py                               |  3 ++-
 src/leap/gui/mainwindow.py                    | 17 +++++++++++++----
 src/leap/gui/wizard.py                        |  7 +++++--
 src/leap/services/eip/providerbootstrapper.py | 19 +++++++++++++++----
 src/leap/util/leap_argparse.py                |  2 ++
 5 files changed, 37 insertions(+), 11 deletions(-)

(limited to 'src')

diff --git a/src/leap/app.py b/src/leap/app.py
index c4a3156e..bb8add0d 100644
--- a/src/leap/app.py
+++ b/src/leap/app.py
@@ -57,6 +57,7 @@ def main():
     _, opts = leap_argparse.init_leapc_args()
     debug = opts.debug
     standalone = opts.standalone
+    bypass_checks = opts.danger
 
     # TODO: get severity from command line args
     if debug:
@@ -118,7 +119,7 @@ def main():
     timer.start(500)
     timer.timeout.connect(lambda: None)
 
-    window = MainWindow(standalone)
+    window = MainWindow(standalone, bypass_checks)
     window.show()
 
     sigint_window = partial(sigint_handler, window, logger=logger)
diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py
index bf8491d0..c9743f95 100644
--- a/src/leap/gui/mainwindow.py
+++ b/src/leap/gui/mainwindow.py
@@ -68,13 +68,16 @@ class MainWindow(QtGui.QMainWindow):
     new_updates = QtCore.Signal(object)
     raise_window = QtCore.Signal([])
 
-    def __init__(self, standalone=False):
+    def __init__(self, standalone=False, bypass_checks=False):
         """
         Constructor for the client main window
 
         @param standalone: Set to true if the app should use configs
         inside its pwd
         @type standalone: bool
+        @param bypass_checks: Set to true if the app should bypass
+        first round of checks for CA certificates at bootstrap
+        @type bypass_checks: bool
         """
         QtGui.QMainWindow.__init__(self)
 
@@ -136,7 +139,7 @@ class MainWindow(QtGui.QMainWindow):
         # This thread is always running, although it's quite
         # lightweight when it's done setting up provider
         # configuration and certificate.
-        self._provider_bootstrapper = ProviderBootstrapper()
+        self._provider_bootstrapper = ProviderBootstrapper(bypass_checks)
 
         # Intermediate stages, only do something if there was an error
         self._provider_bootstrapper.name_resolution.connect(
@@ -237,9 +240,14 @@ class MainWindow(QtGui.QMainWindow):
 
         self._wizard = None
         self._wizard_firstrun = False
+
+        self._bypass_checks = bypass_checks
+
         if self._first_run():
             self._wizard_firstrun = True
-            self._wizard = Wizard(self._checker_thread, standalone=standalone)
+            self._wizard = Wizard(self._checker_thread,
+                                  standalone=standalone,
+                                  bypass_checks=bypass_checks)
             # Give this window time to finish init and then show the wizard
             QtCore.QTimer.singleShot(1, self._launch_wizard)
             self._wizard.accepted.connect(self._finish_init)
@@ -256,7 +264,8 @@ class MainWindow(QtGui.QMainWindow):
 
     def _launch_wizard(self):
         if self._wizard is None:
-            self._wizard = Wizard(self._checker_thread)
+            self._wizard = Wizard(self._checker_thread,
+                                  bypass_checks=self._bypass_checks)
         self._wizard.exec_()
         self._wizard = None
 
diff --git a/src/leap/gui/wizard.py b/src/leap/gui/wizard.py
index 4da4c815..33c3ed0c 100644
--- a/src/leap/gui/wizard.py
+++ b/src/leap/gui/wizard.py
@@ -51,7 +51,7 @@ class Wizard(QtGui.QWizard):
 
     BARE_USERNAME_REGEX = r"^[A-Za-z\d_]+$"
 
-    def __init__(self, checker, standalone=False):
+    def __init__(self, checker, standalone=False, bypass_checks=False):
         """
         Constructor for the main Wizard.
 
@@ -60,6 +60,9 @@ class Wizard(QtGui.QWizard):
         @param standalone: If True, the application is running as standalone
             and the wizard should display some messages according to this.
         @type standalone: bool
+        @param bypass_checks: Set to true if the app should bypass
+        first round of checks for CA certificates at bootstrap
+        @type bypass_checks: bool
         """
         QtGui.QWizard.__init__(self)
 
@@ -98,7 +101,7 @@ class Wizard(QtGui.QWizard):
         self.ui.btnCheck.clicked.connect(self._check_provider)
         self.ui.lnProvider.returnPressed.connect(self._check_provider)
 
-        self._provider_bootstrapper = ProviderBootstrapper()
+        self._provider_bootstrapper = ProviderBootstrapper(bypass_checks)
         self._provider_bootstrapper.name_resolution.connect(
             self._name_resolution)
         self._provider_bootstrapper.https_connection.connect(
diff --git a/src/leap/services/eip/providerbootstrapper.py b/src/leap/services/eip/providerbootstrapper.py
index 778d5149..f5559143 100644
--- a/src/leap/services/eip/providerbootstrapper.py
+++ b/src/leap/services/eip/providerbootstrapper.py
@@ -58,7 +58,14 @@ class ProviderBootstrapper(QtCore.QObject):
     check_ca_fingerprint = QtCore.Signal(dict)
     check_api_certificate = QtCore.Signal(dict)
 
-    def __init__(self):
+    def __init__(self, bypass_checks=False):
+        """
+        Constructor for provider bootstrapper object
+
+        @param bypass_checks: Set to true if the app should bypass
+        first round of checks for CA certificates at bootstrap
+        @type bypass_checks: bool
+        """
         QtCore.QObject.__init__(self)
 
         # **************************************************** #
@@ -71,6 +78,7 @@ class ProviderBootstrapper(QtCore.QObject):
         self._domain = None
         self._provider_config = None
         self._download_if_needed = False
+        self._bypass_checks = bypass_checks
 
     def _check_name_resolution(self):
         """
@@ -124,7 +132,8 @@ class ProviderBootstrapper(QtCore.QObject):
         # system to work
 
         try:
-            res = self._session.get("https://%s" % (self._domain,))
+            res = self._session.get("https://%s" % (self._domain,),
+                                    verify=not self._bypass_checks)
             res.raise_for_status()
             https_data[self.PASSED_KEY] = True
         except requests.exceptions.SSLError as e:
@@ -171,7 +180,8 @@ class ProviderBootstrapper(QtCore.QObject):
 
             res = self._session.get("https://%s/%s" % (self._domain,
                                                        "provider.json"),
-                                    headers=headers)
+                                    headers=headers,
+                                    verify=not self._bypass_checks)
             res.raise_for_status()
 
             # Not modified
@@ -270,7 +280,8 @@ class ProviderBootstrapper(QtCore.QObject):
             return download_ca_cert_data[self.PASSED_KEY]
 
         try:
-            res = self._session.get(self._provider_config.get_ca_cert_uri())
+            res = self._session.get(self._provider_config.get_ca_cert_uri(),
+                                    verify=not self._bypass_checks)
             res.raise_for_status()
 
             cert_path = self._provider_config.get_ca_cert_path(
diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py
index 66268f6f..8300e4d8 100644
--- a/src/leap/util/leap_argparse.py
+++ b/src/leap/util/leap_argparse.py
@@ -29,6 +29,8 @@ Launches the LEAP Client""", epilog=epilog)
     parser.add_argument('-d', '--debug', action="store_true",
                         help=("Launches client in debug mode, writing debug"
                               "info to stdout"))
+    parser.add_argument('--danger', action="store_true",
+                        help=("Bypasses the certificate check for bootstrap"))
     parser.add_argument('-l', '--logfile', metavar="LOG FILE", nargs='?',
                         action="store", dest="log_file",
                         #type=argparse.FileType('w'),
-- 
cgit v1.2.3