From: Christian Korber Date: Mon, 27 Apr 2026 14:05:47 +0000 (+0200) Subject: luci-app-acl: enforce password policy X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=8dd088d4b3f129a55c3dd18868823b09396d0d3a;p=openwrt-luci.git luci-app-acl: enforce password policy Validation is performed if the password complies to password policy. Signed-off-by: Christian Korber --- diff --git a/applications/luci-app-acl/htdocs/luci-static/resources/view/system/acl.js b/applications/luci-app-acl/htdocs/luci-static/resources/view/system/acl.js index 4dcad0cc59..9a4952e479 100644 --- a/applications/luci-app-acl/htdocs/luci-static/resources/view/system/acl.js +++ b/applications/luci-app-acl/htdocs/luci-static/resources/view/system/acl.js @@ -7,6 +7,7 @@ 'require uci'; 'require form'; 'require tools.widgets as widgets'; +'require tools.password as pwtool'; const aclList = {}; @@ -17,6 +18,31 @@ const callSetPassword = rpc.declare({ expect: { result: 1 } }); +function checkPassword(value) { + const pw_enabled = uci.get('rpcd', 'policy', 'enabled'); + const pw_length = uci.get('rpcd', 'policy', 'pw_length'); + const pw_digits = uci.get('rpcd', 'policy', 'digits'); + const pw_ul = uci.get('rpcd', 'policy', 'uc_lc'); + const special = uci.get('rpcd', 'policy', 'special_characters'); + + if (!pw_enabled) + return true; + + if (pw_length && !pwtool.checkLength(value, pw_length)) + return _('Policy: min. length of %s characters').format(pw_length); + + if (pw_digits && !pwtool.checkDigits(value)) + return _('Policy: contain digits'); + + if (pw_ul && !pwtool.checkUpperLower(value)) + return _('Policy: contain uppercase/lowercase'); + + if (special && !pwtool.checkSpecialChars(value)) + return _('Policy: contain special characters'); + + return true; +} + function globListToRegExp(section_id, option) { const list = L.toArray(uci.get('rpcd', section_id, option)); const positivePatterns = []; @@ -170,7 +196,8 @@ return view.extend({ return L.resolveDefault(fs.list('/usr/share/rpcd/acl.d'), []).then(function(entries) { const tasks = [ L.resolveDefault(fs.stat('/usr/sbin/uhttpd'), null), - fs.lines('/etc/passwd') + fs.lines('/etc/passwd'), + uci.load('rpcd') ]; for (let e of entries) @@ -181,7 +208,7 @@ return view.extend({ }); }, - render([has_uhttpd, passwd, ...acls]) { + render([has_uhttpd, passwd, uci_rpcd, ...acls]) { ui.addNotification(null, E('p', [ _('The LuCI ACL management is in an experimental stage! It does not yet work reliably with all applications') ]), 'warning'); @@ -275,7 +302,7 @@ return view.extend({ return _('Cannot encrypt plaintext password since uhttpd is not installed.'); } - return true; + return checkPassword(value); }; o.write = function(section_id, value) { const variant = this.map.lookupOption('_variant', section_id)[0]; @@ -286,8 +313,6 @@ return view.extend({ if (!success) throw new Error('Failed to create password'); }); - - uci.set('rpcd', section_id, 'password', value); }; o.remove = function() {};