mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-08-16 22:20:30 +03:00
Pull request: 3503 password policy
Merge in DNS/adguard-home from 3503-password-policy to master
Closes #3503.
Squashed commit of the following:
commit 1f03cd9ef6e76a691ae383d6ba4b7f851eabddb8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Feb 10 18:24:59 2022 +0300
client: imp msg
commit e164ae2544284cf9a1d3333c50b68e361f78ce2a
Merge: b7efd764 f53f48cc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Feb 10 16:52:01 2022 +0300
Merge branch 'master' into 3503-password-policy
commit b7efd7640ec0fa3deac5290f8306ce5142428718
Author: Ildar Kamalov <ik@adguard.com>
Date: Thu Feb 10 16:17:59 2022 +0300
client: remove empty line
commit f19aba6cb579d2c4681675c881000c8f16257ab9
Author: Ildar Kamalov <ik@adguard.com>
Date: Thu Feb 10 16:09:14 2022 +0300
client: validate password length
commit a6943c94483306ecfc0d1431d576d42053823b61
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Fri Feb 4 18:57:02 2022 +0300
all: fix docs again
commit 9346bb6c393af0799a79b228285acdd8f8799b83
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Fri Feb 4 18:54:15 2022 +0300
openapi: fix docs
commit a8016443237c130f69108970ddfc77ef71126be6
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Fri Feb 4 18:25:55 2022 +0300
all: validate passwd runes count
This commit is contained in:
parent
f53f48cc33
commit
0ef8344178
@ -72,6 +72,7 @@ In this release, the schema version has changed from 12 to 13.
|
||||
|
||||
### Security
|
||||
|
||||
- Enforced password strength policy ([3503]).
|
||||
- Weaker cipher suites that use the CBC (cipher block chaining) mode of
|
||||
operation have been disabled ([#2993]).
|
||||
|
||||
@ -79,6 +80,7 @@ In this release, the schema version has changed from 12 to 13.
|
||||
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
|
||||
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
|
||||
[#3367]: https://github.com/AdguardTeam/AdGuardHome/issues/3367
|
||||
[#3503]: https://github.com/AdguardTeam/AdGuardHome/issues/3503
|
||||
[#4216]: https://github.com/AdguardTeam/AdGuardHome/issues/4216
|
||||
[#4221]: https://github.com/AdguardTeam/AdGuardHome/issues/4221
|
||||
[#4238]: https://github.com/AdguardTeam/AdGuardHome/issues/4238
|
||||
|
114
client/package-lock.json
generated
vendored
114
client/package-lock.json
generated
vendored
@ -1700,6 +1700,12 @@
|
||||
"v8-to-istanbul": "^4.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
@ -1720,6 +1726,12 @@
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"char-regex": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
|
||||
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
|
||||
"dev": true
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@ -1747,6 +1759,25 @@
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"string-length": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
|
||||
"integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"char-regex": "^1.0.2",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
@ -3959,10 +3990,9 @@
|
||||
"integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
|
||||
},
|
||||
"char-regex": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
|
||||
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
|
||||
"dev": true
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.0.tgz",
|
||||
"integrity": "sha512-oGu2QekBMXgyQNWPDRQ001bjvDnZe4/zBTz37TMbiKz1NbNiyiH5hRkobe7npRN6GfbGbxMYFck/vQ1r9c1VMA=="
|
||||
},
|
||||
"character-entities": {
|
||||
"version": "1.2.4",
|
||||
@ -10037,6 +10067,12 @@
|
||||
"string-length": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
@ -10057,6 +10093,12 @@
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"char-regex": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
|
||||
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
|
||||
"dev": true
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@ -10078,6 +10120,25 @@
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"string-length": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
|
||||
"integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"char-regex": "^1.0.2",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
@ -14193,38 +14254,26 @@
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"string-length": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz",
|
||||
"integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==",
|
||||
"dev": true,
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz",
|
||||
"integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==",
|
||||
"requires": {
|
||||
"char-regex": "^1.0.2",
|
||||
"strip-ansi": "^6.0.0"
|
||||
"char-regex": "^2.0.0",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"dev": true
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dev": true,
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
|
||||
"integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
"ansi-regex": "^6.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14297,6 +14346,15 @@
|
||||
"define-properties": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"stringify-entities": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz",
|
||||
|
1
client/package.json
vendored
1
client/package.json
vendored
@ -42,6 +42,7 @@
|
||||
"redux-actions": "^2.6.5",
|
||||
"redux-form": "^8.3.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"string-length": "^5.0.1",
|
||||
"url-polyfill": "^1.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -627,5 +627,6 @@
|
||||
"use_saved_key": "Use the previously saved key",
|
||||
"parental_control": "Parental Control",
|
||||
"safe_browsing": "Safe Browsing",
|
||||
"served_from_cache": "{{value}} <i>(served from cache)</i>"
|
||||
"served_from_cache": "{{value}} <i>(served from cache)</i>",
|
||||
"form_error_password_length": "Password must be at least {{value}} characters long"
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ export const R_WIN_ABSOLUTE_PATH = /^([a-zA-Z]:)?(\\|\/)(?:[^\\/:*?"<>|\x00]+\\)
|
||||
|
||||
export const R_CLIENT_ID = /^[a-z0-9-]{1,63}$/;
|
||||
|
||||
export const MIN_PASSWORD_LENGTH = 8;
|
||||
|
||||
export const HTML_PAGES = {
|
||||
INSTALL: '/install.html',
|
||||
LOGIN: '/login.html',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import i18next from 'i18next';
|
||||
import stringLength from 'string-length';
|
||||
|
||||
import {
|
||||
MAX_PORT,
|
||||
@ -13,6 +14,7 @@ import {
|
||||
UNSAFE_PORTS,
|
||||
R_CLIENT_ID,
|
||||
R_DOMAIN,
|
||||
MIN_PASSWORD_LENGTH,
|
||||
} from './constants';
|
||||
import { ip4ToInt, isValidAbsolutePath } from './form';
|
||||
import { isIpInCidr, parseSubnetMask } from './helpers';
|
||||
@ -320,10 +322,20 @@ export const validatePath = (value) => {
|
||||
* @param cidr {string}
|
||||
* @returns {Function}
|
||||
*/
|
||||
|
||||
export const validateIpv4InCidr = (valueIp, allValues) => {
|
||||
if (!isIpInCidr(valueIp, allValues.cidr)) {
|
||||
return i18next.t('form_error_subnet', { ip: valueIp, cidr: allValues.cidr });
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @returns {Function}
|
||||
*/
|
||||
export const validatePasswordLength = (value) => {
|
||||
if (value && stringLength(value) < MIN_PASSWORD_LENGTH) {
|
||||
return i18next.t('form_error_password_length', { value: MIN_PASSWORD_LENGTH });
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ import i18n from '../../i18n';
|
||||
import Controls from './Controls';
|
||||
import { renderInputField } from '../../helpers/form';
|
||||
import { FORM_NAME } from '../../helpers/constants';
|
||||
import { validatePasswordLength } from '../../helpers/validators';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
@ -67,7 +68,7 @@ const Auth = (props) => {
|
||||
type="password"
|
||||
className="form-control"
|
||||
placeholder={ t('install_auth_password_enter') }
|
||||
validate={[required]}
|
||||
validate={[required, validatePasswordLength]}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||
@ -359,6 +360,9 @@ func shutdownSrv(ctx context.Context, srv *http.Server) {
|
||||
}
|
||||
}
|
||||
|
||||
// PasswordMinRunes is the minimum length of user's password in runes.
|
||||
const PasswordMinRunes = 8
|
||||
|
||||
// Apply new configuration, start DNS server, restart Web server
|
||||
func (web *Web) handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
req, restartHTTP, err := decodeApplyConfigReq(r.Body)
|
||||
@ -368,6 +372,18 @@ func (web *Web) handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(req.Password) < PasswordMinRunes {
|
||||
aghhttp.Error(
|
||||
r,
|
||||
w,
|
||||
http.StatusUnprocessableEntity,
|
||||
"password must be at least %d symbols long",
|
||||
PasswordMinRunes,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("udp", req.DNS.IP, req.DNS.Port)
|
||||
if err != nil {
|
||||
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
||||
|
@ -4,6 +4,12 @@
|
||||
|
||||
## v0.107.3: API changes
|
||||
|
||||
### The new possible status code in `/install/configure` response.
|
||||
|
||||
* The new status code `422 Unprocessable Entity` in the response for
|
||||
`POST /install/configure` which means that the specified password does not
|
||||
meet the strength requirements.
|
||||
|
||||
### The new field `"version"` in `AddressesInfo`
|
||||
|
||||
* The new field `"version"` in `GET /install/get_addresses` is the version of
|
||||
|
@ -1088,6 +1088,9 @@
|
||||
'description': >
|
||||
Failed to parse initial configuration or cannot listen to the
|
||||
specified addresses.
|
||||
'422':
|
||||
'description': >
|
||||
The specified password does not meet the strength requirements.
|
||||
'500':
|
||||
'description': 'Cannot start the DNS server'
|
||||
'/login':
|
||||
|
Loading…
Reference in New Issue
Block a user