feat!: persist ssh keys across builds by writing them in data dir
This commit is contained in:
parent
7a55e0defd
commit
3e44d24f9b
7 changed files with 145 additions and 57 deletions
|
@ -1,4 +1,11 @@
|
||||||
{
|
{
|
||||||
|
// Paths to SSH private keys to use for encryption
|
||||||
|
"private_keys": {
|
||||||
|
"ssh-rsa": "$DATA_DIR/ssh/id_rsa",
|
||||||
|
"ecdsa-sha2-nistp256": "$DATA_DIR/ssh/id_ecdsa",
|
||||||
|
"ssh-ed25519": "$DATA_DIR/ssh/id_ed25519"
|
||||||
|
},
|
||||||
|
|
||||||
"keybindings": {
|
"keybindings": {
|
||||||
"Home": {
|
"Home": {
|
||||||
"<q>": "Quit", // Quit the application
|
"<q>": "Quit", // Quit the application
|
||||||
|
|
46
Cargo.lock
generated
46
Cargo.lock
generated
|
@ -1807,7 +1807,16 @@ version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys",
|
"dirs-sys 0.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys 0.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1818,10 +1827,22 @@ checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users 0.4.6",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"option-ext",
|
||||||
|
"redox_users 0.5.2",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -6075,6 +6096,17 @@ dependencies = [
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.16",
|
||||||
|
"libredox",
|
||||||
|
"thiserror 2.0.14",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
|
@ -6899,6 +6931,15 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shellexpand"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb"
|
||||||
|
dependencies = [
|
||||||
|
"dirs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -7117,6 +7158,7 @@ dependencies = [
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"shellexpand",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"ssh-key",
|
"ssh-key",
|
||||||
"strip-ansi-escapes",
|
"strip-ansi-escapes",
|
||||||
|
|
|
@ -27,6 +27,9 @@ blog = [
|
||||||
"dep:patch-crate"
|
"dep:patch-crate"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 2
|
||||||
|
|
||||||
[package.metadata.patch]
|
[package.metadata.patch]
|
||||||
crates = ["ratatui-image"]
|
crates = ["ratatui-image"]
|
||||||
|
|
||||||
|
@ -76,6 +79,7 @@ russh = "0.49.2"
|
||||||
rust-embed = { version = "8.7.2", features = ["actix"] }
|
rust-embed = { version = "8.7.2", features = ["actix"] }
|
||||||
serde = { version = "1.0.211", features = ["derive"] }
|
serde = { version = "1.0.211", features = ["derive"] }
|
||||||
serde_json = "1.0.132"
|
serde_json = "1.0.132"
|
||||||
|
ssh-key = { version = "0.6.7", features = ["getrandom", "crypto"] }
|
||||||
signal-hook = "0.3.17"
|
signal-hook = "0.3.17"
|
||||||
strip-ansi-escapes = "0.2.0"
|
strip-ansi-escapes = "0.2.0"
|
||||||
strum = { version = "0.26.3", features = ["derive"] }
|
strum = { version = "0.26.3", features = ["derive"] }
|
||||||
|
@ -85,10 +89,10 @@ tracing = "0.1.40"
|
||||||
tracing-error = "0.2.0"
|
tracing-error = "0.2.0"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
||||||
tui-markdown = { version = "0.3.5", optional = true }
|
tui-markdown = { version = "0.3.5", optional = true }
|
||||||
|
shellexpand = "3.1.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0.90"
|
anyhow = "1.0.90"
|
||||||
atrium-codegen = { git = "https://github.com/atrium-rs/atrium.git", rev = "ccc0213", optional = true }
|
atrium-codegen = { git = "https://github.com/atrium-rs/atrium.git", rev = "ccc0213", optional = true }
|
||||||
patch-crate = { version = "0.1.13", optional = true }
|
patch-crate = { version = "0.1.13", optional = true }
|
||||||
ssh-key = { version = "0.6.7", features = ["getrandom", "crypto"] }
|
|
||||||
vergen-gix = { version = "1.0.2", features = ["build", "cargo"] }
|
vergen-gix = { version = "1.0.2", features = ["build", "cargo"] }
|
||||||
|
|
25
build.rs
25
build.rs
|
@ -1,19 +1,12 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ssh_key::{rand_core, Algorithm, EcdsaCurve, LineEnding, PrivateKey};
|
|
||||||
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
||||||
|
|
||||||
#[cfg(feature = "blog")]
|
#[cfg(feature = "blog")]
|
||||||
const ATPROTO_LEXICON_DIR: &str = "src/atproto/lexicons";
|
const ATPROTO_LEXICON_DIR: &str = "src/atproto/lexicons";
|
||||||
#[cfg(feature = "blog")]
|
#[cfg(feature = "blog")]
|
||||||
const ATPROTO_CLIENT_DIR: &str = "src/atproto";
|
const ATPROTO_CLIENT_DIR: &str = "src/atproto";
|
||||||
const SSH_KEY_ALGOS: &[(&str, Algorithm)] = &[
|
|
||||||
("rsa.pem", Algorithm::Rsa { hash: None }),
|
|
||||||
("ed25519.pem", Algorithm::Ed25519),
|
|
||||||
("ecdsa.pem", Algorithm::Ecdsa { curve: EcdsaCurve::NistP256 }),
|
|
||||||
];
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
@ -29,24 +22,6 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate openSSH host keys
|
|
||||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
||||||
let mut rng = rand_core::OsRng;
|
|
||||||
for (file_name, algo) in SSH_KEY_ALGOS {
|
|
||||||
let path = out_dir.join(file_name);
|
|
||||||
if path.exists() {
|
|
||||||
println!(
|
|
||||||
"cargo:warning=Skipping existing host key: {:?}",
|
|
||||||
path.file_stem().unwrap()
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let key =
|
|
||||||
PrivateKey::random(&mut rng, algo.to_owned()).map_err(anyhow::Error::from)?;
|
|
||||||
key.write_openssh_file(&path, LineEnding::default())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate ATProto client with lexicon validation
|
// Generate ATProto client with lexicon validation
|
||||||
#[cfg(feature = "blog")]
|
#[cfg(feature = "blog")]
|
||||||
atrium_codegen::genapi(
|
atrium_codegen::genapi(
|
||||||
|
|
|
@ -15,7 +15,7 @@ use tokio_util::sync::CancellationToken;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::action::Action;
|
use crate::action::Action;
|
||||||
use crate::components::*;
|
use crate::{components::*, CONFIG};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::keycode::KeyCodeExt;
|
use crate::keycode::KeyCodeExt;
|
||||||
use crate::tui::terminal::{TerminalInfo, TerminalKind, UnsupportedReason};
|
use crate::tui::terminal::{TerminalInfo, TerminalKind, UnsupportedReason};
|
||||||
|
@ -90,7 +90,7 @@ impl App {
|
||||||
should_suspend: false,
|
should_suspend: false,
|
||||||
needs_resize: false,
|
needs_resize: false,
|
||||||
|
|
||||||
config: Config::new()?,
|
config: CONFIG.clone(),
|
||||||
mode: Mode::Home,
|
mode: Mode::Home,
|
||||||
last_tick_key_events: Vec::new(),
|
last_tick_key_events: Vec::new(),
|
||||||
action_tx,
|
action_tx,
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
#![allow(dead_code)] // Remove this once you start using the code
|
#![allow(dead_code)] // Remove this once you start using the code
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||||
use derive_deref::{Deref, DerefMut};
|
use derive_deref::{Deref, DerefMut};
|
||||||
use directories::ProjectDirs;
|
use directories::{ProjectDirs, UserDirs};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use ratatui::style::{Color, Modifier, Style};
|
use ratatui::style::{Color, Modifier, Style};
|
||||||
use serde::de::Deserializer;
|
use serde::{de::Deserializer, Deserialize};
|
||||||
use serde::Deserialize;
|
use ssh_key::{rand_core, Algorithm, LineEnding, PrivateKey};
|
||||||
use tracing::error;
|
use tracing::{debug, error, info, info_span};
|
||||||
|
|
||||||
use crate::action::Action;
|
use crate::action::Action;
|
||||||
use crate::app::Mode;
|
use crate::app::Mode;
|
||||||
|
@ -31,6 +32,8 @@ pub struct AppConfig {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(default, flatten)]
|
#[serde(default, flatten)]
|
||||||
pub config: AppConfig,
|
pub config: AppConfig,
|
||||||
|
#[serde(default, deserialize_with = "private_key_deserialize")]
|
||||||
|
pub private_keys: Vec<PrivateKey>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub keybindings: KeyBindings,
|
pub keybindings: KeyBindings,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -39,9 +42,9 @@ pub struct Config {
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string();
|
pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string();
|
||||||
pub static ref DATA_FOLDER: Option<PathBuf> =
|
pub static ref DATA_DIR: Option<PathBuf> =
|
||||||
env::var(format!("{}_DATA", PROJECT_NAME.clone())).ok().map(PathBuf::from);
|
env::var(format!("{}_DATA", PROJECT_NAME.clone())).ok().map(PathBuf::from);
|
||||||
pub static ref CONFIG_FOLDER: Option<PathBuf> =
|
pub static ref CONFIG_DIR: Option<PathBuf> =
|
||||||
env::var(format!("{}_CONFIG", PROJECT_NAME.clone())).ok().map(PathBuf::from);
|
env::var(format!("{}_CONFIG", PROJECT_NAME.clone())).ok().map(PathBuf::from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +53,10 @@ impl Config {
|
||||||
let default_config: Config = json5::from_str(CONFIG).unwrap();
|
let default_config: Config = json5::from_str(CONFIG).unwrap();
|
||||||
let data_dir = get_data_dir();
|
let data_dir = get_data_dir();
|
||||||
let config_dir = get_config_dir();
|
let config_dir = get_config_dir();
|
||||||
|
|
||||||
|
info!("Using data directory: {}", data_dir.display());
|
||||||
|
info!("Using config directory: {}", config_dir.display());
|
||||||
|
|
||||||
let mut builder = config::Config::builder()
|
let mut builder = config::Config::builder()
|
||||||
.set_default("data_dir", data_dir.to_str().unwrap())?
|
.set_default("data_dir", data_dir.to_str().unwrap())?
|
||||||
.set_default("config_dir", config_dir.to_str().unwrap())?;
|
.set_default("config_dir", config_dir.to_str().unwrap())?;
|
||||||
|
@ -88,13 +95,18 @@ impl Config {
|
||||||
user_styles.entry(style_key.clone()).or_insert(*style);
|
user_styles.entry(style_key.clone()).or_insert(*style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if cfg.private_keys.is_empty() {
|
||||||
|
for key in default_config.private_keys {
|
||||||
|
cfg.private_keys.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(cfg)
|
Ok(cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_data_dir() -> PathBuf {
|
pub fn get_data_dir() -> PathBuf {
|
||||||
let directory = if let Some(s) = DATA_FOLDER.clone() {
|
let directory = if let Some(s) = DATA_DIR.clone() {
|
||||||
s
|
s
|
||||||
} else if let Some(proj_dirs) = project_directory() {
|
} else if let Some(proj_dirs) = project_directory() {
|
||||||
proj_dirs.data_local_dir().to_path_buf()
|
proj_dirs.data_local_dir().to_path_buf()
|
||||||
|
@ -105,7 +117,7 @@ pub fn get_data_dir() -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config_dir() -> PathBuf {
|
pub fn get_config_dir() -> PathBuf {
|
||||||
let directory = if let Some(s) = CONFIG_FOLDER.clone() {
|
let directory = if let Some(s) = CONFIG_DIR.clone() {
|
||||||
s
|
s
|
||||||
} else if let Some(proj_dirs) = project_directory() {
|
} else if let Some(proj_dirs) = project_directory() {
|
||||||
proj_dirs.config_local_dir().to_path_buf()
|
proj_dirs.config_local_dir().to_path_buf()
|
||||||
|
@ -116,7 +128,60 @@ pub fn get_config_dir() -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn project_directory() -> Option<ProjectDirs> {
|
fn project_directory() -> Option<ProjectDirs> {
|
||||||
ProjectDirs::from("com", "kdheepak", env!("CARGO_PKG_NAME"))
|
ProjectDirs::from("xyz", "devcomp", env!("CARGO_PKG_NAME"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn private_key_deserialize<'de, D>(deserializer: D) -> Result<Vec<PrivateKey>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>, {
|
||||||
|
let keys = HashMap::<String, String>::deserialize(deserializer)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|(pem_type, pem_or_path)| {
|
||||||
|
debug!("Loading {} private key", pem_type);
|
||||||
|
PrivateKey::from_openssh(pem_or_path.as_bytes()).or_else(|_| {
|
||||||
|
debug!("Failed to parse {} PEM from string, trying as file path", pem_type);
|
||||||
|
|
||||||
|
let ud = UserDirs::new().ok_or(ssh_key::Error::Io(io::ErrorKind::NotFound))?;
|
||||||
|
let expanded_path = PathBuf::from(&*shellexpand::full_with_context_no_errors(
|
||||||
|
&pem_or_path,
|
||||||
|
|| ud.home_dir().to_str(),
|
||||||
|
|var| match var {
|
||||||
|
"DATA_DIR" => get_data_dir().to_str().map(|s| s.to_string()),
|
||||||
|
"CONFIG_DIR" => get_config_dir().to_str().map(|s| s.to_string()),
|
||||||
|
"HOME" => Some(String::from("~")),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
if !expanded_path.exists() {
|
||||||
|
let span = info_span!("host_keygen", algo = %pem_type, path = %expanded_path.display());
|
||||||
|
let _lock = span.enter();
|
||||||
|
|
||||||
|
if let Some(parent) = expanded_path.parent() {
|
||||||
|
std::fs::create_dir_all(parent)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Generating key... (this may take a while)");
|
||||||
|
let algo = Algorithm::from_str(&pem_type)?;
|
||||||
|
let key = PrivateKey::random(&mut rand_core::OsRng, algo.to_owned())?;
|
||||||
|
key.write_openssh_file(&expanded_path, LineEnding::default())?;
|
||||||
|
|
||||||
|
return Ok(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrivateKey::read_openssh_file(&expanded_path)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<PrivateKey>, ssh_key::Error>>()
|
||||||
|
.map_err(serde::de::Error::custom)
|
||||||
|
.inspect_err(|err| error!("Loading private keys error: {}", err))?;
|
||||||
|
|
||||||
|
if keys.is_empty() {
|
||||||
|
return Err(serde::de::Error::custom("No valid private keys found in configuration"))
|
||||||
|
.inspect_err(|err| error!("{}", err));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -5,8 +5,7 @@ use cli::Cli;
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use russh::keys::PrivateKey;
|
use russh::server::Config as SshConfig;
|
||||||
use russh::server::Config;
|
|
||||||
use russh::MethodSet;
|
use russh::MethodSet;
|
||||||
use ssh::SshServer;
|
use ssh::SshServer;
|
||||||
|
|
||||||
|
@ -14,7 +13,9 @@ use ssh::SshServer;
|
||||||
pub(crate) use atproto::com;
|
pub(crate) use atproto::com;
|
||||||
#[cfg(feature = "blog")]
|
#[cfg(feature = "blog")]
|
||||||
pub(crate) use atrium_api::*;
|
pub(crate) use atrium_api::*;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::landing::WebLandingServer;
|
use crate::landing::WebLandingServer;
|
||||||
|
|
||||||
mod action;
|
mod action;
|
||||||
|
@ -31,14 +32,9 @@ mod logging;
|
||||||
mod ssh;
|
mod ssh;
|
||||||
mod tui;
|
mod tui;
|
||||||
|
|
||||||
const SSH_KEYS: &[&[u8]] = &[
|
|
||||||
include_bytes!(concat!(env!("OUT_DIR"), "/rsa.pem")),
|
|
||||||
include_bytes!(concat!(env!("OUT_DIR"), "/ecdsa.pem")),
|
|
||||||
include_bytes!(concat!(env!("OUT_DIR"), "/ed25519.pem")),
|
|
||||||
];
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
pub(crate) static ref CONFIG: Config = Config::new().expect("Config loading error, see above");
|
||||||
pub(crate) static ref OPTIONS: Cli = Cli::parse();
|
pub(crate) static ref OPTIONS: Cli = Cli::parse();
|
||||||
pub(crate) static ref SSH_SOCKET_ADDR: Option<SocketAddr> = Some(SocketAddr::from((host_ip().ok()?, OPTIONS.ssh_port)));
|
pub(crate) static ref SSH_SOCKET_ADDR: Option<SocketAddr> = Some(SocketAddr::from((host_ip().ok()?, OPTIONS.ssh_port)));
|
||||||
pub(crate) static ref WEB_SERVER_ADDR: Option<SocketAddr> = Some(SocketAddr::from((host_ip().ok()?, OPTIONS.web_port)));
|
pub(crate) static ref WEB_SERVER_ADDR: Option<SocketAddr> = Some(SocketAddr::from((host_ip().ok()?, OPTIONS.web_port)));
|
||||||
|
@ -53,8 +49,9 @@ async fn main() -> Result<()> {
|
||||||
let ssh_socket_addr = SSH_SOCKET_ADDR.ok_or(eyre!("Invalid host IP provided"))?;
|
let ssh_socket_addr = SSH_SOCKET_ADDR.ok_or(eyre!("Invalid host IP provided"))?;
|
||||||
let web_server_addr = WEB_SERVER_ADDR.ok_or(eyre!("Invalid host IP provided"))?;
|
let web_server_addr = WEB_SERVER_ADDR.ok_or(eyre!("Invalid host IP provided"))?;
|
||||||
|
|
||||||
|
let ssh_config = tokio::task::block_in_place(ssh_config);
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
ssh_res = SshServer::start(ssh_socket_addr, ssh_config()) => ssh_res,
|
ssh_res = SshServer::start(ssh_socket_addr, ssh_config) => ssh_res,
|
||||||
web_res = WebLandingServer::start(web_server_addr) => web_res.map_err(|err| eyre!(err)),
|
web_res = WebLandingServer::start(web_server_addr) => web_res.map_err(|err| eyre!(err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,17 +72,15 @@ pub fn host_ip() -> Result<[u8; 4]> {
|
||||||
.map_err(|_| eyre!("Invalid host IP provided"))
|
.map_err(|_| eyre!("Invalid host IP provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ssh_config() -> Config {
|
#[instrument]
|
||||||
let conf = Config {
|
fn ssh_config() -> SshConfig {
|
||||||
|
let conf = SshConfig {
|
||||||
methods: MethodSet::NONE,
|
methods: MethodSet::NONE,
|
||||||
keys: SSH_KEYS
|
keys: CONFIG.private_keys.clone(),
|
||||||
.to_vec()
|
|
||||||
.iter()
|
|
||||||
.filter_map(|pem| PrivateKey::from_openssh(pem).ok())
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::trace!("SSH config: {:#?}", conf);
|
tracing::info!("SSH will use {} host keys", conf.keys.len());
|
||||||
|
tracing::trace!("SSH config: {:?}", conf);
|
||||||
conf
|
conf
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue