From 97554d4c413dd60be4ed67c9553cb0976ce420b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 6 Mar 2013 15:37:07 -0300 Subject: Add SRP related code: authentication and registration --- src/leap/crypto/srpregister.py | 154 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/leap/crypto/srpregister.py (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py new file mode 100644 index 00000000..d9b2b22b --- /dev/null +++ b/src/leap/crypto/srpregister.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# srpregister.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import requests +import binascii +import srp +import logging + +from urlparse import urlparse + +from leap.config.providerconfig import ProviderConfig +from leap.crypto.constants import SIGNUP_TIMEOUT + +logger = logging.getLogger(__name__) + + +class SRPRegister(object): + """ + Registers a user to a specific provider using SRP + """ + + USER_LOGIN_KEY = 'user[login]' + USER_VERIFIER_KEY = 'user[password_verifier]' + USER_SALT_KEY = 'user[password_salt]' + + def __init__(self, + provider_config=None, + register_path="users"): + """ + Constructor + + @param provider_config: provider configuration instance, + properly loaded + @type privider_config: ProviderConfig + @param register_path: webapp path for registering users + @type register_path; str + """ + + assert provider_config, "Please provider a provider" + assert isinstance(provider_config, ProviderConfig), \ + "We need a ProviderConfig instead of %r" % (provider_config,) + + self._provider_config = provider_config + + # **************************************************** # + # Dependency injection helpers, override this for more + # granular testing + self._fetcher = requests + self._srp = srp + self._hashfun = self._srp.SHA256 + self._ng = self._srp.NG_1024 + # **************************************************** # + + parsed_url = urlparse(provider_config.get_api_uri()) + self._provider = parsed_url.hostname + self._port = parsed_url.port + + self._register_path = register_path + + self._session = self._fetcher.session() + + def _get_registration_uri(self): + """ + Returns the URI where the register request should be made for + the provider + + @rtype: str + """ + + if self._port: + uri = "https://%s:%s/%s/%s" % ( + self._provider, + self._port, + self._provider_config.get_api_version(), + self._register_path) + else: + uri = "https://%s/%s/%s" % ( + self._provider, + self._provider_config.get_api_version(), + self._register_path) + + return uri + + def register_user(self, username, password): + """ + Registers a user with the validator based on the password provider + + @param username: username to register + @type username: str + @param password: password for this username + @type password: str + + @rtype: tuple + @rparam: (ok, request) + """ + salt, verifier = self._srp.create_salted_verification_key( + username, + password, + self._hashfun, + self._ng) + + user_data = { + self.USER_LOGIN_KEY: username, + self.USER_VERIFIER_KEY: binascii.hexlify(verifier), + self.USER_SALT_KEY: binascii.hexlify(salt) + } + + uri = self._get_registration_uri() + + logger.debug('Post to uri: %s' % uri) + logger.debug("Will try to register user = %s" % (username,)) + logger.debug("user_data => %r" % (user_data,)) + + req = self._session.post(uri, + data=user_data, + timeout=SIGNUP_TIMEOUT, + verify=self._provider_config. + get_ca_cert_path()) + + return (req.ok, req) + + +if __name__ == "__main__": + logger = logging.getLogger(name='leap') + logger.setLevel(logging.DEBUG) + console = logging.StreamHandler() + console.setLevel(logging.DEBUG) + formatter = logging.Formatter( + '%(asctime)s ' + '- %(name)s - %(levelname)s - %(message)s') + console.setFormatter(formatter) + logger.addHandler(console) + + provider = ProviderConfig() + + if provider.load("leap/providers/bitmask.net/provider.json"): + register = SRPRegister(provider_config=provider) + print "Registering user..." + print register.register_user("test1", "sarasaaaa") + print register.register_user("test2", "sarasaaaa") -- cgit v1.2.3 From 751638b4eb8208e1eaa1beaaed284da6b412bca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 7 Mar 2013 19:05:11 -0300 Subject: Change asserts for a custom leap_assert method Also: - Make SRPAuth and the Bootstrappers be a QObject instead of a QThread so we can use them inside another more generic thread - Add a generic CheckerThread that runs checks or whatever operation as long as it returns a boolean value - Closes the whole application if the wizard is rejected at the first run - Do not fail when the config directory doesn't exist - Set the wizard pixmap logo as LEAP's logo - Improve wizard checks - Make SRPRegister play nice with the CheckerThread --- src/leap/crypto/srpregister.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index d9b2b22b..cf673e35 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -20,15 +20,17 @@ import binascii import srp import logging +from PySide import QtCore from urlparse import urlparse from leap.config.providerconfig import ProviderConfig from leap.crypto.constants import SIGNUP_TIMEOUT +from leap.util.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) -class SRPRegister(object): +class SRPRegister(QtCore.QObject): """ Registers a user to a specific provider using SRP """ @@ -37,6 +39,8 @@ class SRPRegister(object): USER_VERIFIER_KEY = 'user[password_verifier]' USER_SALT_KEY = 'user[password_salt]' + registration_finished = QtCore.Signal(bool, object) + def __init__(self, provider_config=None, register_path="users"): @@ -49,10 +53,9 @@ class SRPRegister(object): @param register_path: webapp path for registering users @type register_path; str """ - - assert provider_config, "Please provider a provider" - assert isinstance(provider_config, ProviderConfig), \ - "We need a ProviderConfig instead of %r" % (provider_config,) + QtCore.QObject.__init__(self) + leap_assert(provider_config, "Please provider a provider") + leap_assert_type(provider_config, ProviderConfig) self._provider_config = provider_config @@ -131,7 +134,9 @@ class SRPRegister(object): verify=self._provider_config. get_ca_cert_path()) - return (req.ok, req) + self.registration_finished.emit(req.ok, req) + + return req.ok if __name__ == "__main__": -- cgit v1.2.3 From 98699d1c1c9d4698faa6bd7b1c7cf5b576372381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 11:39:06 -0300 Subject: Separate stdlibs from non-std in imports --- src/leap/crypto/srpregister.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index cf673e35..471ef28f 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -15,11 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import requests import binascii -import srp import logging +import requests +import srp + from PySide import QtCore from urlparse import urlparse -- cgit v1.2.3 From fc80cfd6d393534d71bfd0489557d3b4203cf4fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 11:45:34 -0300 Subject: Default to port 443 if no port is specified --- src/leap/crypto/srpregister.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index 471ef28f..c99f79ab 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -72,6 +72,8 @@ class SRPRegister(QtCore.QObject): parsed_url = urlparse(provider_config.get_api_uri()) self._provider = parsed_url.hostname self._port = parsed_url.port + if self._port is None: + self._port = "443" self._register_path = register_path @@ -85,17 +87,11 @@ class SRPRegister(QtCore.QObject): @rtype: str """ - if self._port: - uri = "https://%s:%s/%s/%s" % ( - self._provider, - self._port, - self._provider_config.get_api_version(), - self._register_path) - else: - uri = "https://%s/%s/%s" % ( - self._provider, - self._provider_config.get_api_version(), - self._register_path) + uri = "https://%s:%s/%s/%s" % ( + self._provider, + self._port, + self._provider_config.get_api_version(), + self._register_path) return uri -- cgit v1.2.3 From d0dfad6ac2af360de6421ce74a6831b5b81ad019 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 14 Mar 2013 07:08:31 +0900 Subject: namespace leap + leap.common split leap is a namespace package from here on. common folder will be deleted and moved to leap_pycommon repository. --- src/leap/crypto/srpregister.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index c99f79ab..9a9cac76 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -26,7 +26,7 @@ from urlparse import urlparse from leap.config.providerconfig import ProviderConfig from leap.crypto.constants import SIGNUP_TIMEOUT -from leap.util.check import leap_assert, leap_assert_type +from leap.common.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) -- cgit v1.2.3 From d193fee401d606f6120ac11819a0127e7ee92458 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 26 Mar 2013 01:15:44 +0900 Subject: tests for srpregister and srpauth in this commit too, the twisted fake_provider implementation --- src/leap/crypto/srpregister.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index 9a9cac76..dc137aeb 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -55,7 +55,7 @@ class SRPRegister(QtCore.QObject): @type register_path; str """ QtCore.QObject.__init__(self) - leap_assert(provider_config, "Please provider a provider") + leap_assert(provider_config, "Please provide a provider") leap_assert_type(provider_config, ProviderConfig) self._provider_config = provider_config @@ -125,15 +125,24 @@ class SRPRegister(QtCore.QObject): logger.debug("Will try to register user = %s" % (username,)) logger.debug("user_data => %r" % (user_data,)) - req = self._session.post(uri, - data=user_data, - timeout=SIGNUP_TIMEOUT, - verify=self._provider_config. - get_ca_cert_path()) + try: + req = self._session.post(uri, + data=user_data, + timeout=SIGNUP_TIMEOUT, + verify=self._provider_config. + get_ca_cert_path()) - self.registration_finished.emit(req.ok, req) + except requests.exceptions.SSLError as exc: + logger.error("SSLError: %s" % exc.message) + _ok = False + req = None - return req.ok + else: + _ok = req.ok + + self.registration_finished.emit(_ok, req) + + return _ok if __name__ == "__main__": -- cgit v1.2.3 From 42593d4c6bda51a544a72abc0f935633939dad49 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 8 Apr 2013 23:44:22 +0900 Subject: Several fixes as per review --- src/leap/crypto/srpregister.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index dc137aeb..59aaf257 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -125,6 +125,7 @@ class SRPRegister(QtCore.QObject): logger.debug("Will try to register user = %s" % (username,)) logger.debug("user_data => %r" % (user_data,)) + ok = None try: req = self._session.post(uri, data=user_data, @@ -134,15 +135,12 @@ class SRPRegister(QtCore.QObject): except requests.exceptions.SSLError as exc: logger.error("SSLError: %s" % exc.message) - _ok = False req = None - + ok = False else: - _ok = req.ok - - self.registration_finished.emit(_ok, req) - - return _ok + ok = req.ok + self.registration_finished.emit(ok, req) + return ok if __name__ == "__main__": -- cgit v1.2.3 From f74849f4c926a83190169cae570e9ec826fd46da Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 1 May 2013 04:14:15 +0900 Subject: pep8 --- src/leap/crypto/srpregister.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index 59aaf257..749b6f8c 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -128,10 +128,10 @@ class SRPRegister(QtCore.QObject): ok = None try: req = self._session.post(uri, - data=user_data, - timeout=SIGNUP_TIMEOUT, - verify=self._provider_config. - get_ca_cert_path()) + data=user_data, + timeout=SIGNUP_TIMEOUT, + verify=self._provider_config. + get_ca_cert_path()) except requests.exceptions.SSLError as exc: logger.error("SSLError: %s" % exc.message) -- cgit v1.2.3 From 2dae2703fb8c2ae7e721ce83020c0dd10ff9ca33 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 May 2013 02:59:22 +0900 Subject: updated documentation * documentation reviewed after rewrite, ready for 0.2.1 * updated docstrings format to fit sphinx autodoc --- src/leap/crypto/srpregister.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/leap/crypto/srpregister.py') diff --git a/src/leap/crypto/srpregister.py b/src/leap/crypto/srpregister.py index 749b6f8c..07b3c917 100644 --- a/src/leap/crypto/srpregister.py +++ b/src/leap/crypto/srpregister.py @@ -48,11 +48,11 @@ class SRPRegister(QtCore.QObject): """ Constructor - @param provider_config: provider configuration instance, + :param provider_config: provider configuration instance, properly loaded - @type privider_config: ProviderConfig - @param register_path: webapp path for registering users - @type register_path; str + :type privider_config: ProviderConfig + :param register_path: webapp path for registering users + :type register_path; str """ QtCore.QObject.__init__(self) leap_assert(provider_config, "Please provide a provider") @@ -84,7 +84,7 @@ class SRPRegister(QtCore.QObject): Returns the URI where the register request should be made for the provider - @rtype: str + :rtype: str """ uri = "https://%s:%s/%s/%s" % ( @@ -99,13 +99,13 @@ class SRPRegister(QtCore.QObject): """ Registers a user with the validator based on the password provider - @param username: username to register - @type username: str - @param password: password for this username - @type password: str + :param username: username to register + :type username: str + :param password: password for this username + :type password: str - @rtype: tuple - @rparam: (ok, request) + :rtype: tuple + :rparam: (ok, request) """ salt, verifier = self._srp.create_salted_verification_key( username, -- cgit v1.2.3