wip: user/login: request signed cert
parent
3b55f7418e
commit
036304c686
|
@ -0,0 +1,63 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use reqwest::multipart::{Form, Part};
|
||||||
|
use reqwest::{StatusCode, Url};
|
||||||
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
|
pub async fn sign_key(token: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let url = crate::get_sshca_server_url()?;
|
||||||
|
|
||||||
|
let pubkey = Path::new("/home/dustin/.ssh/id_ed25519.pub");
|
||||||
|
let pubkey_path = pubkey.to_owned();
|
||||||
|
let pubkey = std::fs::read_to_string(&pubkey_path)?;
|
||||||
|
|
||||||
|
let mut url =
|
||||||
|
Url::parse(&url).map_err(|e| format!("Invalid URL: {}", e))?;
|
||||||
|
url.path_segments_mut()
|
||||||
|
.map_err(|_| "Invalid URL: missing host")?
|
||||||
|
.pop_if_empty()
|
||||||
|
.push("user")
|
||||||
|
.push("sign");
|
||||||
|
|
||||||
|
let form = Form::new().part(
|
||||||
|
"pubkey",
|
||||||
|
Part::bytes(pubkey.into_bytes()).file_name(
|
||||||
|
pubkey_path
|
||||||
|
.file_name()
|
||||||
|
.ok_or("Invalid public key file path")?
|
||||||
|
.to_str()
|
||||||
|
.ok_or("Invalid public key file path")?
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
info!(
|
||||||
|
"Requesting SSH user certificate for {} with key {}",
|
||||||
|
"-",
|
||||||
|
pubkey_path.display()
|
||||||
|
);
|
||||||
|
debug!("Request: POST {}", url);
|
||||||
|
let res = client
|
||||||
|
.post(url)
|
||||||
|
.header("Authorization", format!("Bearer {}", token))
|
||||||
|
.multipart(form)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
debug!("Response: {:?} {}", &res.version(), &res.status());
|
||||||
|
match res.error_for_status_ref() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) if e.status() == Some(StatusCode::BAD_REQUEST) => {
|
||||||
|
let msg = res.text().await.unwrap_or_else(|e| e.to_string());
|
||||||
|
error!("{}: {}", e, msg);
|
||||||
|
return Err(format!("{}\n{}", e, msg).into());
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let cert = res.text().await?;
|
||||||
|
println!("{}", cert);
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! The `sshca user` sub-command handles user-based operations, such
|
//! The `sshca user` sub-command handles user-based operations, such
|
||||||
//! as signing an SSH user certificate.
|
//! as signing an SSH user certificate.
|
||||||
|
mod cert;
|
||||||
mod login;
|
mod login;
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -54,6 +55,6 @@ async fn login(args: LoginArgs) -> MainResult {
|
||||||
let url = super::get_sshca_server_url()?;
|
let url = super::get_sshca_server_url()?;
|
||||||
let config = login::get_oidc_config(&url).await?;
|
let config = login::get_oidc_config(&url).await?;
|
||||||
let token = login::login(config, listen, timeout).await?;
|
let token = login::login(config, listen, timeout).await?;
|
||||||
println!("{}", token);
|
cert::sign_key(&token).await.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue