mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
check for dovecot supported password schemes
call doveadm pw -l to list password schemes only show supported password schemes
This commit is contained in:
@@ -7,6 +7,8 @@ from django.conf import settings
|
||||
from django.contrib.auth import password_validation
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
from modoboa.core.password_hashers import get_dovecot_schemes
|
||||
from modoboa.core.password_hashers.base import PasswordHasher
|
||||
from modoboa.lib import fields as lib_fields
|
||||
from modoboa.lib.form_utils import (
|
||||
HorizontalRadioSelect, SeparatorField, YesNoField
|
||||
@@ -45,14 +47,9 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
|
||||
|
||||
password_scheme = forms.ChoiceField(
|
||||
label=ugettext_lazy("Default password scheme"),
|
||||
choices=[("sha512crypt", "sha512crypt"),
|
||||
("sha256crypt", "sha256crypt"),
|
||||
("blfcrypt", "bcrypt"),
|
||||
("md5crypt", ugettext_lazy("md5crypt (weak)")),
|
||||
("sha256", ugettext_lazy("sha256 (weak)")),
|
||||
("md5", ugettext_lazy("md5 (weak)")),
|
||||
("crypt", ugettext_lazy("crypt (weak)")),
|
||||
("plain", ugettext_lazy("plain (weak)"))],
|
||||
choices=[(hasher.name, ugettext_lazy(hasher.label))
|
||||
for hasher in PasswordHasher.get_password_hashers()
|
||||
if hasher().scheme in get_dovecot_schemes()],
|
||||
initial="sha512crypt",
|
||||
help_text=ugettext_lazy("Scheme used to crypt mailbox passwords"),
|
||||
widget=forms.Select(attrs={"class": "form-control"})
|
||||
|
||||
@@ -6,12 +6,17 @@ Password hashers for Modoboa.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from modoboa.core.password_hashers.advanced import ( # NOQA:F401
|
||||
BLFCRYPTHasher, MD5CRYPTHasher, SHA256CRYPTHasher, SHA512CRYPTHasher
|
||||
)
|
||||
from modoboa.core.password_hashers.base import ( # NOQA:F401
|
||||
CRYPTHasher, MD5Hasher, PLAINHasher, SHA256Hasher
|
||||
)
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
|
||||
|
||||
def get_password_hasher(scheme):
|
||||
@@ -29,3 +34,25 @@ def get_password_hasher(scheme):
|
||||
except KeyError:
|
||||
hasher = PLAINHasher
|
||||
return hasher
|
||||
|
||||
def get_dovecot_schemes():
|
||||
"""Return schemes supported by dovecot"""
|
||||
supported_schemes = ["{PLAIN}"]
|
||||
dpath = None
|
||||
code, output = exec_cmd("which doveadm")
|
||||
if not code:
|
||||
dpath = force_text(output).strip()
|
||||
else:
|
||||
known_paths = ("/usr/bin/doveadm", "/usr/local/bin/doveadm")
|
||||
for fpath in known_paths:
|
||||
if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
|
||||
dpath = fpath
|
||||
if dpath:
|
||||
try:
|
||||
code, schemes = exec_cmd("%s pw -l" % dpath)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
supported_schemes = ["{{{}}}".format(scheme) for scheme in force_text(schemes).split()]
|
||||
|
||||
return supported_schemes
|
||||
|
||||
@@ -21,6 +21,9 @@ class BLFCRYPTHasher(PasswordHasher):
|
||||
Supports rounds and provides compatibility with dovecot on
|
||||
*BSD systems.
|
||||
"""
|
||||
name = "blfcrypt"
|
||||
label = "blfcrypt"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{BLF-CRYPT}" if self._target == "local" else "{CRYPT}"
|
||||
@@ -49,6 +52,9 @@ class MD5CRYPTHasher(PasswordHasher):
|
||||
|
||||
This scheme can't be considered as secure anymore.
|
||||
"""
|
||||
name = "md5crypt"
|
||||
label = "md5crypt"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{MD5-CRYPT}" if self._target == "local" else "{CRYPT}"
|
||||
@@ -71,6 +77,9 @@ class SHA256CRYPTHasher(PasswordHasher):
|
||||
Supports rounds and is a good compromise between security and
|
||||
performance.
|
||||
"""
|
||||
name = "sha256crypt"
|
||||
label = "sha256crypt"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{SHA256-CRYPT}" if self._target == "local" else "{CRYPT}"
|
||||
@@ -95,6 +104,9 @@ class SHA512CRYPTHasher(PasswordHasher):
|
||||
Supports rounds and is the strongest scheme provided by
|
||||
Modoboa. Requires more resource than SHA256-CRYPT.
|
||||
"""
|
||||
name = "sha512crypt"
|
||||
label = "sha512crypt"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{SHA512-CRYPT}" if self._target == "local" else "{CRYPT}"
|
||||
|
||||
@@ -68,12 +68,19 @@ class PasswordHasher(object):
|
||||
hashed_value
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_password_hashers(cls):
|
||||
return cls.__subclasses__()
|
||||
|
||||
|
||||
class PLAINHasher(PasswordHasher):
|
||||
|
||||
"""
|
||||
Plain (ie. clear) password hasher.
|
||||
"""
|
||||
name = "plain"
|
||||
label = "plain (weak)"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{PLAIN}"
|
||||
@@ -89,6 +96,9 @@ class CRYPTHasher(PasswordHasher):
|
||||
|
||||
Uses python `crypt` standard module.
|
||||
"""
|
||||
name = "crypt"
|
||||
label = "crypt (weak)"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{CRYPT}"
|
||||
@@ -112,6 +122,9 @@ class MD5Hasher(PasswordHasher):
|
||||
|
||||
Uses python `hashlib` standard module.
|
||||
"""
|
||||
name = "md5"
|
||||
label = "md5 (weak)"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{MD5}"
|
||||
@@ -128,6 +141,9 @@ class SHA256Hasher(PasswordHasher):
|
||||
|
||||
Uses python `hashlib` and `base64` standard modules.
|
||||
"""
|
||||
name = "sha256"
|
||||
label = "sha256 (weak)"
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
return "{SHA256}"
|
||||
|
||||
Reference in New Issue
Block a user