[enh] Check password in cli/api

This commit is contained in:
ljf 2018-08-27 03:40:50 +02:00
parent cda8bcf206
commit 06276a621b
5 changed files with 51 additions and 10 deletions

View file

@ -1489,6 +1489,9 @@ tools:
--ignore-dyndns:
help: Do not subscribe domain to a DynDNS service
action: store_true
--force-password:
help: Use this if you really want to set a weak password
action: store_true
### tools_update()
update:

View file

@ -2251,6 +2251,9 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
raise MoulinetteError(errno.EINVAL,
m18n.n('app_argument_choice_invalid',
name=arg_name, choices='yes, no, y, n, 1, 0'))
elif arg_type == 'password':
from yunohost.tools import _check_password
_check_password(arg_value)
args_dict[arg_name] = arg_value
# END loop over action_args...

View file

@ -35,6 +35,12 @@ DEFAULTS = OrderedDict([
("example.int", {"type": "int", "default": 42}),
("example.string", {"type": "string", "default": "yolo swag"}),
("example.enum", {"type": "enum", "default": "a", "choices": ["a", "b", "c"]}),
# Control the way password are checked
# -1 No control
# 0 Just display weak password info in debug
# 1 Warn user about weak password
# 2 Raise an error when the user put a weak password
("security.password.check_mode", {"type": "int", "default": 2}),
])
@ -90,9 +96,12 @@ def settings_set(key, value):
received_type=type(value).__name__, expected_type=key_type))
elif key_type == "int":
if not isinstance(value, int) or isinstance(value, bool):
raise MoulinetteError(errno.EINVAL, m18n.n(
'global_settings_bad_type_for_setting', setting=key,
received_type=type(value).__name__, expected_type=key_type))
if isinstance(value, str):
value=int(value)
else:
raise MoulinetteError(errno.EINVAL, m18n.n(
'global_settings_bad_type_for_setting', setting=key,
received_type=type(value).__name__, expected_type=key_type))
elif key_type == "string":
if not isinstance(value, basestring):
raise MoulinetteError(errno.EINVAL, m18n.n(

View file

@ -32,6 +32,7 @@ import logging
import subprocess
import pwd
import socket
import cracklib
from xmlrpclib import Fault
from importlib import import_module
from collections import OrderedDict
@ -53,6 +54,7 @@ from yunohost.monitor import monitor_disk, monitor_system
from yunohost.utils.packages import ynh_packages_version
from yunohost.utils.network import get_public_ip
from yunohost.log import is_unit_operation, OperationLogger
from yunohost.settings import settings_get
# FIXME this is a duplicate from apps.py
APPS_SETTING_PATH = '/etc/yunohost/apps/'
@ -127,6 +129,8 @@ def tools_adminpw(auth, new_password):
"""
from yunohost.user import _hash_user_password
_check_password(new_password)
try:
auth.update("cn=admin", {
"userPassword": _hash_user_password(new_password),
@ -250,7 +254,8 @@ def _is_inside_container():
@is_unit_operation()
def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False):
def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
force_password=False):
"""
YunoHost post-install
@ -268,6 +273,10 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False):
raise MoulinetteError(errno.EPERM,
m18n.n('yunohost_already_installed'))
# Check password
if not force_password:
_check_password(password)
if not ignore_dyndns:
# Check if yunohost dyndns can handle the given domain
# (i.e. is it a .nohost.me ? a .noho.st ?)
@ -299,6 +308,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False):
else:
dyndns = False
operation_logger.start()
logger.info(m18n.n('yunohost_installing'))
@ -1046,3 +1056,24 @@ class Migration(object):
@property
def description(self):
return m18n.n("migration_description_%s" % self.id)
def _check_password(password):
security_level = settings_get('security.password.check_mode')
if security_level == -1:
return
try:
if password in ["yunohost", "olinuxino", "olinux"]:
raise MoulinetteError(errno.EINVAL, m18n.n('password_too_weak') +
' : it is based on a (reversed) dictionary word' )
try:
cracklib.VeryFascistCheck(password)
except ValueError as e:
raise MoulinetteError(errno.EINVAL, m18n.n('password_too_weak') + " : " + str(e) )
except MoulinetteError as e:
if security_level >= 2:
raise
elif security_level == 1:
logger.warn(e.strerror)
else:
logger.debug(e.strerror)

View file

@ -39,15 +39,10 @@ from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger
from yunohost.service import service_status
from yunohost.log import is_unit_operation
from yunohost.tools import _check_password
logger = getActionLogger('yunohost.user')
def _check_password(password):
try:
cracklib.VeryFascistCheck(password)
except ValueError as e:
raise MoulinetteError(errno.EINVAL, m18n.n('password_too_weak') + " : " + str(e) )
def user_list(auth, fields=None):
"""
List users