From 7d16769263b9cdefadb5059c04c0fc8892353c54 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 3 Oct 2017 12:34:50 +0200 Subject: [PATCH] [IMP] config: support hashed master passwords - Add support for hashed master passwords (super-admin password) using a strong scheme (PBKDF2_SHA512). - Replace the password with a hash in memory (tools.config map), after verifying it - Automatically replace the plaintext master password with a hash when saving it after a password change - Preserve support for setting/using plaintext passwords when necessary (e.g. as a temporary deployment thing) --- addons/web/controllers/main.py | 2 +- odoo/service/db.py | 4 ++-- odoo/tools/config.py | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 2e3ad2357fe..cc2ef4201df 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -647,7 +647,7 @@ class Database(http.Controller): def _render_template(self, **d): d.setdefault('manage',True) - d['insecure'] = odoo.tools.config['admin_passwd'] == 'admin' + d['insecure'] = odoo.tools.config.verify_admin_password('admin') d['list_db'] = odoo.tools.config['list_db'] d['langs'] = odoo.service.db.exp_list_lang() d['countries'] = odoo.service.db.exp_list_countries() diff --git a/odoo/service/db.py b/odoo/service/db.py index b8851b17edd..045afc9f0d8 100644 --- a/odoo/service/db.py +++ b/odoo/service/db.py @@ -35,7 +35,7 @@ class DatabaseExists(Warning): #---------------------------------------------------------- def check_super(passwd): - if passwd and passwd == odoo.tools.config['admin_passwd']: + if passwd and odoo.tools.config.verify_admin_password(passwd): return True raise odoo.exceptions.AccessDenied() @@ -299,7 +299,7 @@ def exp_rename(old_name, new_name): return True def exp_change_admin_password(new_password): - odoo.tools.config['admin_passwd'] = new_password + odoo.tools.config.set_admin_password(new_password) odoo.tools.config.save() return True diff --git a/odoo/tools/config.py b/odoo/tools/config.py index 25d62ef0cf7..ba7121e7ca8 100644 --- a/odoo/tools/config.py +++ b/odoo/tools/config.py @@ -14,6 +14,9 @@ import odoo from .. import release, conf, loglevels from . import appdirs, pycompat +from passlib.context import CryptContext +crypt_context = CryptContext(schemes=['pbkdf2_sha512', 'plaintext'], + deprecated=['plaintext']) class MyOption (optparse.Option, object): """ optparse Option with two additional attributes. @@ -625,4 +628,19 @@ class configmanager(object): def filestore(self, dbname): return os.path.join(self['data_dir'], 'filestore', dbname) + def set_admin_password(self, new_password): + self.options['admin_passwd'] = crypt_context.encrypt(new_password) + + def verify_admin_password(self, password): + """Verifies the super-admin password, possibly updating the stored hash if needed""" + stored_hash = self.options['admin_passwd'] + if not stored_hash: + # empty password/hash => authentication forbidden + return False + result, updated_hash = crypt_context.verify_and_update(password, stored_hash) + if result: + if updated_hash: + self.options['admin_passwd'] = updated_hash + return True + config = configmanager()