Consolidate session production to just the session struct

pull/38/head
Chip Senkbeil 3 years ago
parent de69b419a4
commit d9c2b9942a
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

@ -117,6 +117,11 @@ impl Session {
.map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x))
}
/// Consumes the session and returns the auth key
pub fn into_auth_key(self) -> SecretKey {
self.auth_key
}
/// Returns the ip address associated with the session based on the host
pub async fn to_ip_addr(&self) -> io::Result<IpAddr> {
let addr = match self.host.parse::<IpAddr>() {
@ -143,14 +148,14 @@ impl Session {
}
/// Converts to unprotected string that exposes the auth key in the form of
/// `DISTANT DATA <addr> <port> <auth key>`
pub async fn to_unprotected_string(&self) -> io::Result<String> {
Ok(format!(
/// `DISTANT DATA <host> <port> <auth key>`
pub fn to_unprotected_string(&self) -> String {
format!(
"DISTANT DATA {} {} {}",
self.to_ip_addr().await?,
self.host,
self.port,
self.to_unprotected_hex_auth_key()
))
)
}
}
@ -205,7 +210,7 @@ impl SessionFile {
/// Saves a session to to a file at the specified path
pub async fn save_to(&self, path: impl AsRef<Path>) -> io::Result<()> {
tokio::fs::write(path.as_ref(), self.0.to_unprotected_string().await?).await
tokio::fs::write(path.as_ref(), self.0.to_unprotected_string()).await
}
/// Loads a session from the global session file

@ -93,7 +93,6 @@ fn spawn_stdin_reader() -> mpsc::Receiver<String> {
x
);
}
// std::thread::sleep(std::time::Duration::from_millis(1));
std::thread::yield_now();
}
}
@ -139,7 +138,7 @@ async fn interactive_loop(
Err(x) => error!("Failed to format response: {}", x),
},
Err(x) => {
error!("Failed to send request to remote process ({}): {}", id, x)
error!("Failed to send request: {}", x)
}
},
Err(x) => {
@ -169,7 +168,7 @@ async fn interactive_loop(
Err(x) => error!("Failed to format response: {}", x),
},
Err(x) => {
error!("Failed to send request to remote process ({}): {}", id, x)
error!("Failed to send request: {}", x)
}
},
Err(x) => {

@ -4,7 +4,7 @@ use crate::{
};
use derive_more::{Display, Error, From};
use hex::FromHexError;
use orion::{aead::SecretKey, errors::UnknownCryptoError};
use orion::errors::UnknownCryptoError;
use std::string::FromUtf8Error;
use tokio::{io, process::Command};
@ -56,35 +56,14 @@ async fn run_async(cmd: LaunchSubcommand, _opt: CommonOpt) -> Result<(), Error>
)));
}
// Parse our output for the specific info line
// Parse our output for the specific session line
// NOTE: The host provided on this line isn't valid, so we fill it in with our actual host
let out = String::from_utf8(out.stdout)?.trim().to_string();
let result = out
let mut session = out
.lines()
.find_map(|line| {
let tokens: Vec<&str> = line.split(' ').take(4).collect();
let is_data_line = tokens.len() == 4 && tokens[0] == "DISTANT" && tokens[1] == "DATA";
match tokens[2].parse::<u16>() {
Ok(port) if is_data_line => {
let key = hex::decode(tokens[3])
.map_err(Error::from)
.and_then(|bytes| SecretKey::from_slice(&bytes).map_err(Error::from));
match key {
Ok(key) => Some(Ok((port, key))),
Err(x) => Some(Err(x)),
}
}
_ => None,
}
})
.unwrap_or(Err(Error::MissingSessionData));
// Write a session file containing our data for use in subsequent calls
let (port, auth_key) = result?;
let session = Session {
host: cmd.host,
port,
auth_key,
};
.find_map(|line| line.parse::<Session>().ok())
.ok_or(Error::MissingSessionData)?;
session.host = cmd.host;
// Handle sharing resulting session in different ways
// NOTE: Environment is unreachable here as we disallow it from the defined options since
@ -92,7 +71,7 @@ async fn run_async(cmd: LaunchSubcommand, _opt: CommonOpt) -> Result<(), Error>
match cmd.session {
SessionSharing::Environment => unreachable!(),
SessionSharing::File => SessionFile::from(session).save().await?,
SessionSharing::Pipe => println!("{}", session.to_unprotected_string().await?),
SessionSharing::Pipe => println!("{}", session.to_unprotected_string()),
}
Ok(())

@ -2,6 +2,7 @@ use crate::{
data::{Request, Response},
net::{Transport, TransportReadHalf, TransportWriteHalf},
opt::{CommonOpt, ConvertToIpAddrError, ListenSubcommand},
session::Session,
};
use derive_more::{Display, Error, From};
use fork::{daemon, Fork};
@ -100,10 +101,18 @@ async fn run_async(cmd: ListenSubcommand, _opt: CommonOpt, is_forked: bool) -> R
let port = listener.local_addr()?.port();
debug!("Bound to port: {}", port);
let key = Arc::new(SecretKey::default());
// Print information about port, key, etc.
publish_data(port, &key);
let key = {
let session = Session {
host: "--".to_string(),
port,
auth_key: SecretKey::default(),
};
println!("{}", session.to_unprotected_string());
Arc::new(session.into_auth_key())
};
// For the child, we want to fully disconnect it from pipes, which we do now
if is_forked {
@ -209,14 +218,3 @@ async fn response_loop(
}
}
}
/// Prints out the port and **secret auth key** to share with a client when
/// establishing communication. This is **highly unsafe** and should only be
/// done when the server is launched over a secure channel such as SSH.
fn publish_data(port: u16, key: &SecretKey) {
println!(
"DISTANT DATA {} {}",
port,
hex::encode(key.unprotected_as_bytes())
);
}

Loading…
Cancel
Save