Exemple #1
0
    def __init__(self, cookie=None, **settings):
        if cookie is not None and not isinstance(cookie, str):
            raise ValueError("Cookie must be str, cast it explicitly")
        self.modified = False
        self.is_new = False
        self._saved = False
        self._aborted = False
        self._data = None
        log.debug("Recieved cookie '%s'" % cookie)
        self._id_length = settings.get("session_id_length", 32)
        self.enc_key = settings.get("encryption_key", None)
        self.sig_key = settings["signature_key"]
        self.hashalg = settings.get("hashalg", HASHALG)
        self.refresh_on_access = settings.get("refresh_on_access", True)
        self.serializer = settings.get("serializer", json)

        # Cookie settings
        self.name = settings.get("name", b"session")
        self.path = settings.get("path", "/")
        self.domain = settings["domain"]
        self.max_age = settings.get("max_age", None)
        self.secure = settings.get("secure", False)
        self.httponly = settings.get("httponly", False)

        # Make sure if we have an encryption key that we are also able to
        # encrypt.
        if self.enc_key:
            use_encryption = encryption_available()
            if not use_encryption:
                raise CryptoError("Encryption key was given but encryption is " "not available.")
        else:
            use_encryption = False

        # Choose the correct class for creating a cookie and prepare it
        if use_encryption:
            CookieClass = functools.partial(EncryptedCookie, self.serializer, self.sig_key, self.hashalg, self.enc_key)
        else:
            CookieClass = functools.partial(SignedCookie, self.serializer, self.sig_key, self.hashalg)

        if cookie:
            # Load the cookie data and on error create a new cookie
            try:
                self._cookie = CookieClass(input=cookie)
                sess_id = self._get_session_id_from_cookie()
                log.debug("Loaded old cookie with session ID %s from input %s" % (sess_id, cookie))
            except Cookie.CookieError as e:
                log.debug("Creating new cookie because of the following " "exception: %s" % e)
                self._cookie = CookieClass(input=None)
            except CryptoError as e:
                log.warning("Cryptographic Error '%s' when loading cookie " "'%s': %r" % (e.message, cookie, e))
                self._cookie = CookieClass(input=None)
            except Exception as e:
                log.info("Error loading cookie '%s' because of exception '%r'" % (cookie, e))
                self._cookie = CookieClass(input=None)
        else:
            log.debug("Starting new session because of empty cookie.")
            self._cookie = CookieClass(input=None)

        if self._get_session_id_from_cookie() is None:
            self.is_new = True
def authenced(request):
    """Encrypt and authenticate a testvalue and return a three-tuple
    (testval, ciphertext, tag)."""
    if not encryption_available():
        pytest.skip("pycrypto not available")
    testval = request.param
    ciphertext, tag = encrypt_then_authenticate(testval, test_enc_key,
                                                test_sig_key, hashlib.sha256)
    return testval, ciphertext, tag
Exemple #3
0
    def configure(self, **settings):
        """
        Configure sessions with default arguments. The settings passed in here
        will be used for all newly created sessions, unless superseded by the
        settings explicity passed to :meth:`sessionmaker.__call__`.

        The following configuration settings are available exclusively to the
        sessionmaker:

        :param backend: The name of the backend to be used. This setting is
                        mandatory, but can also be passed individually on
                        session creation.

        :param secret_file: If this is specified, a file is used to store keys
                            for both encryption and signing of the cookie.
                            This option conflicts with the ``signature_key``
                            and ``encryption_key`` options, so you can only use
                            one of them. Defaults to a file called `secret` in
                            the current working directory.

        :param enable_encryption: Only useful in conjunction with
                                  ``secret_file``, as it specifies to not only
                                  load a signature key but also an encryption
                                  key. This requires `PyCrypto`_. Defaults to
                                  no encryption.

        .. _PyCrypto: https://www.dlitz.net/software/pycrypto/
        """
        if hasattr(self, 'settings'):
            raise SessionConfigurationError("Session already configured.")
        self._check_settings_sanity(settings)
        self._init_keys(settings)
        assert 'signature_key' in settings
        self.settings = settings
        try:
            backend = self.settings['backend']
            self.session_class = get_session_class(backend)
        except ValueError:
            raise SessionConfigurationError("Backend %s not found." % backend)
        except KeyError:
            raise SessionConfigurationError("No backend given, please "
                                            "specifiy a 'backend' setting.")

        # Check if we can encrypt:
        # This is just a failsafe check to throw up at configuration already
        if 'encryption_key' in self.settings and not encryption_available():
            raise CryptoError("Encryption not available, install pycrypto.")
def test_encryption_available_recheck():
    assert encryption_available()
    del crypto.conf["encryption_available"]
    with pytest.raises(KeyError):
        assert not encryption_available()
    assert encryption_available(recheck=True)
def test_encryption_available_fails():
    oldval = crypto.conf["encryption_available"]
    crypto.conf["encryption_available"] = False
    assert not encryption_available()
    crypto.conf["encryption_available"] = oldval
def test_encryption_available():
    assert encryption_available()