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

Rework the poll logic #234

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.6.6"
version = "0.6.7"
authors = [
"David Mulder <dmulder@suse.com>"
]
Expand Down Expand Up @@ -76,7 +76,7 @@ tracing-forest = "^0.1.6"
rusqlite = "^0.32.0"
hashbrown = { version = "0.14.0", features = ["serde", "inline-more", "ahash"] }
lru = "^0.12.3"
kanidm_lib_crypto = { path = "./src/crypto", version = "0.6.6" }
kanidm_lib_crypto = { path = "./src/crypto", version = "0.6.7" }
kanidm_utils_users = { path = "./src/users" }
walkdir = "2"
csv = "1.2.2"
Expand Down
135 changes: 59 additions & 76 deletions src/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use std::time::Duration;
include!("./opt/tool.rs");

macro_rules! match_sm_auth_client_response {
($expr:expr, $opts:ident, $($pat:pat => $result:expr),*) => {
($expr:expr, $req:ident, $($pat:pat => $result:expr),*) => {
match $expr {
Ok(r) => match r {
$($pat => $result),*
Expand All @@ -47,6 +47,56 @@ macro_rules! match_sm_auth_client_response {
println!("auth user unknown");
break;
}
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::SetupPin {
msg,
}) => {
println!("{}", msg);

let mut pin;
let mut confirm;
loop {
pin = match prompt_password("New PIN: ") {
Ok(password) => password,
Err(err) => {
println!("unable to get pin: {:?}", err);
return ExitCode::FAILURE;
}
};

confirm = match prompt_password("Confirm PIN: ") {
Ok(password) => password,
Err(err) => {
println!("unable to get confirmation pin: {:?}", err);
return ExitCode::FAILURE;
}
};

if pin == confirm {
break;
} else {
println!("Inputs did not match. Try again.");
}
}

// Now setup the request for the next loop.
$req = ClientRequest::PamAuthenticateStep(PamAuthRequest::SetupPin {
pin,
});
continue;
},
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::Pin) => {
let cred = match prompt_password("PIN: ") {
Ok(password) => password,
Err(err) => {
debug!("unable to get pin: {:?}", err);
return ExitCode::FAILURE;
}
};

// Now setup the request for the next loop.
$req = ClientRequest::PamAuthenticateStep(PamAuthRequest::Pin { cred });
continue;
}
_ => {
// unexpected response.
error!("Error: unexpected response -> {:?}", r);
Expand Down Expand Up @@ -107,7 +157,7 @@ async fn main() -> ExitCode {

let mut req = ClientRequest::PamAuthenticateInit(account_id.clone());
loop {
match_sm_auth_client_response!(daemon_client.call_and_wait(&req, timeout), opts,
match_sm_auth_client_response!(daemon_client.call_and_wait(&req, timeout), req,
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::Password) => {
// Prompt for and get the password
let cred = match prompt_password("Password: ") {
Expand All @@ -123,22 +173,6 @@ async fn main() -> ExitCode {
req = ClientRequest::PamAuthenticateStep(PamAuthRequest::Password { cred });
continue;
},
ClientResponse::PamAuthenticateStepResponse(
PamAuthResponse::DeviceAuthorizationGrant { data },
) => {
let msg = match &data.message {
Some(msg) => msg.clone(),
None => format!("Using a browser on another device, visit:\n{}\nAnd enter the code:\n{}",
data.verification_uri, data.user_code)
};
println!("{}", msg);

timeout = u64::from(data.expires_in);
req = ClientRequest::PamAuthenticateStep(
PamAuthRequest::DeviceAuthorizationGrant { data },
);
continue;
},
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::MFACode {
msg,
}) => {
Expand Down Expand Up @@ -166,80 +200,29 @@ async fn main() -> ExitCode {
// Prompt the MFA message
println!("{}", msg);

let mut poll_attempt = 0;
req = ClientRequest::PamAuthenticateStep(PamAuthRequest::MFAPoll { poll_attempt });
loop {
thread::sleep(Duration::from_secs(polling_interval.into()));
timeout = cfg.get_unix_sock_timeout();
req = ClientRequest::PamAuthenticateStep(PamAuthRequest::MFAPoll);

// Counter intuitive, but we don't need a max poll attempts here because
// if the resolver goes away, then this will error on the sock and
// will shutdown. This allows the resolver to dynamically extend the
// timeout if needed, and removes logic from the front end.
match_sm_auth_client_response!(
daemon_client.call_and_wait(&req, timeout), opts,
daemon_client.call_and_wait(&req, timeout), req,
ClientResponse::PamAuthenticateStepResponse(
PamAuthResponse::MFAPollWait,
) => {
// Continue polling if the daemon says to wait
poll_attempt += 1;
req = ClientRequest::PamAuthenticateStep(
PamAuthRequest::MFAPoll { poll_attempt }
);
continue;
}
);

}
},
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::SetupPin {
msg,
}) => {
// Prompt for a new Hello PIN
println!("{}", msg);

let mut pin;
let mut confirm;
loop {
pin = match prompt_password("New PIN: ") {
Ok(p) => p,
Err(e) => {
error!("Problem getting input: {}", e);
return ExitCode::FAILURE;
}
};

confirm = match prompt_password("Confirm PIN: ") {
Ok(p) => p,
Err(e) => {
error!("Problem getting input: {}", e);
return ExitCode::FAILURE;
}
};

if pin == confirm {
break;
} else {
println!("Inputs did not match. Try again.");
}
}

// Now setup the request for the next loop.
timeout = cfg.get_unix_sock_timeout();
req = ClientRequest::PamAuthenticateStep(PamAuthRequest::SetupPin {
pin,
});
continue;
},
ClientResponse::PamAuthenticateStepResponse(PamAuthResponse::Pin) => {
// Prompt for and get the Hello PIN
let cred = match prompt_password("PIN: ") {
Ok(p) => p,
Err(e) => {
error!("Problem getting input: {}", e);
return ExitCode::FAILURE;
}
};

// Now setup the request for the next loop.
timeout = cfg.get_unix_sock_timeout();
req = ClientRequest::PamAuthenticateStep(PamAuthRequest::Pin { cred });
continue;
}
);
}
Expand Down
Loading
Loading