summaryrefslogtreecommitdiff
path: root/service/pixelated/bitmask_libraries
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2017-07-25 11:40:11 -0400
committerKali Kaneko <kali@leap.se>2017-07-25 11:40:29 -0400
commit91e4481c450eb7eb928debc1cb7fa59bdb63dd7b (patch)
tree8fd7e6e77b6df669c33d96b7edad6db3cbe14dfe /service/pixelated/bitmask_libraries
parente4f755309d4cf5cfb6b0bcc62ed73d6070956ab5 (diff)
[pkg] packaging and path changes
- move all the pixelated python package under src/ - move the pixelated_www package under the leap namespace - allow to set globally the static folder - add hours and minutes to the timestamp in package version, to allow for several releases a day.
Diffstat (limited to 'service/pixelated/bitmask_libraries')
-rw-r--r--service/pixelated/bitmask_libraries/__init__.py0
-rw-r--r--service/pixelated/bitmask_libraries/certs.py41
-rw-r--r--service/pixelated/bitmask_libraries/keymanager.py111
-rw-r--r--service/pixelated/bitmask_libraries/provider.py213
-rw-r--r--service/pixelated/bitmask_libraries/smtp.py24
5 files changed, 0 insertions, 389 deletions
diff --git a/service/pixelated/bitmask_libraries/__init__.py b/service/pixelated/bitmask_libraries/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/service/pixelated/bitmask_libraries/__init__.py
+++ /dev/null
diff --git a/service/pixelated/bitmask_libraries/certs.py b/service/pixelated/bitmask_libraries/certs.py
deleted file mode 100644
index 9a76a01d..00000000
--- a/service/pixelated/bitmask_libraries/certs.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright (c) 2014 ThoughtWorks, Inc.
-#
-# Pixelated is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Pixelated is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-import os
-
-from pixelated.config import leap_config
-
-
-class LeapCertificate(object):
-
- LEAP_CERT = None
- LEAP_FINGERPRINT = None
-
- def __init__(self, provider):
- self._server_name = provider.server_name
- self._provider = provider
-
- @staticmethod
- def set_cert_and_fingerprint(cert_file=None, cert_fingerprint=None):
- if cert_fingerprint is None:
- LeapCertificate.LEAP_CERT = str(cert_file) if cert_file else True
- LeapCertificate.LEAP_FINGERPRINT = None
- else:
- LeapCertificate.LEAP_FINGERPRINT = cert_fingerprint
- LeapCertificate.LEAP_CERT = False
-
- @property
- def provider_web_cert(self):
- return self.LEAP_CERT
diff --git a/service/pixelated/bitmask_libraries/keymanager.py b/service/pixelated/bitmask_libraries/keymanager.py
deleted file mode 100644
index 9a1b730e..00000000
--- a/service/pixelated/bitmask_libraries/keymanager.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# Copyright (c) 2014 ThoughtWorks, Inc.
-#
-# Pixelated is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Pixelated is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-
-from twisted.internet import defer
-from twisted.logger import Logger
-
-from leap.bitmask.keymanager import KeyManager, KeyNotFound
-
-from pixelated.config import leap_config
-
-logger = Logger()
-
-
-class UploadKeyError(Exception):
- pass
-
-
-TWO_MONTHS = 60
-DEFAULT_EXTENSION_THRESHOLD = TWO_MONTHS
-
-
-class Keymanager(object):
-
- def __init__(self, provider, soledad, email_address, token, uuid):
- nicknym_url = provider._discover_nicknym_server()
- self._email = email_address
- self.keymanager = KeyManager(self._email, nicknym_url,
- soledad,
- token=token, ca_cert_path=provider.provider_api_cert, api_uri=provider.api_uri,
- api_version=provider.api_version,
- uid=uuid, gpgbinary=leap_config.gpg_binary,
- combined_ca_bundle=provider.combined_cerfificates_path)
-
- @defer.inlineCallbacks
- def generate_openpgp_key(self):
- current_key = yield self._key_exists(self._email)
- if not current_key:
- current_key = yield self._generate_key_and_send_to_leap()
- elif current_key.needs_renewal(DEFAULT_EXTENSION_THRESHOLD):
- current_key = yield self._regenerate_key_and_send_to_leap()
-
- self._synchronize_remote_key(current_key)
- logger.debug("Current key for {}: {}".format(self._email, current_key.fingerprint))
-
- @defer.inlineCallbacks
- def _synchronize_remote_key(self, current_key):
- if not self._is_key_synchronized_with_server(current_key):
- try:
- yield self.keymanager.send_key()
- except Exception as e:
- raise UploadKeyError(e.message)
-
- @defer.inlineCallbacks
- def _is_key_synchronized_with_server(self, current_key):
- remote_key = yield self.get_key(self._email, private=False, fetch_remote=True)
- defer.returnValue(remote_key.fingerprint == current_key.fingerprint)
-
- @defer.inlineCallbacks
- def _regenerate_key_and_send_to_leap(self):
- logger.info("Regenerating keys - this could take a while...")
- key = yield self.keymanager.regenerate_key()
- try:
- yield self.keymanager.send_key()
- defer.returnValue(key)
- except Exception as e:
- raise UploadKeyError(e.message)
-
- @defer.inlineCallbacks
- def _generate_key_and_send_to_leap(self):
- logger.info("Generating keys - this could take a while...")
- key = yield self.keymanager.gen_key()
- try:
- yield self.keymanager.send_key()
- defer.returnValue(key)
- except Exception as e:
- yield self.delete_key_pair()
- raise UploadKeyError(e.message)
-
- @defer.inlineCallbacks
- def _key_exists(self, email):
- try:
- current_key = yield self.get_key(email, private=True, fetch_remote=False)
- defer.returnValue(current_key)
- except KeyNotFound:
- defer.returnValue(None)
-
- @defer.inlineCallbacks
- def get_key(self, email, private=False, fetch_remote=True):
- key = yield self.keymanager.get_key(email, private=private, fetch_remote=fetch_remote)
- defer.returnValue(key)
-
- @defer.inlineCallbacks
- def delete_key_pair(self):
- private_key = yield self.get_key(self._email, private=True, fetch_remote=False)
- public_key = yield self.get_key(self._email, private=False, fetch_remote=False)
-
- self.keymanager.delete_key(private_key)
- self.keymanager.delete_key(public_key)
diff --git a/service/pixelated/bitmask_libraries/provider.py b/service/pixelated/bitmask_libraries/provider.py
deleted file mode 100644
index 96935fbc..00000000
--- a/service/pixelated/bitmask_libraries/provider.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# Copyright (c) 2014 ThoughtWorks, Inc.
-#
-# Pixelated is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Pixelated is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-import json
-import os
-import fileinput
-import tempfile
-import requests
-
-from leap.common.certs import get_digest
-from leap.common import ca_bundle
-from .certs import LeapCertificate
-from pixelated.config import leap_config
-from pixelated.support.tls_adapter import EnforceTLSv1Adapter
-
-REQUESTS_TIMEOUT = 15
-
-
-class LeapProvider(object):
- def __init__(self, server_name):
- self.server_name = server_name
- self.local_ca_crt = '%s/ca.crt' % leap_config.leap_home
- self.provider_json = self.fetch_provider_json()
-
- @property
- def provider_api_cert(self):
- return str(os.path.join(leap_config.leap_home, 'providers', self.server_name, 'keys', 'client', 'api.pem'))
-
- @property
- def combined_cerfificates_path(self):
- return str(os.path.join(leap_config.leap_home, 'providers', self.server_name, 'keys', 'client', 'ca_bundle'))
-
- @property
- def api_uri(self):
- return self.provider_json.get('api_uri')
-
- @property
- def ca_cert_fingerprint(self):
- return self.provider_json.get('ca_cert_fingerprint')
-
- @property
- def ca_cert_uri(self):
- return self.provider_json.get('ca_cert_uri')
-
- @property
- def api_version(self):
- return self.provider_json.get('api_version')
-
- @property
- def domain(self):
- return self.provider_json.get('domain')
-
- @property
- def services(self):
- return self.provider_json.get('services')
-
- def __hash__(self):
- return hash(self.server_name)
-
- def __eq__(self, other):
- return self.server_name == other.server_name
-
- def ensure_supports_mx(self):
- if 'mx' not in self.services:
- raise Exception
-
- def download_soledad_json(self):
- self.soledad_json = self.fetch_soledad_json()
-
- def download_smtp_json(self):
- self.smtp_json = self.fetch_smtp_json()
-
- def download_certificate(self, filename=None):
- """
- Downloads the server certificate, validates it against the provided fingerprint and stores it to file
- """
- path = filename or self.local_ca_crt
-
- directory = self._extract_directory(path)
- if not os.path.exists(directory):
- os.makedirs(directory)
-
- cert = self.fetch_valid_certificate()
- with open(path, 'w') as out:
- out.write(cert)
-
- def _extract_directory(self, path):
- splited = path.split('/')
- splited.pop(-1)
- directory = '/'.join(splited)
- return directory
-
- def fetch_valid_certificate(self):
- cert = self._fetch_certificate()
- self.validate_certificate(cert)
- return cert
-
- def _fetch_certificate(self):
- cert_url = '%s/ca.crt' % self._provider_base_url()
- response = self._validated_get(cert_url)
- cert_data = response.content
- return cert_data
-
- def validate_certificate(self, cert_data=None):
- if cert_data is None:
- cert_data = self._fetch_certificate()
-
- parts = str(self.ca_cert_fingerprint).split(':')
- method = parts[0].strip()
- fingerprint = parts[1].strip()
-
- digest = get_digest(cert_data, method)
-
- if fingerprint.strip() != digest:
- raise Exception('Certificate fingerprints don\'t match! Expected [%s] but got [%s]' % (fingerprint.strip(), digest))
-
- def smtp_info(self):
- hosts = self.smtp_json['hosts']
- hostname = hosts.keys()[0]
- host = hosts[hostname]
- return host['hostname'], host['port']
-
- def _validated_get(self, url):
- session = requests.session()
- try:
- session.mount('https://', EnforceTLSv1Adapter(assert_fingerprint=LeapCertificate.LEAP_FINGERPRINT))
- response = session.get(url, verify=LeapCertificate(self).provider_web_cert, timeout=REQUESTS_TIMEOUT)
- response.raise_for_status()
- return response
- finally:
- session.close()
-
- def fetch_provider_json(self):
- url = '%s/provider.json' % self._provider_base_url()
- response = self._validated_get(url)
- json_data = json.loads(response.content)
- return json_data
-
- def fetch_soledad_json(self):
- service_url = "%s/%s/config/soledad-service.json" % (
- self.api_uri, self.api_version)
- response = requests.get(service_url, verify=self.provider_api_cert, timeout=REQUESTS_TIMEOUT)
- response.raise_for_status()
- return json.loads(response.content)
-
- def fetch_smtp_json(self):
- service_url = '%s/%s/config/smtp-service.json' % (
- self.api_uri, self.api_version)
- response = requests.get(service_url, verify=self.provider_api_cert, timeout=REQUESTS_TIMEOUT)
- response.raise_for_status()
- return json.loads(response.content)
-
- def _provider_base_url(self):
- return 'https://%s' % self.server_name
-
- def address_for(self, username):
- return '%s@%s' % (username, self.domain)
-
- def discover_soledad_server(self, user_uuid):
- hosts = self.soledad_json['hosts']
- host = hosts.keys()[0]
- server_url = 'https://%s:%d/user-%s' % \
- (hosts[host]['hostname'], hosts[host]['port'], user_uuid)
- return server_url
-
- def _discover_nicknym_server(self):
- return 'https://nicknym.%s:6425/' % self.domain
-
- def create_combined_bundle_file(self):
- leap_ca_bundle = ca_bundle.where()
-
- if self.provider_api_cert == leap_ca_bundle:
- return self.provider_api_cert
- elif not self.provider_api_cert:
- return leap_ca_bundle
-
- with open(self.combined_cerfificates_path, 'w') as fout:
- fin = fileinput.input(files=(leap_ca_bundle, self.provider_api_cert))
- for line in fin:
- fout.write(line)
- fin.close()
-
- def setup_ca_bundle(self):
- path = os.path.join(leap_config.leap_home, 'providers', self.server_name, 'keys', 'client')
- if not os.path.isdir(path):
- os.makedirs(path, 0700)
- self._download_cert(self.provider_api_cert)
-
- def _download_cert(self, cert_file_name):
- cert = self.fetch_valid_certificate()
- with open(cert_file_name, 'w') as file:
- file.write(cert)
-
- def setup_ca(self):
- self.download_certificate()
- self.setup_ca_bundle()
- self.create_combined_bundle_file()
-
- def download_settings(self):
- self.download_soledad_json()
- self.download_smtp_json()
diff --git a/service/pixelated/bitmask_libraries/smtp.py b/service/pixelated/bitmask_libraries/smtp.py
deleted file mode 100644
index 643d4d4a..00000000
--- a/service/pixelated/bitmask_libraries/smtp.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2014 ThoughtWorks, Inc.
-#
-# Pixelated is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Pixelated is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-
-
-class LeapSMTPConfig(object):
-
- def __init__(self, account_email, cert_path, remote_smtp_host, remote_smtp_port):
- self.account_email = account_email
- self.cert_path = cert_path
- self.remote_smtp_host = remote_smtp_host
- self.remote_smtp_port = remote_smtp_port