From 607df76ebdf5516085835a0a1f7718baf966a6e0 Mon Sep 17 00:00:00 2001
From: Ruben Pollan <meskio@sindominio.net>
Date: Tue, 20 Sep 2016 16:45:53 +0200
Subject: [feat] discover gpg bin path instead of hardcode it

---
 src/leap/bitmask/core/mail_services.py             |  8 ++-
 src/leap/bitmask/keymanager/testing/__init__.py    | 11 +---
 src/leap/bitmask/mail/imap/service/imap-server.tac |  3 +-
 src/leap/bitmask/mail/testing/__init__.py          | 10 +---
 src/leap/bitmask/util.py                           | 58 +++++++++++++++++++++-
 5 files changed, 66 insertions(+), 24 deletions(-)

(limited to 'src/leap/bitmask')

diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py
index ea53ee07..c0c986a4 100644
--- a/src/leap/bitmask/core/mail_services.py
+++ b/src/leap/bitmask/core/mail_services.py
@@ -30,6 +30,7 @@ from collections import namedtuple
 from twisted.application import service
 from twisted.internet import defer
 from twisted.python import log
+from twisted.python.procutils import which
 
 # TODO move to bitmask.common
 from leap.common.service_hooks import HookableService
@@ -43,6 +44,7 @@ from leap.bitmask.mail.imap.service import imap
 from leap.bitmask.mail.incoming.service import IncomingMail
 from leap.bitmask.mail.incoming.service import INCOMING_CHECK_PERIOD
 from leap.bitmask.mail import smtp
+from leap.bitmask.util import get_gpg_bin_path
 from leap.soledad.client.api import Soledad
 
 from leap.bitmask.core.uuid_map import UserMap
@@ -282,15 +284,11 @@ class KeymanagerContainer(Container):
 
         km_args = (userid, nickserver_uri, soledad)
 
-        # TODO use the method in
-        # services.soledadbootstrapper._get_gpg_bin_path.
-        # That should probably live in keymanager package.
-
         km_kwargs = {
             "token": token, "uid": uuid,
             "api_uri": api_uri, "api_version": "1",
             "ca_cert_path": cert_path,
-            "gpgbinary": "/usr/bin/gpg"
+            "gpgbinary": get_gpg_bin_path()
         }
         keymanager = KeyManager(*km_args, **km_kwargs)
         return keymanager
diff --git a/src/leap/bitmask/keymanager/testing/__init__.py b/src/leap/bitmask/keymanager/testing/__init__.py
index 7c918c99..3a78c516 100644
--- a/src/leap/bitmask/keymanager/testing/__init__.py
+++ b/src/leap/bitmask/keymanager/testing/__init__.py
@@ -1,10 +1,10 @@
-import distutils.spawn
 import os.path
 
 from twisted.internet.defer import gatherResults
 from twisted.trial import unittest
 
 from leap.common.testing.basetest import BaseLeapTest
+from leap.bitmask.util import get_gpg_bin_path
 from leap.bitmask.keymanager import KeyManager
 from leap.soledad.client import Soledad
 
@@ -241,7 +241,7 @@ THx7N776fcYHGumbqUMYrxrcZSbNveE6SaK8fphRam1dewM0
 class KeyManagerWithSoledadTestCase(unittest.TestCase, BaseLeapTest):
 
     def setUp(self):
-        self.gpg_binary_path = self._find_gpg()
+        self.gpg_binary_path = get_gpg_bin_path()
 
         self._soledad = Soledad(
             u"leap@leap.se",
@@ -290,13 +290,6 @@ class KeyManagerWithSoledadTestCase(unittest.TestCase, BaseLeapTest):
                           gpgbinary=self.gpg_binary_path,
                           ca_cert_path=ca_cert_path)
 
-    def _find_gpg(self):
-        gpg_path = distutils.spawn.find_executable('gpg')
-        if gpg_path is not None:
-            return os.path.realpath(gpg_path)
-        else:
-            return "/usr/bin/gpg"
-
     def get_public_binary_key(self):
         with open(PATH + '/public_key.bin', 'r') as binary_public_key:
             return binary_public_key.read()
diff --git a/src/leap/bitmask/mail/imap/service/imap-server.tac b/src/leap/bitmask/mail/imap/service/imap-server.tac
index 685db6bc..e695630b 100644
--- a/src/leap/bitmask/mail/imap/service/imap-server.tac
+++ b/src/leap/bitmask/mail/imap/service/imap-server.tac
@@ -36,6 +36,7 @@ import sys
 
 from twisted.application import service, internet
 
+from leap.bitmask.util import get_gpg_bin_path
 from leap.bitmask.keymanager import KeyManager
 from leap.bitmask.mail.imap.service import imap
 from leap.soledad.client import Soledad
@@ -123,7 +124,7 @@ km_kwargs = {
     "api_uri":  "",
     "api_version": "",
     "uid": uuid,
-    "gpgbinary": "/usr/bin/gpg"
+    "gpgbinary": get_gpg_bin_path()
 }
 keymanager = KeyManager(*km_args, **km_kwargs)
 
diff --git a/src/leap/bitmask/mail/testing/__init__.py b/src/leap/bitmask/mail/testing/__init__.py
index b5a2a424..5ebfaf52 100644
--- a/src/leap/bitmask/mail/testing/__init__.py
+++ b/src/leap/bitmask/mail/testing/__init__.py
@@ -25,6 +25,7 @@ from twisted.trial import unittest
 from twisted.internet import defer
 
 from leap.common.testing.basetest import BaseLeapTest
+from leap.bitmask.util import get_gpg_bin_path
 from leap.bitmask.keymanager import KeyManager
 from leap.soledad.client import Soledad
 
@@ -46,7 +47,7 @@ class defaultMockSharedDB(object):
 class KeyManagerWithSoledadTestCase(unittest.TestCase, BaseLeapTest):
 
     def setUp(self):
-        self.gpg_binary_path = self._find_gpg()
+        self.gpg_binary_path = get_gpg_bin_path()
 
         self._soledad = Soledad(
             u"leap@leap.se",
@@ -110,13 +111,6 @@ class KeyManagerWithSoledadTestCase(unittest.TestCase, BaseLeapTest):
                           gpgbinary=self.gpg_binary_path,
                           ca_cert_path=ca_cert_path)
 
-    def _find_gpg(self):
-        gpg_path = distutils.spawn.find_executable('gpg')
-        if gpg_path is not None:
-            return os.path.realpath(gpg_path)
-        else:
-            return "/usr/bin/gpg"
-
     def get_public_binary_key(self):
         with open(PATH + '/fixtures/public_key.bin', 'r') as binary_public_key:
             return binary_public_key.read()
diff --git a/src/leap/bitmask/util.py b/src/leap/bitmask/util.py
index 96dafe06..6da8571b 100644
--- a/src/leap/bitmask/util.py
+++ b/src/leap/bitmask/util.py
@@ -18,11 +18,17 @@
 Handy common utils
 """
 import os
+import platform
 import sys
 
+from twisted.python import log
+
+
+STANDALONE = getattr(sys, 'frozen', False)
+
 
 def here(module=None):
-    if getattr(sys, 'frozen', False):
+    if STANDALONE:
         # we are running in a |PyInstaller| bundle
         return sys._MEIPASS
     else:
@@ -31,3 +37,53 @@ def here(module=None):
             return dirname(module.__file__)
         else:
             return dirname(__file__)
+
+
+def get_gpg_bin_path():
+    """
+    Return the path to gpg binary.
+
+    :returns: the gpg binary path
+    :rtype: str
+    """
+    gpgbin = None
+
+    # During the transition towards gpg2, we can look for /usr/bin/gpg1
+    # binary, in case it was renamed using dpkg-divert or manually.
+    # We could just pick gpg2, but we need to solve #7564 first.
+    try:
+        gpgbin_options = which("gpg1")
+        for opt in gpgbin_options:
+            if not os.path.islink(opt):
+                gpgbin = opt
+                break
+    except IndexError as e:
+        log.msg("Couldn't find the gpg1 binary!: %s" % (e,))
+    if gpgbin is not None:
+        return gpgbin
+
+    if STANDALONE:
+        gpgbin = os.path.join(
+            get_path_prefix(), "..", "apps", "mail", "gpg")
+        if platform.system() == "Windows":
+            gpgbin += ".exe"
+    else:
+        try:
+            gpgbin_options = which("gpg")
+            # gnupg checks that the path to the binary is not a
+            # symlink, so we need to filter those and come up with
+            # just one option.
+            for opt in gpgbin_options:
+                if not os.path.islink(opt):
+                    gpgbin = opt
+                    break
+        except IndexError as e:
+            log.msg("Couldn't find the gpg binary!: %s" % (e,))
+            log.exception(e)
+    if platform.system() == "Darwin":
+        gpgbin = os.path.abspath(
+            os.path.join(here(), "apps", "mail", "gpg"))
+
+    if gpgbin is None:
+        log.msg("Could not find gpg1 binary")
+    return gpgbin
-- 
cgit v1.2.3