the clueless rename

This commit is contained in:
nora 2024-08-24 00:51:47 +02:00
parent ea28daca0c
commit 9ce60280b1
46 changed files with 264 additions and 262 deletions

304
Cargo.lock generated
View file

@ -273,6 +273,158 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cluelessh"
version = "0.1.0"
dependencies = [
"clap",
"cluelessh-agent-client",
"cluelessh-protocol",
"cluelessh-tokio",
"cluelessh-transport",
"eyre",
"rand",
"rpassword",
"tokio",
"tracing",
"tracing-subscriber",
"users",
]
[[package]]
name = "cluelessh-agent-client"
version = "0.1.0"
dependencies = [
"cluelessh-transport",
"eyre",
"tokio",
"tracing",
]
[[package]]
name = "cluelessh-agentctl"
version = "0.1.0"
dependencies = [
"clap",
"cluelessh-agent-client",
"cluelessh-transport",
"eyre",
"hex",
"pem",
"rpassword",
"sha2",
"tokio",
"tracing-subscriber",
]
[[package]]
name = "cluelessh-connection"
version = "0.1.0"
dependencies = [
"cluelessh-transport",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "cluelessh-dos"
version = "0.1.0"
dependencies = [
"clap",
"cluelessh-protocol",
"cluelessh-transport",
"eyre",
"futures",
"rand",
"rpassword",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "cluelessh-faked"
version = "0.1.0"
dependencies = [
"cluelessh-protocol",
"eyre",
"hex-literal",
"rand",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "cluelessh-key"
version = "0.1.0"
dependencies = [
"base64",
"clap",
"cluelessh-keys",
"eyre",
"pem",
"rpassword",
"tracing",
]
[[package]]
name = "cluelessh-keys"
version = "0.1.0"
dependencies = [
"aes",
"bcrypt-pbkdf",
"cluelessh-transport",
"ctr",
"ed25519-dalek",
"pem",
"rand",
]
[[package]]
name = "cluelessh-protocol"
version = "0.1.0"
dependencies = [
"cluelessh-connection",
"cluelessh-transport",
"rand",
"tracing",
]
[[package]]
name = "cluelessh-tokio"
version = "0.1.0"
dependencies = [
"cluelessh-connection",
"cluelessh-protocol",
"cluelessh-transport",
"eyre",
"futures",
"tokio",
"tracing",
]
[[package]]
name = "cluelessh-transport"
version = "0.1.0"
dependencies = [
"aes",
"aes-gcm",
"base64",
"chacha20",
"crypto-bigint",
"ctr",
"ed25519-dalek",
"hex-literal",
"p256",
"poly1305",
"rand_core",
"sha2",
"subtle",
"tracing",
"x25519-dalek",
]
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.2" version = "1.0.2"
@ -446,19 +598,6 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "fakesshd"
version = "0.1.0"
dependencies = [
"eyre",
"hex-literal",
"rand",
"ssh-protocol",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]] [[package]]
name = "ff" name = "ff"
version = "0.13.0" version = "0.13.0"
@ -1200,145 +1339,6 @@ dependencies = [
"der", "der",
] ]
[[package]]
name = "ssh"
version = "0.1.0"
dependencies = [
"clap",
"eyre",
"rand",
"rpassword",
"ssh-agent-client",
"ssh-protocol",
"ssh-tokio",
"ssh-transport",
"tokio",
"tracing",
"tracing-subscriber",
"users",
]
[[package]]
name = "ssh-agent-client"
version = "0.1.0"
dependencies = [
"eyre",
"ssh-transport",
"tokio",
"tracing",
]
[[package]]
name = "ssh-agentctl"
version = "0.1.0"
dependencies = [
"clap",
"eyre",
"hex",
"pem",
"rpassword",
"sha2",
"ssh-agent-client",
"ssh-transport",
"tokio",
"tracing-subscriber",
]
[[package]]
name = "ssh-connection"
version = "0.1.0"
dependencies = [
"ssh-transport",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "ssh-key"
version = "0.1.0"
dependencies = [
"base64",
"clap",
"eyre",
"pem",
"rpassword",
"ssh-keys",
"tracing",
]
[[package]]
name = "ssh-keys"
version = "0.1.0"
dependencies = [
"aes",
"bcrypt-pbkdf",
"ctr",
"ed25519-dalek",
"pem",
"rand",
"ssh-transport",
]
[[package]]
name = "ssh-protocol"
version = "0.1.0"
dependencies = [
"rand",
"ssh-connection",
"ssh-transport",
"tracing",
]
[[package]]
name = "ssh-tokio"
version = "0.1.0"
dependencies = [
"eyre",
"futures",
"ssh-connection",
"ssh-protocol",
"ssh-transport",
"tokio",
"tracing",
]
[[package]]
name = "ssh-transport"
version = "0.1.0"
dependencies = [
"aes",
"aes-gcm",
"base64",
"chacha20",
"crypto-bigint",
"ctr",
"ed25519-dalek",
"hex-literal",
"p256",
"poly1305",
"rand_core",
"sha2",
"subtle",
"tracing",
"x25519-dalek",
]
[[package]]
name = "sshdos"
version = "0.1.0"
dependencies = [
"clap",
"eyre",
"futures",
"rand",
"rpassword",
"ssh-protocol",
"ssh-transport",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"

View file

@ -1,11 +1,11 @@
[package] [package]
name = "ssh-agentctl" name = "cluelessh-agentctl"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
ssh-agent-client = { path = "../../lib/ssh-agent-client" } cluelessh-agent-client = { path = "../../lib/cluelessh-agent-client" }
ssh-transport = { path = "../../lib/ssh-transport" } cluelessh-transport = { path = "../../lib/cluelessh-transport" }
clap = { version = "4.5.16", features = ["derive"] } clap = { version = "4.5.16", features = ["derive"] }
eyre = "0.6.12" eyre = "0.6.12"

View file

@ -3,8 +3,8 @@ use std::{io::Write, path::PathBuf};
use clap::Parser; use clap::Parser;
use eyre::{bail, Context}; use eyre::{bail, Context};
use sha2::Digest; use sha2::Digest;
use ssh_agent_client::{IdentityAnswer, SocketAgentConnection}; use cluelessh_agent_client::{IdentityAnswer, SocketAgentConnection};
use ssh_transport::{key::PublicKey, parse::Writer}; use cluelessh_transport::{key::PublicKey, parse::Writer};
#[derive(clap::Parser, Debug)] #[derive(clap::Parser, Debug)]
struct Args { struct Args {
@ -52,7 +52,7 @@ async fn main() -> eyre::Result<()> {
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")); .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info"));
tracing_subscriber::fmt().with_env_filter(env_filter).init(); tracing_subscriber::fmt().with_env_filter(env_filter).init();
let mut agent = ssh_agent_client::SocketAgentConnection::from_env().await?; let mut agent = cluelessh_agent_client::SocketAgentConnection::from_env().await?;
match args.command { match args.command {
Subcommand::AddIdentity { identity } => { Subcommand::AddIdentity { identity } => {

View file

@ -1,11 +1,11 @@
[package] [package]
name = "sshdos" name = "cluelessh-dos"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
ssh-protocol = { path = "../../lib/ssh-protocol" } cluelessh-protocol = { path = "../../lib/cluelessh-protocol" }
ssh-transport = { path = "../../lib/ssh-transport" } cluelessh-transport = { path = "../../lib/cluelessh-transport" }
clap = { version = "4.5.15", features = ["derive"] } clap = { version = "4.5.15", features = ["derive"] }
eyre = "0.6.12" eyre = "0.6.12"
rand = "0.8.5" rand = "0.8.5"

View file

@ -16,14 +16,14 @@ use tokio::{
}; };
use tracing::{error, info}; use tracing::{error, info};
use ssh_protocol::{ use cluelessh_protocol::{
transport::{self}, transport::{self},
SshStatus, SshStatus,
}; };
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
struct ThreadRngRand; struct ThreadRngRand;
impl ssh_protocol::transport::SshRng for ThreadRngRand { impl cluelessh_protocol::transport::SshRng for ThreadRngRand {
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
rand::thread_rng().fill_bytes(dest); rand::thread_rng().fill_bytes(dest);
} }
@ -96,9 +96,9 @@ async fn execute_attempt_inner(mut conn: TcpStream) -> eyre::Result<()> {
let mut transport = transport::client::ClientConnection::new(ThreadRngRand); let mut transport = transport::client::ClientConnection::new(ThreadRngRand);
transport.abort_for_dos = true; transport.abort_for_dos = true;
let mut state = ssh_protocol::ClientConnection::new( let mut state = cluelessh_protocol::ClientConnection::new(
transport, transport,
ssh_protocol::auth::ClientAuth::new(username.as_bytes().to_vec()), cluelessh_protocol::auth::ClientAuth::new(username.as_bytes().to_vec()),
); );
let mut buf = [0; 1024]; let mut buf = [0; 1024];

View file

@ -1,5 +1,5 @@
[package] [package]
name = "fakesshd" name = "cluelessh-faked"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -7,7 +7,7 @@ edition = "2021"
eyre = "0.6.12" eyre = "0.6.12"
hex-literal = "0.4.1" hex-literal = "0.4.1"
rand = "0.8.5" rand = "0.8.5"
ssh-protocol = { path = "../../lib/ssh-protocol" } cluelessh-protocol = { path = "../../lib/cluelessh-protocol" }
tokio = { version = "1.39.2", features = ["full"] } tokio = { version = "1.39.2", features = ["full"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] }

View file

@ -2,9 +2,11 @@
set -euxo pipefail set -euxo pipefail
cargo build -p fakesshd pkill cluelessh-faked || true
cargo run -p fakesshd & cargo build -p cluelessh-faked
cargo run -p cluelessh-faked &
sleep 1 sleep 1
@ -13,4 +15,4 @@ ssh -p 2222 -oCiphers=aes256-gcm@openssh.com \
-oHostKeyAlgorithms=ecdsa-sha2-nistp256 \ -oHostKeyAlgorithms=ecdsa-sha2-nistp256 \
-oKexAlgorithms=ecdh-sha2-nistp256 127.0.0.1 true -oKexAlgorithms=ecdh-sha2-nistp256 127.0.0.1 true
pkill fakesshd pkill cluelessh-faked

View file

@ -8,7 +8,7 @@ use tokio::{
}; };
use tracing::{debug, error, info, info_span, Instrument}; use tracing::{debug, error, info, info_span, Instrument};
use ssh_protocol::{ use cluelessh_protocol::{
connection::{ChannelOpen, ChannelOperationKind, ChannelRequest}, connection::{ChannelOpen, ChannelOperationKind, ChannelRequest},
transport::{self}, transport::{self},
ChannelUpdateKind, ServerConnection, SshStatus, ChannelUpdateKind, ServerConnection, SshStatus,
@ -16,7 +16,7 @@ use ssh_protocol::{
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
struct ThreadRngRand; struct ThreadRngRand;
impl ssh_protocol::transport::SshRng for ThreadRngRand { impl cluelessh_protocol::transport::SshRng for ThreadRngRand {
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
rand::thread_rng().fill_bytes(dest); rand::thread_rng().fill_bytes(dest);
} }
@ -94,7 +94,7 @@ async fn handle_connection(
0x95, 0x18, 0x4b, 0xd2, 0xcb, 0xd0, 0x64, 0x06, 0x95, 0x18, 0x4b, 0xd2, 0xcb, 0xd0, 0x64, 0x06,
]; ];
struct HardcodedRng(Vec<u8>); struct HardcodedRng(Vec<u8>);
impl ssh_protocol::transport::SshRng for HardcodedRng { impl cluelessh_protocol::transport::SshRng for HardcodedRng {
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
dest.copy_from_slice(&self.0[..dest.len()]); dest.copy_from_slice(&self.0[..dest.len()]);
self.0.splice(0..dest.len(), []); self.0.splice(0..dest.len(), []);

View file

@ -1,5 +1,5 @@
[package] [package]
name = "ssh-key" name = "cluelessh-key"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -8,7 +8,7 @@ clap = { version = "4.5.16", features = ["derive"] }
eyre = "0.6.12" eyre = "0.6.12"
tracing.workspace = true tracing.workspace = true
ssh-keys = { path = "../../lib/ssh-keys" } cluelessh-keys = { path = "../../lib/cluelessh-keys" }
base64 = "0.22.1" base64 = "0.22.1"
rpassword = "7.3.1" rpassword = "7.3.1"
pem = "3.0.4" pem = "3.0.4"

View file

@ -6,8 +6,8 @@ use std::{
use base64::Engine; use base64::Engine;
use clap::Parser; use clap::Parser;
use cluelessh_keys::{KeyEncryptionParams, PrivateKeyType};
use eyre::{bail, Context}; use eyre::{bail, Context};
use ssh_keys::{KeyEncryptionParams, PrivateKeyType};
#[derive(clap::Parser)] #[derive(clap::Parser)]
struct Args { struct Args {
@ -82,7 +82,7 @@ fn main() -> eyre::Result<()> {
} => { } => {
let file = std::fs::read(&id_file) let file = std::fs::read(&id_file)
.wrap_err_with(|| format!("reading file {}", id_file.display()))?; .wrap_err_with(|| format!("reading file {}", id_file.display()))?;
let keys = ssh_keys::EncryptedPrivateKeys::parse(&file)?; let keys = cluelessh_keys::EncryptedPrivateKeys::parse(&file)?;
let passphrase = if keys.requires_passphrase() { let passphrase = if keys.requires_passphrase() {
let phrase = rpassword::prompt_password("passphrase: ")?; let phrase = rpassword::prompt_password("passphrase: ")?;
Some(phrase) Some(phrase)
@ -115,7 +115,7 @@ fn info(id_file: &Path, decrypt: bool, show_private: bool) -> eyre::Result<()> {
let file = let file =
std::fs::read(&id_file).wrap_err_with(|| format!("reading file {}", id_file.display()))?; std::fs::read(&id_file).wrap_err_with(|| format!("reading file {}", id_file.display()))?;
let keys = ssh_keys::EncryptedPrivateKeys::parse(&file)?; let keys = cluelessh_keys::EncryptedPrivateKeys::parse(&file)?;
if decrypt { if decrypt {
let passphrase = if keys.requires_passphrase() { let passphrase = if keys.requires_passphrase() {
@ -149,14 +149,14 @@ fn info(id_file: &Path, decrypt: bool, show_private: bool) -> eyre::Result<()> {
fn generate(type_: KeyType, comment: String, path: &Path) -> eyre::Result<()> { fn generate(type_: KeyType, comment: String, path: &Path) -> eyre::Result<()> {
let type_ = match type_ { let type_ = match type_ {
KeyType::Ed25519 => ssh_keys::KeyType::Ed25519, KeyType::Ed25519 => cluelessh_keys::KeyType::Ed25519,
}; };
let passphrase = rpassword::prompt_password("Enter passphrase (empty for no passphrase): ")?; let passphrase = rpassword::prompt_password("Enter passphrase (empty for no passphrase): ")?;
let key = ssh_keys::PlaintextPrivateKey::generate( let key = cluelessh_keys::PlaintextPrivateKey::generate(
comment, comment,
ssh_keys::KeyGenerationParams { key_type: type_ }, cluelessh_keys::KeyGenerationParams { key_type: type_ },
); );
println!("{} {}", key.private_key.public_key(), key.comment); println!("{} {}", key.private_key.public_key(), key.comment);

View file

@ -1,13 +1,13 @@
[package] [package]
name = "ssh" name = "cluelessh"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
ssh-protocol = { path = "../../lib/ssh-protocol" } cluelessh-protocol = { path = "../../lib/cluelessh-protocol" }
ssh-transport = { path = "../../lib/ssh-transport" } cluelessh-transport = { path = "../../lib/cluelessh-transport" }
ssh-agent-client = { path = "../../lib/ssh-agent-client" } cluelessh-agent-client = { path = "../../lib/cluelessh-agent-client" }
ssh-tokio = { path = "../../lib/ssh-tokio" } cluelessh-tokio = { path = "../../lib/cluelessh-tokio" }
clap = { version = "4.5.15", features = ["derive"] } clap = { version = "4.5.15", features = ["derive"] }
eyre = "0.6.12" eyre = "0.6.12"

View file

@ -3,12 +3,12 @@ use std::{collections::HashSet, sync::Arc};
use clap::Parser; use clap::Parser;
use eyre::{bail, Context, ContextCompat, OptionExt, Result}; use eyre::{bail, Context, ContextCompat, OptionExt, Result};
use ssh_tokio::client::{PendingChannel, SignatureResult}; use cluelessh_tokio::client::{PendingChannel, SignatureResult};
use ssh_transport::{key::PublicKey, numbers, parse::Writer}; use cluelessh_transport::{key::PublicKey, numbers, parse::Writer};
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tracing::{debug, error}; use tracing::{debug, error};
use ssh_protocol::connection::{ChannelOpen, ChannelOperationKind, ChannelRequest}; use cluelessh_protocol::connection::{ChannelOpen, ChannelOperationKind, ChannelRequest};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
#[derive(clap::Parser, Debug)] #[derive(clap::Parser, Debug)]
@ -50,9 +50,9 @@ async fn main() -> eyre::Result<()> {
.wrap_err("connecting")?; .wrap_err("connecting")?;
let username1 = username.clone(); let username1 = username.clone();
let mut tokio_conn = ssh_tokio::client::ClientConnection::connect( let mut tokio_conn = cluelessh_tokio::client::ClientConnection::connect(
conn, conn,
ssh_tokio::client::ClientAuth { cluelessh_tokio::client::ClientAuth {
username: username.clone(), username: username.clone(),
prompt_password: Arc::new(move || { prompt_password: Arc::new(move || {
let username = username1.clone(); let username = username1.clone();
@ -76,7 +76,7 @@ async fn main() -> eyre::Result<()> {
Box::pin(async move { Box::pin(async move {
// TODO: support agentless manual key opening // TODO: support agentless manual key opening
// TODO: move // TODO: move
let mut agent = ssh_agent_client::SocketAgentConnection::from_env() let mut agent = cluelessh_agent_client::SocketAgentConnection::from_env()
.await .await
.wrap_err("failed to connect to SSH agent")?; .wrap_err("failed to connect to SSH agent")?;
let identities = agent.list_identities().await?; let identities = agent.list_identities().await?;

View file

@ -1,10 +1,10 @@
[package] [package]
name = "ssh-agent-client" name = "cluelessh-agent-client"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
eyre = "0.6.12" eyre = "0.6.12"
ssh-transport = { path = "../ssh-transport" } cluelessh-transport = { path = "../cluelessh-transport" }
tokio = { version = "1.39.3", features = ["net"] } tokio = { version = "1.39.3", features = ["net"] }
tracing.workspace = true tracing.workspace = true

View file

@ -1,5 +1,5 @@
use eyre::{bail, eyre, Context}; use eyre::{bail, eyre, Context};
use ssh_transport::{ use cluelessh_transport::{
packet::PacketParser, packet::PacketParser,
parse::{Parser, Writer}, parse::{Parser, Writer},
SshStatus, SshStatus,

View file

@ -1,10 +1,10 @@
[package] [package]
name = "ssh-connection" name = "cluelessh-connection"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
ssh-transport = { path = "../ssh-transport" } cluelessh-transport = { path = "../cluelessh-transport" }
tracing.workspace = true tracing.workspace = true
[dev-dependencies] [dev-dependencies]

View file

@ -1,4 +1,4 @@
# ssh-connection # cluelessh-connection
Connection layer for SSH. This crate takes care of channel multiplexing. Connection layer for SSH. This crate takes care of channel multiplexing.

View file

@ -2,9 +2,9 @@ use std::cmp;
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use tracing::{debug, info, trace, warn}; use tracing::{debug, info, trace, warn};
use ssh_transport::packet::Packet; use cluelessh_transport::packet::Packet;
use ssh_transport::Result; use cluelessh_transport::Result;
use ssh_transport::{numbers, peer_error}; use cluelessh_transport::{numbers, peer_error};
/// A channel number (on our side). /// A channel number (on our side).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -728,7 +728,7 @@ impl ChannelOperation {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ssh_transport::{numbers, packet::Packet}; use cluelessh_transport::{numbers, packet::Packet};
use crate::{ChannelNumber, ChannelOperation, ChannelOperationKind, ChannelsState}; use crate::{ChannelNumber, ChannelOperation, ChannelOperationKind, ChannelsState};

View file

@ -1,5 +1,5 @@
[package] [package]
name = "ssh-keys" name = "cluelessh-keys"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -10,4 +10,4 @@ ctr = "0.9.2"
ed25519-dalek = { version = "2.1.1", features = ["rand_core"] } ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }
pem = "3.0.4" pem = "3.0.4"
rand = "0.8.5" rand = "0.8.5"
ssh-transport = { path = "../ssh-transport" } cluelessh-transport = { path = "../cluelessh-transport" }

View file

@ -1,7 +1,7 @@
use std::str::FromStr; use std::str::FromStr;
use aes::cipher::{KeySizeUser, StreamCipher}; use aes::cipher::{KeySizeUser, StreamCipher};
use ssh_transport::parse::{self, Parser, Writer}; use cluelessh_transport::parse::{self, Parser, Writer};
use crate::PrivateKeyType; use crate::PrivateKeyType;

View file

@ -1,7 +1,7 @@
mod crypto; mod crypto;
use crypto::{Cipher, Kdf}; use crypto::{Cipher, Kdf};
use ssh_transport::{ use cluelessh_transport::{
key::PublicKey, key::PublicKey,
parse::{self, Parser, Writer}, parse::{self, Parser, Writer},
}; };

View file

@ -0,0 +1,11 @@
[package]
name = "cluelessh-protocol"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8.5"
cluelessh-connection = { path = "../cluelessh-connection" }
cluelessh-transport = { path = "../cluelessh-transport" }
tracing.workspace = true

View file

@ -1,5 +1,5 @@
# ssh-protocol # cluelessh-protocol
Combines `ssh-connection` and `ssh-transport` into a higher level interface. Combines `cluelessh-connection` and `cluelessh-transport` into a higher level interface.
Also implements authentication based on [RFC 4252 The Secure Shell (SSH) Authentication Protocol](https://datatracker.ietf.org/doc/html/rfc4252). Also implements authentication based on [RFC 4252 The Secure Shell (SSH) Authentication Protocol](https://datatracker.ietf.org/doc/html/rfc4252).

View file

@ -1,10 +1,10 @@
use std::mem; use std::mem;
pub use ssh_connection as connection; pub use cluelessh_connection as connection;
use ssh_connection::ChannelOperation; use cluelessh_connection::ChannelOperation;
pub use ssh_connection::{ChannelUpdate, ChannelUpdateKind}; pub use cluelessh_connection::{ChannelUpdate, ChannelUpdateKind};
pub use ssh_transport as transport; pub use cluelessh_transport as transport;
pub use ssh_transport::{Result, SshStatus}; pub use cluelessh_transport::{Result, SshStatus};
use tracing::debug; use tracing::debug;
pub struct ThreadRngRand; pub struct ThreadRngRand;
@ -16,17 +16,17 @@ impl transport::SshRng for ThreadRngRand {
} }
pub struct ServerConnection { pub struct ServerConnection {
transport: ssh_transport::server::ServerConnection, transport: cluelessh_transport::server::ServerConnection,
state: ServerConnectionState, state: ServerConnectionState,
} }
enum ServerConnectionState { enum ServerConnectionState {
Auth(auth::BadAuth), Auth(auth::BadAuth),
Open(ssh_connection::ChannelsState), Open(cluelessh_connection::ChannelsState),
} }
impl ServerConnection { impl ServerConnection {
pub fn new(transport: ssh_transport::server::ServerConnection) -> Self { pub fn new(transport: cluelessh_transport::server::ServerConnection) -> Self {
Self { Self {
transport, transport,
state: ServerConnectionState::Auth(auth::BadAuth::new()), state: ServerConnectionState::Auth(auth::BadAuth::new()),
@ -45,7 +45,7 @@ impl ServerConnection {
} }
if auth.is_authenticated() { if auth.is_authenticated() {
self.state = self.state =
ServerConnectionState::Open(ssh_connection::ChannelsState::new(true)); ServerConnectionState::Open(cluelessh_connection::ChannelsState::new(true));
} }
} }
ServerConnectionState::Open(con) => { ServerConnectionState::Open(con) => {
@ -59,11 +59,11 @@ impl ServerConnection {
Ok(()) Ok(())
} }
pub fn next_msg_to_send(&mut self) -> Option<ssh_transport::Msg> { pub fn next_msg_to_send(&mut self) -> Option<cluelessh_transport::Msg> {
self.transport.next_msg_to_send() self.transport.next_msg_to_send()
} }
pub fn next_channel_update(&mut self) -> Option<ssh_connection::ChannelUpdate> { pub fn next_channel_update(&mut self) -> Option<cluelessh_connection::ChannelUpdate> {
match &mut self.state { match &mut self.state {
ServerConnectionState::Auth(_) => None, ServerConnectionState::Auth(_) => None,
ServerConnectionState::Open(con) => con.next_channel_update(), ServerConnectionState::Open(con) => con.next_channel_update(),
@ -97,18 +97,18 @@ impl ServerConnection {
} }
pub struct ClientConnection { pub struct ClientConnection {
transport: ssh_transport::client::ClientConnection, transport: cluelessh_transport::client::ClientConnection,
state: ClientConnectionState, state: ClientConnectionState,
} }
enum ClientConnectionState { enum ClientConnectionState {
Setup(Option<auth::ClientAuth>), Setup(Option<auth::ClientAuth>),
Auth(auth::ClientAuth), Auth(auth::ClientAuth),
Open(ssh_connection::ChannelsState), Open(cluelessh_connection::ChannelsState),
} }
impl ClientConnection { impl ClientConnection {
pub fn new(transport: ssh_transport::client::ClientConnection, auth: auth::ClientAuth) -> Self { pub fn new(transport: cluelessh_transport::client::ClientConnection, auth: auth::ClientAuth) -> Self {
Self { Self {
transport, transport,
state: ClientConnectionState::Setup(Some(auth)), state: ClientConnectionState::Setup(Some(auth)),
@ -140,7 +140,7 @@ impl ClientConnection {
} }
if auth.is_authenticated() { if auth.is_authenticated() {
self.state = self.state =
ClientConnectionState::Open(ssh_connection::ChannelsState::new(false)); ClientConnectionState::Open(cluelessh_connection::ChannelsState::new(false));
} }
} }
ClientConnectionState::Open(con) => { ClientConnectionState::Open(con) => {
@ -162,7 +162,7 @@ impl ClientConnection {
} }
} }
pub fn channels(&mut self) -> Option<&mut ssh_connection::ChannelsState> { pub fn channels(&mut self) -> Option<&mut cluelessh_connection::ChannelsState> {
match &mut self.state { match &mut self.state {
ClientConnectionState::Open(channels) => Some(channels), ClientConnectionState::Open(channels) => Some(channels),
_ => None, _ => None,
@ -173,11 +173,11 @@ impl ClientConnection {
matches!(self.state, ClientConnectionState::Open(_)) matches!(self.state, ClientConnectionState::Open(_))
} }
pub fn next_msg_to_send(&mut self) -> Option<ssh_transport::Msg> { pub fn next_msg_to_send(&mut self) -> Option<cluelessh_transport::Msg> {
self.transport.next_msg_to_send() self.transport.next_msg_to_send()
} }
pub fn next_channel_update(&mut self) -> Option<ssh_connection::ChannelUpdate> { pub fn next_channel_update(&mut self) -> Option<cluelessh_connection::ChannelUpdate> {
match &mut self.state { match &mut self.state {
ClientConnectionState::Setup(_) => None, ClientConnectionState::Setup(_) => None,
ClientConnectionState::Auth(_) => None, ClientConnectionState::Auth(_) => None,
@ -218,7 +218,7 @@ impl ClientConnection {
pub mod auth { pub mod auth {
use std::collections::VecDeque; use std::collections::VecDeque;
use ssh_transport::{numbers, packet::Packet, parse::NameList, peer_error, Result}; use cluelessh_transport::{numbers, packet::Packet, parse::NameList, peer_error, Result};
use tracing::{debug, info}; use tracing::{debug, info};
pub struct BadAuth { pub struct BadAuth {

View file

@ -0,0 +1,13 @@
[package]
name = "cluelessh-tokio"
version = "0.1.0"
edition = "2021"
[dependencies]
eyre = "0.6.12"
cluelessh-transport = { path = "../cluelessh-transport" }
cluelessh-connection = { path = "../cluelessh-connection" }
cluelessh-protocol = { path = "../cluelessh-protocol" }
tokio = { version = "1.39.3", features = ["net"] }
tracing.workspace = true
futures = "0.3.30"

View file

@ -1,10 +1,10 @@
use ssh_connection::{ChannelNumber, ChannelOpen, ChannelOperation, ChannelOperationKind}; use cluelessh_connection::{ChannelNumber, ChannelOpen, ChannelOperation, ChannelOperationKind};
use std::{collections::HashMap, pin::Pin, sync::Arc}; use std::{collections::HashMap, pin::Pin, sync::Arc};
use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::io::{AsyncReadExt, AsyncWriteExt};
use eyre::{bail, ContextCompat, OptionExt, Result, WrapErr}; use eyre::{bail, ContextCompat, OptionExt, Result, WrapErr};
use futures::future::BoxFuture; use futures::future::BoxFuture;
use ssh_protocol::{ChannelUpdateKind, SshStatus}; use cluelessh_protocol::{ChannelUpdateKind, SshStatus};
use tokio::io::{AsyncRead, AsyncWrite}; use tokio::io::{AsyncRead, AsyncWrite};
use tracing::{debug, info, warn}; use tracing::{debug, info, warn};
@ -12,7 +12,7 @@ pub struct ClientConnection<S> {
stream: Pin<Box<S>>, stream: Pin<Box<S>>,
buf: [u8; 1024], buf: [u8; 1024],
proto: ssh_protocol::ClientConnection, proto: cluelessh_protocol::ClientConnection,
operations_send: tokio::sync::mpsc::Sender<Operation>, operations_send: tokio::sync::mpsc::Sender<Operation>,
operations_recv: tokio::sync::mpsc::Receiver<Operation>, operations_recv: tokio::sync::mpsc::Receiver<Operation>,
@ -74,9 +74,9 @@ impl<S: AsyncRead + AsyncWrite> ClientConnection<S> {
channel_ops_send, channel_ops_send,
channel_ops_recv, channel_ops_recv,
channels: HashMap::new(), channels: HashMap::new(),
proto: ssh_protocol::ClientConnection::new( proto: cluelessh_protocol::ClientConnection::new(
ssh_transport::client::ClientConnection::new(ssh_protocol::ThreadRngRand), cluelessh_transport::client::ClientConnection::new(cluelessh_protocol::ThreadRngRand),
ssh_protocol::auth::ClientAuth::new(auth.username.as_bytes().to_vec()), cluelessh_protocol::auth::ClientAuth::new(auth.username.as_bytes().to_vec()),
), ),
auth, auth,
}; };
@ -94,7 +94,7 @@ impl<S: AsyncRead + AsyncWrite> ClientConnection<S> {
if let Some(auth) = self.proto.auth() { if let Some(auth) = self.proto.auth() {
for req in auth.user_requests() { for req in auth.user_requests() {
match req { match req {
ssh_protocol::auth::ClientUserRequest::Password => { cluelessh_protocol::auth::ClientUserRequest::Password => {
let send = self.operations_send.clone(); let send = self.operations_send.clone();
let prompt_password = self.auth.prompt_password.clone(); let prompt_password = self.auth.prompt_password.clone();
tokio::spawn(async move { tokio::spawn(async move {
@ -102,7 +102,7 @@ impl<S: AsyncRead + AsyncWrite> ClientConnection<S> {
let _ = send.send(Operation::PasswordEntered(password)).await; let _ = send.send(Operation::PasswordEntered(password)).await;
}); });
} }
ssh_protocol::auth::ClientUserRequest::PrivateKeySign { cluelessh_protocol::auth::ClientUserRequest::PrivateKeySign {
session_identifier, session_identifier,
} => { } => {
let send = self.operations_send.clone(); let send = self.operations_send.clone();
@ -112,7 +112,7 @@ impl<S: AsyncRead + AsyncWrite> ClientConnection<S> {
let _ = send.send(Operation::Signature(signature_result)).await; let _ = send.send(Operation::Signature(signature_result)).await;
}); });
} }
ssh_protocol::auth::ClientUserRequest::Banner(_) => { cluelessh_protocol::auth::ClientUserRequest::Banner(_) => {
warn!("ignoring banner as it's not implemented..."); warn!("ignoring banner as it's not implemented...");
} }
} }

View file

@ -1,5 +1,5 @@
[package] [package]
name = "ssh-transport" name = "cluelessh-transport"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

View file

@ -1,4 +1,4 @@
# ssh-transport # cluelessh-transport
Transport layer of SSH. Transport layer of SSH.

View file

@ -1,11 +0,0 @@
[package]
name = "ssh-protocol"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8.5"
ssh-connection = { path = "../ssh-connection" }
ssh-transport = { path = "../ssh-transport" }
tracing.workspace = true

View file

@ -1,13 +0,0 @@
[package]
name = "ssh-tokio"
version = "0.1.0"
edition = "2021"
[dependencies]
eyre = "0.6.12"
ssh-transport = { path = "../ssh-transport" }
ssh-connection = { path = "../ssh-connection" }
ssh-protocol = { path = "../ssh-protocol" }
tokio = { version = "1.39.3", features = ["net"] }
tracing.workspace = true
futures = "0.3.30"