mailinabox/management
Joshua Tauberer 6a979f4f52
Add TOTP two-factor authentication to admin panel login (#1814)
* add user interface for managing 2fa

* update user schema with 2fa columns

* implement two factor check during login

* Use pyotp for validating TOTP codes

* also implements resynchronisation support via `pyotp`'s `valid_window option

* Update API route naming, update setup page

* Rename /two-factor-auth/ => /2fa/
* Nest totp routes under /2fa/totp/
* Update ids and methods in panel to allow for different setup types

* Autofocus otp input when logging in, update layout

* Extract TOTPStrategy class to totp.py

* this decouples `TOTP` validation and storage logic from `auth` and moves it to `totp`
* reduce `pyotp.validate#valid_window` from `2` to `1`

* Update OpenApi docs, rename /2fa/ => /mfa/

* Decouple totp from users table by moving to totp_credentials table

* this allows implementation of other mfa schemes in the future (webauthn)
* also makes key management easier and enforces one totp credentials per user on db-level

* Add sqlite migration

* Rename internal validate_two_factor_secret => validate_two_factor_secret

* conn.close() if mru_token update can't .commit()

* Address review feedback, thanks @hija

* Use hmac.compare_digest() to compare mru_token

* Safeguard against empty mru_token column

* hmac.compare_digest() expects arguments of type string, make sure we don't pass None
 * Currently, this cannot happen but we might not want to store `mru_token` during setup

* Do not log failed login attempts for MissingToken errors

* Due to the way that the /login UI works, this persists at least one failed login each time a user logs into the admin panel. This in turn triggers fail2ban at some point.

* Add TOTP secret to user_key hash

thanks @downtownallday
* this invalidates all user_keys after TOTP status is changed for user
* after changing TOTP state, a login is required
* due to the forced login, we can't and don't need to store the code used for setup in `mru_code`

* Typo

* Reorganize the MFA backend methods

* Reorganize MFA front-end and add label column

* Fix handling of bad input when enabling mfa

* Update openAPI docs

* Remove unique key constraint on foreign key user_id in mfa table

* Don't expose mru_token and secret for enabled mfas over HTTP

* Only update mru_token for matched mfa row

* Exclude mru_token in user key hash

* Rename tools/mail.py to management/cli.py

* Add MFA list/disable to the management CLI so admins can restore access if MFA device is lost

Co-authored-by: Joshua Tauberer <jt@occams.info>
2020-10-31 10:27:38 -04:00
..
templates Add TOTP two-factor authentication to admin panel login (#1814) 2020-10-31 10:27:38 -04:00
auth.py Exclude mru_token in user key hash 2020-09-30 12:34:26 +02:00
backup.py Update usage hint in backup.py (#1662) 2019-11-23 08:04:22 -05:00
cli.py Add MFA list/disable to the management CLI so admins can restore access if MFA device is lost 2020-10-31 10:23:43 -04:00
csr_country_codes.tsv drop the CSR_COUNTRY setting and ask within the control panel 2015-12-26 11:48:23 -05:00
daemon.py Add MFA list/disable to the management CLI so admins can restore access if MFA device is lost 2020-10-31 10:23:43 -04:00
daily_tasks.sh daily_tasks.sh: redirect stderr to stdout (#1768) 2020-06-07 09:56:45 -04:00
dns_update.py Drop the MTA-STS TLSRPT record unless set explicitly 2020-09-21 15:57:17 -04:00
email_administrator.py send the mail_log.py report to the box admin every Monday 2018-02-25 11:55:06 -05:00
mail_log.py Fix Feb 29 issue #1733 2020-03-03 20:59:28 +01:00
mailconfig.py Reorganize the MFA backend methods 2020-09-26 09:58:25 -04:00
mfa.py Add MFA list/disable to the management CLI so admins can restore access if MFA device is lost 2020-10-31 10:23:43 -04:00
munin_start.sh update bind9 configuration 2018-10-03 14:28:43 -04:00
ssl_certificates.py Display certificate expiry dates in ISO format (#1841) 2020-10-16 16:22:36 -04:00
status_checks.py status_checks.py: Properly terminate the process pools (#1795) 2020-08-09 11:42:39 -04:00
utils.py move the custom exclusive process code from utils.py into a new python package named exclusiveprocess 2017-01-15 11:02:23 -05:00
web_update.py Use tabs instead of spaces in nginx conf (#1827) 2020-09-27 07:13:33 -04:00