From 61459651546146037f15fef1eab10c6144b511fd Mon Sep 17 00:00:00 2001 From: Arvedui Date: Sun, 3 Mar 2019 00:22:55 +0100 Subject: [PATCH] Implement support for the argon2 password hash --- modoboa/core/password_hashers/__init__.py | 2 +- modoboa/core/password_hashers/advanced.py | 51 ++++++++++++++++++++++- requirements.txt | 1 + 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/modoboa/core/password_hashers/__init__.py b/modoboa/core/password_hashers/__init__.py index b03b5e3d0..802b9a480 100644 --- a/modoboa/core/password_hashers/__init__.py +++ b/modoboa/core/password_hashers/__init__.py @@ -9,7 +9,7 @@ from __future__ import unicode_literals from django.utils.encoding import smart_text from modoboa.core.password_hashers.advanced import ( # NOQA:F401 - BLFCRYPTHasher, MD5CRYPTHasher, SHA256CRYPTHasher, SHA512CRYPTHasher + BLFCRYPTHasher, MD5CRYPTHasher, SHA256CRYPTHasher, SHA512CRYPTHasher, ARGON2IDHasher ) from modoboa.core.password_hashers.base import ( # NOQA:F401 CRYPTHasher, MD5Hasher, PLAINHasher, SHA256Hasher diff --git a/modoboa/core/password_hashers/advanced.py b/modoboa/core/password_hashers/advanced.py index 3024924fc..e58c5ba83 100644 --- a/modoboa/core/password_hashers/advanced.py +++ b/modoboa/core/password_hashers/advanced.py @@ -9,6 +9,9 @@ This module relies on `passlib` to provide more secure hashers. from __future__ import unicode_literals from passlib.hash import bcrypt, md5_crypt, sha256_crypt, sha512_crypt +from argon2 import PasswordHasher as argon2_hasher + +from django.conf import settings from modoboa.parameters import tools as param_tools from .base import PasswordHasher @@ -91,8 +94,7 @@ class SHA512CRYPTHasher(PasswordHasher): """ SHA512-CRYPT password hasher. - Supports rounds and is the strongest scheme provided by - Modoboa. Requires more resource than SHA256-CRYPT. + Supports rounds. Requires more resource than SHA256-CRYPT. """ @property @@ -108,3 +110,48 @@ class SHA512CRYPTHasher(PasswordHasher): def verify(self, clearvalue, hashed_value): return sha512_crypt.verify(clearvalue, hashed_value) + + +class ARGON2IDHasher(PasswordHasher): + """ + argon2 password hasher. + + Supports rounds, memory and number of threads. To be set in settings.py. + It is the strongest scheme provided by modoboa + but can only be used with dovecot >= 2.3 and libsodium >= 1.0.13 + """ + + def __init__(self,): + super(ARGON2IDHasher, self).__init__() + + parameters = dict() + + if hasattr(settings, "MODOBOA_ARGON2_TIME_COST"): + parameters["time_cost"] = settings.MODOBOA_ARGON2_TIME_COST + + if hasattr(settings, "MODOBOA_ARGON2_MEMORY_COST"): + parameters["memory_cost"] = settings.MODOBOA_ARGON2_MEMORY_COST + + if hasattr(settings, "MODOBOA_ARGON2_PARALLELISM"): + parameters["parallelism"] = settings.MODOBOA_ARGON2_PARALLELISM + + self.hasher = argon2_hasher(**parameters) + + @property + def scheme(self): + return "{ARGON2ID}" if self._target == "local" else "{CRYPT}" + + def _b64encode(self, pwhash): + return pwhash + + def _encrypt(self, clearvalue, salt=None): + return self.hasher.hash(clearvalue) + + def verify(self, clearvalue, hashed_value): + try: + return self.hasher.verify(hashed_value, clearvalue) + except argon2_hasher.exceptions.VerifyMismatchError: + return False + + def needs_rehash(self, hashed_value): + return self.hasher.check_needs_rehash(hashed_value.strip(self.scheme)) diff --git a/requirements.txt b/requirements.txt index eb80cd838..b96c62c70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,3 +29,4 @@ rfc6266 lxml backports.csv; python_version < '3' chardet +argon2_cffi