diff options
| author | Kali Kaneko <kali@leap.se> | 2014-06-12 16:30:04 -0500 | 
|---|---|---|
| committer | Kali Kaneko <kali@leap.se> | 2014-06-13 11:15:23 -0500 | 
| commit | 0a32a844127f610027ea011182a0612d6dd61c5a (patch) | |
| tree | 4aaae5e37125a2ad5390571b6e284486ce11f66e | |
| parent | dea498f1e09c17b6c86519dd95ea430744ecd30d (diff) | |
do reinstall binaries if their hash is not the expected
Closes: #5759
For this to work, the bundle needs to call::
``python setup.py hash_binaries`` during the bundling process, so that
the right hash gets updated in the bitmask/_binaries.py file.
| -rw-r--r-- | changes/feature_update-bundle-binaries | 1 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/vpnlauncher.py | 64 | 
2 files changed, 58 insertions, 7 deletions
| diff --git a/changes/feature_update-bundle-binaries b/changes/feature_update-bundle-binaries new file mode 100644 index 00000000..f573ee61 --- /dev/null +++ b/changes/feature_update-bundle-binaries @@ -0,0 +1 @@ +- Update the bundled binaries to their path if their sha256 is not correct. Closes:#5759 diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index 58ca0c33..0731bee3 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -18,6 +18,7 @@  Platform independant VPN launcher interface.  """  import getpass +import hashlib  import logging  import os  import stat @@ -77,7 +78,7 @@ def _has_updown_scripts(path, warn=True):  def _has_other_files(path, warn=True):      """ -    Checks the existence of other important files. +    Check the existence of other important files.      :param path: the path to be checked      :type path: str @@ -256,7 +257,7 @@ class VPNLauncher(object):      @classmethod      def get_vpn_env(kls):          """ -        Returns a dictionary with the custom env for the platform. +        Return a dictionary with the custom env for the platform.          This is mainly used for setting LD_LIBRARY_PATH to the correct          path when distributing a standalone client @@ -267,7 +268,7 @@ class VPNLauncher(object):      @classmethod      def missing_updown_scripts(kls):          """ -        Returns what updown scripts are missing. +        Return what updown scripts are missing.          :rtype: list          """ @@ -287,7 +288,7 @@ class VPNLauncher(object):      @classmethod      def missing_other_files(kls):          """ -        Returns what other important files are missing during startup. +        Return what other important files are missing during startup.          Same as missing_updown_scripts but does not check for exec bit.          :rtype: list @@ -297,6 +298,55 @@ class VPNLauncher(object):                      "auncher before calling this method")          other = force_eval(kls.OTHER_FILES)          file_exist = partial(_has_other_files, warn=False) -        zipped = zip(other, map(file_exist, other)) -        missing = filter(lambda (path, exists): exists is False, zipped) -        return [path for path, exists in missing] + +        if flags.STANDALONE: +            try: +                from leap.bitmask import _binaries +            except ImportError: +                raise RuntimeError( +                    "Could not find binary hash info in this bundle!") + +            _, bitmask_root_path, openvpn_bin_path = other + +            check_hash = _has_expected_binary_hash +            openvpn_hash = _binaries.OPENVPN_BIN +            bitmask_root_hash = _binaries.BITMASK_ROOT + +            correct_hash = ( +                True,  # we do not check the polkit file +                check_hash(bitmask_root_path, bitmask_root_hash), +                check_hash(openvpn_bin_path, openvpn_hash)) + +            zipped = zip(other, map(file_exist, other), correct_hash) +            missing = filter( +                lambda (path, exists, hash_ok): ( +                    exists is False or hash_ok is False), +                zipped) +            return [path for path, exists, hash_ok in missing] +        else: +            zipped = zip(other, map(file_exist, other)) +            missing = filter(lambda (path, exists): exists is False, zipped) +            return [path for path, exists in missing] + + +def _has_expected_binary_hash(path, expected_hash): +    """ +    Check if the passed path matches the expected hash. + +    Used from within the bundle, to know if we have to reinstall the shipped +    binaries into the system path. + +    This path will be /usr/local/sbin for linux. + +    :param path: the path to check. +    :type path: str +    :param expected_hash: the sha256 hash that we expect +    :type expected_hash: str +    :rtype: bool +    """ +    try: +        with open(path) as f: +            file_hash = hashlib.sha256(f.read()).hexdigest() +        return expected_hash == file_hash +    except IOError: +        return False | 
