From 7b87d07dc801e43825beae3dc36dab70dc04ed63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 13 Jan 2009 13:16:51 +0100 Subject: [PATCH] Add exponential timeout on failed login attempts. Thanks to Bruce's comment about the Twitter issue. --- trytond/security.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/trytond/security.py b/trytond/security.py index bc1586770e..8f8004b162 100644 --- a/trytond/security.py +++ b/trytond/security.py @@ -26,29 +26,39 @@ class Session(int): self.__data['timestamp'] = time.time() _USER_CACHE = {} +_USER_TRY = {} def login(dbname, loginname, password, cache=True): + _USER_TRY.setdefault(dbname, {}) cursor = pooler.get_db(dbname).cursor() password_sha = sha.new(password).hexdigest() - cursor.execute('SELECT id FROM res_user ' - 'WHERE login = %s and password = %s and active', - (loginname, password_sha)) - res = cursor.fetchone() - cursor.close() - if res: + cursor.execute('SELECT id, password, active FROM res_user ' + 'WHERE login = %s', (loginname,)) + if cursor.rowcount: + res = cursor.fetchone() + cursor.close() user_id = res[0] if user_id == 0: return False - if cache: - _USER_CACHE.setdefault(dbname, {}) - _USER_CACHE[dbname].setdefault(user_id, []) - session = Session(user_id) - _USER_CACHE[dbname][user_id].append(session) - return (user_id, session.session) - else: - return user_id - else: + _USER_TRY[dbname].setdefault(user_id, 0) + if res[1] == password_sha and res[2]: + _USER_TRY[dbname][user_id] = 0 + if cache: + _USER_CACHE.setdefault(dbname, {}) + _USER_CACHE[dbname].setdefault(user_id, []) + session = Session(user_id) + _USER_CACHE[dbname][user_id].append(session) + return (user_id, session.session) + else: + return user_id + time.sleep(2 ** _USER_TRY[dbname][user_id]) + _USER_TRY[dbname][user_id] += 1 return False + cursor.close() + _USER_TRY[dbname].setdefault(0, 0) + time.sleep(2 ** _USER_TRY[dbname][0]) + _USER_TRY[dbname][0] += 1 + return False def check_super(passwd): if passwd == CONFIG['admin_passwd']: