summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/bitmask_libraries/certs.py45
-rw-r--r--service/pixelated/bitmask_libraries/config.py4
-rw-r--r--service/pixelated/bitmask_libraries/provider.py6
-rw-r--r--service/test/unit/bitmask_libraries/test_abstract_leap.py2
-rw-r--r--service/test/unit/bitmask_libraries/test_certs.py24
-rw-r--r--service/test/unit/bitmask_libraries/test_nicknym.py2
-rw-r--r--service/test/unit/bitmask_libraries/test_provider.py33
7 files changed, 93 insertions, 23 deletions
diff --git a/service/pixelated/bitmask_libraries/certs.py b/service/pixelated/bitmask_libraries/certs.py
index 4ee28a19..bafc809d 100644
--- a/service/pixelated/bitmask_libraries/certs.py
+++ b/service/pixelated/bitmask_libraries/certs.py
@@ -27,7 +27,13 @@ LEAP_CERT = None
def which_bundle(provider):
if LEAP_CERT:
return LEAP_CERT
- return str(LeapCertificate(provider).auto_detect_ca_bundle())
+ return str(LeapCertificate(provider).provider_ca_bundle())
+
+
+def which_bootstrap_bundle(provider):
+ if LEAP_CERT:
+ return LEAP_CERT
+ return str(LeapCertificate(provider).auto_detect_bootstrap_ca_bundle())
class LeapCertificate(object):
@@ -35,18 +41,37 @@ class LeapCertificate(object):
self._config = provider.config
self._server_name = provider.server_name
self._certs_home = self._config.certs_home
+ self._provider = provider
- def auto_detect_ca_bundle(self):
- if self._config.ca_cert_bundle == AUTO_DETECT_CA_BUNDLE:
- local_cert = self._local_server_cert()
+ def auto_detect_bootstrap_ca_bundle(self):
+ if self._config.bootstrap_ca_cert_bundle == AUTO_DETECT_CA_BUNDLE:
+ local_cert = self._local_bootstrap_server_cert()
if local_cert:
return local_cert
else:
return ca_bundle.where()
else:
- return self._config.ca_cert_bundle
+ return self._config.bootstrap_ca_cert_bundle
+
+ def provider_ca_bundle(self):
+ if self._provider.config.ca_cert_bundle:
+ return self._provider.config.ca_cert_bundle
+
+ certs_root = self._provider_certs_root_path()
+ cert_file = os.path.join(certs_root, 'provider.pem')
+
+ if not os.path.isfile(cert_file):
+ self._download_server_cert(cert_file)
+
+ return cert_file
+
+ def _provider_certs_root_path(self):
+ path = os.path.join(self._provider.config.leap_home, 'providers', self._server_name, 'keys', 'client')
+ if not os.path.isdir(path):
+ os.makedirs(path, 0700)
+ return path
- def _local_server_cert(self):
+ def _local_bootstrap_server_cert(self):
cert_file = os.path.join(self._certs_home, '%s.ca.crt' % self._server_name)
if not os.path.isfile(cert_file):
self._download_server_cert(cert_file)
@@ -54,11 +79,7 @@ class LeapCertificate(object):
return cert_file
def _download_server_cert(self, cert_file_name):
- response = requests.get('https://%s/provider.json' % self._server_name)
- provider_data = json.loads(response.content)
- ca_cert_uri = str(provider_data['ca_cert_uri'])
+ cert = self._provider.fetch_valid_certificate()
- response = requests.get(ca_cert_uri)
with open(cert_file_name, 'w') as file:
- file.write(response.content)
- file.close
+ file.write(cert)
diff --git a/service/pixelated/bitmask_libraries/config.py b/service/pixelated/bitmask_libraries/config.py
index db0df762..56f28706 100644
--- a/service/pixelated/bitmask_libraries/config.py
+++ b/service/pixelated/bitmask_libraries/config.py
@@ -42,7 +42,8 @@ class LeapConfig(object):
"""
- def __init__(self, leap_home=DEFAULT_LEAP_HOME, ca_cert_bundle=AUTO_DETECT_CA_BUNDLE, verify_ssl=True,
+ def __init__(self, leap_home=DEFAULT_LEAP_HOME, bootstrap_ca_cert_bundle=AUTO_DETECT_CA_BUNDLE,
+ ca_cert_bundle=AUTO_DETECT_CA_BUNDLE, verify_ssl=True,
fetch_interval_in_s=30,
timeout_in_s=15, start_background_jobs=False, gpg_binary=discover_gpg_binary(), certs_home=None):
"""
@@ -75,6 +76,7 @@ class LeapConfig(object):
"""
self.leap_home = leap_home
self.certs_home = certs_home
+ self.bootstrap_ca_cert_bundle = bootstrap_ca_cert_bundle
self.ca_cert_bundle = ca_cert_bundle
self.verify_ssl = verify_ssl
self.timeout_in_s = timeout_in_s
diff --git a/service/pixelated/bitmask_libraries/provider.py b/service/pixelated/bitmask_libraries/provider.py
index 4fe5f17d..5304e662 100644
--- a/service/pixelated/bitmask_libraries/provider.py
+++ b/service/pixelated/bitmask_libraries/provider.py
@@ -17,7 +17,7 @@ import json
from leap.common.certs import get_digest
import requests
-from .certs import which_bundle
+from .certs import which_bootstrap_bundle, which_bundle
class LeapProvider(object):
@@ -78,7 +78,7 @@ class LeapProvider(object):
session = requests.session()
try:
cert_url = '%s/ca.crt' % self._provider_base_url()
- response = session.get(cert_url, verify=which_bundle(self), timeout=self.config.timeout_in_s)
+ response = session.get(cert_url, verify=which_bootstrap_bundle(self), timeout=self.config.timeout_in_s)
response.raise_for_status()
cert_data = response.content
@@ -101,7 +101,7 @@ class LeapProvider(object):
def fetch_provider_json(self):
url = '%s/provider.json' % self._provider_base_url()
- response = requests.get(url, verify=which_bundle(self), timeout=self.config.timeout_in_s)
+ response = requests.get(url, verify=which_bootstrap_bundle(self), timeout=self.config.timeout_in_s)
response.raise_for_status()
json_data = json.loads(response.content)
diff --git a/service/test/unit/bitmask_libraries/test_abstract_leap.py b/service/test/unit/bitmask_libraries/test_abstract_leap.py
index 2634f330..c11c7ea9 100644
--- a/service/test/unit/bitmask_libraries/test_abstract_leap.py
+++ b/service/test/unit/bitmask_libraries/test_abstract_leap.py
@@ -28,7 +28,7 @@ class AbstractLeapTest(unittest.TestCase):
leap_home = os.path.join(tempfile.mkdtemp(), 'leap')
- config = Mock(leap_home=leap_home, ca_cert_bundle='/some/path/to/ca_cert', gpg_binary='/path/to/gpg')
+ config = Mock(leap_home=leap_home, bootstrap_ca_cert_bundle='/some/path/to/ca_cert', ca_cert_bundle='/some/path/to/provider_ca_cert', gpg_binary='/path/to/gpg')
provider = Mock(config=config, server_name='some-server.test', domain='some-server.test',
api_uri='https://api.some-server.test:4430', api_version='1')
soledad = Mock()
diff --git a/service/test/unit/bitmask_libraries/test_certs.py b/service/test/unit/bitmask_libraries/test_certs.py
index 8caafe7e..3683f9ae 100644
--- a/service/test/unit/bitmask_libraries/test_certs.py
+++ b/service/test/unit/bitmask_libraries/test_certs.py
@@ -1,6 +1,6 @@
import unittest
-from pixelated.bitmask_libraries.certs import which_bundle
+from pixelated.bitmask_libraries.certs import which_bootstrap_bundle, which_bundle
from pixelated.bitmask_libraries.config import AUTO_DETECT_CA_BUNDLE
from mock import MagicMock, patch
@@ -8,12 +8,28 @@ from mock import MagicMock, patch
class CertsTest(unittest.TestCase):
@patch('pixelated.bitmask_libraries.certs.os.path.isfile')
- def test_that_which_bundle_returns_byte_string(self, mock_isfile):
+ @patch('pixelated.bitmask_libraries.certs.os.path.isdir')
+ def test_that_which_bootstrap_bundle_returns_byte_string(self, mock_isdir, mock_isfile):
mock_isfile.return_value = True
- config = MagicMock(ca_cert_bundle=AUTO_DETECT_CA_BUNDLE, certs_home='/some/path')
+ mock_isdir.return_value = True
+ config = MagicMock(bootstrap_ca_cert_bundle=AUTO_DETECT_CA_BUNDLE, certs_home='/some/path')
provider = MagicMock(server_name=u'test.leap.net', config=config)
- bundle = which_bundle(provider)
+ bundle = which_bootstrap_bundle(provider)
self.assertEqual('/some/path/test.leap.net.ca.crt', bundle)
self.assertEqual(str, type(bundle))
+
+ @patch('pixelated.bitmask_libraries.certs.os.path.isfile')
+ @patch('pixelated.bitmask_libraries.certs.os.path.isdir')
+ def test_that_which_bundle_returns_byte_string(self, mock_isdir, mock_isfile):
+ mock_isfile.return_value = True
+ mock_isdir.return_value = True
+
+ config = MagicMock(bootstrap_ca_cert_bundle=AUTO_DETECT_CA_BUNDLE, ca_cert_bundle=None, leap_home='/some/leap/home', certs_home='/some/path')
+ provider = MagicMock(server_name=u'test.leap.net', config=config)
+
+ bundle = which_bundle(provider)
+
+ self.assertEqual('/some/leap/home/providers/test.leap.net/keys/client/provider.pem', bundle)
+ self.assertEqual(str, type(bundle))
diff --git a/service/test/unit/bitmask_libraries/test_nicknym.py b/service/test/unit/bitmask_libraries/test_nicknym.py
index 7dec4b2c..6e589ae9 100644
--- a/service/test/unit/bitmask_libraries/test_nicknym.py
+++ b/service/test/unit/bitmask_libraries/test_nicknym.py
@@ -30,7 +30,7 @@ class NickNymTest(AbstractLeapTest):
# then
init_mock.assert_called_with('test_user@some-server.test', 'https://nicknym.some-server.test:6425/',
- self.soledad, self.token, '/some/path/to/ca_cert',
+ self.soledad, self.token, '/some/path/to/provider_ca_cert',
'https://api.some-server.test:4430', '1', self.uuid,
'/path/to/gpg')
diff --git a/service/test/unit/bitmask_libraries/test_provider.py b/service/test/unit/bitmask_libraries/test_provider.py
index af8aa291..8c0cf97e 100644
--- a/service/test/unit/bitmask_libraries/test_provider.py
+++ b/service/test/unit/bitmask_libraries/test_provider.py
@@ -15,11 +15,14 @@
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
import json
+from mock import patch, MagicMock
from httmock import all_requests, HTTMock, urlmatch
from requests import HTTPError
from pixelated.bitmask_libraries.config import LeapConfig
from pixelated.bitmask_libraries.provider import LeapProvider
from test_abstract_leap import AbstractLeapTest
+from requests import Session
+import requests
@all_requests
@@ -130,9 +133,13 @@ VeJ6
"""
+CA_CERT = '/tmp/ca.crt'
+BOOTSTRAP_CA_CERT = '/tmp/bootstrap-ca.crt'
+
+
class LeapProviderTest(AbstractLeapTest):
def setUp(self):
- self.config = LeapConfig(verify_ssl=False, leap_home='/tmp/foobar', ca_cert_bundle='/tmp/ca.crt')
+ self.config = LeapConfig(verify_ssl=False, leap_home='/tmp/foobar', bootstrap_ca_cert_bundle=BOOTSTRAP_CA_CERT, ca_cert_bundle=CA_CERT)
def test_provider_fetches_provider_json(self):
with HTTMock(provider_json_mock):
@@ -183,3 +190,27 @@ class LeapProviderTest(AbstractLeapTest):
with HTTMock(provider_json_invalid_fingerprint_mock, ca_cert_mock, not_found_mock):
provider = LeapProvider('some-provider.test', self.config)
self.assertRaises(Exception, provider.fetch_valid_certificate)
+
+ def test_that_bootstrap_cert_is_used_to_fetch_certificate(self):
+ session = MagicMock(wraps=requests.session())
+ session_func = MagicMock(return_value=session)
+ get_func = MagicMock(wraps=requests.get)
+
+ with patch('pixelated.bitmask_libraries.provider.requests.session', new=session_func):
+ with patch('pixelated.bitmask_libraries.provider.requests.get', new=get_func):
+ with HTTMock(provider_json_mock, ca_cert_mock, not_found_mock):
+ provider = LeapProvider('some-provider.test', self.config)
+ provider.fetch_valid_certificate()
+
+ get_func.assert_called_once_with('https://some-provider.test/provider.json', verify=BOOTSTRAP_CA_CERT, timeout=15)
+ session.get.assert_called_once_with('https://some-provider.test/ca.crt', verify=BOOTSTRAP_CA_CERT, timeout=15)
+
+ def test_that_provider_cert_is_used_to_fetch_soledad_json(self):
+ get_func = MagicMock(wraps=requests.get)
+
+ with patch('pixelated.bitmask_libraries.provider.requests.get', new=get_func):
+ with HTTMock(provider_json_mock, soledad_json_mock, not_found_mock):
+ provider = LeapProvider('some-provider.test', self.config)
+ provider.fetch_soledad_json()
+
+ get_func.assert_called_with('https://api.some-provider.test:4430/1/config/soledad-service.json', verify=CA_CERT, timeout=15)