def _download_config(self, *args): """ Downloads the SMTP config for the given provider """ leap_assert(self._provider_config, "We need a provider configuration!") logger.debug("Downloading SMTP config for %s" % (self._provider_config.get_domain(),)) headers = {} mtime = get_mtime(os.path.join(self._smtp_config .get_path_prefix(), "leap", "providers", self._provider_config.get_domain(), "smtp-service.json")) if self._download_if_needed and mtime: headers['if-modified-since'] = mtime api_version = self._provider_config.get_api_version() # there is some confusion with this uri, config_uri = "%s/%s/config/smtp-service.json" % ( self._provider_config.get_api_uri(), api_version) logger.debug('Downloading SMTP config from: %s' % config_uri) srp_auth = SRPAuth(self._provider_config) session_id = srp_auth.get_session_id() cookies = None if session_id: cookies = {"_session_id": session_id} res = self._session.get(config_uri, verify=self._provider_config .get_ca_cert_path(), headers=headers, cookies=cookies) res.raise_for_status() self._smtp_config.set_api_version(api_version) # Not modified if res.status_code == 304: logger.debug("SMTP definition has not been modified") self._smtp_config.load(os.path.join( "leap", "providers", self._provider_config.get_domain(), "smtp-service.json")) else: smtp_definition, mtime = get_content(res) self._smtp_config.load(data=smtp_definition, mtime=mtime) self._smtp_config.save(["leap", "providers", self._provider_config.get_domain(), "smtp-service.json"])
def download_client_cert(provider_config, path, session): """ Downloads the client certificate for each service. :param provider_config: instance of a ProviderConfig :type provider_config: ProviderConfig :param path: the path to download the cert to. :type path: str :param session: a fetcher.session instance. For the moment we only support requests.sessions :type session: requests.sessions.Session """ # TODO we should implement the @with_srp_auth decorator # again. srp_auth = SRPAuth(provider_config) session_id = srp_auth.get_session_id() token = srp_auth.get_token() cookies = None if session_id is not None: cookies = {"_session_id": session_id} cert_uri = "%s/%s/cert" % ( provider_config.get_api_uri(), provider_config.get_api_version()) logger.debug('getting cert from uri: %s' % cert_uri) headers = {} # API v2 will only support token auth, but in v1 we can send both if token is not None: headers["Authorization"] = 'Token token="{0}"'.format(token) res = session.get(cert_uri, verify=provider_config .get_ca_cert_path(), cookies=cookies, timeout=REQUEST_TIMEOUT, headers=headers) res.raise_for_status() client_cert = res.content if not leap_certs.is_valid_pemfile(client_cert): # XXX raise more specific exception. raise Exception("The downloaded certificate is not a " "valid PEM file") mkdir_p(os.path.dirname(path)) try: with open(path, "w") as f: f.write(client_cert) except IOError as exc: logger.error( "Error saving client cert: %r" % (exc,)) raise check_and_fix_urw_only(path)
def download_client_cert(provider_config, path, session): """ Downloads the client certificate for each service. :param provider_config: instance of a ProviderConfig :type provider_config: ProviderConfig :param path: the path to download the cert to. :type path: str :param session: a fetcher.session instance. For the moment we only support requests.sessions :type session: requests.sessions.Session """ # TODO we should implement the @with_srp_auth decorator # again. srp_auth = SRPAuth(provider_config) session_id = srp_auth.get_session_id() token = srp_auth.get_token() cookies = None if session_id is not None: cookies = {"_session_id": session_id} cert_uri = "%s/%s/cert" % (provider_config.get_api_uri(), provider_config.get_api_version()) logger.debug('getting cert from uri: %s' % cert_uri) headers = {} # API v2 will only support token auth, but in v1 we can send both if token is not None: headers["Authorization"] = 'Token token="{0}"'.format(token) res = session.get(cert_uri, verify=provider_config.get_ca_cert_path(), cookies=cookies, timeout=REQUEST_TIMEOUT, headers=headers) res.raise_for_status() client_cert = res.content if not leap_certs.is_valid_pemfile(client_cert): # XXX raise more specific exception. raise Exception("The downloaded certificate is not a " "valid PEM file") mkdir_p(os.path.dirname(path)) try: with open(path, "w") as f: f.write(client_cert) except IOError as exc: logger.error("Error saving client cert: %r" % (exc, )) raise check_and_fix_urw_only(path)
def __init__(self, signaler=None): """ Constructor for the Authenticate component :param signaler: Object in charge of handling communication back to the frontend :type signaler: Signaler """ self.key = "authenticate" self._signaler = signaler self._login_defer = None self._srp_auth = SRPAuth(ProviderConfig(), self._signaler)
def _download_client_certificates(self, *args): """ Downloads the EIP client certificate for the given provider """ leap_assert(self._provider_config, "We need a provider configuration!") leap_assert(self._eip_config, "We need an eip configuration!") logger.debug("Downloading EIP client certificate for %s" % (self._provider_config.get_domain(),)) client_cert_path = self._eip_config.\ get_client_cert_path(self._provider_config, about_to_download=True) # For re-download if something is wrong with the cert self._download_if_needed = self._download_if_needed and \ not certs.should_redownload(client_cert_path) if self._download_if_needed and \ os.path.exists(client_cert_path): check_and_fix_urw_only(client_cert_path) return srp_auth = SRPAuth(self._provider_config) session_id = srp_auth.get_session_id() cookies = None if session_id: cookies = {"_session_id": session_id} cert_uri = "%s/%s/cert" % ( self._provider_config.get_api_uri(), self._provider_config.get_api_version()) logger.debug('getting cert from uri: %s' % cert_uri) res = self._session.get(cert_uri, verify=self._provider_config .get_ca_cert_path(), cookies=cookies, timeout=REQUEST_TIMEOUT) res.raise_for_status() client_cert = res.content if not certs.is_valid_pemfile(client_cert): raise Exception(self.tr("The downloaded certificate is not a " "valid PEM file")) mkdir_p(os.path.dirname(client_cert_path)) with open(client_cert_path, "w") as f: f.write(client_cert) check_and_fix_urw_only(client_cert_path)
def srpauth(self): if flags.OFFLINE is True: return None if self._srpauth is None: leap_assert(self._provider_config is not None, "We need a provider config") self._srpauth = SRPAuth(self._provider_config) return self._srpauth
def login(self, domain, username, password): """ Execute the whole authentication process for a user :param domain: the domain where we need to authenticate. :type domain: unicode :param username: username for this session :type username: str :param password: password for this user :type password: str :returns: the defer for the operation running in a thread. :rtype: twisted.internet.defer.Deferred """ config = ProviderConfig.get_provider_config(domain) if config is not None: self._srp_auth = SRPAuth(config, self._signaler) self._login_defer = self._srp_auth.authenticate(username, password) return self._login_defer else: if self._signaler is not None: self._signaler.signal(self._signaler.srp_auth_error) logger.error("Could not load provider configuration.")
def download_service_config(provider_config, service_config, session, download_if_needed=True): """ Downloads config for a given service. :param provider_config: an instance of ProviderConfig :type provider_config: ProviderConfig :param service_config: an instance of a particular Service config. :type service_config: BaseConfig :param session: an instance of a fetcher.session (currently we're using requests only, but it can be anything that implements that interface) :type session: requests.sessions.Session """ service_name = service_config.name service_json = "{0}-service.json".format(service_name) headers = {} mtime = get_mtime(os.path.join(util.get_path_prefix(), "leap", "providers", provider_config.get_domain(), service_json)) if download_if_needed and mtime: headers['if-modified-since'] = mtime api_version = provider_config.get_api_version() config_uri = "%s/%s/config/%s-service.json" % ( provider_config.get_api_uri(), api_version, service_name) logger.debug('Downloading %s config from: %s' % ( service_name.upper(), config_uri)) # XXX make and use @with_srp_auth decorator srp_auth = SRPAuth(provider_config) session_id = srp_auth.get_session_id() token = srp_auth.get_token() cookies = None if session_id is not None: cookies = {"_session_id": session_id} # API v2 will only support token auth, but in v1 we can send both if token is not None: headers["Authorization"] = 'Token token="{0}"'.format(token) verify = provider_config.get_ca_cert_path() if verify: verify = verify.encode(sys.getfilesystemencoding()) res = session.get(config_uri, verify=verify, headers=headers, timeout=REQUEST_TIMEOUT, cookies=cookies) res.raise_for_status() service_config.set_api_version(api_version) # Not modified service_path = ("leap", "providers", provider_config.get_domain(), service_json) if res.status_code == 304: logger.debug( "{0} definition has not been modified".format( service_name.upper())) service_config.load(os.path.join(*service_path)) else: service_definition, mtime = get_content(res) service_config.load(data=service_definition, mtime=mtime) service_config.save(service_path)
def init_soledad(_): token = srpauth.get_token() print "token", token global soledad soledad = Soledad(uuid, _pass, secrets_path, local_db_path, server_url, cert_file, auth_token=token, defer_encryption=False) def getall(_): d = soledad.get_all_docs() return d d1 = soledad.create_doc({"test": 42}) d1.addCallback(getall) d1.addCallbacks(printStuff, printErr) d2 = soledad.sync() d2.addCallbacks(printStuff, printErr) d2.addBoth(lambda r: reactor.stop()) srpauth = SRPAuth(provider) d = srpauth.authenticate(user, _pass) d.addCallbacks(init_soledad, printErr) from twisted.internet import reactor reactor.run()
class Authenticate(object): """ Interfaces with setup and bootstrapping operations for a provider """ zope.interface.implements(ILEAPComponent) def __init__(self, signaler=None): """ Constructor for the Authenticate component :param signaler: Object in charge of handling communication back to the frontend :type signaler: Signaler """ self.key = "authenticate" self._signaler = signaler self._login_defer = None self._srp_auth = SRPAuth(ProviderConfig(), self._signaler) def login(self, domain, username, password): """ Execute the whole authentication process for a user :param domain: the domain where we need to authenticate. :type domain: unicode :param username: username for this session :type username: str :param password: password for this user :type password: str :returns: the defer for the operation running in a thread. :rtype: twisted.internet.defer.Deferred """ config = ProviderConfig.get_provider_config(domain) if config is not None: self._srp_auth = SRPAuth(config, self._signaler) self._login_defer = self._srp_auth.authenticate(username, password) return self._login_defer else: if self._signaler is not None: self._signaler.signal(self._signaler.srp_auth_error) logger.error("Could not load provider configuration.") def cancel_login(self): """ Cancel the ongoing login defer (if any). """ d = self._login_defer if d is not None: d.cancel() def change_password(self, current_password, new_password): """ Change the user's password. :param current_password: the current password of the user. :type current_password: str :param new_password: the new password for the user. :type new_password: str :returns: a defer to interact with. :rtype: twisted.internet.defer.Deferred """ if not self._is_logged_in(): if self._signaler is not None: self._signaler.signal(self._signaler.srp_not_logged_in_error) return return self._srp_auth.change_password(current_password, new_password) def logout(self): """ Log out the current session. Expects a session_id to exists, might raise AssertionError """ if not self._is_logged_in(): if self._signaler is not None: self._signaler.signal(self._signaler.srp_not_logged_in_error) return self._srp_auth.logout() def _is_logged_in(self): """ Return whether the user is logged in or not. :rtype: bool """ return (self._srp_auth is not None and self._srp_auth.is_authenticated()) def get_logged_in_status(self): """ Signal if the user is currently logged in or not. """ if self._signaler is None: return signal = None if self._is_logged_in(): signal = self._signaler.srp_status_logged_in else: signal = self._signaler.srp_status_not_logged_in self._signaler.signal(signal)
def download_client_cert(provider_config, path, session, kind="vpn"): """ Downloads the client certificate for each service. :param provider_config: instance of a ProviderConfig :type provider_config: ProviderConfig :param path: the path to download the cert to. :type path: str :param session: a fetcher.session instance. For the moment we only support requests.sessions :type session: requests.sessions.Session :param kind: the kind of certificate being requested. Valid values are "vpn" or "smtp". :type kind: string """ srp_auth = SRPAuth(provider_config) session_id = srp_auth.get_session_id() token = srp_auth.get_token() cookies = None if session_id is not None: cookies = {"_session_id": session_id} if kind == "vpn": cert_uri_template = "%s/%s/cert" method = "get" params = {} elif kind == "smtp": cert_uri_template = "%s/%s/smtp_cert" method = "post" params = {"address": srp_auth.get_username()} else: raise ValueError("Incorrect value passed to kind parameter") cert_uri = cert_uri_template % (provider_config.get_api_uri(), provider_config.get_api_version()) logger.debug("getting %s cert from uri: %s" % (kind, cert_uri)) headers = {} # API v2 will only support token auth, but in v1 we can send both if token is not None: headers["Authorization"] = "Token token={0}".format(token) call = getattr(session, method) res = call( cert_uri, verify=provider_config.get_ca_cert_path(), cookies=cookies, params=params, timeout=REQUEST_TIMEOUT, headers=headers, data=params, ) res.raise_for_status() client_cert = res.content if not leap_certs.is_valid_pemfile(client_cert): # XXX raise more specific exception. raise Exception("The downloaded certificate is not a " "valid PEM file") mkdir_p(os.path.dirname(path)) try: with open(path, "w") as f: f.write(client_cert) except IOError as exc: logger.error("Error saving client cert: %r" % (exc,)) raise check_and_fix_urw_only(path)
def init_soledad(_): token = srpauth.get_token() print "token", token global soledad soledad = Soledad(uuid, _pass, secrets_path, local_db_path, server_url, cert_file, auth_token=token, defer_encryption=False) def getall(_): d = soledad.get_all_docs() return d d1 = soledad.create_doc({"test": 42}) d1.addCallback(getall) d1.addCallbacks(printStuff, printErr) d2 = soledad.sync() d2.addCallbacks(printStuff, printErr) d2.addBoth(lambda r: reactor.stop()) srpauth = SRPAuth(provider) d = srpauth.authenticate(user, _pass) d.addCallbacks(init_soledad, printErr) reactor.run()
def download_client_cert(provider_config, path, session, kind="vpn"): """ Downloads the client certificate for each service. :param provider_config: instance of a ProviderConfig :type provider_config: ProviderConfig :param path: the path to download the cert to. :type path: str :param session: a fetcher.session instance. For the moment we only support requests.sessions :type session: requests.sessions.Session :param kind: the kind of certificate being requested. Valid values are "vpn" or "smtp". :type kind: string """ srp_auth = SRPAuth(provider_config) session_id = srp_auth.get_session_id() token = srp_auth.get_token() cookies = None if session_id is not None: cookies = {"_session_id": session_id} if kind == "vpn": cert_uri_template = "%s/%s/cert" method = 'get' params = {} elif kind == 'smtp': cert_uri_template = "%s/%s/smtp_cert" method = 'post' params = {'address': srp_auth.get_username()} else: raise ValueError("Incorrect value passed to kind parameter") cert_uri = cert_uri_template % ( provider_config.get_api_uri(), provider_config.get_api_version()) logger.debug('getting %s cert from uri: %s' % (kind, cert_uri)) headers = {} # API v2 will only support token auth, but in v1 we can send both if token is not None: headers["Authorization"] = 'Token token={0}'.format(token) call = getattr(session, method) res = call(cert_uri, verify=provider_config.get_ca_cert_path(), cookies=cookies, params=params, timeout=REQUEST_TIMEOUT, headers=headers, data=params) res.raise_for_status() client_cert = res.content if not leap_certs.is_valid_pemfile(client_cert): # XXX raise more specific exception. raise Exception("The downloaded certificate is not a " "valid PEM file") mkdir_p(os.path.dirname(path)) try: with open(path, "w") as f: f.write(client_cert) except IOError as exc: logger.error( "Error saving client cert: %r" % (exc,)) raise check_and_fix_urw_only(path)
def srpauth(self): if flags.OFFLINE is True: return None leap_assert(self._provider_config is not None, "We need a provider config") return SRPAuth(self._provider_config)
class Authenticate(object): """ Interfaces with setup and bootstrapping operations for a provider """ zope.interface.implements(ILEAPComponent) def __init__(self, signaler=None): """ Constructor for the Authenticate component :param signaler: Object in charge of handling communication back to the frontend :type signaler: Signaler """ self.key = "authenticate" self._signaler = signaler self._login_defer = None self._srp_auth = SRPAuth(ProviderConfig(), self._signaler) def login(self, domain, username, password): """ Execute the whole authentication process for a user :param domain: the domain where we need to authenticate. :type domain: unicode :param username: username for this session :type username: str :param password: password for this user :type password: str :returns: the defer for the operation running in a thread. :rtype: twisted.internet.defer.Deferred """ config = ProviderConfig.get_provider_config(domain) if config is not None: self._srp_auth = SRPAuth(config, self._signaler) self._login_defer = self._srp_auth.authenticate(username, password) return self._login_defer else: if self._signaler is not None: self._signaler.signal(self._signaler.srp_auth_error) logger.error("Could not load provider configuration.") def cancel_login(self): """ Cancel the ongoing login defer (if any). """ d = self._login_defer if d is not None: d.cancel() def change_password(self, current_password, new_password): """ Change the user's password. :param current_password: the current password of the user. :type current_password: str :param new_password: the new password for the user. :type new_password: str :returns: a defer to interact with. :rtype: twisted.internet.defer.Deferred """ if not self._is_logged_in(): if self._signaler is not None: self._signaler.signal(self._signaler.srp_not_logged_in_error) return return self._srp_auth.change_password(current_password, new_password) def logout(self): """ Log out the current session. Expects a session_id to exists, might raise AssertionError """ if not self._is_logged_in(): if self._signaler is not None: self._signaler.signal(self._signaler.srp_not_logged_in_error) return self._srp_auth.logout() def _is_logged_in(self): """ Return whether the user is logged in or not. :rtype: bool """ return (self._srp_auth is not None and self._srp_auth.is_authenticated()) def get_logged_in_status(self): """ Signal if the user is currently logged in or not. If logged in, authenticated username is passed as argument to the signal. """ if self._signaler is None: return if self._is_logged_in(): self._signaler.signal(self._signaler.srp_status_logged_in) else: self._signaler.signal(self._signaler.srp_status_not_logged_in)