wip: user/login: request signed cert

Dustin 2023-11-22 07:20:12 -06:00
parent 3b55f7418e
commit 036304c686
2 changed files with 65 additions and 1 deletions

63
src/user/cert.rs Normal file
View File

@ -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(())
}

View File

@ -2,6 +2,7 @@
//!
//! The `sshca user` sub-command handles user-based operations, such
//! as signing an SSH user certificate.
mod cert;
mod login;
use std::time::Duration;
@ -54,6 +55,6 @@ async fn login(args: LoginArgs) -> MainResult {
let url = super::get_sshca_server_url()?;
let config = login::get_oidc_config(&url).await?;
let token = login::login(config, listen, timeout).await?;
println!("{}", token);
cert::sign_key(&token).await.unwrap();
Ok(())
}