93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
use std::net::SocketAddr;
|
|
|
|
use clap::Parser as _;
|
|
use cli::Cli;
|
|
use color_eyre::eyre::eyre;
|
|
use color_eyre::Result;
|
|
use lazy_static::lazy_static;
|
|
use russh::keys::PrivateKey;
|
|
use russh::server::Config;
|
|
use russh::MethodSet;
|
|
use ssh::SshServer;
|
|
|
|
#[cfg(feature = "blog")]
|
|
pub(crate) use atproto::com;
|
|
#[cfg(feature = "blog")]
|
|
pub(crate) use atrium_api::*;
|
|
|
|
use crate::landing::WebLandingServer;
|
|
|
|
mod action;
|
|
mod app;
|
|
#[cfg(feature = "blog")]
|
|
pub(crate) mod atproto;
|
|
mod cli;
|
|
mod components;
|
|
mod config;
|
|
mod errors;
|
|
mod keycode;
|
|
mod landing;
|
|
mod logging;
|
|
mod ssh;
|
|
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]
|
|
lazy_static! {
|
|
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 WEB_SERVER_ADDR: Option<SocketAddr> = Some(SocketAddr::from((host_ip().ok()?, OPTIONS.web_port)));
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
crate::errors::init()?;
|
|
crate::logging::init()?;
|
|
let _ = *OPTIONS; // force clap to run by evaluating it
|
|
|
|
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"))?;
|
|
|
|
tokio::select! {
|
|
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)),
|
|
}
|
|
}
|
|
|
|
/// Converts the supplied hostname IP via CLI to a fixed size array of `[u8; 4]`, defaults to `127.0.0.1`
|
|
pub fn host_ip() -> Result<[u8; 4]> {
|
|
TryInto::<[u8; 4]>::try_into(
|
|
OPTIONS
|
|
.host
|
|
.splitn(4, ".")
|
|
.map(|octet_str| {
|
|
octet_str.parse::<u8>().map_err(|_| {
|
|
eyre!("Octet component out of range (expected u8)")
|
|
})
|
|
})
|
|
.collect::<Result<Vec<u8>>>()?,
|
|
)
|
|
.map_err(|_| eyre!("Invalid host IP provided"))
|
|
}
|
|
|
|
fn ssh_config() -> Config {
|
|
let conf = Config {
|
|
methods: MethodSet::NONE,
|
|
keys: SSH_KEYS
|
|
.to_vec()
|
|
.iter()
|
|
.filter_map(|pem| PrivateKey::from_openssh(pem).ok())
|
|
.collect(),
|
|
..Default::default()
|
|
};
|
|
|
|
tracing::trace!("SSH config: {:#?}", conf);
|
|
conf
|
|
}
|