diff options
author | Eli Collins <elic@assurancetechnologies.com> | 2011-07-08 16:12:53 -0400 |
---|---|---|
committer | Eli Collins <elic@assurancetechnologies.com> | 2011-07-08 16:12:53 -0400 |
commit | 1cea29b9f5d957aca436031f770f9f27d505ae43 (patch) | |
tree | ea84595b809fae1b423bb3cb4bc393745ad6c1f8 | |
parent | 4475fba1e1f6b5fc22283fcf4011c17dcd2f85f8 (diff) | |
download | passlib-1cea29b9f5d957aca436031f770f9f27d505ae43.tar.gz |
stripped trailing whitespace from a bunch of files
31 files changed, 168 insertions, 168 deletions
@@ -65,7 +65,7 @@ The source file ``passlib/utils/des.py`` contains code derived from a pure-java implementation of the historic unix-crypt password hash algorithm. It is available under the following license:: - UnixCrypt.java 0.9 96/11/25 + UnixCrypt.java 0.9 96/11/25 Copyright (c) 1996 Aki Yoshida. All rights reserved. Permission to use, copy, modify and distribute this software for non-commercial or commercial purposes and without fee is diff --git a/docs/lib/passlib.apps.rst b/docs/lib/passlib.apps.rst index 1273094..b5da280 100644 --- a/docs/lib/passlib.apps.rst +++ b/docs/lib/passlib.apps.rst @@ -111,7 +111,7 @@ It is found in a wide range of PHP applications, including Drupal and Wordpress. BCrypt is used as the default if support is available, otherwise the Portable Hash will be used as the default. - + .. versionchanged:: 1.5 Now uses Portable Hash as fallback if BCrypt isn't available. Previously used BSDI-Crypt as fallback @@ -163,8 +163,8 @@ The following contexts are available for reading Roundup password hash fields: .. data:: roundup15_context Roundup 1.4.17 adds support for :class:`~passlib.hash.ldap_pbkdf2_sha1` - as it's preferred hash format. - This context supports all the :data:`roundup10_context` hashes, + as it's preferred hash format. + This context supports all the :data:`roundup10_context` hashes, but adds that hash as well (and uses it as the default). .. data:: roundup_context diff --git a/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst b/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst index d6edadb..a2a0a05 100644 --- a/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst +++ b/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst @@ -4,7 +4,7 @@ .. index:: pair: atlassian; pbkdf2 hash - + .. currentmodule:: passlib.hash This class provides an implementation of diff --git a/docs/lib/passlib.hash.cta_pbkdf2_sha1.rst b/docs/lib/passlib.hash.cta_pbkdf2_sha1.rst index 2814764..526c408 100644 --- a/docs/lib/passlib.hash.cta_pbkdf2_sha1.rst +++ b/docs/lib/passlib.hash.cta_pbkdf2_sha1.rst @@ -15,7 +15,7 @@ variable length salts, variable number of rounds. :doc:`passlib.hash.pbkdf2_digest <passlib.hash.pbkdf2_digest>` for some other PBKDF2-based hashes. - + :doc:`passlib.hash.dlitz_pbkdf2_sha1 <passlib.hash.dlitz_pbkdf2_sha1>` for another hash which looks almost exactly like this one. diff --git a/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst b/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst index 9967385..3151b23 100644 --- a/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst +++ b/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst @@ -15,7 +15,7 @@ variable length salts, variable number of rounds. :doc:`passlib.hash.pbkdf2_digest <passlib.hash.pbkdf2_digest>` for some other PBKDF2-based hashes. - + :doc:`passlib.hash.cta_pbkdf2_sha1 <passlib.hash.cta_pbkdf2_sha1>` for another hash which looks almost exactly like this one. diff --git a/docs/lib/passlib.hash.fshp.rst b/docs/lib/passlib.hash.fshp.rst index 69a8c4e..95f52fb 100644 --- a/docs/lib/passlib.hash.fshp.rst +++ b/docs/lib/passlib.hash.fshp.rst @@ -3,10 +3,10 @@ ========================================================== .. index:: fshp - + .. currentmodule:: passlib.hash -The Fairly Secure Hashed Password (FSHP) scheme [#home]_ +The Fairly Secure Hashed Password (FSHP) scheme [#home]_ is a cross-platform hash based on PBKDF1 [#pbk]_, and uses an LDAP-style hash format. It features a variable length salt, variable rounds, and support for cryptographic hashes from SHA-1 up to SHA-512. @@ -26,7 +26,7 @@ as well as a special digest keyword for selecting the variant of FSHP to use. This class can be used directly as follows:: >>> from passlib.hash import fshp - + >>> #generate new salt, encrypt password >>> h = fshp.encrypt("password") >>> h @@ -72,7 +72,7 @@ A example hash (of ``password``) is: * :samp:`<rounds>` is a decimal integer identifying the number of rounds to apply when calculating the checksum (see below). ``16384`` in the example. - + * :samp:`<data>` is a base64-encoded string which, when decoded, contains a salt string of the specified size, followed by the checksum. In the example, the data portion decodes to @@ -89,7 +89,7 @@ The checksum is calculated using :func:`~passlib.utils.pbkdf2.pbkdf1`, passing in the password, the decoded salt string, the number of rounds, and hash function specified by the variant identifier. FSHP has one quirk in that the password is passed in as the pbkdf1 salt, -and the salt is passed in as the pbkdf1 password. +and the salt is passed in as the pbkdf1 password. Security Issues =============== @@ -97,7 +97,7 @@ Security Issues from what is described in the PBKDF1 standard. This issue is mainly noted in order to dismiss it: while the swap permits an attacker to pre-calculate part of the initial digest, - the impact of this is negligible when a large number of rounds is used. + the impact of this is negligible when a large number of rounds is used. * Since PBKDF1 is based on repeated composition of a hash, it is vulnerable to any first-preimage attacks on the underlying hash. diff --git a/docs/lib/passlib.hash.oracle10.rst b/docs/lib/passlib.hash.oracle10.rst index 832082f..06941ff 100644 --- a/docs/lib/passlib.hash.oracle10.rst +++ b/docs/lib/passlib.hash.oracle10.rst @@ -112,7 +112,7 @@ References PassLib uses ``utf-16-be``, as this is both compatible with existing test vectors and supports unicode input. -.. [#flaws] Whitepaper analyzing flaws in this algorithm - +.. [#flaws] Whitepaper analyzing flaws in this algorithm - `<http://www.isg.rhul.ac.uk/~ccid/publications/oracle_passwd.pdf>`_. .. [#] Description of Oracle10g and Oracle11g algorithms - diff --git a/docs/lib/passlib.utils.handlers.rst b/docs/lib/passlib.utils.handlers.rst index 4670fe7..301448c 100644 --- a/docs/lib/passlib.utils.handlers.rst +++ b/docs/lib/passlib.utils.handlers.rst @@ -103,7 +103,7 @@ Some additional notes: For faster identification purposes, subclasses may fill in the :attr:`~GenericHandler.ident` attribute with the hash's identifying prefix, which :meth:`~GenericHandler.identify` will then test for instead of calling :meth:`~GenericHandler.from_string`. - For more complex situations, a custom implementation should be used; + For more complex situations, a custom implementation should be used; the :class:`HasManyIdents` mixin may also be helpful. * This class does not support context kwds of any type, diff --git a/docs/lib/passlib.utils.pbkdf2.rst b/docs/lib/passlib.utils.pbkdf2.rst index d4fb46e..7e7904d 100644 --- a/docs/lib/passlib.utils.pbkdf2.rst +++ b/docs/lib/passlib.utils.pbkdf2.rst @@ -27,6 +27,6 @@ Helper Functions ================ .. autofunction:: get_prf -.. +.. given how this module is expanding in scope, perhaps it should be renamed "kdf"? diff --git a/docs/modular_crypt_format.rst b/docs/modular_crypt_format.rst index b91ab51..da01d9c 100644 --- a/docs/modular_crypt_format.rst +++ b/docs/modular_crypt_format.rst @@ -123,7 +123,7 @@ Identifiers & Platform Support ============================== The following table lists of all the major MCF hashes supported by passlib, -and indicates which operating systems offer native support. +and indicates which operating systems offer native support. ==================================== ==================== =========== =========== =========== =========== ======= Scheme Prefix Linux FreeBSD NetBSD OpenBSD Solaris @@ -136,7 +136,7 @@ Scheme Prefix Linux FreeBSD :class:`~passlib.hash.nthash` ``$3$`` y :class:`~passlib.hash.sha256_crypt` ``$5$`` y y :class:`~passlib.hash.sha512_crypt` ``$6$`` y y -:class:`~passlib.hash.sha1_crypt` ``$sha1$`` y +:class:`~passlib.hash.sha1_crypt` ``$sha1$`` y ==================================== ==================== =========== =========== =========== =========== ======= The following table lists the other MCF hashes supported by passlib, @@ -159,4 +159,4 @@ Scheme Prefix Known Uses the same identifier. They can be distinguished by the fact that cta hashes will always end in ``=``, while dlitz hashes contain no ``=`` at all. -
\ No newline at end of file + diff --git a/docs/new_app_quickstart.rst b/docs/new_app_quickstart.rst index b86042f..622bfa8 100644 --- a/docs/new_app_quickstart.rst +++ b/docs/new_app_quickstart.rst @@ -53,14 +53,14 @@ All of these hashes share the following properties: * no known vulnerabilties. * based on documented & widely reviewed algorithms. - * basic architecture has been under heavy scrutiny and use for at least 10 years. + * basic architecture has been under heavy scrutiny and use for at least 10 years. * public-domain or BSD-licensed reference implementations available. * in use across a number of OSes and/or a wide variety of applications. * variable rounds for configuring flexible cpu cost on a per-hash basis. * at least 96 bits of salt. The following comparison should help you choose which hash is -most appropriate for your application. +most appropriate for your application. BCrypt ------ diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst index fe3b499..ae929b6 100644 --- a/docs/password_hash_api.rst +++ b/docs/password_hash_api.rst @@ -114,7 +114,7 @@ Required Attributes ``salt`` If present, this means the algorithm contains some number of bits of salt - which should vary with every new hash created. + which should vary with every new hash created. Additionally, this means :meth:`~PasswordHash.genconfig` and :meth:`~PasswordHash.encrypt` @@ -239,7 +239,7 @@ which scheme a hash belongs to when multiple schemes are in use. :func:`~PasswordHash.verify` or :func:`~PasswordHash.genhash`. Because of this, applications should rely on this method only for identification, not confirmation that a hash is correctly formed. - + .. classmethod:: PasswordHash.verify(secret, hash, \*\*context_kwds) verify a secret against an existing hash. @@ -453,7 +453,7 @@ the following attributes are usually exposed. string containing list of all characters which are allowed to be specified in salt parameter. for most hashes, this is equal to :data:`passlib.utils.h64.CHARS`. - + this must be a unicode string if the salt is encoded, or (rarely) bytes if the salt is unencoded raw bytes. @@ -497,7 +497,7 @@ For the application developer in a hurry: While they may be provided as :class:`bytes`, in that case it is strongly suggested they be encoded using ``utf-8`` or ``ascii``. - + * Passlib will always return hashes as native python strings. This means :class:`unicode` under Python 3, and ``ascii``-encoded :class:`bytes` under Python 2. @@ -525,23 +525,23 @@ the following issues: For handlers implementing such hashes, passwords provided as :class:`unicode` should be encoded to ``utf-8``, and passwords provided as :class:`bytes` should be treated as opaque. - + A few of these hashes officially specify this behavior; the rest have no preferred encoding at all, so this was chosen as a sensible standard behavior. Unless the underlying algorithm specifies an alternate policy, handlers should always encode unicode to ``utf-8``. - + * Because of the above behavior for :class:`unicode` inputs, applications which encode their passwords are urged to use ``utf-8`` or ``ascii``, so that hashes they generate with encoded bytes will verify correctly if/when they start using unicode. - + Applications which need to verify existing hashes using an alternate encoding such as ``latin-1`` - should be wary of this future "gotcha". - + should be wary of this future "gotcha". + * A few hashes operate on :class:`unicode` strings instead. For handlers implementing such hashes: passwords provided as :class:`unicode` should be handled as appropriate, @@ -568,7 +568,7 @@ by design requirements, and more by compatibility and ease of implementation issues: * Handlers should accept hashes as either :class:`unicode` or - as ``ascii``-encoded :class:`bytes`. + as ``ascii``-encoded :class:`bytes`. This behavior allows applications to provide hashes as unicode or as bytes, as they please; making @@ -587,12 +587,12 @@ and ease of implementation issues: * Handlers should return hashes as native python strings. This means :class:`unicode` under Python 3, and ``ascii``-encoded :class:`bytes` under Python 2. - + This behavior was chosen to fit with Python 3's unicode-oriented philosophy, while retaining backwards compatibility with Passlib 1.4 and earlier under Python 2. - + Handlers should use the :func:`passlib.utils.to_hash_str` function to coerce their unicode hashes to whatever is appropriate for the platform before returning them. diff --git a/passlib/apache.py b/passlib/apache.py index 55786e1..0069ef3 100644 --- a/passlib/apache.py +++ b/passlib/apache.py @@ -83,7 +83,7 @@ class _CommonFile(object): entry_map = self._entry_map = {} for line in lines: #XXX: found mention that "#" comment lines may be supported by htpasswd, - # should verify this. + # should verify this. key, value = pl(line) if key in entry_map: #XXX: should we use data from first entry, or last entry? @@ -155,7 +155,7 @@ class _CommonFile(object): def _encode_ident(self, ident, errname="user/realm"): "ensure identifier is bytes encoded using specified encoding, or rejected" - encoding = self.encoding + encoding = self.encoding if encoding: if isinstance(ident, unicode): return ident.encode(encoding) @@ -179,7 +179,7 @@ class _CommonFile(object): #FIXME: htpasswd doc sez passwords limited to 255 chars under Windows & MPE, # longer ones are truncated. may be side-effect of those platforms # supporting plaintext. we don't currently check for this. - + #========================================================= #htpasswd editing #========================================================= @@ -217,29 +217,29 @@ class HtpasswdFile(_CommonFile): if set to ``None``, user names must be specified as bytes, and will be returned as bytes. - + if set to an encoding, user names must be specified as unicode, and will be returned as unicode. when stored, then will use the specified encoding. - + for backwards compatibility with passlib 1.4, this defaults to ``None`` under Python 2, and ``utf-8`` under Python 3. - + .. note:: this is not the encoding for the entire file, just for the usernames within the file. this must be an encoding which is compatible - with 7-bit ascii (which is used by rest of file). + with 7-bit ascii (which is used by rest of file). :param context: :class:`~passlib.context.CryptContext` instance used to handle hashes in this file. - + .. warning:: - + this should usually be left at the default, though it can be overridden to implement non-standard hashes within the htpasswd file. @@ -280,7 +280,7 @@ class HtpasswdFile(_CommonFile): def _render_line(self, user, hash): return render_bytes("%s:%s\n", user, hash) - + def users(self): "return list of all users in file" return map(self._decode_ident, self._entry_order) @@ -335,16 +335,16 @@ class HtdigestFile(_CommonFile): :param encoding: optionally specify encoding used for usernames / realms. - + if set to ``None``, user names & realms must be specified as bytes, and will be returned as bytes. - + if set to an encoding, user names & realms must be specified as unicode, and will be returned as unicode. when stored, then will use the specified encoding. - + for backwards compatibility with passlib 1.4, this defaults to ``None`` under Python 2, and ``utf-8`` under Python 3. @@ -354,7 +354,7 @@ class HtdigestFile(_CommonFile): this is not the encoding for the entire file, just for the usernames & realms within the file. this must be an encoding which is compatible - with 7-bit ascii (which is used by rest of file). + with 7-bit ascii (which is used by rest of file). Loading & Saving ================ @@ -389,16 +389,16 @@ class HtdigestFile(_CommonFile): # until it causes problems - in which case stopgap of setting this attr # per-instance can be used. password_encoding = "utf-8" - - #XXX: provide rename() & rename_realm() ? - + + #XXX: provide rename() & rename_realm() ? + def _parse_line(self, line): user, realm, hash = line.rstrip().split(BCOLON) return (user, realm), hash def _render_line(self, key, hash): return render_bytes("%s:%s:%s\n", key[0], key[1], hash) - + #TODO: would frontend to calc_digest be useful? ##def encrypt(self, password, user, realm): ## user = self._norm_user(user) @@ -463,7 +463,7 @@ class HtdigestFile(_CommonFile): def find(self, user, realm): """return digest hash for specified user+realm; returns ``None`` if not found - + :returns: htdigest hash or None :rtype: bytes or None """ @@ -474,7 +474,7 @@ class HtdigestFile(_CommonFile): #decode hash if in unicode mode hash = hash.decode("ascii") return hash - + def verify(self, user, realm, password): """verify password for specified user + realm. diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py index 5ced795..a363ab6 100644 --- a/passlib/handlers/bcrypt.py +++ b/passlib/handlers/bcrypt.py @@ -135,7 +135,7 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. @classproperty def _has_backend_bcryptor(cls): return bcryptor_engine is not None - + @classproperty def _has_backend_os_crypt(cls): return ( @@ -181,11 +181,11 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. # returns ascii bytes # py3: can't get to install if isinstance(secret, unicode): - secret = secret.encode("utf-8") + secret = secret.encode("utf-8") hash = bcryptor_engine(False).hash_key(secret, self.to_string(native=False)) return hash[-31:].decode("ascii") - + #========================================================= #eoc #========================================================= diff --git a/passlib/handlers/fshp.py b/passlib/handlers/fshp.py index 91e064a..edf58e1 100644 --- a/passlib/handlers/fshp.py +++ b/passlib/handlers/fshp.py @@ -31,7 +31,7 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): :param salt: Optional raw salt string. If not specified, one will be autogenerated (this is recommended). - + :param salt_size: Optional number of bytes to use when autogenerating new salts. Defaults to 16 bytes, but can be any non-negative value. @@ -39,15 +39,15 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): :param rounds: Optional number of rounds to use. Defaults to 40000, must be between 1 and 4294967295, inclusive. - + :param variant: Optionally specifies variant of FSHP to use. - + * ``0`` - uses SHA-1 digest (deprecated) * ``1`` - uses SHA-2/256 digest (default) * ``2`` - uses SHA-2/384 digest * ``3`` - uses SHA-2/512 digest - + Aliases ``sha1``, ``sha256`` etc are also allowed. """ @@ -88,7 +88,7 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): #instance attrs #========================================================= variant = None - + #========================================================= #init #========================================================= @@ -124,17 +124,17 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): @property def _info(self): return self._variant_info[self.variant] - + #========================================================= #formatting #========================================================= - + @classmethod def identify(cls, hash): - return uh.identify_prefix(hash, u"{FSHP") + return uh.identify_prefix(hash, u"{FSHP") _fshp_re = re.compile(ur"^\{FSHP(\d+)\|(\d+)\|(\d+)\}([a-zA-Z0-9+/]+={0,3})$") - + @classmethod def from_string(cls, hash): if not hash: diff --git a/passlib/handlers/ldap_digests.py b/passlib/handlers/ldap_digests.py index 2a7d826..148e288 100644 --- a/passlib/handlers/ldap_digests.py +++ b/passlib/handlers/ldap_digests.py @@ -90,10 +90,10 @@ class _SaltedBase64DigestHelper(uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHand return cls(checksum=chk, salt=salt, strict=True) def to_string(self): - data = (self.checksum or self._stub_checksum) + self.salt + data = (self.checksum or self._stub_checksum) + self.salt hash = self.ident + b64encode(data).decode("ascii") return to_hash_str(hash) - + def calc_checksum(self, secret): if secret is None: raise TypeError("no secret provided") diff --git a/passlib/handlers/md5_crypt.py b/passlib/handlers/md5_crypt.py index 74968c2..585d478 100644 --- a/passlib/handlers/md5_crypt.py +++ b/passlib/handlers/md5_crypt.py @@ -27,17 +27,17 @@ B_APR_MAGIC = b("$apr1$") def raw_md5_crypt(secret, salt, apr=False): """perform raw md5-crypt calculation - + :arg secret: password, bytes or unicode (encoded to utf-8) - + :arg salt: salt portion of hash, bytes or unicode (encoded to ascii), clipped to max 8 bytes. - + :param apr: flag to use apache variant - + :returns: encoded checksum as unicode """ @@ -216,13 +216,13 @@ class md5_crypt(uh.HasManyBackends, _Md5Common): #========================================================= name = "md5_crypt" ident = u"$1$" - + #========================================================= #primary interface #========================================================= #FIXME: can't find definitive policy on how md5-crypt handles non-ascii. # all backends currently coerce -> utf-8 - + backends = ("os_crypt", "builtin") _has_backend_builtin = True diff --git a/passlib/handlers/misc.py b/passlib/handlers/misc.py index 7357adf..80910af 100644 --- a/passlib/handlers/misc.py +++ b/passlib/handlers/misc.py @@ -61,7 +61,7 @@ class plaintext(uh.StaticHandler): Unicode passwords will be encoded using utf-8. """ name = "plaintext" - + @classmethod def identify(cls, hash): return hash is not None diff --git a/passlib/handlers/nthash.py b/passlib/handlers/nthash.py index f761305..e8e65a4 100644 --- a/passlib/handlers/nthash.py +++ b/passlib/handlers/nthash.py @@ -80,7 +80,7 @@ class nthash(uh.HasManyIdents, uh.GenericHandler): @staticmethod def raw_nthash(secret, hex=False): """encode password using md4-based NTHASH algorithm - + :returns: returns string of raw bytes if ``hex=False``, returns digest as hexidecimal unicode if ``hex=True``. diff --git a/passlib/handlers/sha2_crypt.py b/passlib/handlers/sha2_crypt.py index 914d955..80308a4 100644 --- a/passlib/handlers/sha2_crypt.py +++ b/passlib/handlers/sha2_crypt.py @@ -335,7 +335,7 @@ class sha256_crypt(uh.HasManyBackends, uh.HasRounds, uh.HasSalt, uh.GenericHandl def _calc_checksum_builtin(self, secret): if isinstance(secret, unicode): - secret = secret.encode("utf-8") + secret = secret.encode("utf-8") checksum, salt, rounds = raw_sha256_crypt(secret, self.salt.encode("ascii"), self.rounds) diff --git a/passlib/tests/test_apache.py b/passlib/tests/test_apache.py index 6fce388..984d2b7 100644 --- a/passlib/tests/test_apache.py +++ b/passlib/tests/test_apache.py @@ -40,7 +40,7 @@ def backdate_file_mtime(path, offset=10): class HtpasswdFileTest(TestCase): "test HtpasswdFile class" case_prefix = "HtpasswdFile" - + sample_01 = b('user2:2CHkkwa2AtqGs\nuser3:{SHA}3ipNV1GrBtxPmHFC21fCbVCSXIo=\nuser4:pass4\nuser1:$apr1$t4tc7jTh$GPIWVUo8sQKJlUdV8V5vu0\n') sample_02 = b('user3:{SHA}3ipNV1GrBtxPmHFC21fCbVCSXIo=\nuser4:pass4\n') sample_03 = b('user2:pass2x\nuser3:{SHA}3ipNV1GrBtxPmHFC21fCbVCSXIo=\nuser4:pass4\nuser1:$apr1$t4tc7jTh$GPIWVUo8sQKJlUdV8V5vu0\nuser5:pass5\n') @@ -152,7 +152,7 @@ class HtpasswdFileTest(TestCase): set_file(path, self.sample_dup) hc = apache.HtpasswdFile(path) self.assert_(hc.verify('user1','pass1')) - + def test_06_save(self): "test save()" #load from file @@ -182,11 +182,11 @@ class HtpasswdFileTest(TestCase): #check users() returns native string by default ht = apache.HtpasswdFile(path) self.assertIsInstance(ht.users()[0], native_str) - + #check returns unicode if encoding explicitly set ht = apache.HtpasswdFile(path, encoding="utf-8") self.assertIsInstance(ht.users()[0], unicode) - + #check returns bytes if encoding explicitly disabled ht = apache.HtpasswdFile(path, encoding=None) self.assertIsInstance(ht.users()[0], bytes) @@ -371,12 +371,12 @@ class HtdigestFileTest(TestCase): ht = apache.HtdigestFile(path) self.assertIsInstance(ht.realms()[0], native_str) self.assertIsInstance(ht.users("realm")[0], native_str) - + #check returns unicode if encoding explicitly set ht = apache.HtdigestFile(path, encoding="utf-8") self.assertIsInstance(ht.realms()[0], unicode) self.assertIsInstance(ht.users(u"realm")[0], unicode) - + #check returns bytes if encoding explicitly disabled ht = apache.HtdigestFile(path, encoding=None) self.assertIsInstance(ht.realms()[0], bytes) diff --git a/passlib/tests/test_context.py b/passlib/tests/test_context.py index 68afcbe..42f42c4 100644 --- a/passlib/tests/test_context.py +++ b/passlib/tests/test_context.py @@ -207,7 +207,7 @@ admin.sha512_crypt.max_rounds = 40000 policy = CryptPolicy.from_string(self.sample_config_4s) self.assertEquals(policy.to_dict(), self.sample_config_4pd) - + #test with custom encoding uc2 = to_bytes(self.sample_config_1s, "utf-16", source_encoding="utf-8") policy = CryptPolicy.from_string(uc2, encoding="utf-16") diff --git a/passlib/tests/test_utils.py b/passlib/tests/test_utils.py index 8a9d1bb..e432ee1 100644 --- a/passlib/tests/test_utils.py +++ b/passlib/tests/test_utils.py @@ -84,7 +84,7 @@ class MiscTest(TestCase): self.assertNotEqual(x,y) #NOTE: decoding this due to py3 bytes self.assertEqual(sorted(set(x.decode("ascii"))), [u'a',u'b',u'c']) - + #generate_password self.assertEqual(len(utils.generate_password(15)), 15) @@ -110,7 +110,7 @@ class MiscTest(TestCase): "test safe_os_crypt() wrapper" if not safe_os_crypt: raise self.SkipTest("stdlib crypt module not available") - + #NOTE: this is assuming EVERY crypt will support des_crypt. # if this fails on some platform, this test will need modifying. @@ -119,18 +119,18 @@ class MiscTest(TestCase): self.assertTrue(ok) self.assertIsInstance(hash, unicode) self.assertEqual(hash, u'aaqPiZY5xR5l.') - + #test hash-as-bytes self.assertRaises(TypeError, safe_os_crypt, u'test', b('aa')) - + #test password as ascii ret = safe_os_crypt(b('test'), u'aa') self.assertEqual(ret, (True, u'aaqPiZY5xR5l.')) - + #test unicode password w/ high char ret = safe_os_crypt(u'test\u1234', u'aa') self.assertEqual(ret, (True, u'aahWwbrUsKZk.')) - + #test utf-8 password w/ high char ret = safe_os_crypt(b('test\xe1\x88\xb4'), u'aa') self.assertEqual(ret, (True, u'aahWwbrUsKZk.')) @@ -148,7 +148,7 @@ class MiscTest(TestCase): #========================================================= class CodecTest(TestCase): "tests bytes/unicode helpers in passlib.utils" - + def test_bytes(self): "test b() helper, bytes and native_str types" # Py2k # @@ -166,14 +166,14 @@ class CodecTest(TestCase): # Py3k # #self.assertEqual(b('\x00\xff'), b"\x00\xff") # end Py3k # - + def test_to_bytes(self): "test to_bytes()" - + #check unicode inputs self.assertEqual(to_bytes(u'abc'), b('abc')) self.assertEqual(to_bytes(u'\x00\xff'), b('\x00\xc3\xbf')) - + #check unicode w/ encodings self.assertEqual(to_bytes(u'\x00\xff', 'latin-1'), b('\x00\xff')) self.assertRaises(ValueError, to_bytes, u'\x00\xff', 'ascii') @@ -186,28 +186,28 @@ class CodecTest(TestCase): #check byte inputs ignores enocding self.assertEqual(to_bytes(b('\x00\xc3\xbf'), "latin-1"), - b('\x00\xc3\xbf')) + b('\x00\xc3\xbf')) self.assertEqual(to_bytes(b('\x00\xc3\xbf'), None, "utf-8"), b('\x00\xc3\xbf')) - + #check bytes transcoding self.assertEqual(to_bytes(b('\x00\xc3\xbf'), "latin-1", "utf-8"), b('\x00\xff')) - + #check other self.assertRaises(TypeError, to_bytes, None) def test_to_unicode(self): "test to_unicode()" - + #check unicode inputs self.assertEqual(to_unicode(u'abc'), u'abc') self.assertEqual(to_unicode(u'\x00\xff'), u'\x00\xff') - + #check unicode input ignores encoding self.assertEqual(to_unicode(u'\x00\xff', None), u'\x00\xff') self.assertEqual(to_unicode(u'\x00\xff', "ascii"), u'\x00\xff') - + #check bytes input self.assertEqual(to_unicode(b('abc')), u'abc') self.assertEqual(to_unicode(b('\x00\xc3\xbf')), u'\x00\xff') @@ -215,13 +215,13 @@ class CodecTest(TestCase): u'\x00\xff') self.assertRaises(ValueError, to_unicode, b('\x00\xff')) self.assertRaises(TypeError, to_unicode, b('\x00\xff'), None) - + #check other self.assertRaises(TypeError, to_unicode, None) - + def test_to_native_str(self): "test to_native_str()" - + self.assertEqual(to_native_str(u'abc'), 'abc') self.assertEqual(to_native_str(b('abc')), 'abc') self.assertRaises(TypeError, to_native_str, None) @@ -233,7 +233,7 @@ class CodecTest(TestCase): b('\x00\xff')) self.assertEqual(to_native_str(b('\x00\xff'), 'latin-1'), b('\x00\xff')) - + # Py3k # #self.assertEqual(to_native_str(u'\x00\xff'), '\x00\xff') #self.assertEqual(to_native_str(b('\x00\xc3\xbf')), '\x00\xff') @@ -243,31 +243,31 @@ class CodecTest(TestCase): # '\x00\xff') # # end Py3k # - + #TODO: test to_hash_str() - + def test_is_ascii_safe(self): - "test is_ascii_safe()" + "test is_ascii_safe()" self.assertTrue(is_ascii_safe(b("\x00abc\x7f"))) self.assertTrue(is_ascii_safe(u"\x00abc\x7f")) self.assertFalse(is_ascii_safe(b("\x00abc\x80"))) self.assertFalse(is_ascii_safe(u"\x00abc\x80")) - - + + def test_is_same_codec(self): "test is_same_codec()" self.assertTrue(is_same_codec(None, None)) self.assertFalse(is_same_codec(None, 'ascii')) - + self.assertTrue(is_same_codec("ascii", "ascii")) self.assertTrue(is_same_codec("ascii", "ASCII")) - + self.assertTrue(is_same_codec("utf-8", "utf-8")) self.assertTrue(is_same_codec("utf-8", "utf8")) self.assertTrue(is_same_codec("utf-8", "UTF_8")) self.assertFalse(is_same_codec("ascii", "utf-8")) - + #========================================================= #test des module #========================================================= @@ -489,9 +489,9 @@ class MD4_Test(TestCase): "test md4 update" h = md4(b('')) self.assertEqual(h.hexdigest(), "31d6cfe0d16ae931b73c59d7e0c089c0") - + #NOTE: under py2, hashlib methods try to encode to ascii, - # though shouldn't rely on that. + # though shouldn't rely on that. # Py3k # #self.assertRaises(TypeError, h.update, u'x') # end Py3k # @@ -536,7 +536,7 @@ from passlib.utils import pbkdf2 class KdfTest(TestCase): "test kdf helpers" - + def test_pbkdf1(self): "test pbkdf1" for secret, salt, rounds, klen, hash, correct in [ @@ -546,7 +546,7 @@ class KdfTest(TestCase): ]: result = pbkdf2.pbkdf1(secret, salt, rounds, klen, hash) self.assertEqual(result, correct) - + #test rounds < 1 #test klen < 0 #test klen > block size diff --git a/passlib/tests/test_win32.py b/passlib/tests/test_win32.py index 8508c2e..524fda6 100644 --- a/passlib/tests/test_win32.py +++ b/passlib/tests/test_win32.py @@ -25,8 +25,8 @@ class UtilTest(TestCase): ("NEWPASSWORD", u'09eeab5aa415d6e4d408e6b105741864'), ("welcome", u"c23413a8a1e7665faad3b435b51404ee"), ]: - result = mod.raw_lmhash(secret, hex=True) - self.assertEquals(result, hash) + result = mod.raw_lmhash(secret, hex=True) + self.assertEquals(result, hash) def test_nthash(self): for secret, hash in [ diff --git a/passlib/utils/__init__.py b/passlib/utils/__init__.py index ffbc60f..6fe4fa9 100644 --- a/passlib/utils/__init__.py +++ b/passlib/utils/__init__.py @@ -131,7 +131,7 @@ native_str = bytes # if py25 compat were sacrificed, this func could be removed. def b(source): "convert native str to bytes (noop under py2; uses latin-1 under py3)" - #assert isinstance(source, native_str) + #assert isinstance(source, native_str) # Py2k # return source # Py3k # @@ -147,23 +147,23 @@ try: from crypt import crypt as os_crypt except ImportError: #pragma: no cover safe_os_crypt = os_crypt = None -else: +else: def safe_os_crypt(secret, hash): """wrapper around stdlib's crypt. - + Python 3's crypt behaves slightly differently from Python 2's crypt. for one, it takes in and returns unicode. - internally, it converts to utf-8 before hashing. + internally, it converts to utf-8 before hashing. Annoyingly, *there is no way to call it using bytes*. thus, it can't be used to hash non-ascii passwords using any encoding but utf-8 (eg, using latin-1). - + This wrapper attempts to gloss over all those issues: Under Python 2, it accept passwords as unicode or bytes, accepts hashes only as unicode, and always returns unicode. Under Python 3, it will signal that it cannot hash a password if provided as non-utf-8 bytes, but otherwise behave the same as crypt. - + :arg secret: password as bytes or unicode :arg hash: hash/salt as unicode :returns: @@ -171,8 +171,8 @@ else: or ``(True, result: unicode)`` otherwise. """ #XXX: source indicates crypt() may return None on some systems - # if an error occurrs - could make this return False in that case. - + # if an error occurrs - could make this return False in that case. + # Py2k # #NOTE: this guard logic is designed purely to match py3 behavior, # with the exception that it accepts secret as bytes @@ -183,7 +183,7 @@ else: else: hash = hash.encode("utf-8") return True, os_crypt(secret, hash).decode("ascii") - + # Py3k # #if isinstance(secret, bytes): # #decode to utf-8. if successful, will be reencoded with os_crypt, @@ -301,15 +301,15 @@ def has_salt_info(handler): def to_bytes(source, encoding="utf-8", source_encoding=None, errname="value"): """helper to encoding unicode -> bytes - + this function takes in a ``source`` string. - if unicode, encodes it using the specified ``encoding``. + if unicode, encodes it using the specified ``encoding``. if bytes, returns unchanged - unless ``source_encoding`` is specified, in which case the bytes are transcoded if and only if the source encoding doesn't match the desired encoding. all other types result in a :exc:`TypeError`. - + :arg source: source bytes/unicode to process :arg encoding: target character encoding or ``None``. :param source_encoding: optional source encoding @@ -317,11 +317,11 @@ def to_bytes(source, encoding="utf-8", source_encoding=None, errname="value"): :raises TypeError: if unicode encountered but ``encoding=None`` specified; or if source is not unicode or bytes. - + :returns: bytes object - + .. note:: - + if ``encoding`` is set to ``None``, then unicode strings will be rejected, and only byte strings will be allowed through. """ @@ -332,7 +332,7 @@ def to_bytes(source, encoding="utf-8", source_encoding=None, errname="value"): else: return source elif not encoding: - raise TypeError("%s must be bytes, not %s" % (errname, type(source))) + raise TypeError("%s must be bytes, not %s" % (errname, type(source))) elif isinstance(source, unicode): return source.encode(encoding) elif source_encoding: @@ -340,15 +340,15 @@ def to_bytes(source, encoding="utf-8", source_encoding=None, errname="value"): (errname, source_encoding, type(source))) else: raise TypeError("%s must be unicode or bytes, not %s" % (errname, type(source))) - + def to_unicode(source, source_encoding="utf-8", errname="value"): """take in unicode or bytes, return unicode - + if bytes provided, decodes using specified encoding. leaves unicode alone. - + :raises TypeError: if source is not unicode or bytes. - + :arg source: source bytes/unicode to process :arg source_encoding: encoding to use when decoding bytes instances :param errname: optional name of variable/noun to reference when raising errors @@ -367,12 +367,12 @@ def to_unicode(source, source_encoding="utf-8", errname="value"): def to_native_str(source, encoding="utf-8", errname="value"): """take in unicode or bytes, return native string - + python 2: encodes unicode using specified encoding, leaves bytes alone. python 3: decodes bytes using specified encoding, leaves unicode alone. - + :raises TypeError: if source is not unicode or bytes. - + :arg source: source bytes/unicode to process :arg encoding: encoding to use when encoding unicode / decoding bytes :param errname: optional name of variable/noun to reference when raising errors @@ -386,7 +386,7 @@ def to_native_str(source, encoding="utf-8", errname="value"): # Py3k # #return source.decode(encoding) # end Py3k # - + elif isinstance(source, unicode): # Py2k # return source.encode(encoding) @@ -452,13 +452,13 @@ ujoin = u''.join def belem_join(elems): """takes series of bytes elements, returns bytes. - + elem should be result of bytes[x]. this is another bytes instance under py2, but it int under py3. - + returns bytes. - + this is bytes() constructor under py3, but b"".join() under py2. """ @@ -477,13 +477,13 @@ belem_join = bjoin def bord(elem): """takes bytes element, returns integer. - + elem should be result of bytes[x]. this is another bytes instance under py2, but it int under py3. - + returns int in range(0,256). - + this is ord() under py2, and noop under py3. """ # Py2k # @@ -516,12 +516,12 @@ def bjoin_ints(values): def render_bytes(source, *args): """helper for using formatting operator with bytes. - + this function is motivated by the fact that :class:`bytes` instances do not support % or {} formatting under python 3. this function is an attempt to provide a replacement that will work uniformly under python 2 & 3. - + it converts everything to unicode (including bytes arguments), then encodes the result to latin-1. """ @@ -740,7 +740,7 @@ def getrandstr(rng, charset, count): yield charset[value % letters] value //= letters i += 1 - + if isinstance(charset, unicode): return ujoin(helper()) else: diff --git a/passlib/utils/des.py b/passlib/utils/des.py index 88b591d..805a265 100644 --- a/passlib/utils/des.py +++ b/passlib/utils/des.py @@ -7,7 +7,7 @@ found at `<http://www.dynamic.net.au/christos/crypt/UnixCrypt2.txt>`_. The copyright & license for that source is as follows:: - UnixCrypt.java 0.9 96/11/25 + UnixCrypt.java 0.9 96/11/25 Copyright (c) 1996 Aki Yoshida. All rights reserved. Permission to use, copy, modify and distribute this software for non-commercial or commercial purposes and without fee is @@ -17,8 +17,8 @@ The copyright & license for that source is as follows:: --- Unix crypt(3C) utility - @version 0.9, 11/25/96 - @author Aki Yoshida + @version 0.9, 11/25/96 + @author Aki Yoshida --- @@ -575,7 +575,7 @@ def expand_des_key(key): "convert 7 byte des key to 8 byte des key (by adding parity bit every 7 bits)" if not isinstance(key, bytes): raise TypeError("key must be bytes, not %s" % (type(key),)) - + #NOTE: could probably do this much more cleverly and efficiently, # but no need really given it's use. @@ -605,10 +605,10 @@ def expand_des_key(key): def des_encrypt_block(key, input): """do traditional encryption of a single DES block - :arg key: 8 byte des key + :arg key: 8 byte des key :arg input: 8 byte plaintext :returns: 8 byte ciphertext - + all values must be :class:`bytes` """ if not isinstance(key, bytes): diff --git a/passlib/utils/handlers.py b/passlib/utils/handlers.py index 8d23200..9c5176b 100644 --- a/passlib/utils/handlers.py +++ b/passlib/utils/handlers.py @@ -70,7 +70,7 @@ def identify_prefix(hash, prefix): hash = hash.decode("ascii") except UnicodeDecodeError: return False - return hash.startswith(prefix) + return hash.startswith(prefix) #========================================================= #parsing helpers @@ -224,7 +224,7 @@ class StaticHandler(object): hash = cls._norm_hash(hash) result = cls.genhash(secret, hash, *cargs, **context) return cls._norm_hash(result) == hash - + @classmethod def _norm_hash(cls, hash): """[helper for verify] normalize hash for comparsion purposes""" @@ -273,7 +273,7 @@ class GenericHandler(object): If this attribute is filled in, the default :meth:`identify` method will use it as a identifying prefix that can be used to recognize instances of this handler's hash. Filling this out is recommended for speed. - + This should be a unicode str. .. attribute:: checksum_size @@ -389,9 +389,9 @@ class GenericHandler(object): @classmethod def from_string(cls, hash): #pragma: no cover """return parsed instance from hash/configuration string - + :raises ValueError: if hash is incorrectly formatted - + :returns: hash parsed into components, for formatting / calculating checksum. @@ -400,12 +400,12 @@ class GenericHandler(object): def to_string(self): #pragma: no cover """render instance to hash or configuration string - + :returns: if :attr:`checksum` is set, should return full hash string. if not, should either return abbreviated configuration string, or fill in a stub checksum. - + should return native string type (ascii-bytes under python 2, unicode under python 3) """ diff --git a/passlib/utils/md4.py b/passlib/utils/md4.py index 40a48e4..0e70f1e 100644 --- a/passlib/utils/md4.py +++ b/passlib/utils/md4.py @@ -224,7 +224,7 @@ class md4(object): def hexdigest(self): return to_native_str(hexlify(self.digest()), "latin-1") - + #========================================================================= #eoc #========================================================================= diff --git a/passlib/win32.py b/passlib/win32.py index 21191b1..4ba694c 100644 --- a/passlib/win32.py +++ b/passlib/win32.py @@ -49,7 +49,7 @@ def raw_lmhash(secret, encoding="ascii", hex=False): # for it's encoding. until a clear reference is found, # as well as a path for getting the encoding, # letting this default to "ascii" to prevent incorrect hashes - # from being made w/o user explicitly choosing an encoding. + # from being made w/o user explicitly choosing an encoding. if isinstance(secret, unicode): secret = secret.encode(encoding) ns = secret.upper()[:14] + b("\x00") * (14-len(secret)) @@ -1,7 +1,7 @@ [egg_info] # XXX: should stop relying on this section, # it's only used by setuptools/distribute, -# and will be phased out in distutils2 +# and will be phased out in distutils2 tag_build = a1.dev tag_date = true @@ -29,7 +29,7 @@ if py3k: #monkeypatch preprocessor into lib2to3 from passlib.setup.cond2to3 import patch2to3 patch2to3() - + #enable 2to3 translation in build_py if has_distribute: opts['use_2to3'] = True @@ -61,7 +61,7 @@ to providing full-strength password hashing for multi-user application. for details, installation instructions, and examples. * See the `passlib homepage <http://passlib.googlecode.com>`_ - for the latest news, more information, and additional downloads. + for the latest news, more information, and additional downloads. * See the `changelog <http://packages.python.org/passlib/history.html>`_ for description of what's new in Passlib. |