Beispiel #1
0
    def _registration_finished(self, ok, req):
        if ok:
            user_domain = self._username + "@" + self._domain
            message = "<font color='green'><h3>"
            message += self.tr("User %s successfully registered.") % (
                user_domain, )
            message += "</h3></font>"
            self._set_register_status(message)

            self.ui.lblPassword2.clearFocus()
            self._set_registration_fields_visibility(False)

            # Allow the user to remember his password
            if has_keyring():
                self.ui.chkRemember.setVisible(True)
                self.ui.chkRemember.setEnabled(True)

            self.page(self.REGISTER_USER_PAGE).set_completed()
            self.button(QtGui.QWizard.BackButton).setEnabled(False)
        else:
            old_username = self._username
            self._username = None
            self._password = None
            error_msg = self.tr("Unknown error")
            try:
                content, _ = get_content(req)
                json_content = json.loads(content)
                error_msg = json_content.get("errors").get("login")[0]
                if not error_msg.istitle():
                    error_msg = "%s %s" % (old_username, error_msg)
            except Exception as e:
                logger.error("Unknown error: %r" % (e,))

            self._set_register_status(error_msg, error=True)
            self.ui.btnRegister.setEnabled(True)
    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_config(self, *args):
        """
        Downloads the EIP config for the given provider
        """

        leap_assert(self._provider_config,
                    "We need a provider configuration!")

        logger.debug("Downloading EIP config for %s" %
                     (self._provider_config.get_domain(),))

        api_version = self._provider_config.get_api_version()
        self._eip_config = EIPConfig()
        self._eip_config.set_api_version(api_version)

        headers = {}
        mtime = get_mtime(os.path.join(self._eip_config
                                       .get_path_prefix(),
                                       "leap",
                                       "providers",
                                       self._provider_config.get_domain(),
                                       "eip-service.json"))

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        # there is some confusion with this uri,
        # it's in 1/config/eip, config/eip and config/1/eip...
        config_uri = "%s/%s/config/eip-service.json" % (
            self._provider_config.get_api_uri(),
            api_version)
        logger.debug('Downloading eip config from: %s' % config_uri)

        res = self._session.get(config_uri,
                                verify=self._provider_config
                                .get_ca_cert_path(),
                                headers=headers,
                                timeout=REQUEST_TIMEOUT)
        res.raise_for_status()

        # Not modified
        if res.status_code == 304:
            logger.debug("EIP definition has not been modified")
        else:
            eip_definition, mtime = get_content(res)

            self._eip_config.load(data=eip_definition, mtime=mtime)
            self._eip_config.save(["leap",
                                   "providers",
                                   self._provider_config.get_domain(),
                                   "eip-service.json"])
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)
Beispiel #5
0
    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

        :returns: if the registration went ok or not, and the returned status
                  code of of the request
        :rtype: (bool, int)
        """

        username = username.lower().encode('utf-8')
        password = password.encode('utf-8')

        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,))

        ok = False
        req = None
        try:
            req = self._session.post(uri,
                                     data=user_data,
                                     timeout=SIGNUP_TIMEOUT,
                                     verify=self._provider_config.
                                     get_ca_cert_path())

        except requests.exceptions.RequestException as exc:
            logger.error(exc.message)
        else:
            ok = req.ok

        status_code = self.STATUS_ERROR
        if req is not None:
            status_code = req.status_code

        if not ok:
            try:
                content, _ = get_content(req)
                json_content = json.loads(content)
                error_msg = json_content.get("errors").get("login")[0]
                if not error_msg.istitle():
                    error_msg = "%s %s" % (username, error_msg)
                logger.error(error_msg)
            except Exception as e:
                logger.error("Unknown error: %r" % (e, ))

        return ok, status_code
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")
        logger.debug("Downloading provider info for %r" % (self._domain))

        # --------------------------------------------------------------
        # TODO factor out with the download routines in services.
        # Watch out! We're handling the verify paramenter differently here.

        headers = {}
        domain = self._domain.encode(sys.getfilesystemencoding())
        provider_json = os.path.join(util.get_path_prefix(),
                                     get_provider_path(domain))

        if domain in PinnedProviders.domains() and \
           not os.path.exists(provider_json):
            mkdir_p(os.path.join(os.path.dirname(provider_json),
                                 "keys", "ca"))
            cacert = os.path.join(os.path.dirname(provider_json),
                                  "keys", "ca", "cacert.pem")
            PinnedProviders.save_hardcoded(domain, provider_json, cacert)

        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = self.verify

        if mtime:  # the provider.json exists
            # So, we're getting it from the api.* and checking against
            # the provider ca.
            try:
                provider_config = ProviderConfig()
                provider_config.load(provider_json)
                uri = provider_config.get_api_uri() + '/provider.json'
                verify = provider_config.get_ca_cert_path()
            except MissingCACert:
                # no ca? then download from main domain again.
                pass

        if verify:
            verify = verify.encode(sys.getfilesystemencoding())
        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri.encode('idna'), verify=verify,
                                headers=headers, timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        min_client_version = res.headers.get(self.MIN_CLIENT_VERSION, '0')

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        # --------------------------------------------------------------
        # end refactor, more or less...
        # XXX Watch out, have to check the supported api yet.
        else:
            if flags.APP_VERSION_CHECK:
                # TODO split
                if not provider.supports_client(min_client_version):
                    self._signaler.signal(
                        self._signaler.prov_unsupported_client)
                    raise UnsupportedClientVersionError()

            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(["leap", "providers",
                                  domain, "provider.json"])

            if flags.API_VERSION_CHECK:
                # TODO split
                api_version = provider_config.get_api_version()
                if provider.supports_api(api_version):
                    logger.debug("Provider definition has been modified")
                else:
                    api_supported = ', '.join(provider.SUPPORTED_APIS)
                    error = ('Unsupported provider API version. '
                             'Supported versions are: {0}. '
                             'Found: {1}.').format(api_supported, api_version)

                    logger.error(error)
                    self._signaler.signal(self._signaler.prov_unsupported_api)
                    raise UnsupportedProviderAPI(error)
        def _process_challenge(self, salt_B, username):
            """
            Given the salt and B processes the auth challenge and
            generates the M2 parameter

            Might raise SRPAuthenticationError based:
              SRPAuthenticationError
              SRPAuthBadDataFromServer
              SRPAuthConnectionError
              SRPAuthJSONDecodeError
              SRPAuthBadUserOrPassword

            :param salt_B: salt and B parameters for the username
            :type salt_B: tuple
            :param username: username for this session
            :type username: str

            :return: the M2 SRP parameter
            :rtype: str
            """
            logger.debug("Processing challenge...")
            try:
                salt, B = salt_B
                unhex_salt = self._safe_unhexlify(salt)
                unhex_B = self._safe_unhexlify(B)
            except (TypeError, ValueError) as e:
                logger.error("Bad data from server: %r" % (e,))
                raise SRPAuthBadDataFromServer(
                    self.tr("The data sent from the server had errors"))
            M = self._srp_user.process_challenge(unhex_salt, unhex_B)

            auth_url = "%s/%s/%s/%s" % (self._provider_config.get_api_uri(),
                                        self._provider_config.
                                        get_api_version(),
                                        "sessions",
                                        username)

            auth_data = {
                self.CLIENT_AUTH_KEY: binascii.hexlify(M)
            }

            try:
                auth_result = self._session.put(auth_url,
                                                data=auth_data,
                                                verify=self._provider_config.
                                                get_ca_cert_path(),
                                                timeout=REQUEST_TIMEOUT)
            except requests.exceptions.ConnectionError as e:
                logger.error("No connection made (HAMK): %r" % (e,))
                raise SRPAuthConnectionError(self.tr("Could not connect to "
                                                     "the server"))

            try:
                content, mtime = reqhelper.get_content(auth_result)
            except JSONDecodeError:
                raise SRPAuthJSONDecodeError("Bad JSON content in auth result")

            if auth_result.status_code == 422:
                error = ""
                try:
                    error = json.loads(content).get("errors", "")
                except ValueError:
                    logger.error("Problem parsing the received response: %s"
                                 % (content,))
                except AttributeError:
                    logger.error("Expecting a dict but something else was "
                                 "received: %s", (content,))
                logger.error("[%s] Wrong password (HAMK): [%s]" %
                             (auth_result.status_code, error))
                raise SRPAuthBadUserOrPassword(self._WRONG_USER_PASS)

            if auth_result.status_code not in (200,):
                logger.error("No valid response (HAMK): "
                             "Status code = %s. Content = %r" %
                             (auth_result.status_code, content))
                raise SRPAuthBadStatusCode(self.tr("Unknown error (%s)") %
                                           (auth_result.status_code,))

            return json.loads(content)
        def _start_authentication(self, _, username):
            """
            Sends the first request for authentication to retrieve the
            salt and B parameter

            Might raise all SRPAuthenticationError based:
              SRPAuthenticationError
              SRPAuthConnectionError
              SRPAuthBadStatusCode
              SRPAuthNoSalt
              SRPAuthNoB

            :param _: IGNORED, output from the previous callback (None)
            :type _: IGNORED
            :param username: username to login
            :type username: str

            :return: salt and B parameters
            :rtype: tuple
            """
            logger.debug("Starting authentication process...")
            try:
                auth_data = {
                    self.LOGIN_KEY: username,
                    self.A_KEY: binascii.hexlify(self._srp_a)
                }
                sessions_url = "%s/%s/%s/" % \
                    (self._provider_config.get_api_uri(),
                     self._provider_config.get_api_version(),
                     "sessions")

                ca_cert_path = self._provider_config.get_ca_cert_path()
                ca_cert_path = ca_cert_path.encode(sys.getfilesystemencoding())

                init_session = self._session.post(sessions_url,
                                                  data=auth_data,
                                                  verify=ca_cert_path,
                                                  timeout=REQUEST_TIMEOUT)
                # Clean up A value, we don't need it anymore
                self._srp_a = None
            except requests.exceptions.ConnectionError as e:
                logger.error("No connection made (salt): %r" %
                             (e,))
                raise SRPAuthConnectionError("Could not establish a "
                                             "connection")
            except Exception as e:
                logger.error("Unknown error: %r" % (e,))
                raise SRPAuthenticationError("Unknown error: %r" %
                                             (e,))

            content, mtime = reqhelper.get_content(init_session)

            if init_session.status_code not in (200,):
                logger.error("No valid response (salt): "
                             "Status code = %r. Content: %r" %
                             (init_session.status_code, content))
                if init_session.status_code == 422:
                    raise SRPAuthBadUserOrPassword(self._WRONG_USER_PASS)

                raise SRPAuthBadStatusCode(self.tr("There was a problem with"
                                                   " authentication"))

            json_content = json.loads(content)
            salt = json_content.get("salt", None)
            B = json_content.get("B", None)

            if salt is None:
                logger.error("No salt parameter sent")
                raise SRPAuthNoSalt(self.tr("The server did not send "
                                            "the salt parameter"))
            if B is None:
                logger.error("No B parameter sent")
                raise SRPAuthNoB(self.tr("The server did not send "
                                         "the B parameter"))

            return salt, B
Beispiel #9
0
    def _process_challenge(self, salt_B, username):
        """
        Given the salt and B processes the auth challenge and
        generates the M2 parameter

        Might raise SRPAuthenticationError based:
          SRPAuthenticationError
          SRPAuthBadDataFromServer
          SRPAuthConnectionError
          SRPAuthJSONDecodeError
          SRPAuthBadUserOrPassword

        :param salt_B: salt and B parameters for the username
        :type salt_B: tuple
        :param username: username for this session
        :type username: str

        :return: the M2 SRP parameter
        :rtype: str
        """
        logger.debug("Processing challenge...")
        try:
            salt, B = salt_B
            unhex_salt = self._safe_unhexlify(salt)
            unhex_B = self._safe_unhexlify(B)
        except (TypeError, ValueError) as e:
            logger.error("Bad data from server: %r" % (e, ))
            raise SRPAuthBadDataFromServer()
        M = self._srp_user.process_challenge(unhex_salt, unhex_B)

        auth_url = "%s/%s/%s/%s" % (self._provider_config.get_api_uri(),
                                    self._provider_config.get_api_version(),
                                    "sessions", username)

        auth_data = {self.CLIENT_AUTH_KEY: binascii.hexlify(M)}

        try:
            auth_result = self._session.put(
                auth_url,
                data=auth_data,
                verify=self._provider_config.get_ca_cert_path(),
                timeout=REQUEST_TIMEOUT)
        except requests.exceptions.ConnectionError as e:
            logger.error("No connection made (HAMK): %r" % (e, ))
            raise SRPAuthConnectionError()

        try:
            content, mtime = reqhelper.get_content(auth_result)
        except JSONDecodeError:
            logger.error("Bad JSON content in auth result.")
            raise SRPAuthJSONDecodeError()

        if auth_result.status_code == 422:
            error = ""
            try:
                error = json.loads(content).get("errors", "")
            except ValueError:
                logger.error("Problem parsing the received response: %s" %
                             (content, ))
            except AttributeError:
                logger.error(
                    "Expecting a dict but something else was "
                    "received: %s", (content, ))
            logger.error("[%s] Wrong password (HAMK): [%s]" %
                         (auth_result.status_code, error))
            raise SRPAuthBadUserOrPassword()

        if auth_result.status_code not in (200, ):
            logger.error("No valid response (HAMK): "
                         "Status code = %s. Content = %r" %
                         (auth_result.status_code, content))
            raise SRPAuthBadStatusCode()

        return json.loads(content)
Beispiel #10
0
    def _start_authentication(self, _, username):
        """
        Sends the first request for authentication to retrieve the
        salt and B parameter

        Might raise all SRPAuthenticationError based:
          SRPAuthenticationError
          SRPAuthConnectionError
          SRPAuthBadStatusCode
          SRPAuthNoSalt
          SRPAuthNoB

        :param _: IGNORED, output from the previous callback (None)
        :type _: IGNORED
        :param username: username to login
        :type username: str

        :return: salt and B parameters
        :rtype: tuple
        """
        logger.debug("Starting authentication process...")
        try:
            auth_data = {
                self.LOGIN_KEY: username,
                self.A_KEY: binascii.hexlify(self._srp_a)
            }
            sessions_url = "%s/%s/%s/" % \
                (self._provider_config.get_api_uri(),
                 self._provider_config.get_api_version(),
                 "sessions")

            ca_cert_path = self._provider_config.get_ca_cert_path()
            ca_cert_path = ca_cert_path.encode(sys.getfilesystemencoding())

            init_session = self._session.post(sessions_url,
                                              data=auth_data,
                                              verify=ca_cert_path,
                                              timeout=REQUEST_TIMEOUT)
            # Clean up A value, we don't need it anymore
            self._srp_a = None
        except requests.exceptions.ConnectionError as e:
            logger.error("No connection made (salt): {0!r}".format(e))
            raise SRPAuthConnectionError()
        except Exception as e:
            logger.error("Unknown error: %r" % (e, ))
            raise SRPAuthenticationError()

        content, mtime = reqhelper.get_content(init_session)

        if init_session.status_code not in (200, ):
            logger.error("No valid response (salt): "
                         "Status code = %r. Content: %r" %
                         (init_session.status_code, content))
            if init_session.status_code == 422:
                logger.error("Invalid username or password.")
                raise SRPAuthBadUserOrPassword()

            logger.error("There was a problem with authentication.")
            raise SRPAuthBadStatusCode()

        json_content = json.loads(content)
        salt = json_content.get("salt", None)
        B = json_content.get("B", None)

        if salt is None:
            logger.error("The server didn't send the salt parameter.")
            raise SRPAuthNoSalt()
        if B is None:
            logger.error("The server didn't send the B parameter.")
            raise SRPAuthNoB()

        return salt, B
Beispiel #11
0
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")
        logger.debug("Downloading provider info for %r" % (self._domain))

        # --------------------------------------------------------------
        # TODO factor out with the download routines in services.
        # Watch out! We're handling the verify paramenter differently here.

        headers = {}
        domain = self._domain.encode(sys.getfilesystemencoding())
        provider_json = os.path.join(util.get_path_prefix(),
                                     get_provider_path(domain))

        if domain in PinnedProviders.domains() and \
           not os.path.exists(provider_json):
            mkdir_p(os.path.join(os.path.dirname(provider_json), "keys", "ca"))
            cacert = os.path.join(os.path.dirname(provider_json), "keys", "ca",
                                  "cacert.pem")
            PinnedProviders.save_hardcoded(domain, provider_json, cacert)

        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = self.verify

        if mtime:  # the provider.json exists
            # So, we're getting it from the api.* and checking against
            # the provider ca.
            try:
                provider_config = ProviderConfig()
                provider_config.load(provider_json)
                uri = provider_config.get_api_uri() + '/provider.json'
                verify = provider_config.get_ca_cert_path()
            except MissingCACert:
                # no ca? then download from main domain again.
                pass

        if verify:
            verify = verify.encode(sys.getfilesystemencoding())
        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri.encode('idna'),
                                verify=verify,
                                headers=headers,
                                timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        min_client_version = res.headers.get(self.MIN_CLIENT_VERSION, '0')

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        # --------------------------------------------------------------
        # end refactor, more or less...
        # XXX Watch out, have to check the supported api yet.
        else:
            if flags.APP_VERSION_CHECK:
                # TODO split
                if not provider.supports_client(min_client_version):
                    if self._signaler is not None:
                        self._signaler.signal(
                            self._signaler.prov_unsupported_client)
                    raise UnsupportedClientVersionError()

            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(
                ["leap", "providers", domain, "provider.json"])

            if flags.API_VERSION_CHECK:
                # TODO split
                api_version = provider_config.get_api_version()
                if provider.supports_api(api_version):
                    logger.debug("Provider definition has been modified")
                else:
                    api_supported = ', '.join(provider.SUPPORTED_APIS)
                    error = ('Unsupported provider API version. '
                             'Supported versions are: {0}. '
                             'Found: {1}.').format(api_supported, api_version)

                    logger.error(error)
                    if self._signaler is not None:
                        self._signaler.signal(
                            self._signaler.prov_unsupported_api)
                    raise UnsupportedProviderAPI(error)
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")

        logger.debug("Downloading provider info for %s" % (self._domain))

        headers = {}

        provider_json = os.path.join(
            ProviderConfig().get_path_prefix(), "leap", "providers",
            self._domain, "provider.json")
        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = not self._bypass_checks

        if mtime:  # the provider.json exists
            provider_config = ProviderConfig()
            provider_config.load(provider_json)
            try:
                verify = provider_config.get_ca_cert_path()
                uri = provider_config.get_api_uri() + '/provider.json'
            except MissingCACert:
                # get_ca_cert_path fails if the certificate does not exists.
                pass

        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri, verify=verify,
                                headers=headers, timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        else:
            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(["leap",
                                  "providers",
                                  self._domain,
                                  "provider.json"])

            api_version = provider_config.get_api_version()
            if SupportedAPIs.supports(api_version):
                logger.debug("Provider definition has been modified")
            else:
                api_supported = ', '.join(SupportedAPIs.SUPPORTED_APIS)
                error = ('Unsupported provider API version. '
                         'Supported versions are: {}. '
                         'Found: {}.').format(api_supported, api_version)

                logger.error(error)
                raise UnsupportedProviderAPI(error)