[#2310] [WebUI] Fix unicode password support

hashlib requires UTF-8 encoded string
Passes flake8 but with warning for global __request__
This commit is contained in:
Calum Lind 2014-02-17 23:59:07 +00:00
parent 32d5a0bab2
commit 22946700dd
1 changed files with 32 additions and 30 deletions

View File

@ -32,6 +32,20 @@
# statement from all source files in the program, then also delete it here. # statement from all source files in the program, then also delete it here.
# #
# #
import time
import random
import hashlib
import logging
from datetime import datetime, timedelta
from email.utils import formatdate
from twisted.internet.task import LoopingCall
from deluge import component
from deluge.ui.web.json_api import JSONComponent, export
from deluge.common import utf8_encoded
log = logging.getLogger(__name__)
AUTH_LEVEL_NONE = 0 AUTH_LEVEL_NONE = 0
AUTH_LEVEL_READONLY = 1 AUTH_LEVEL_READONLY = 1
@ -40,30 +54,10 @@ AUTH_LEVEL_ADMIN = 10
AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL
class AuthError(Exception):
"""
An exception that might be raised when checking a request for
authentication.
"""
pass
import time
import random
import hashlib
import logging
from datetime import datetime, timedelta
from email.utils import formatdate
from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall
from deluge import component
from deluge.ui.web.json_api import JSONComponent, export
log = logging.getLogger(__name__)
def make_checksum(session_id): def make_checksum(session_id):
return reduce(lambda x,y:x+y, map(ord, session_id)) return reduce(lambda x, y: x+y, map(ord, session_id))
def get_session_id(session_id): def get_session_id(session_id):
""" """
@ -83,12 +77,14 @@ def get_session_id(session_id):
log.exception(e) log.exception(e)
return None return None
def make_expires(timeout): def make_expires(timeout):
dt = timedelta(seconds=timeout) dt = timedelta(seconds=timeout)
expires = time.mktime((datetime.now() + dt).timetuple()) expires = time.mktime((datetime.now() + dt).timetuple())
expires_str = formatdate(timeval=expires, localtime=False, usegmt=True) expires_str = formatdate(timeval=expires, localtime=False, usegmt=True)
return expires, expires_str return expires, expires_str
class Auth(JSONComponent): class Auth(JSONComponent):
""" """
The component that implements authentification into the JSON interface. The component that implements authentification into the JSON interface.
@ -136,7 +132,7 @@ class Auth(JSONComponent):
checksum = str(make_checksum(session_id)) checksum = str(make_checksum(session_id))
request.addCookie('_session_id', session_id + checksum, request.addCookie('_session_id', session_id + checksum,
path=request.base+"json", expires=expires_str) path=request.base+"json", expires=expires_str)
log.debug("Creating session for %s", login) log.debug("Creating session for %s", login)
config = component.get("DelugeWeb").config config = component.get("DelugeWeb").config
@ -158,7 +154,7 @@ class Auth(JSONComponent):
log.debug("Received a password via the 1.2-dev auth method") log.debug("Received a password via the 1.2-dev auth method")
m = hashlib.md5() m = hashlib.md5()
m.update(config["pwd_salt"]) m.update(config["pwd_salt"])
m.update(password) m.update(utf8_encoded(password))
if m.hexdigest() == config['pwd_md5']: if m.hexdigest() == config['pwd_md5']:
# We want to move the password over to sha1 and remove # We want to move the password over to sha1 and remove
# the old passwords from the config file. # the old passwords from the config file.
@ -178,7 +174,7 @@ class Auth(JSONComponent):
from base64 import decodestring from base64 import decodestring
m = hashlib.md5() m = hashlib.md5()
m.update(decodestring(config["old_pwd_salt"])) m.update(decodestring(config["old_pwd_salt"]))
m.update(password) m.update(utf8_encoded(password))
if m.digest() == decodestring(config["old_pwd_md5"]): if m.digest() == decodestring(config["old_pwd_md5"]):
# We want to move the password over to sha1 and remove # We want to move the password over to sha1 and remove
@ -194,7 +190,7 @@ class Auth(JSONComponent):
log.debug("Received a password via the 1.2 auth method") log.debug("Received a password via the 1.2 auth method")
s = hashlib.sha1() s = hashlib.sha1()
s.update(config["pwd_salt"]) s.update(config["pwd_salt"])
s.update(password) s.update(utf8_encoded(password))
if s.hexdigest() == config["pwd_sha1"]: if s.hexdigest() == config["pwd_sha1"]:
return True return True
@ -233,7 +229,7 @@ class Auth(JSONComponent):
_session_id = request.getCookie("_session_id") _session_id = request.getCookie("_session_id")
request.addCookie('_session_id', _session_id, request.addCookie('_session_id', _session_id,
path=request.base+"json", expires=expires_str) path=request.base+"json", expires=expires_str)
if method: if method:
if not hasattr(method, "_json_export"): if not hasattr(method, "_json_export"):
@ -265,7 +261,7 @@ class Auth(JSONComponent):
log.debug("Changing password") log.debug("Changing password")
salt = hashlib.sha1(str(random.getrandbits(40))).hexdigest() salt = hashlib.sha1(str(random.getrandbits(40))).hexdigest()
s = hashlib.sha1(salt) s = hashlib.sha1(salt)
s.update(new_password) s.update(utf8_encoded(new_password))
config = component.get("DelugeWeb").config config = component.get("DelugeWeb").config
config["pwd_salt"] = salt config["pwd_salt"] = salt
config["pwd_sha1"] = s.hexdigest() config["pwd_sha1"] = s.hexdigest()
@ -303,7 +299,6 @@ class Auth(JSONComponent):
:param session_id: the id for the session to remove :param session_id: the id for the session to remove
:type session_id: string :type session_id: string
""" """
d = Deferred()
config = component.get("DelugeWeb").config config = component.get("DelugeWeb").config
del config["sessions"][__request__.session_id] del config["sessions"][__request__.session_id]
return True return True
@ -318,9 +313,16 @@ class Auth(JSONComponent):
:returns: a session id or False :returns: a session id or False
:rtype: string or False :rtype: string or False
""" """
if self.check_password(password): if self.check_password(password):
return self._create_session(__request__) return self._create_session(__request__)
else: else:
log.error('Login failed (ClientIP %s)', __request__.getClientIP()) log.error('Login failed (ClientIP %s)', __request__.getClientIP())
return False return False
class AuthError(Exception):
"""
An exception that might be raised when checking a request for
authentication.
"""
pass