Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MFA with Duo's Universal Prompt #4637

Merged
merged 22 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
849ce1e
Add initial working Duo Universal Prompt support.
0x0fbc May 30, 2024
6f86749
Add db schema and models for Duo 2FA state storage
0x0fbc Jun 7, 2024
36f90cd
store duo states in the database and validate during authentication
0x0fbc Jun 7, 2024
328c4a3
cleanup & comments
0x0fbc Jun 7, 2024
41f94e2
bump state/nonce length
0x0fbc Jun 7, 2024
90b73c6
replace stray use of TimeDelta
0x0fbc Jun 7, 2024
f489930
more cleanup
0x0fbc Jun 7, 2024
6f06fa9
bind Duo oauth flow to device id, drop redundant device type handling
0x0fbc Jun 7, 2024
4df7fcf
drop redundant alphanum string generation code
0x0fbc Jun 7, 2024
e7a058c
error handling cleanup
0x0fbc Jun 7, 2024
3ae5a0b
directly use JWT_VALIDITY_SECS constant instead of copying it to DuoC…
0x0fbc Jun 7, 2024
d89a7b7
remove redundant explicit returns, rustfmt
0x0fbc Jun 7, 2024
f907e02
rearrange constants, update comments, error message
0x0fbc Jun 7, 2024
8092bb3
override charset on duo state column to ascii for mysql
0x0fbc Jun 10, 2024
8fa181a
Reduce twofactor_duo_ctx state/nonce column size in postgres and maria
0x0fbc Jun 11, 2024
df57395
Add fixes suggested by clippy
0x0fbc Jun 11, 2024
fd00f3e
rustfmt
0x0fbc Jun 11, 2024
256f87a
Update to use the make_http_request
BlackDex Jul 17, 2024
28bbd72
Don't handle OrganizationDuo
0x0fbc Jul 20, 2024
3365838
move Duo API endpoint fmt strings out of macros and into format! calls
0x0fbc Jul 20, 2024
2475e8e
Add missing indentation
0x0fbc Jul 23, 2024
973ae47
remove redundant expiry check when purging Duo contexts
0x0fbc Jul 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@
## Cron schedule of the job that cleans old auth requests from the auth request.
## Defaults to every minute. Set blank to disable this job.
# AUTH_REQUEST_PURGE_SCHEDULE="30 * * * * *"
##
## Cron schedule of the job that cleans expired Duo contexts from the database. Does nothing if Duo MFA is disabled or set to use the legacy iframe prompt.
## Defaults to every minute. Set blank to disable this job.
# DUO_CONTEXT_PURGE_SCHEDULE="30 * * * * *"

########################
### General settings ###
Expand Down Expand Up @@ -422,15 +426,21 @@
# YUBICO_SERVER=http://yourdomain.com/wsapi/2.0/verify

## Duo Settings
## You need to configure all options to enable global Duo support, otherwise users would need to configure it themselves
## You need to configure the DUO_IKEY, DUO_SKEY, and DUO_HOST options to enable global Duo support.
## Otherwise users will need to configure it themselves.
## Create an account and protect an application as mentioned in this link (only the first step, not the rest):
## https://help.bitwarden.com/article/setup-two-step-login-duo/#create-a-duo-security-account
## Then set the following options, based on the values obtained from the last step:
# DUO_IKEY=<Integration Key>
# DUO_SKEY=<Secret Key>
# DUO_IKEY=<Client ID>
# DUO_SKEY=<Client Secret>
# DUO_HOST=<API Hostname>
## After that, you should be able to follow the rest of the guide linked above,
## ignoring the fields that ask for the values that you already configured beforehand.
##
## If you want to attempt to use Duo's 'Traditional Prompt' (deprecated, iframe based) set DUO_USE_IFRAME to 'true'.
## Duo no longer supports this, but it still works for some integrations.
## If you aren't sure, leave this alone.
# DUO_USE_IFRAME=false

## Email 2FA settings
## Email token size
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE twofactor_duo_ctx;
8 changes: 8 additions & 0 deletions migrations/mysql/2024-06-05-131359_add_2fa_duo_store/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE twofactor_duo_ctx (
state VARCHAR(64) NOT NULL,
user_email VARCHAR(255) NOT NULL,
nonce VARCHAR(64) NOT NULL,
exp BIGINT NOT NULL,

PRIMARY KEY (state)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE twofactor_duo_ctx;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE twofactor_duo_ctx (
state VARCHAR(64) NOT NULL,
user_email VARCHAR(255) NOT NULL,
nonce VARCHAR(64) NOT NULL,
exp BIGINT NOT NULL,

PRIMARY KEY (state)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE twofactor_duo_ctx;
8 changes: 8 additions & 0 deletions migrations/sqlite/2024-06-05-131359_add_2fa_duo_store/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE twofactor_duo_ctx (
state TEXT NOT NULL,
user_email TEXT NOT NULL,
nonce TEXT NOT NULL,
exp INTEGER NOT NULL,

PRIMARY KEY (state)
);
2 changes: 1 addition & 1 deletion src/api/core/two_factor/duo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ async fn get_user_duo_data(uuid: &str, conn: &mut DbConn) -> DuoStatus {
}

// let (ik, sk, ak, host) = get_duo_keys();
async fn get_duo_keys_email(email: &str, conn: &mut DbConn) -> ApiResult<(String, String, String, String)> {
pub(crate) async fn get_duo_keys_email(email: &str, conn: &mut DbConn) -> ApiResult<(String, String, String, String)> {
let data = match User::find_by_mail(email, conn).await {
Some(u) => get_user_duo_data(&u.uuid, conn).await.data(),
_ => DuoData::global(),
Expand Down
Loading
Loading