This builds, I guess.

This commit is contained in:
2025-01-12 14:10:23 -08:00
parent b30823a502
commit 268ca2d1a5
25 changed files with 1750 additions and 735 deletions

View File

@@ -1,12 +1,13 @@
use crate::config::{ClientCommand, ClientConfiguration};
use crate::config::client::{ClientCommand, ClientConfiguration};
use crate::crypto::{
CompressionAlgorithm, EncryptionAlgorithm, HostKeyAlgorithm, KeyExchangeAlgorithm, MacAlgorithm,
};
use crate::network::host::Host;
use crate::ssh;
use crate::network::resolver::Resolver;
use crate::ssh::{self, SshKeyExchange};
use crate::OperationalError;
use error_stack::{report, Report, ResultExt};
use std::fmt::Display;
use std::fmt;
use std::str::FromStr;
use thiserror::Error;
use tracing::Instrument;
@@ -27,12 +28,19 @@ pub async fn hush(base_config: ClientConfiguration) -> error_stack::Result<(), O
}
}
#[derive(Debug)]
struct Target {
username: String,
host: Host,
port: u16,
}
impl fmt::Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}@{}:{}", self.username, self.host, self.port)
}
}
#[derive(Debug, Error)]
pub enum TargetParseError {
#[error("Invalid port number '{port_string}': {error}")]
@@ -87,35 +95,54 @@ impl FromStr for Target {
}
}
#[allow(unreachable_code,unused_variables)]
async fn connect(
base_config: &ClientConfiguration,
target: &str,
) -> error_stack::Result<(), OperationalError> {
let resolver = base_config.resolver();
let resolver: Resolver = unimplemented!();
// let mut resolver = Resolver::new(&base_config.resolver)
// .await
// .change_context(OperationalError::DnsConfig)?;
let target = Target::from_str(target)
.change_context(OperationalError::UnableToParseHostAddress)
.attach_printable_lazy(|| format!("target address '{}'", target))?;
tracing::trace!(%target, "determined SSH target");
let mut stream = target
.host
.connect(resolver, 22)
.connect(&mut resolver, 22)
.await
.change_context(OperationalError::Connection)?;
let server_addr_str = stream
.peer_addr()
.map(|x| x.to_string())
.unwrap_or_else(|_| "<unknown>".to_string());
let client_addr_str = stream
.local_addr()
.map(|x| x.to_string())
.unwrap_or_else(|_| "<unknown>".to_string());
let stream_span = tracing::debug_span!(
"client connection",
server = %stream.peer_addr().map(|x| x.to_string()).unwrap_or_else(|_| "<unknown>".to_string()),
client = %stream.local_addr().map(|x| x.to_string()).unwrap_or_else(|_| "<unknown>".to_string()),
server = %server_addr_str,
client = %client_addr_str,
);
tracing::trace!(%target, "connected to target server");
let stream_error_info = || server_addr_str.clone();
let their_preamble = ssh::Preamble::read(&mut stream)
.instrument(stream_span.clone())
.await
.change_context(OperationalError::Connection)?;
tracing::trace!("received their preamble");
let our_preamble = ssh::Preamble::default()
let _our_preamble = ssh::Preamble::default()
.write(&mut stream)
.instrument(stream_span)
.await
.change_context(OperationalError::Connection)?;
tracing::trace!("wrote our preamble");
if !their_preamble.preamble.is_empty() {
for line in their_preamble.preamble.lines() {
@@ -130,13 +157,22 @@ async fn connect(
"received server preamble"
);
let mut stream = ssh::SshChannel::new(stream);
let stream = ssh::SshChannel::new(stream);
let their_initial = stream
.read()
.await
.attach_printable_lazy(stream_error_info)
.change_context(OperationalError::KeyExchange)?
.ok_or_else();
.ok_or_else(|| report!(OperationalError::KeyExchange))
.attach_printable_lazy(stream_error_info)
.attach_printable_lazy(|| "No initial key exchange message found")?;
let their_kex: SshKeyExchange = SshKeyExchange::try_from(their_initial)
.attach_printable_lazy(stream_error_info)
.change_context(OperationalError::KeyExchange)?;
println!("their_key: {:?}", their_kex);
// let mut rng = rand::thread_rng();
//
// let packet = stream
@@ -165,7 +201,7 @@ async fn connect(
Ok(())
}
fn print_options<T: Display>(items: &[T]) -> error_stack::Result<(), OperationalError> {
fn print_options<T: fmt::Display>(items: &[T]) -> error_stack::Result<(), OperationalError> {
for item in items.iter() {
println!("{}", item);
}