diff options
| -rw-r--r-- | CHANGELOG.rst | 24 | ||||
| -rw-r--r-- | README.rst | 3 | ||||
| -rwxr-xr-x | pkg/tools/with_venvwrapper.sh | 16 | ||||
| -rw-r--r-- | relnotes.txt | 8 | ||||
| -rwxr-xr-x | run_tests.sh | 26 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/eip_preferenceswindow.py | 35 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/eip_status.py | 18 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 80 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/preferenceswindow.py | 9 | ||||
| -rw-r--r-- | src/leap/bitmask/provider/providerbootstrapper.py | 32 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/eipconfig.py | 14 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/linuxvpnlauncher.py | 17 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/vpnlauncher.py | 3 | ||||
| -rw-r--r-- | src/leap/bitmask/services/soledad/soledadbootstrapper.py | 2 | ||||
| -rw-r--r-- | versioneer.py | 10 | 
15 files changed, 205 insertions, 92 deletions
| diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4fc4246e..866d6f28 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,30 @@  History  ------- +0.3.8 Dec 6 -- the "Three week child" release: ++++++++++++++++++++++++++++++++++++++++++++++++ +- Make the preferences window selects the current selected provider in +  the login widget even if the user is not logged in. Closes #4490. +- Support non-ascii characters in a provider name. Closes #4952. +- Disable Turn On EIP in tray if the service is disabled. Closes #4630. +- Do not show the generic message "EIP has stopped" since it's +  redundant. Fixes #4632. +- Avoid attempt to install policykit file in debian package. Closes: +  #4404 +- Properly close Soledad at quit time. Fixes #4504. +- Fix soledad bootstrap subtasks order. Closes #4537. +- Add --nobind as a VPN parameter to prevent binding on local +  addresses. Fixes #4543. +- Disable Turn On EIP until we have an usable provider. Closes #4523. +- Load provider if the wizard was rejected and the setup was +  completed. +- Disable Turn On EIP if the "Encrypted Internet" service is disabled. +  Closes #4555. +- If EIP service is disabled display 'Disabled' instead of 'You need +  to login to use Encrypted Internet'. +- Disable eip-config until we have configured the provider. Closes +  #4422. +  0.3.7 Nov 15 -- the "The Big Lebowsky" release:  +++++++++++++++++++++++++++++++++++++++++++++++  - Use custom SysTray in order to display per-service tooltip easily. @@ -5,6 +5,9 @@ Bitmask  .. image:: https://pypip.in/v/leap.bitmask/badge.png          :target: https://crate.io/packages/leap.bitmask +.. image:: https://pypip.in/d/leap.bitmask/badge.png +.. image:: http://lemur.leap.se:8010/png?builder=bitmask-linux-quick +  **Bitmask** is the multiplatform desktop client for the services offered by  `the LEAP Platform`_. diff --git a/pkg/tools/with_venvwrapper.sh b/pkg/tools/with_venvwrapper.sh new file mode 100755 index 00000000..693c0ac9 --- /dev/null +++ b/pkg/tools/with_venvwrapper.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +#Wraps a command in a virtualenwrapper passed as first argument. +#Example: +#with_virtualenvwrapper.sh leap-bitmask ./run_tests.sh + +wd=`pwd` +alias pyver='python -c "import $1;print $1.__path__[0]; print $1.__version__;"' + +source `which virtualenvwrapper.sh` +echo "Activating virtualenv " $1 +echo "------------------------------------" +workon $1 +cd $wd +echo "running version: " `pyver leap.bitmask` +$2 $3 $4 $5 diff --git a/relnotes.txt b/relnotes.txt index 99898aa2..98af7a30 100644 --- a/relnotes.txt +++ b/relnotes.txt @@ -1,8 +1,8 @@  ANNOUNCING Bitmask, the internet encryption toolkit, release 0.3.7  The LEAP  team is  pleased to announce  the immediate  availability of -version 0.3.7  of Bitmask,  the Internet Encryption  Toolkit, codename -"The Big Lebowsky". +version 0.3.8  of Bitmask,  the Internet Encryption  Toolkit, codename +"Three week child".  https://downloads.leap.se/client/ @@ -34,7 +34,7 @@ NOT trust your life to it (yet!).  WHAT CAN THIS VERSION OF BITMASK DO FOR ME? -Bitmask  0.3.7 improves  greatly  its mail  support  and stability  in +Bitmask  0.3.8 improves  greatly  its mail  support  and stability  in  general, among other various bug fixes. You can refer to the CHANGELOG  for the meat. @@ -93,6 +93,6 @@ beyond any border.  The LEAP team, -Nov 15, 2013 +Dec 6, 2013  Somewhere in the middle of the intertubes.  EOF diff --git a/run_tests.sh b/run_tests.sh index 9f9262ba..13050872 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,9 +1,9 @@  #!/bin/bash -set -eu +set -e  function usage { -  echo "Usage: $0 [OPTION]..." +  echo "Usage: $0 [OPTION]...[@virtualenv-name]"    echo "Run leap-client test suite"    echo ""    echo "  -V, --virtual-env        Always use virtualenv.  Install automatically if not present" @@ -22,6 +22,8 @@ function usage {    echo "Note: with no options specified, the script will try to run the tests in a virtual environment,"    echo "      If no virtualenv is found, the script will ask if you would like to create one.  If you "    echo "      prefer to run tests NOT in a virtual environment, simply pass the -N option." +  echo "      If you pass @virtualenv-name, the given virtualenv will be used as long as " +  echo "      virtualenvwrapper.sh can be found in the PATH."    exit  } @@ -37,6 +39,7 @@ function process_option {      -c|--coverage) coverage=1;;      -A|--all) alltests=1;;      -i|--progressive) progressive=1;; +    @*) venvwrapper=1; source_venv=`echo $1 | cut -c 2-`;;      -*) noseopts="$noseopts $1";;      *) noseargs="$noseargs $1"    esac @@ -44,6 +47,7 @@ function process_option {  venv=.venv  with_venv=pkg/tools/with_venv.sh +with_venvwrapper=pkg/tools/with_venvwrapper.sh  always_venv=0  never_venv=0  force=0 @@ -51,6 +55,8 @@ no_site_packages=0  installvenvopts=  noseargs=  noseopts= +venvwrapper=0 +source_venv=  wrapper=""  just_pep8=0  no_pep8=0 @@ -82,9 +88,19 @@ if [ $progressive -eq 1 ]; then      noseopts="$noseopts --with-progressive"  fi -  function run_tests {    echo "running tests..." + +  if [ $venvwrapper -eq 1 ]; then +	  VIRTUAL_ENV=$WORKON_HOME/$source_venv +	  wrapper="$with_venvwrapper $source_venv" + +  fi + +  #NOSETESTS="nosetests leap --exclude=soledad* $noseopts $noseargs" +  NOSETESTS="$VIRTUAL_ENV/bin/nosetests . $noseopts $noseargs" +  #--with-coverage --cover-package=leap" +    # Just run the test suites in current environment    echo "NOSETESTS=$NOSETESTS"    ${wrapper} $NOSETESTS @@ -98,6 +114,7 @@ function run_pep8 {    srcfiles="src/leap"    # Just run PEP8 in current environment    pep8_opts="--ignore=E202,W602 --exclude=*_rc.py,ui_*,_version.py --repeat" +    ${wrapper} pep8 ${pep8_opts} ${srcfiles}  } @@ -105,9 +122,6 @@ function run_pep8 {  # in the current debhelper build process,  # so I exclude the topmost tests -#NOSETESTS="nosetests leap --exclude=soledad* $noseopts $noseargs" -NOSETESTS="$VIRTUAL_ENV/bin/nosetests . $noseopts $noseargs" -#--with-coverage --cover-package=leap"  if [ $never_venv -eq 0 ]  then diff --git a/src/leap/bitmask/gui/eip_preferenceswindow.py b/src/leap/bitmask/gui/eip_preferenceswindow.py index e0c5d51f..504d1cf1 100644 --- a/src/leap/bitmask/gui/eip_preferenceswindow.py +++ b/src/leap/bitmask/gui/eip_preferenceswindow.py @@ -28,6 +28,7 @@ from leap.bitmask.config.leapsettings import LeapSettings  from leap.bitmask.config.providerconfig import ProviderConfig  from leap.bitmask.gui.ui_eippreferences import Ui_EIPPreferences  from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector +from leap.bitmask.services.eip.eipconfig import get_eipconfig_path  logger = logging.getLogger(__name__) @@ -52,7 +53,7 @@ class EIPPreferencesWindow(QtGui.QDialog):          self.ui.lblProvidersGatewayStatus.setVisible(False)          # Connections -        self.ui.cbProvidersGateway.currentIndexChanged[unicode].connect( +        self.ui.cbProvidersGateway.currentIndexChanged[int].connect(              self._populate_gateways)          self.ui.cbGateways.currentIndexChanged[unicode].connect( @@ -93,7 +94,11 @@ class EIPPreferencesWindow(QtGui.QDialog):              return          for provider in providers: -            self.ui.cbProvidersGateway.addItem(provider) +            label = provider +            eip_config_path = get_eipconfig_path(provider, relative=False) +            if not os.path.isfile(eip_config_path): +                label = provider + self.tr(" (uninitialized)") +            self.ui.cbProvidersGateway.addItem(label, userData=provider)      def _save_selected_gateway(self, provider):          """ @@ -120,7 +125,7 @@ class EIPPreferencesWindow(QtGui.QDialog):              "Gateway settings for provider '{0}' saved.").format(provider)          self._set_providers_gateway_status(msg, success=True) -    def _populate_gateways(self, domain): +    def _populate_gateways(self, domain_idx):          """          SLOT          TRIGGERS: @@ -129,15 +134,29 @@ class EIPPreferencesWindow(QtGui.QDialog):          Loads the gateways that the provider provides into the UI for          the user to select. -        :param domain: the domain of the provider to load gateways from. -        :type domain: str +        :param domain: the domain index of the provider to load gateways from. +        :type domain: int          """          # We hide the maybe-visible status label after a change          self.ui.lblProvidersGatewayStatus.setVisible(False) -        if not domain: +        if domain_idx == -1:              return +        domain = self.ui.cbProvidersGateway.itemData(domain_idx) + +        if not os.path.isfile(get_eipconfig_path(domain, relative=False)): +            self._set_providers_gateway_status( +                self.tr("This is an uninitialized provider, " +                        "please log in first."), +                error=True) +            self.ui.pbSaveGateway.setEnabled(False) +            self.ui.cbGateways.setEnabled(False) +            return +        else: +            self.ui.pbSaveGateway.setEnabled(True) +            self.ui.cbGateways.setEnabled(True) +          try:              # disconnect previously connected save method              self.ui.pbSaveGateway.clicked.disconnect() @@ -151,11 +170,9 @@ class EIPPreferencesWindow(QtGui.QDialog):          eip_config = EIPConfig()          provider_config = ProviderConfig.get_provider_config(domain) -        eip_config_path = os.path.join("leap", "providers", -                                       domain, "eip-service.json")          api_version = provider_config.get_api_version()          eip_config.set_api_version(api_version) -        eip_loaded = eip_config.load(eip_config_path) +        eip_loaded = eip_config.load(get_eipconfig_path(domain))          if not eip_loaded or provider_config is None:              self._set_providers_gateway_status( diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py index 1899d6a4..4b4d360f 100644 --- a/src/leap/bitmask/gui/eip_status.py +++ b/src/leap/bitmask/gui/eip_status.py @@ -77,6 +77,10 @@ class EIPStatusWidget(QtGui.QWidget):          self._provider = "" +        # Action for the systray +        self._eip_disabled_action = QtGui.QAction( +            "{0} is {1}".format(self._service_name, self.tr("disabled")), self) +      def _make_status_clickable(self):          """          Makes upload and download figures clickable. @@ -252,6 +256,15 @@ class EIPStatusWidget(QtGui.QWidget):          self.eip_button.hide()          msg = self.tr("You must login to use {0}".format(self._service_name))          self.eip_label.setText(msg) +        self._eip_status_menu.setTitle("{0} is {1}".format( +            self._service_name, self.tr("disabled"))) + +        # Replace EIP tray menu with an action that displays a "disabled" text +        menu = self._systray.contextMenu() +        menu.insertAction( +            self._eip_status_menu.menuAction(), +            self._eip_disabled_action) +        self._eip_status_menu.menuAction().setVisible(False)      @QtCore.Slot()      def enable_eip_start(self): @@ -262,6 +275,11 @@ class EIPStatusWidget(QtGui.QWidget):          logger.debug('Showing EIP start button')          self.eip_button.show() +        # Restore the eip action menu +        menu = self._systray.contextMenu() +        menu.removeAction(self._eip_disabled_action) +        self._eip_status_menu.menuAction().setVisible(True) +      # XXX disable (later) --------------------------      def set_eip_status(self, status, error=False):          """ diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index b0f25af1..929919ac 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -22,7 +22,7 @@ import os  from PySide import QtCore, QtGui  from twisted.internet import threads -from zope.proxy import ProxyBase, setProxiedObject, sameProxiedObjects +from zope.proxy import ProxyBase, setProxiedObject  from leap.bitmask import __version__ as VERSION  from leap.bitmask.config.leapsettings import LeapSettings @@ -44,6 +44,8 @@ from leap.bitmask.platform_init import IS_WIN, IS_MAC  from leap.bitmask.platform_init.initializers import init_platform  from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper +from leap.bitmask.services import get_service_display_name, EIP_SERVICE +  from leap.bitmask.services.mail import conductor as mail_conductor  from leap.bitmask.services import EIP_SERVICE, MX_SERVICE @@ -339,6 +341,8 @@ class MainWindow(QtGui.QMainWindow):          self.start_eip_machine()          self._mail_conductor.start_mail_machine() +        self._eip_name = get_service_display_name(EIP_SERVICE) +          if self._first_run():              self._wizard_firstrun = True              self._wizard = Wizard(bypass_checks=bypass_checks) @@ -358,15 +362,19 @@ class MainWindow(QtGui.QMainWindow):          Called if the wizard has been cancelled or closed before          finishing. +        This is executed for the first run wizard only. Any other execution of +        the wizard won't reach this point.          """ -        if self._wizard_firstrun: -            providers = self._settings.get_configured_providers() -            has_provider_on_disk = len(providers) != 0 -            if not has_provider_on_disk: -                # if we don't have any provider configured (included a pinned -                # one) we can't use the application, so quit. -                self.quit() +        providers = self._settings.get_configured_providers() +        has_provider_on_disk = len(providers) != 0 +        if not has_provider_on_disk: +            # if we don't have any provider configured (included a pinned +            # one) we can't use the application, so quit. +            self.quit()          else: +            # This happens if the user finishes the provider +            # setup but does not register +            self._wizard = None              self._finish_init()      def _launch_wizard(self): @@ -463,9 +471,9 @@ class MainWindow(QtGui.QMainWindow):          Displays the preferences window.          """ -        preferences_window = PreferencesWindow(self, self._srp_auth, -                                               self._provider_config, -                                               self._soledad) +        preferences_window = PreferencesWindow( +            self, self._srp_auth, self._provider_config, self._soledad, +            self._login_widget.get_selected_provider())          self.soledad_ready.connect(preferences_window.set_soledad_ready)          preferences_window.show() @@ -538,8 +546,7 @@ class MainWindow(QtGui.QMainWindow):          TRIGGERS:            self._wizard.accepted -        Also called at the end of the constructor if not first run, -        and after _rejected_wizard if not first run. +        Also called at the end of the constructor if not first run.          Implements the behavior after either constructing the          mainwindow object, loading the saved user/password, or after @@ -574,6 +581,9 @@ class MainWindow(QtGui.QMainWindow):              if possible_password is not None:                  self._login_widget.set_password(possible_password)                  self._login() +            else: +                self.eip_needs_login.emit() +              self._wizard = None          else:              self._try_autostart_eip() @@ -637,7 +647,8 @@ class MainWindow(QtGui.QMainWindow):          systrayMenu.addAction(self._action_visible)          systrayMenu.addSeparator() -        eip_menu = systrayMenu.addMenu(self.tr("Encrypted Internet: OFF")) +        eip_status_label = "{0}: {1}".format(self._eip_name, self.tr("OFF")) +        eip_menu = systrayMenu.addMenu(eip_status_label)          eip_menu.addAction(self._action_eip_startstop)          self._eip_status.set_eip_status_menu(eip_menu)          systrayMenu.addSeparator() @@ -1224,10 +1235,9 @@ class MainWindow(QtGui.QMainWindow):              provider_config, self._eip_config, provider)          if not loaded: -            self._eip_status.set_eip_status( -                self.tr("Could not load Encrypted Internet " -                        "Configuration."), -                error=True) +            eip_status_label = self.tr("Could not load {0} configuration.") +            eip_status_label = eip_status_label.format(self._eip_name) +            self._eip_status.set_eip_status(eip_status_label, error=True)              # signal connection aborted to state machine              qtsigs = self._eip_connection.qtsigs              qtsigs.connection_aborted_signal.emit() @@ -1264,9 +1274,9 @@ class MainWindow(QtGui.QMainWindow):              self._set_eipstatus_off()          except EIPNoTunKextLoaded:              self._eip_status.set_eip_status( -                self.tr("Encrypted Internet cannot be started because " +                self.tr("{0} cannot be started because "                          "the tuntap extension is not installed properly " -                        "in your system.")) +                        "in your system.").format(self._eip_name))              self._set_eipstatus_off()          except EIPNoPkexecAvailable:              self._eip_status.set_eip_status( @@ -1363,8 +1373,7 @@ class MainWindow(QtGui.QMainWindow):          Sets eip status to off          """          # XXX this should be handled by the state machine. -        self._eip_status.set_eip_status(self.tr("EIP has stopped"), -                                        error=error) +        self._eip_status.set_eip_status("", error=error)          self._eip_status.set_eip_status_icon("error")      def _eip_finished(self, exitCode): @@ -1402,17 +1411,18 @@ class MainWindow(QtGui.QMainWindow):          # XXX check if these exitCodes are pkexec/cocoasudo specific          if exitCode in (126, 127): -            self._eip_status.set_eip_status( -                self.tr("Encrypted Internet could not be launched " -                        "because you did not authenticate properly."), -                error=True) +            eip_status_label = self.tr( +                "{0} could not be launched " +                "because you did not authenticate properly.") +            eip_status_label = eip_status_label.format(self._eip_name) +            self._eip_status.set_eip_status(eip_status_label, error=True)              self._vpn.killit()              signal = qtsigs.connection_aborted_signal          elif exitCode != 0 or not self.user_stopped_eip: -            self._eip_status.set_eip_status( -                self.tr("Encrypted Internet finished in an " -                        "unexpected manner!"), error=True) +            eip_status_label = self.tr("{0} finished in an unexpected manner!") +            eip_status_label = eip_status_label.format(self._eip_name) +            self._eip_status.set_eip_status(eip_status_label, error=True)              signal = qtsigs.connection_died_signal          if exitCode == 0 and IS_MAC: @@ -1449,6 +1459,7 @@ class MainWindow(QtGui.QMainWindow):                      self.tr("Not supported"),                      error=True)              else: +                self._eip_status.disable_eip_start()                  self._eip_status.set_eip_status(self.tr("Disabled"))      def _finish_eip_bootstrap(self, data): @@ -1480,10 +1491,9 @@ class MainWindow(QtGui.QMainWindow):              # DO START EIP Connection!              self._eip_connection.qtsigs.do_connect_signal.emit()          else: -            self._eip_status.set_eip_status( -                self.tr("Could not load Encrypted Internet " -                        "Configuration."), -                error=True) +            eip_status_label = self.tr("Could not load {0} configuration.") +            eip_status_label = eip_status_label.format(self._eip_name) +            self._eip_status.set_eip_status(eip_status_label, error=True)      def _eip_intermediate_stage(self, data):          # TODO missing param @@ -1645,9 +1655,9 @@ class MainWindow(QtGui.QMainWindow):                  # XXX this can timeout after loong time: See #3368                  self._srp_auth.logout() -        if self._soledad: +        if self._soledad_bootstrapper.soledad is not None:              logger.debug("Closing soledad...") -            self._soledad.close() +            self._soledad_bootstrapper.soledad.close()          else:              logger.error("No instance of soledad was found.") diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 8e9ef95a..b4bddef2 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -42,7 +42,7 @@ class PreferencesWindow(QtGui.QDialog):      """      Window that displays the preferences.      """ -    def __init__(self, parent, srp_auth, provider_config, soledad): +    def __init__(self, parent, srp_auth, provider_config, soledad, domain):          """          :param parent: parent object of the PreferencesWindow.          :parent type: QWidget @@ -52,6 +52,8 @@ class PreferencesWindow(QtGui.QDialog):          :type provider_config: ProviderConfig          :param soledad: Soledad instance          :type soledad: Soledad +        :param domain: the selected domain in the login widget +        :type domain: unicode          """          QtGui.QDialog.__init__(self, parent)          self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic") @@ -83,9 +85,6 @@ class PreferencesWindow(QtGui.QDialog):          # check if the user is logged in          if srp_auth is not None and srp_auth.get_token() is not None:              # check if provider has 'mx' ... -            domain = provider_config.get_domain() -            self._select_provider_by_name(domain) -              if provider_config.provides_mx():                  enabled_services = self._settings.get_enabled_services(domain)                  mx_name = get_service_display_name(MX_SERVICE) @@ -111,6 +110,8 @@ class PreferencesWindow(QtGui.QDialog):                  "In order to change your password you need to be logged in.")              self._set_password_change_status(msg) +        self._select_provider_by_name(domain) +          self.ui.gbPasswordChange.setEnabled(pw_enabled)      def set_soledad_ready(self): diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index 2adf8aa8..f5a2003f 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -105,13 +105,13 @@ class ProviderBootstrapper(AbstractBootstrapper):          Checks that the name resolution for the provider name works          """          leap_assert(self._domain, "Cannot check DNS without a domain") -        logger.debug("Checking name resolution for %s" % (self._domain)) +        logger.debug("Checking name resolution for %r" % (self._domain))          # We don't skip this check, since it's basic for the whole          # system to work          # err --- but we can do it after a failure, to diagnose what went          # wrong. Right now we're just adding connection overhead. -- kali -        socket.gethostbyname(self._domain) +        socket.gethostbyname(self._domain.encode('idna'))      def _check_https(self, *args):          """ @@ -119,7 +119,7 @@ class ProviderBootstrapper(AbstractBootstrapper):          checks out          """          leap_assert(self._domain, "Cannot check HTTPS without a domain") -        logger.debug("Checking https for %s" % (self._domain)) +        logger.debug("Checking https for %r" % (self._domain))          # We don't skip this check, since it's basic for the whole          # system to work. @@ -131,8 +131,8 @@ class ProviderBootstrapper(AbstractBootstrapper):              verify = self.verify.encode(sys.getfilesystemencoding())          try: -            res = self._session.get("https://%s" % (self._domain,), -                                    verify=verify, +            uri = "https://{0}".format(self._domain.encode('idna')) +            res = self._session.get(uri, verify=verify,                                      timeout=REQUEST_TIMEOUT)              res.raise_for_status()          except requests.exceptions.SSLError as exc: @@ -154,17 +154,17 @@ class ProviderBootstrapper(AbstractBootstrapper):          """          leap_assert(self._domain,                      "Cannot download provider info without a domain") -        logger.debug("Downloading provider info for %s" % (self._domain)) +        logger.debug("Downloading provider info for %r" % (self._domain))          # --------------------------------------------------------------          # TODO factor out with the download routines in services.          # Watch out! We're handling the verify paramenter differently here.          headers = {} +        domain = self._domain.encode(sys.getfilesystemencoding())          provider_json = os.path.join(util.get_path_prefix(), -                                     "leap", -                                     "providers", -                                     self._domain, "provider.json") +                                     "leap", "providers", domain, +                                     "provider.json")          mtime = get_mtime(provider_json)          if self._download_if_needed and mtime: @@ -190,7 +190,7 @@ class ProviderBootstrapper(AbstractBootstrapper):          logger.debug("Requesting for provider.json... "                       "uri: {0}, verify: {1}, headers: {2}".format(                           uri, verify, headers)) -        res = self._session.get(uri, verify=verify, +        res = self._session.get(uri.encode('idna'), verify=verify,                                  headers=headers, timeout=REQUEST_TIMEOUT)          res.raise_for_status()          logger.debug("Request status code: {0}".format(res.status_code)) @@ -206,10 +206,8 @@ class ProviderBootstrapper(AbstractBootstrapper):              provider_config = ProviderConfig()              provider_config.load(data=provider_definition, mtime=mtime) -            provider_config.save(["leap", -                                  "providers", -                                  self._domain, -                                  "provider.json"]) +            provider_config.save(["leap", "providers", +                                  domain, "provider.json"])              api_version = provider_config.get_api_version()              if SupportedAPIs.supports(api_version): @@ -228,7 +226,7 @@ class ProviderBootstrapper(AbstractBootstrapper):          Populates the check queue.          :param domain: domain to check -        :type domain: str +        :type domain: unicode          :param download_if_needed: if True, makes the checks do not                                     overwrite already downloaded data @@ -271,7 +269,7 @@ class ProviderBootstrapper(AbstractBootstrapper):          leap_assert(self._provider_config, "Cannot download the ca cert "                      "without a provider config!") -        logger.debug("Downloading ca cert for %s at %s" % +        logger.debug("Downloading ca cert for %r at %r" %                       (self._domain, self._provider_config.get_ca_cert_uri()))          if not self._should_proceed_cert(): @@ -302,7 +300,7 @@ class ProviderBootstrapper(AbstractBootstrapper):          leap_assert(self._provider_config, "Cannot check the ca cert "                      "without a provider config!") -        logger.debug("Checking ca fingerprint for %s and cert %s" % +        logger.debug("Checking ca fingerprint for %r and cert %r" %                       (self._domain,                        self._provider_config.get_ca_cert_path())) diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 16ed4cc0..09a3d257 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -33,17 +33,25 @@ from leap.common.check import leap_assert, leap_assert_type  logger = logging.getLogger(__name__) -def get_eipconfig_path(domain): +def get_eipconfig_path(domain, relative=True):      """ -    Returns relative path for EIP config. +    Returns relative or absolute path for EIP config.      :param domain: the domain to which this eipconfig belongs to.      :type domain: str +    :param relative: defines whether the path should be relative or absolute. +    :type relative: bool      :returns: the path      :rtype: str      """      leap_assert(domain is not None, "get_eipconfig_path: We need a domain") -    return os.path.join("leap", "providers", domain, "eip-service.json") + +    path = os.path.join("leap", "providers", domain, "eip-service.json") + +    if not relative: +        path = os.path.join(get_path_prefix(), path) + +    return path  def load_eipconfig_if_needed(provider_config, eip_config, domain): diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index d02f6f96..d24e7ae7 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -77,7 +77,7 @@ def _try_to_launch_agent():      Tries to launch a polkit daemon.      """      env = None -    if flags.STANDALONE is True: +    if flags.STANDALONE:          env = {"PYTHONPATH": os.path.abspath('../../../../lib/')}      try:          # We need to quote the command because subprocess call @@ -148,18 +148,21 @@ class LinuxVPNLauncher(VPNLauncher):      def missing_other_files(kls):          """          'Extend' the VPNLauncher's missing_other_files to check if the polkit -        files is outdated. If the polkit file that is in OTHER_FILES exists but -        is not up to date, it is added to the missing list. +        files is outdated, in the case of an standalone bundle. +        If the polkit file that is in OTHER_FILES exists but is not up to date, +        it is added to the missing list.          :returns: a list of missing files          :rtype: list of str          """          # we use `super` in order to send the class to use          missing = super(LinuxVPNLauncher, kls).missing_other_files() -        polkit_file = LinuxPolicyChecker.get_polkit_path() -        if polkit_file not in missing: -            if privilege_policies.is_policy_outdated(kls.OPENVPN_BIN_PATH): -                missing.append(polkit_file) + +        if flags.STANDALONE: +            polkit_file = LinuxPolicyChecker.get_polkit_path() +            if polkit_file not in missing: +                if privilege_policies.is_policy_outdated(kls.OPENVPN_BIN_PATH): +                    missing.append(polkit_file)          return missing diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index 07497814..99cae7f9 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -147,7 +147,8 @@ class VPNLauncher(object):          args = []          args += [ -            '--setenv', "LEAPOPENVPN", "1" +            '--setenv', "LEAPOPENVPN", "1", +            '--nobind'          ]          if openvpn_verb is not None: diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index e8c7e9ce..d078ae96 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -196,7 +196,7 @@ class SoledadBootstrapper(AbstractBootstrapper):          leap_assert(not sameProxiedObjects(self._soledad, None),                      "Null soledad, error while initializing") -        self.deferred = deferToThread(self._do_soledad_sync) +        self._do_soledad_sync()      def _do_soledad_sync(self):          """ diff --git a/versioneer.py b/versioneer.py index 34e48073..885ebcfd 100644 --- a/versioneer.py +++ b/versioneer.py @@ -230,7 +230,7 @@ def versions_from_vcs(tag_prefix, versionfile_source, verbose=False):      GIT = "git"      if sys.platform == "win32": -        GIT = "git.cmd" +        GIT = "git.exe"      stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"],                           cwd=root)      if stdout is None: @@ -420,7 +420,7 @@ def versions_from_vcs(tag_prefix, versionfile_source, verbose=False):      GIT = "git"      if sys.platform == "win32": -        GIT = "git.cmd" +        GIT = "git.exe"      stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"],                           cwd=root)      if stdout is None: @@ -476,7 +476,7 @@ import sys  def do_vcs_install(versionfile_source, ipy):      GIT = "git"      if sys.platform == "win32": -        GIT = "git.cmd" +        GIT = "git.exe"      run_command([GIT, "add", "versioneer.py"])      run_command([GIT, "add", versionfile_source])      run_command([GIT, "add", ipy]) @@ -489,13 +489,13 @@ def do_vcs_install(versionfile_source, ipy):                      present = True          f.close()      except EnvironmentError: -        pass     +        pass      if not present:          f = open(".gitattributes", "a+")          f.write("%s export-subst\n" % versionfile_source)          f.close()          run_command([GIT, "add", ".gitattributes"]) -     +  SHORT_VERSION_PY = """  # This file was generated by 'versioneer.py' (0.7+) from | 
