summaryrefslogtreecommitdiff
path: root/paste/auth
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-04-21 15:57:41 +0200
committerVictor Stinner <victor.stinner@gmail.com>2015-04-21 15:57:41 +0200
commitb4187e5d61acb98ffb86767c82a60280db7833f3 (patch)
tree6ee1e8ba1d6834f343d960aaa3b3868b594d1d29 /paste/auth
parentf3fd444b0bc18e95d08c88567d9d8ed17346027d (diff)
downloadpaste-b4187e5d61acb98ffb86767c82a60280db7833f3.tar.gz
Port paste.auth to Python 3
* md5() and hmac expects bytes: on Python 3, encode text to utf-8 * Don't compare None with int * HTTP body must be bytes
Diffstat (limited to 'paste/auth')
-rw-r--r--paste/auth/cookie.py17
-rw-r--r--paste/auth/digest.py29
2 files changed, 35 insertions, 11 deletions
diff --git a/paste/auth/cookie.py b/paste/auth/cookie.py
index 14b1fd8..8f11d1b 100644
--- a/paste/auth/cookie.py
+++ b/paste/auth/cookie.py
@@ -74,7 +74,10 @@ class CookieTooLarge(RuntimeError):
_all_chars = ''.join([chr(x) for x in range(0, 255)])
def new_secret():
""" returns a 64 byte secret """
- return ''.join(random.sample(_all_chars, 64))
+ secret = ''.join(random.sample(_all_chars, 64))
+ if six.PY3:
+ secret = secret.encode('utf8')
+ return secret
class AuthCookieSigner(object):
"""
@@ -137,12 +140,16 @@ class AuthCookieSigner(object):
need to be escaped and quoted). The expiration of this
cookie is handled server-side in the auth() function.
"""
+ timestamp = make_time(time.time() + 60*self.timeout)
+ if six.PY3:
+ content = content.encode('utf8')
+ timestamp = timestamp.encode('utf8')
cookie = base64.encodestring(
hmac.new(self.secret, content, sha1).digest() +
- make_time(time.time() + 60*self.timeout) +
+ timestamp +
content)
- cookie = cookie.replace("/", "_").replace("=", "~")
- cookie = cookie.replace('\n', '').replace('\r', '')
+ cookie = cookie.replace(b"/", b"_").replace(b"=", b"~")
+ cookie = cookie.replace(b'\n', b'').replace(b'\r', b'')
if len(cookie) > self.maxlen:
raise CookieTooLarge(content, cookie)
return cookie
@@ -298,6 +305,8 @@ class AuthCookieHandler(object):
if content:
content = ";".join(content)
content = self.signer.sign(content)
+ if six.PY3:
+ content = content.decode('utf8')
cookie = '%s=%s; Path=/;' % (self.cookie_name, content)
if 'https' == environ['wsgi.url_scheme']:
cookie += ' secure;'
diff --git a/paste/auth/digest.py b/paste/auth/digest.py
index 798f447..85e0362 100644
--- a/paste/auth/digest.py
+++ b/paste/auth/digest.py
@@ -37,6 +37,7 @@ except ImportError:
from md5 import md5
import time, random
from six.moves.urllib.parse import quote as url_quote
+import six
def _split_auth_string(auth_string):
""" split a digest auth string into individual key=value strings """
@@ -68,7 +69,10 @@ def _auth_to_kv_pairs(auth_string):
def digest_password(realm, username, password):
""" construct the appropriate hashcode needed for HTTP digest """
- return md5("%s:%s:%s" % (username, realm, password)).hexdigest()
+ content = "%s:%s:%s" % (username, realm, password)
+ if six.PY3:
+ content = content.encode('utf8')
+ return md5(content).hexdigest()
class AuthDigestAuthenticator(object):
""" implementation of RFC 2617 - HTTP Digest Authentication """
@@ -79,10 +83,16 @@ class AuthDigestAuthenticator(object):
def build_authentication(self, stale = ''):
""" builds the authentication error """
- nonce = md5(
- "%s:%s" % (time.time(), random.random())).hexdigest()
- opaque = md5(
- "%s:%s" % (time.time(), random.random())).hexdigest()
+ content = "%s:%s" % (time.time(), random.random())
+ if six.PY3:
+ content = content.encode('utf-8')
+ nonce = md5(content).hexdigest()
+
+ content = "%s:%s" % (time.time(), random.random())
+ if six.PY3:
+ content = content.encode('utf-8')
+ opaque = md5(content).hexdigest()
+
self.nonce[nonce] = None
parts = {'realm': self.realm, 'qop': 'auth',
'nonce': nonce, 'opaque': opaque }
@@ -97,17 +107,22 @@ class AuthDigestAuthenticator(object):
""" computes the authentication, raises error if unsuccessful """
if not ha1:
return self.build_authentication()
- ha2 = md5('%s:%s' % (method, path)).hexdigest()
+ content = '%s:%s' % (method, path)
+ if six.PY3:
+ content = content.encode('utf8')
+ ha2 = md5(content).hexdigest()
if qop:
chk = "%s:%s:%s:%s:%s:%s" % (ha1, nonce, nc, cnonce, qop, ha2)
else:
chk = "%s:%s:%s" % (ha1, nonce, ha2)
+ if six.PY3:
+ chk = chk.encode('utf8')
if response != md5(chk).hexdigest():
if nonce in self.nonce:
del self.nonce[nonce]
return self.build_authentication()
pnc = self.nonce.get(nonce,'00000000')
- if nc <= pnc:
+ if pnc is not None and nc <= pnc:
if nonce in self.nonce:
del self.nonce[nonce]
return self.build_authentication(stale = True)