mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] Check password in cli/api
This commit is contained in:
parent
cda8bcf206
commit
06276a621b
5 changed files with 51 additions and 10 deletions
|
@ -1489,6 +1489,9 @@ tools:
|
||||||
--ignore-dyndns:
|
--ignore-dyndns:
|
||||||
help: Do not subscribe domain to a DynDNS service
|
help: Do not subscribe domain to a DynDNS service
|
||||||
action: store_true
|
action: store_true
|
||||||
|
--force-password:
|
||||||
|
help: Use this if you really want to set a weak password
|
||||||
|
action: store_true
|
||||||
|
|
||||||
### tools_update()
|
### tools_update()
|
||||||
update:
|
update:
|
||||||
|
|
|
@ -2251,6 +2251,9 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('app_argument_choice_invalid',
|
m18n.n('app_argument_choice_invalid',
|
||||||
name=arg_name, choices='yes, no, y, n, 1, 0'))
|
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
|
args_dict[arg_name] = arg_value
|
||||||
|
|
||||||
# END loop over action_args...
|
# END loop over action_args...
|
||||||
|
|
|
@ -35,6 +35,12 @@ DEFAULTS = OrderedDict([
|
||||||
("example.int", {"type": "int", "default": 42}),
|
("example.int", {"type": "int", "default": 42}),
|
||||||
("example.string", {"type": "string", "default": "yolo swag"}),
|
("example.string", {"type": "string", "default": "yolo swag"}),
|
||||||
("example.enum", {"type": "enum", "default": "a", "choices": ["a", "b", "c"]}),
|
("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))
|
received_type=type(value).__name__, expected_type=key_type))
|
||||||
elif key_type == "int":
|
elif key_type == "int":
|
||||||
if not isinstance(value, int) or isinstance(value, bool):
|
if not isinstance(value, int) or isinstance(value, bool):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
if isinstance(value, str):
|
||||||
'global_settings_bad_type_for_setting', setting=key,
|
value=int(value)
|
||||||
received_type=type(value).__name__, expected_type=key_type))
|
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":
|
elif key_type == "string":
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise MoulinetteError(errno.EINVAL, m18n.n(
|
||||||
|
|
|
@ -32,6 +32,7 @@ import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import pwd
|
import pwd
|
||||||
import socket
|
import socket
|
||||||
|
import cracklib
|
||||||
from xmlrpclib import Fault
|
from xmlrpclib import Fault
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from collections import OrderedDict
|
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.packages import ynh_packages_version
|
||||||
from yunohost.utils.network import get_public_ip
|
from yunohost.utils.network import get_public_ip
|
||||||
from yunohost.log import is_unit_operation, OperationLogger
|
from yunohost.log import is_unit_operation, OperationLogger
|
||||||
|
from yunohost.settings import settings_get
|
||||||
|
|
||||||
# FIXME this is a duplicate from apps.py
|
# FIXME this is a duplicate from apps.py
|
||||||
APPS_SETTING_PATH = '/etc/yunohost/apps/'
|
APPS_SETTING_PATH = '/etc/yunohost/apps/'
|
||||||
|
@ -127,6 +129,8 @@ def tools_adminpw(auth, new_password):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.user import _hash_user_password
|
from yunohost.user import _hash_user_password
|
||||||
|
|
||||||
|
_check_password(new_password)
|
||||||
try:
|
try:
|
||||||
auth.update("cn=admin", {
|
auth.update("cn=admin", {
|
||||||
"userPassword": _hash_user_password(new_password),
|
"userPassword": _hash_user_password(new_password),
|
||||||
|
@ -250,7 +254,8 @@ def _is_inside_container():
|
||||||
|
|
||||||
|
|
||||||
@is_unit_operation()
|
@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
|
YunoHost post-install
|
||||||
|
|
||||||
|
@ -268,6 +273,10 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False):
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise MoulinetteError(errno.EPERM,
|
||||||
m18n.n('yunohost_already_installed'))
|
m18n.n('yunohost_already_installed'))
|
||||||
|
|
||||||
|
# Check password
|
||||||
|
if not force_password:
|
||||||
|
_check_password(password)
|
||||||
|
|
||||||
if not ignore_dyndns:
|
if not ignore_dyndns:
|
||||||
# Check if yunohost dyndns can handle the given domain
|
# Check if yunohost dyndns can handle the given domain
|
||||||
# (i.e. is it a .nohost.me ? a .noho.st ?)
|
# (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:
|
else:
|
||||||
dyndns = False
|
dyndns = False
|
||||||
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
logger.info(m18n.n('yunohost_installing'))
|
logger.info(m18n.n('yunohost_installing'))
|
||||||
|
|
||||||
|
@ -1046,3 +1056,24 @@ class Migration(object):
|
||||||
@property
|
@property
|
||||||
def description(self):
|
def description(self):
|
||||||
return m18n.n("migration_description_%s" % self.id)
|
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)
|
||||||
|
|
|
@ -39,15 +39,10 @@ from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from yunohost.service import service_status
|
from yunohost.service import service_status
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
|
from yunohost.tools import _check_password
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.user')
|
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):
|
def user_list(auth, fields=None):
|
||||||
"""
|
"""
|
||||||
List users
|
List users
|
||||||
|
|
Loading…
Add table
Reference in a new issue