Example #1
0
    def test_register_crypt_handler(self):
        """test register_crypt_handler()"""

        self.assertRaises(TypeError, register_crypt_handler, {})

        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name=None)))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="AB_CD")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="ab-cd")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="ab__cd")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="default")))

        class dummy_1(uh.StaticHandler):
            name = "dummy_1"

        class dummy_1b(uh.StaticHandler):
            name = "dummy_1"

        self.assertTrue('dummy_1' not in list_crypt_handlers())

        register_crypt_handler(dummy_1)
        register_crypt_handler(dummy_1)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1)

        self.assertRaises(KeyError, register_crypt_handler, dummy_1b)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1)

        register_crypt_handler(dummy_1b, force=True)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1b)

        self.assertTrue('dummy_1' in list_crypt_handlers())
Example #2
0
    def test_register_crypt_handler(self):
        """test register_crypt_handler()"""

        self.assertRaises(TypeError, register_crypt_handler, {})

        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name=None)))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="AB_CD")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="ab-cd")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="ab__cd")))
        self.assertRaises(ValueError, register_crypt_handler, type('x', (uh.StaticHandler,), dict(name="default")))

        class dummy_1(uh.StaticHandler):
            name = "dummy_1"

        class dummy_1b(uh.StaticHandler):
            name = "dummy_1"

        self.assertTrue('dummy_1' not in list_crypt_handlers())

        register_crypt_handler(dummy_1)
        register_crypt_handler(dummy_1)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1)

        self.assertRaises(KeyError, register_crypt_handler, dummy_1b)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1)

        register_crypt_handler(dummy_1b, force=True)
        self.assertIs(get_crypt_handler("dummy_1"), dummy_1b)

        self.assertTrue('dummy_1' in list_crypt_handlers())
Example #3
0
    def test_register_crypt_handler_path(self):
        """test register_crypt_handler_path()"""
        # NOTE: this messes w/ internals of registry, shouldn't be used publically.
        paths = registry._locations

        # check namespace is clear
        self.assertTrue("dummy_0" not in paths)
        self.assertFalse(hasattr(hash, "dummy_0"))

        # check invalid names are rejected
        self.assertRaises(ValueError, register_crypt_handler_path, "dummy_0",
                          ".test_registry")
        self.assertRaises(
            ValueError,
            register_crypt_handler_path,
            "dummy_0",
            __name__ + ":dummy_0:xxx",
        )
        self.assertRaises(
            ValueError,
            register_crypt_handler_path,
            "dummy_0",
            __name__ + ":dummy_0.xxx",
        )

        # try lazy load
        register_crypt_handler_path("dummy_0", __name__)
        self.assertTrue("dummy_0" in list_crypt_handlers())
        self.assertTrue("dummy_0" not in list_crypt_handlers(loaded_only=True))
        self.assertIs(hash.dummy_0, dummy_0)
        self.assertTrue("dummy_0" in list_crypt_handlers(loaded_only=True))
        unload_handler_name("dummy_0")

        # try lazy load w/ alt
        register_crypt_handler_path("dummy_0", __name__ + ":alt_dummy_0")
        self.assertIs(hash.dummy_0, alt_dummy_0)
        unload_handler_name("dummy_0")

        # check lazy load w/ wrong type fails
        register_crypt_handler_path("dummy_x", __name__)
        self.assertRaises(TypeError, get_crypt_handler, "dummy_x")

        # check lazy load w/ wrong name fails
        register_crypt_handler_path("alt_dummy_0", __name__)
        self.assertRaises(ValueError, get_crypt_handler, "alt_dummy_0")
        unload_handler_name("alt_dummy_0")

        # TODO: check lazy load which calls register_crypt_handler (warning should be issued)
        sys.modules.pop("passlib.tests._test_bad_register", None)
        register_crypt_handler_path("dummy_bad",
                                    "passlib.tests._test_bad_register")
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", "xxxxxxxxxx", DeprecationWarning)
            h = get_crypt_handler("dummy_bad")
        from passlib.tests import _test_bad_register as tbr

        self.assertIs(h, tbr.alt_dummy_bad)
Example #4
0
 def test_handlers(self):
     "verify we have tests for all handlers"
     from passlib.registry import list_crypt_handlers
     from passlib.tests.test_handlers import get_handler_case
     for name in list_crypt_handlers():
         if name.startswith("ldap_") and name[5:] in list_crypt_handlers():
             continue
         if name in ["roundup_plaintext"]:
             continue
         self.assertTrue(get_handler_case(name))
Example #5
0
 def test_handlers(self):
     "verify we have tests for all handlers"
     from passlib.registry import list_crypt_handlers
     from passlib.tests.test_handlers import get_handler_case
     for name in list_crypt_handlers():
         if name.startswith("ldap_") and name[5:] in list_crypt_handlers():
             continue
         if name in ["roundup_plaintext"]:
             continue
         self.assertTrue(get_handler_case(name))
Example #6
0
def _load_master_config():
    from passlib.registry import list_crypt_handlers

    # get master list
    schemes = list_crypt_handlers()

    # exclude the ones we know have ambiguous or greedy identify() methods.
    excluded = [
        # frequently confused for eachother
        "bigcrypt",
        "crypt16",
        # no good identifiers
        "cisco_pix",
        "cisco_type7",
        "htdigest",
        "mysql323",
        "oracle10",
        # all have same size
        "lmhash",
        "msdcc",
        "msdcc2",
        "nthash",
        # plaintext handlers
        "plaintext",
        "ldap_plaintext",
        # disabled handlers
        "django_disabled",
        "unix_disabled",
        "unix_fallback",
    ]
    for name in excluded:
        schemes.remove(name)

    # return config
    return dict(schemes=schemes, default="sha256_crypt")
Example #7
0
def _load_master_config():
    from passlib.registry import list_crypt_handlers

    # get master list
    schemes = list_crypt_handlers()

    # exclude the ones we know have ambiguous or greedy identify() methods.
    excluded = [
        # frequently confused for eachother
        "bigcrypt",
        "crypt16",
        # no good identifiers
        "cisco_pix",
        "cisco_type7",
        "htdigest",
        "mysql323",
        "oracle10",
        # all have same size
        "lmhash",
        "msdcc",
        "msdcc2",
        "nthash",
        # plaintext handlers
        "plaintext",
        "ldap_plaintext",
        # disabled handlers
        "django_disabled",
        "unix_disabled",
        "unix_fallback",
    ]
    for name in excluded:
        schemes.remove(name)

    # return config
    return dict(schemes=schemes, default="sha256_crypt")
Example #8
0
    def test_register_crypt_handler_path(self):
        """test register_crypt_handler_path()"""
        # NOTE: this messes w/ internals of registry, shouldn't be used publically.
        paths = registry._locations

        # check namespace is clear
        self.assertTrue('dummy_0' not in paths)
        self.assertFalse(hasattr(hash, 'dummy_0'))

        # check invalid names are rejected
        self.assertRaises(ValueError, register_crypt_handler_path,
                          "dummy_0", ".test_registry")
        self.assertRaises(ValueError, register_crypt_handler_path,
                          "dummy_0", __name__ + ":dummy_0:xxx")
        self.assertRaises(ValueError, register_crypt_handler_path,
                          "dummy_0", __name__ + ":dummy_0.xxx")

        # try lazy load
        register_crypt_handler_path('dummy_0', __name__)
        self.assertTrue('dummy_0' in list_crypt_handlers())
        self.assertTrue('dummy_0' not in list_crypt_handlers(loaded_only=True))
        self.assertIs(hash.dummy_0, dummy_0)
        self.assertTrue('dummy_0' in list_crypt_handlers(loaded_only=True))
        unload_handler_name('dummy_0')

        # try lazy load w/ alt
        register_crypt_handler_path('dummy_0', __name__ + ':alt_dummy_0')
        self.assertIs(hash.dummy_0, alt_dummy_0)
        unload_handler_name('dummy_0')

        # check lazy load w/ wrong type fails
        register_crypt_handler_path('dummy_x', __name__)
        self.assertRaises(TypeError, get_crypt_handler, 'dummy_x')

        # check lazy load w/ wrong name fails
        register_crypt_handler_path('alt_dummy_0', __name__)
        self.assertRaises(ValueError, get_crypt_handler, "alt_dummy_0")
        unload_handler_name("alt_dummy_0")

        # TODO: check lazy load which calls register_crypt_handler (warning should be issued)
        sys.modules.pop("passlib.tests._test_bad_register", None)
        register_crypt_handler_path("dummy_bad", "passlib.tests._test_bad_register")
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", "xxxxxxxxxx", DeprecationWarning)
            h = get_crypt_handler("dummy_bad")
        from passlib.tests import _test_bad_register as tbr
        self.assertIs(h, tbr.alt_dummy_bad)
Example #9
0
 def test_handlers(self):
     """verify we have tests for all builtin handlers"""
     from passlib.registry import list_crypt_handlers
     from passlib.tests.test_handlers import get_handler_case, conditionally_available_hashes
     for name in list_crypt_handlers():
         # skip some wrappers that don't need independant testing
         if name.startswith("ldap_") and name[5:] in list_crypt_handlers():
             continue
         if name in ["roundup_plaintext"]:
             continue
         # check the remaining ones all have a handler
         try:
             self.assertTrue(get_handler_case(name))
         except exc.MissingBackendError:
             if name in conditionally_available_hashes:  # expected to fail on some setups
                 continue
             raise
Example #10
0
 def test_handlers(self):
     """verify we have tests for all builtin handlers"""
     from passlib.registry import list_crypt_handlers
     from passlib.tests.test_handlers import get_handler_case
     for name in list_crypt_handlers():
         # skip some wrappers that don't need independant testing
         if name.startswith("ldap_") and name[5:] in list_crypt_handlers():
             continue
         if name in ["roundup_plaintext"]:
             continue
         # check the remaining ones all have a handler
         try:
             self.assertTrue(get_handler_case(name))
         except exc.MissingBackendError:
             if name in ["bcrypt", "bcrypt_sha256"]: # expected to fail on some setups
                 continue
             raise
Example #11
0
    def test_list_crypt_handlers(self):
        """test list_crypt_handlers()"""
        from passlib.registry import list_crypt_handlers

        # check system & private names aren't returned
        hash.__dict__["_fake"] = "dummy"
        for name in list_crypt_handlers():
            self.assertFalse(name.startswith("_"), "%r: " % name)
        unload_handler_name("_fake")
Example #12
0
    def test_list_crypt_handlers(self):
        """test list_crypt_handlers()"""
        from passlib.registry import list_crypt_handlers

        # check system & private names aren't returned
        import passlib.hash # ensure module imported, so py3.3 sets __package__
        passlib.hash.__dict__["_fake"] = "dummy" # so behavior seen under py2x also
        for name in list_crypt_handlers():
            self.assertFalse(name.startswith("_"), "%r: " % name)
Example #13
0
    def test_list_crypt_handlers(self):
        "test list_crypt_handlers()"
        from passlib.registry import list_crypt_handlers

        # check system & private names aren't returned
        import passlib.hash  # ensure module imported, so py3.3 sets __package__
        passlib.hash.__dict__[
            "_fake"] = "dummy"  # so behavior seen under py2x also
        for name in list_crypt_handlers():
            self.assertFalse(name.startswith("_"), "%r: " % name)
Example #14
0
def hasher_to_passlib_name(hasher_name):
    "convert hasher name -> passlib handler name"
    if hasher_name.startswith(PASSLIB_HASHER_PREFIX):
        return hasher_name[len(PASSLIB_HASHER_PREFIX):]
    for name in list_crypt_handlers():
        if name.startswith(DJANGO_PASSLIB_PREFIX) or name in _other_django_hashes:
            handler = get_crypt_handler(name)
            if getattr(handler, "django_name", None) == hasher_name:
                return name
    # XXX: this should only happen for custom hashers that have been registered.
    #      work in progress (below) that would take care of those.
    raise ValueError("can't translate hasher name to passlib name: %r" %
                     hasher_name)
Example #15
0
def hasher_to_passlib_name(hasher_name):
    "convert hasher name -> passlib handler name"
    if hasher_name.startswith(PASSLIB_HASHER_PREFIX):
        return hasher_name[len(PASSLIB_HASHER_PREFIX):]
    for name in list_crypt_handlers():
        if name.startswith(
                DJANGO_PASSLIB_PREFIX) or name in _other_django_hashes:
            handler = get_crypt_handler(name)
            if getattr(handler, "django_name", None) == hasher_name:
                return name
    # XXX: this should only happen for custom hashers that have been registered.
    #      _HasherHandler (below) is work in progress that would fix this.
    raise ValueError("can't translate hasher name to passlib name: %r" %
                     hasher_name)
Example #16
0
    def get_password_context():
        if User._ctx:
            return User._ctx

        schemes = registry.list_crypt_handlers()
        # scrypt throws a warning if the native wheels aren't found
        schemes.remove('scrypt')
        # we can't leave plaintext schemes as they will be misidentified
        for scheme in schemes:
            if scheme.endswith('plaintext'):
                schemes.remove(scheme)
        User._ctx = context.CryptContext(
            schemes=schemes,
            default='bcrypt_sha256',
            bcrypt_sha256__rounds=app.config['CREDENTIAL_ROUNDS'],
            deprecated='auto')
        return User._ctx
Example #17
0
def hasher_to_passlib_name(hasher_name):
    """convert hasher name -> passlib handler name"""
    if hasher_name.startswith(PASSLIB_HASHER_PREFIX):
        return hasher_name[len(PASSLIB_HASHER_PREFIX):]
    if hasher_name == "unsalted_sha1":
        # django 1.4.6+ uses a separate hasher for "sha1$$digest" hashes,
        # but passlib just reuses the "sha1$salt$digest" handler.
        hasher_name = "sha1"
    for name in list_crypt_handlers():
        if name.startswith(DJANGO_PASSLIB_PREFIX) or name in _other_django_hashes:
            handler = get_crypt_handler(name)
            if getattr(handler, "django_name", None) == hasher_name:
                return name
    # XXX: this should only happen for custom hashers that have been registered.
    #      _HasherHandler (below) is work in progress that would fix this.
    raise ValueError("can't translate hasher name to passlib name: %r" %
                     hasher_name)
Example #18
0
def _load_master_config():
    from passlib.registry import list_crypt_handlers

    # get master list
    schemes = list_crypt_handlers()

    # exclude the ones we know have ambiguous or greedy identify() methods.
    excluded = [
        # frequently confused for eachother
        'bigcrypt',
        'crypt16',

        # no good identifiers
        'cisco_pix',
        'cisco_type7',
        'htdigest',
        'mysql323',
        'oracle10',

        # all have same size
        'lmhash',
        'msdcc',
        'msdcc2',
        'nthash',

        # plaintext handlers
        'plaintext',
        'ldap_plaintext',

        # disabled handlers
        'django_disabled',
        'unix_disabled',
        'unix_fallback',
    ]
    for name in excluded:
        schemes.remove(name)

    # return config
    return dict(schemes=schemes, default="sha256_crypt")
Example #19
0
def _load_master_config():
    from passlib.registry import list_crypt_handlers

    # get master list
    schemes = list_crypt_handlers()

    # exclude the ones we know have ambiguous or greedy identify() methods.
    excluded = [
        # frequently confused for eachother
        'bigcrypt',
        'crypt16',

        # no good identifiers
        'cisco_pix',
        'cisco_type7',
        'htdigest',
        'mysql323',
        'oracle10',

        # all have same size
        'lmhash',
        'msdcc',
        'msdcc2',
        'nthash',

        # plaintext handlers
        'plaintext',
        'ldap_plaintext',

        # disabled handlers
        'django_disabled',
        'unix_disabled',
        'unix_fallback',
    ]
    for name in excluded:
        schemes.remove(name)

    # return config
    return dict(schemes=schemes, default="sha256_crypt")
Example #20
0
        return self.method.name

    @property
    def class_name(self):
        return get_class_name(self.method)

    @property
    def description(self):
        return get_description(self.method)

    @property
    def require_password(self):
        return requires_password(self.method)

    @property
    def require_user(self):
        return requires_user(self.method)

    @property
    def supported(self):
        return is_supported(self.method)

    def __call__(self, password, **params):
        return make_hash(self.method, password, **params)


# Init the hash mappings:
# attr_name -> MethodWrapper(attr_name, implementation_class)
methods = OrderedDict((name, MethodWrapper(get_crypt_handler(name)))
                      for name in list_crypt_handlers())
Example #21
0
    def django_to_passlib(self, django_name, cached=True):
        """
        Convert Django hasher / name to Passlib hasher / name.
        If present, CryptContext will be checked instead of main registry.

        :param django_name:
            Django hasher class or algorithm name.
            "default" allowed if context provided.

        :raises ValueError:
            if can't resolve hasher.

        :returns:
            passlib hasher or name
        """
        # check for django hasher
        if hasattr(django_name, "algorithm"):

            # check for passlib adapter
            if isinstance(django_name, _PasslibHasherWrapper):
                return django_name.passlib_handler

            # resolve django hasher -> name
            django_name = django_name.algorithm

        # check cache
        if cached:
            cache = self._passlib_hasher_cache
            try:
                return cache[django_name]
            except KeyError:
                pass
            result = cache[django_name] = \
                self.django_to_passlib(django_name, cached=False)
            return result

        # check if it's an obviously-wrapped name
        if django_name.startswith(PASSLIB_WRAPPER_PREFIX):
            passlib_name = django_name[len(PASSLIB_WRAPPER_PREFIX):]
            return self._get_passlib_hasher(passlib_name)

        # resolve default
        if django_name == "default":
            context = self.context
            if context is None:
                raise TypeError("can't determine default scheme w/ context")
            return context.handler()

        # special case: Django uses a separate hasher for "sha1$$digest"
        # hashes (unsalted_sha1) and "sha1$salt$digest" (sha1);
        # but passlib uses "django_salted_sha1" for both of these.
        if django_name == "unsalted_sha1":
            django_name = "sha1"

        # resolve name
        # XXX: bother caching these lists / mapping?
        #      not needed in long-term due to cache above.
        context = self.context
        if context is None:
            # check registry
            # TODO: should make iteration via registry easier
            candidates = (
                registry.get_crypt_handler(passlib_name)
                for passlib_name in registry.list_crypt_handlers()
                if passlib_name.startswith(DJANGO_COMPAT_PREFIX) or
                   passlib_name in _other_django_hashes
            )
        else:
            # check context
            candidates = context.schemes(resolve=True)
        for handler in candidates:
            if getattr(handler, "django_name", None) == django_name:
                return handler

        # give up
        # NOTE: this should only happen for custom django hashers that we don't
        #       know the equivalents for. _HasherHandler (below) is work in
        #       progress that would allow us to at least return a wrapper.
        raise ValueError("can't translate django name to passlib name: %r" %
                         (django_name,))
Example #22
0
    def django_to_passlib(self, django_name, cached=True):
        """
        Convert Django hasher / name to Passlib hasher / name.
        If present, CryptContext will be checked instead of main registry.

        :param django_name:
            Django hasher class or algorithm name.
            "default" allowed if context provided.

        :raises ValueError:
            if can't resolve hasher.

        :returns:
            passlib hasher or name
        """
        # check for django hasher
        if hasattr(django_name, "algorithm"):

            # check for passlib adapter
            if isinstance(django_name, _PasslibHasherWrapper):
                return django_name.passlib_handler

            # resolve django hasher -> name
            django_name = django_name.algorithm

        # check cache
        if cached:
            cache = self._passlib_hasher_cache
            try:
                return cache[django_name]
            except KeyError:
                pass
            result = cache[django_name] = self.django_to_passlib(django_name,
                                                                 cached=False)
            return result

        # check if it's an obviously-wrapped name
        if django_name.startswith(PASSLIB_WRAPPER_PREFIX):
            passlib_name = django_name[len(PASSLIB_WRAPPER_PREFIX):]
            return self._get_passlib_hasher(passlib_name)

        # resolve default
        if django_name == "default":
            context = self.context
            if context is None:
                raise TypeError("can't determine default scheme w/ context")
            return context.handler()

        # special case: Django uses a separate hasher for "sha1$$digest"
        # hashes (unsalted_sha1) and "sha1$salt$digest" (sha1);
        # but passlib uses "django_salted_sha1" for both of these.
        if django_name == "unsalted_sha1":
            django_name = "sha1"

        # resolve name
        # XXX: bother caching these lists / mapping?
        #      not needed in long-term due to cache above.
        context = self.context
        if context is None:
            # check registry
            # TODO: should make iteration via registry easier
            candidates = (registry.get_crypt_handler(passlib_name)
                          for passlib_name in registry.list_crypt_handlers()
                          if passlib_name.startswith(DJANGO_COMPAT_PREFIX)
                          or passlib_name in _other_django_hashes)
        else:
            # check context
            candidates = context.schemes(resolve=True)
        for handler in candidates:
            if getattr(handler, "django_name", None) == django_name:
                return handler

        # give up
        # NOTE: this should only happen for custom django hashers that we don't
        #       know the equivalents for. _HasherHandler (below) is work in
        #       progress that would allow us to at least return a wrapper.
        raise ValueError("can't translate django name to passlib name: %r" %
                         (django_name, ))