Some checks failed
CI / Format (pull_request) Successful in 4s
CI / Clippy (push) Failing after 2m48s
CI / Detect Changes (pull_request) Has been skipped
CI / Detect Changes (push) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Agent (push) Has been skipped
CI / Deploy Dashboard (push) Has been skipped
CI / Deploy Docs (push) Has been skipped
CI / Deploy MCP (push) Has been skipped
CI / Clippy (pull_request) Failing after 2m34s
CI / Security Audit (pull_request) Has been skipped
CI / Tests (pull_request) Has been skipped
CI / Format (push) Successful in 3s
CI / Security Audit (push) Has been skipped
CI / Tests (push) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
54 lines
1.7 KiB
Rust
54 lines
1.7 KiB
Rust
use std::path::Path;
|
|
|
|
use crate::error::AgentError;
|
|
|
|
/// Ensure the SSH key pair exists at the given path, generating it if missing.
|
|
/// Returns the public key contents.
|
|
pub fn ensure_ssh_key(key_path: &str) -> Result<String, AgentError> {
|
|
let private_path = Path::new(key_path);
|
|
let public_path = private_path.with_extension("pub");
|
|
|
|
if private_path.exists() && public_path.exists() {
|
|
return std::fs::read_to_string(&public_path)
|
|
.map_err(|e| AgentError::Config(format!("Failed to read SSH public key: {e}")));
|
|
}
|
|
|
|
// Create parent directory
|
|
if let Some(parent) = private_path.parent() {
|
|
std::fs::create_dir_all(parent)?;
|
|
}
|
|
|
|
// Generate ed25519 key pair using ssh-keygen
|
|
let output = std::process::Command::new("ssh-keygen")
|
|
.args([
|
|
"-t",
|
|
"ed25519",
|
|
"-f",
|
|
key_path,
|
|
"-N",
|
|
"", // no passphrase
|
|
"-C",
|
|
"compliance-scanner-agent",
|
|
])
|
|
.output()
|
|
.map_err(|e| AgentError::Config(format!("Failed to run ssh-keygen: {e}")))?;
|
|
|
|
if !output.status.success() {
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
return Err(AgentError::Config(format!("ssh-keygen failed: {stderr}")));
|
|
}
|
|
|
|
// Set correct permissions
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
std::fs::set_permissions(private_path, std::fs::Permissions::from_mode(0o600))?;
|
|
}
|
|
|
|
let public_key = std::fs::read_to_string(&public_path)
|
|
.map_err(|e| AgentError::Config(format!("Failed to read generated SSH public key: {e}")))?;
|
|
|
|
tracing::info!("Generated new SSH key pair at {key_path}");
|
|
Ok(public_key)
|
|
}
|