Skip to content

Commit

Permalink
Pull request: 3503 password policy
Browse files Browse the repository at this point in the history
Merge in DNS/adguard-home from 3503-password-policy to master

Closes #3503.

Squashed commit of the following:

commit 1f03cd9
Author: Eugene Burkov <[email protected]>
Date:   Thu Feb 10 18:24:59 2022 +0300

    client: imp msg

commit e164ae2
Merge: b7efd76 f53f48c
Author: Eugene Burkov <[email protected]>
Date:   Thu Feb 10 16:52:01 2022 +0300

    Merge branch 'master' into 3503-password-policy

commit b7efd76
Author: Ildar Kamalov <[email protected]>
Date:   Thu Feb 10 16:17:59 2022 +0300

    client: remove empty line

commit f19aba6
Author: Ildar Kamalov <[email protected]>
Date:   Thu Feb 10 16:09:14 2022 +0300

    client: validate password length

commit a6943c9
Author: Eugene Burkov <[email protected]>
Date:   Fri Feb 4 18:57:02 2022 +0300

    all: fix docs again

commit 9346bb6
Author: Eugene Burkov <[email protected]>
Date:   Fri Feb 4 18:54:15 2022 +0300

    openapi: fix docs

commit a801644
Author: Eugene Burkov <[email protected]>
Date:   Fri Feb 4 18:25:55 2022 +0300

    all: validate passwd runes count
  • Loading branch information
EugeneOne1 committed Feb 10, 2022
1 parent f53f48c commit 0ef8344
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ 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]).

[#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730
[#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
Expand Down
114 changes: 86 additions & 28 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
3 changes: 2 additions & 1 deletion client/src/__locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
2 changes: 2 additions & 0 deletions client/src/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
14 changes: 13 additions & 1 deletion client/src/helpers/validators.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import i18next from 'i18next';
import stringLength from 'string-length';

import {
MAX_PORT,
Expand All @@ -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';
Expand Down Expand Up @@ -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;
};
3 changes: 2 additions & 1 deletion client/src/install/Setup/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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>
Expand Down
16 changes: 16 additions & 0 deletions internal/home/controlinstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"runtime"
"strings"
"time"
"unicode/utf8"

"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down

0 comments on commit 0ef8344

Please sign in to comment.