summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/backend/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/bitmask/backend/utils.py')
-rw-r--r--src/leap/bitmask/backend/utils.py54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/leap/bitmask/backend/utils.py b/src/leap/bitmask/backend/utils.py
index 18e70743..b2674330 100644
--- a/src/leap/bitmask/backend/utils.py
+++ b/src/leap/bitmask/backend/utils.py
@@ -22,20 +22,63 @@ import os
import shutil
import stat
-import zmq.auth
+import zmq
+try:
+ import zmq.auth
+except ImportError:
+ pass
+
+from leap.bitmask.config import flags
from leap.bitmask.util import get_path_prefix
from leap.common.files import mkdir_p
+from leap.common.check import leap_assert
logger = logging.getLogger(__name__)
KEYS_DIR = os.path.join(get_path_prefix(), 'leap', 'zmq_certificates')
+def _zmq_has_curve():
+ """
+ Return whether the current ZMQ has support for auth and CurveZMQ security.
+
+ :rtype: bool
+
+ Version notes:
+ `zmq.curve_keypair()` is new in version 14.0, new in version libzmq-4.0.
+ Requires libzmq (>= 4.0) to have been linked with libsodium.
+ `zmq.auth` module is new in version 14.1
+ `zmq.has()` is new in version 14.1, new in version libzmq-4.1.
+ """
+ zmq_version = zmq.zmq_version_info()
+ pyzmq_version = zmq.pyzmq_version_info()
+
+ if pyzmq_version >= (14, 1, 0) and zmq_version >= (4, 1):
+ return zmq.has('curve')
+
+ if pyzmq_version < (14, 1, 0):
+ return False
+
+ if zmq_version < (4, 0):
+ # security is new in libzmq 4.0
+ return False
+
+ try:
+ zmq.curve_keypair()
+ except zmq.error.ZMQError:
+ # security requires libzmq to be linked against libsodium
+ return False
+
+ return True
+
+
def generate_zmq_certificates():
"""
Generate client and server CURVE certificate files.
"""
+ leap_assert(flags.ZMQ_HAS_CURVE, "CurveZMQ not supported!")
+
# Create directory for certificates, remove old content if necessary
if os.path.exists(KEYS_DIR):
shutil.rmtree(KEYS_DIR)
@@ -53,6 +96,8 @@ def get_frontend_certificates():
"""
Return the frontend's public and secret certificates.
"""
+ leap_assert(flags.ZMQ_HAS_CURVE, "CurveZMQ not supported!")
+
frontend_secret_file = os.path.join(KEYS_DIR, "frontend.key_secret")
public, secret = zmq.auth.load_certificate(frontend_secret_file)
return public, secret
@@ -62,6 +107,8 @@ def get_backend_certificates(base_dir='.'):
"""
Return the backend's public and secret certificates.
"""
+ leap_assert(flags.ZMQ_HAS_CURVE, "CurveZMQ not supported!")
+
backend_secret_file = os.path.join(KEYS_DIR, "backend.key_secret")
public, secret = zmq.auth.load_certificate(backend_secret_file)
return public, secret
@@ -84,5 +131,8 @@ def generate_zmq_certificates_if_needed():
Generate the needed ZMQ certificates for backend/frontend communication if
needed.
"""
- if not _certificates_exist():
+ if flags.ZMQ_HAS_CURVE and not _certificates_exist():
generate_zmq_certificates()
+
+
+flags.ZMQ_HAS_CURVE = _zmq_has_curve()