From a8fda1aedf1e79361bb167afbfe6134a59b600f5 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Wed, 18 May 2016 22:41:05 +0200 Subject: [PATCH] Cut long lines --- radicale/__init__.py | 3 ++- radicale/auth.py | 42 +++++++++++++++++++++++------------------- radicale/xmlutils.py | 15 +++++++++------ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index 6aecd9c..35ab75d 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -482,7 +482,8 @@ class Application: "DAV": "1, 2, 3, calendar-access, addressbook, extended-mkcol", "Content-Type": "text/xml"} answer = xmlutils.propfind( - environ["PATH_INFO"], content, read_collections, write_collections, user) + environ["PATH_INFO"], content, read_collections, write_collections, + user) return client.MULTI_STATUS, headers, answer def do_PROPPATCH(self, environ, read_collections, write_collections, diff --git a/radicale/auth.py b/radicale/auth.py index 4e0aa7a..00f3eb4 100644 --- a/radicale/auth.py +++ b/radicale/auth.py @@ -21,12 +21,13 @@ Authentication management. Default is htpasswd authentication. -Apache's htpasswd command (httpd.apache.org/docs/programs/htpasswd.html) manages -a file for storing user credentials. It can encrypt passwords using different -methods, e.g. BCRYPT, MD5-APR1 (a version of MD5 modified for Apache), SHA1, or -by using the system's CRYPT routine. The CRYPT and SHA1 encryption methods -implemented by htpasswd are considered as insecure. MD5-APR1 provides medium -security as of 2015. Only BCRYPT can be considered secure by current standards. +Apache's htpasswd command (httpd.apache.org/docs/programs/htpasswd.html) +manages a file for storing user credentials. It can encrypt passwords using +different methods, e.g. BCRYPT, MD5-APR1 (a version of MD5 modified for +Apache), SHA1, or by using the system's CRYPT routine. The CRYPT and SHA1 +encryption methods implemented by htpasswd are considered as insecure. MD5-APR1 +provides medium security as of 2015. Only BCRYPT can be considered secure by +current standards. MD5-APR1-encrypted credentials can be written by all versions of htpasswd (it is the default, in fact), whereas BCRYPT requires htpasswd 2.4.x or newer. @@ -80,9 +81,9 @@ class BaseAuth: def is_authenticated(self, user, password): """Validate credentials. - Iterate through htpasswd credential file until user matches, extract hash - (encrypted password) and check hash against user-given password, using the - method specified in the Radicale config. + Iterate through htpasswd credential file until user matches, extract + hash (encrypted password) and check hash against user-given password, + using the method specified in the Radicale config. """ raise NotImplementedError @@ -135,30 +136,33 @@ class Auth(BaseAuth): "supported." % self.encryption) def _plain(self, hash_value, password): - """Check if ``hash_value`` and ``password`` match, using plain method.""" + """Check if ``hash_value`` and ``password`` match, plain method.""" return hash_value == password def _crypt(self, crypt, hash_value, password): - """Check if ``hash_value`` and ``password`` match, using crypt method.""" + """Check if ``hash_value`` and ``password`` match, crypt method.""" return crypt.crypt(password, hash_value) == hash_value def _sha1(self, hash_value, password): - """Check if ``hash_value`` and ``password`` match, using sha1 method.""" + """Check if ``hash_value`` and ``password`` match, sha1 method.""" hash_value = hash_value.replace("{SHA}", "").encode("ascii") password = password.encode(self.configuration.get("encoding", "stock")) sha1 = hashlib.sha1() # pylint: disable=E1101 sha1.update(password) return sha1.digest() == base64.b64decode(hash_value) - def _ssha(self, hash_salt_value, password): - """Check if ``hash_salt_value`` and ``password`` match, using salted sha1 - method. This method is not directly supported by htpasswd, but it can be - written with e.g. openssl, and nginx can parse it.""" - hash_salt_value = hash_salt_value.replace( + def _ssha(self, hash_value, password): + """Check if ``hash_value`` and ``password`` match, salted sha1 method. + + This method is not directly supported by htpasswd, but it can be + written with e.g. openssl, and nginx can parse it. + + """ + hash_value = hash_value.replace( "{SSHA}", "").encode("ascii").decode('base64') password = password.encode(self.configuration.get("encoding", "stock")) - hash_value = hash_salt_value[:20] - salt_value = hash_salt_value[20:] + hash_value = hash_value[:20] + salt_value = hash_value[20:] sha1 = hashlib.sha1() # pylint: disable=E1101 sha1.update(password) sha1.update(salt_value) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 0c42d72..bd07b2e 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -181,9 +181,9 @@ def _prop_match(item, filter_): filter_.remove(filter_[0]) elif filter_[0].tag == _tag("C", "text-match"): # Point #4 of rfc4791-9.7.2 - # TODO: collations are not supported, but the default ones needed for DAV - # servers are actually pretty useless. Texts are lowered to be - # case-insensitive, almost as the "i;ascii-casemap" value. + # TODO: collations are not supported, but the default ones needed + # for DAV servers are actually pretty useless. Texts are lowered to + # be case-insensitive, almost as the "i;ascii-casemap" value. match = next(filter_[0].itertext()).lower() value = vobject_item.getChildValue(filter_.get("name").lower()) if value is None: @@ -296,7 +296,8 @@ def delete(path, collection): return _pretty_xml(multistatus) -def propfind(path, xml_request, read_collections, write_collections, user=None): +def propfind(path, xml_request, read_collections, write_collections, + user=None): """Read and answer PROPFIND requests. Read rfc4918-9.1 for info. @@ -324,12 +325,14 @@ def propfind(path, xml_request, read_collections, write_collections, user=None): collections = [] for collection in write_collections: collections.append(collection) - response = _propfind_response(path, collection, props, user, write=True) + response = _propfind_response( + path, collection, props, user, write=True) multistatus.append(response) for collection in read_collections: if collection in collections: continue - response = _propfind_response(path, collection, props, user, write=False) + response = _propfind_response( + path, collection, props, user, write=False) multistatus.append(response) return _pretty_xml(multistatus)