feat: added a basic interactivity to the client
This commit is contained in:
parent
7876e00dc8
commit
7f1f43a601
134
Cargo.lock
generated
134
Cargo.lock
generated
@ -263,6 +263,18 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_more"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.30",
|
||||||
|
"quote 0.6.13",
|
||||||
|
"rustc_version",
|
||||||
|
"syn 0.15.44",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -443,8 +455,8 @@ version = "0.3.28"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -700,8 +712,8 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f35583365be5d148e959284f42526841917b7bfa09e2d1a7ad5dde2cf0eaa39"
|
checksum = "0f35583365be5d148e959284f42526841917b7bfa09e2d1a7ad5dde2cf0eaa39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -760,8 +772,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error-attr",
|
"proc-macro-error-attr",
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@ -772,11 +784,20 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "0.4.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.66"
|
version = "1.0.66"
|
||||||
@ -786,13 +807,22 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "0.6.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.30",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -836,6 +866,16 @@ dependencies = [
|
|||||||
"rand_core",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw_tty"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51f512d7504049ef0d3f5d48d8aa5129beaea4fccfaf5c500c9b60101394f8b1"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp"
|
name = "rmp"
|
||||||
version = "0.8.12"
|
version = "0.8.12"
|
||||||
@ -864,6 +904,30 @@ version = "0.1.23"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.188"
|
version = "1.0.188"
|
||||||
@ -888,8 +952,8 @@ version = "1.0.188"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -899,8 +963,8 @@ version = "0.1.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -968,10 +1032,13 @@ dependencies = [
|
|||||||
name = "sparse-05-client"
|
name = "sparse-05-client"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ecies-ed25519",
|
"ecies-ed25519",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
"libc",
|
||||||
"rand",
|
"rand",
|
||||||
|
"raw_tty",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"serde",
|
"serde",
|
||||||
"sparse-05-common",
|
"sparse-05-common",
|
||||||
@ -1044,8 +1111,8 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1055,14 +1122,25 @@ version = "2.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "0.15.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.30",
|
||||||
|
"quote 0.6.13",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1072,8 +1150,8 @@ version = "2.0.29"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1101,8 +1179,8 @@ version = "1.0.48"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1159,8 +1237,8 @@ version = "2.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1199,6 +1277,12 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-hash"
|
name = "universal-hash"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -1417,7 +1501,7 @@ version = "1.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 1.0.66",
|
||||||
"quote",
|
"quote 1.0.33",
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
||||||
@ -4,10 +4,13 @@ version = "0.5.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ansi_term = "0.12.1"
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
ecies-ed25519 = { version = "0.5.1", features = ["serde"] }
|
ecies-ed25519 = { version = "0.5.1", features = ["serde"] }
|
||||||
ed25519-dalek = "1.0.1"
|
ed25519-dalek = "1.0.1"
|
||||||
|
libc = "0.2.147"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
raw_tty = "0.1.0"
|
||||||
rmp-serde = "1.1.2"
|
rmp-serde = "1.1.2"
|
||||||
serde = { version = "1.0.188", features = ["derive"] }
|
serde = { version = "1.0.188", features = ["derive"] }
|
||||||
sparse-05-common = { version = "0.1.0", path = "../sparse-05-common" }
|
sparse-05-common = { version = "0.1.0", path = "../sparse-05-common" }
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
pub mod sysinfo;
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
use sparse_05_common::messages::{Capabilities, OperatingSystem};
|
||||||
|
|
||||||
|
pub fn print_capabilities(capabilities: &Capabilities) {
|
||||||
|
use ansi_term::Colour as Color;
|
||||||
|
|
||||||
|
println!("Capabilities of remote host:");
|
||||||
|
println!(
|
||||||
|
"\tOperating system: \t{}",
|
||||||
|
match &capabilities.operating_system {
|
||||||
|
OperatingSystem::Linux => "Linux",
|
||||||
|
OperatingSystem::Windows => "Windows",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"\tInside a container: \t{}",
|
||||||
|
if capabilities.docker_container {
|
||||||
|
"yes"
|
||||||
|
} else {
|
||||||
|
"no"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if capabilities.docker_container {
|
||||||
|
println!(
|
||||||
|
"\tContainer breakout: \t{}",
|
||||||
|
if capabilities.docker_breakout {
|
||||||
|
Color::Green.paint("successful")
|
||||||
|
} else {
|
||||||
|
Color::Red.paint("unsuccessful")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"\tRemote user: \t\t{}",
|
||||||
|
match &capabilities.userent {
|
||||||
|
Some(user) => Color::White.paint(user),
|
||||||
|
None => Color::Red.paint("unknown"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
match capabilities.operating_system {
|
||||||
|
OperatingSystem::Linux => {
|
||||||
|
println!(
|
||||||
|
"\tAdmin user: \t\t{}",
|
||||||
|
match (capabilities.root, capabilities.setuid) {
|
||||||
|
(false, false) => Color::Red.paint("no"),
|
||||||
|
(_, _) => Color::Green.paint("yes"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"\tsetuid capability: \t{}",
|
||||||
|
match capabilities.setuid {
|
||||||
|
true => Color::Green.paint("yes"),
|
||||||
|
false => Color::Red.paint("no"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OperatingSystem::Windows => {
|
||||||
|
println!(
|
||||||
|
"\tAdmin user: \t\t{}",
|
||||||
|
match capabilities.root {
|
||||||
|
true => Color::Green.paint("yes"),
|
||||||
|
false => Color::Red.paint("no"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("\tTransport type: \t{:?}", capabilities.transport);
|
||||||
|
println!(
|
||||||
|
"\tHost name: \t\t{}",
|
||||||
|
capabilities.hostname.as_deref().unwrap_or("<unknown>")
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,24 +1,28 @@
|
|||||||
use std::{net::SocketAddr, path::PathBuf, sync::Arc};
|
use std::{
|
||||||
|
io::{self, Write},
|
||||||
|
net::SocketAddr,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{bail, Context};
|
use anyhow::{bail, Context};
|
||||||
use ed25519_dalek::{Keypair, Signature, Signer, Verifier};
|
use ed25519_dalek::{Keypair, Signature, Signer, Verifier};
|
||||||
use rmp_serde::decode::ReadSlice;
|
use sparse_05_common::messages::{
|
||||||
use sparse_05_common::messages::{Capabilities, Response, CONNECTED_MESSAGE, CONNECT_MESSAGE};
|
Capabilities, Command, OperatingSystem, Response, CONNECTED_MESSAGE, CONNECT_MESSAGE,
|
||||||
|
};
|
||||||
use tokio::{fs, net::UdpSocket};
|
use tokio::{fs, net::UdpSocket};
|
||||||
|
|
||||||
use crate::configs::ClientConfig;
|
use crate::configs::ClientConfig;
|
||||||
|
|
||||||
enum State {
|
mod commands;
|
||||||
Authenticating,
|
mod shell;
|
||||||
Ready,
|
|
||||||
UploadingFile,
|
|
||||||
DownloadingFile,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Connection {
|
struct Connection {
|
||||||
config: ClientConfig,
|
config: ClientConfig,
|
||||||
foreign_sign_pubkey: ed25519_dalek::PublicKey,
|
foreign_sign_pubkey: ed25519_dalek::PublicKey,
|
||||||
foreign_enc_pubkey: ecies_ed25519::PublicKey,
|
foreign_enc_pubkey: ecies_ed25519::PublicKey,
|
||||||
|
socket: Arc<UdpSocket>,
|
||||||
|
ip: SocketAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
@ -44,6 +48,27 @@ impl Connection {
|
|||||||
|
|
||||||
Ok([&signature.to_bytes(), &*data].concat())
|
Ok([&signature.to_bytes(), &*data].concat())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn send_command(&self, command: Command) -> anyhow::Result<()> {
|
||||||
|
let cmd = rmp_serde::to_vec(&command)?;
|
||||||
|
|
||||||
|
self.socket
|
||||||
|
.send_to(&self.encrypt_and_sign(&cmd)?, self.ip)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_response(&self) -> anyhow::Result<Response> {
|
||||||
|
let mut buffer = [0u8; 2000];
|
||||||
|
let (read, from) = self.socket.recv_from(&mut buffer).await?;
|
||||||
|
|
||||||
|
if from != self.ip {
|
||||||
|
bail!("received packet from wrong computer");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.decrypt_and_verify(&buffer[..read])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn connect(config: PathBuf, ip: SocketAddr) -> anyhow::Result<()> {
|
pub async fn connect(config: PathBuf, ip: SocketAddr) -> anyhow::Result<()> {
|
||||||
@ -58,10 +83,20 @@ pub async fn connect(config: PathBuf, ip: SocketAddr) -> anyhow::Result<()> {
|
|||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
|
|
||||||
let (foreign_sign_pubkey, foreign_enc_pubkey, capabilities) = loop {
|
let (foreign_sign_pubkey, foreign_enc_pubkey, capabilities) = loop {
|
||||||
if counter > 5 {
|
if counter > 25 {
|
||||||
bail!("could not connect to server");
|
bail!("could not connect to server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print!(
|
||||||
|
"\rConnecting{}",
|
||||||
|
match counter % 3 {
|
||||||
|
2 => ".. ",
|
||||||
|
1 => ". ",
|
||||||
|
_ => "...",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
|
||||||
remote.send_to(connect_msg, ip).await?;
|
remote.send_to(connect_msg, ip).await?;
|
||||||
|
|
||||||
let mut buf = [0u8; 2000];
|
let mut buf = [0u8; 2000];
|
||||||
@ -122,17 +157,21 @@ pub async fn connect(config: PathBuf, ip: SocketAddr) -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let connection = Connection {
|
let connection = Arc::new(Connection {
|
||||||
config,
|
config,
|
||||||
foreign_enc_pubkey,
|
foreign_enc_pubkey,
|
||||||
foreign_sign_pubkey,
|
foreign_sign_pubkey,
|
||||||
};
|
socket: Arc::clone(&remote),
|
||||||
|
ip,
|
||||||
|
});
|
||||||
|
|
||||||
remote
|
remote
|
||||||
.send_to(&connection.encrypt_and_sign(CONNECTED_MESSAGE)?, ip)
|
.send_to(&connection.encrypt_and_sign(CONNECTED_MESSAGE)?, ip)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("connected! {:?}", capabilities);
|
println!("\rConnected! ");
|
||||||
|
|
||||||
|
shell::shell(Arc::clone(&connection), capabilities).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
102
sparse-05/sparse-05-client/src/commands/connect/shell.rs
Normal file
102
sparse-05/sparse-05-client/src/commands/connect/shell.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use std::{
|
||||||
|
io::{self, Read, Write},
|
||||||
|
os::fd::AsRawFd,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use sparse_05_common::messages::Capabilities;
|
||||||
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
|
use super::{commands, Connection};
|
||||||
|
|
||||||
|
macro_rules! libc_try {
|
||||||
|
($expr:expr) => {
|
||||||
|
if unsafe { $expr } == -1 {
|
||||||
|
return Err(std::io::Error::last_os_error())?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn get_term_attrs<F: AsRawFd>(fd: &F) -> anyhow::Result<libc::termios> {
|
||||||
|
let mut termios = unsafe { std::mem::zeroed() };
|
||||||
|
libc_try!(libc::tcgetattr(fd.as_raw_fd(), &mut termios));
|
||||||
|
Ok(termios)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn set_term_attrs<F: AsRawFd>(fd: &mut F, attrs: &libc::termios) -> anyhow::Result<()> {
|
||||||
|
libc_try!(libc::tcsetattr(fd.as_raw_fd(), 0, attrs));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn convert_termios_raw(attrs: &mut libc::termios) -> anyhow::Result<()> {
|
||||||
|
unsafe { libc::cfmakeraw(attrs) };
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) async fn shell(
|
||||||
|
connection: Arc<Connection>,
|
||||||
|
mut capabilities: Capabilities,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
println!("Type #help to view a list of sparse commands\n");
|
||||||
|
|
||||||
|
let mut stdin = io::stdin();
|
||||||
|
let mut stdout = io::stdout();
|
||||||
|
let backup_term_attrs = get_term_attrs(&stdin)?;
|
||||||
|
let mut raw_term_attrs = get_term_attrs(&stdin)?;
|
||||||
|
convert_termios_raw(&mut raw_term_attrs)?;
|
||||||
|
|
||||||
|
macro_rules! cmd_matcher {
|
||||||
|
($input:expr, $(($check:ident, $matcher:expr) => {$($body:tt)*}),+, _ => {$($ebody:tt)*}) => {
|
||||||
|
match &$input[..] {
|
||||||
|
$($check if $check.len() >= $matcher.len() && $check[..$matcher.len()] == $matcher[..] => {
|
||||||
|
let $check = &$check[$matcher.len()..];
|
||||||
|
$($body)*
|
||||||
|
}),+
|
||||||
|
_ => {
|
||||||
|
$($ebody)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cwd = "/".to_string();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
print!(
|
||||||
|
"{}@{}:{} {} ",
|
||||||
|
capabilities.userent.as_deref().unwrap_or("unknown user!"),
|
||||||
|
match &capabilities.hostname {
|
||||||
|
Some(n) => n.clone(),
|
||||||
|
None => format!("{}", connection.ip.ip()),
|
||||||
|
},
|
||||||
|
cwd,
|
||||||
|
if capabilities.root { "#" } else { "$" }
|
||||||
|
);
|
||||||
|
stdout.flush().unwrap();
|
||||||
|
|
||||||
|
let mut cmd = [0u8; 256];
|
||||||
|
let amount = stdin.read(&mut cmd)?;
|
||||||
|
|
||||||
|
if amount == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_matcher!(
|
||||||
|
cmd[..amount],
|
||||||
|
(_sysinfo, b"#sysinfo") => {
|
||||||
|
commands::sysinfo::print_capabilities(&capabilities)
|
||||||
|
},
|
||||||
|
(_help, b"#help") => {},
|
||||||
|
(_exit, b"#exit") => {
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -12,19 +12,23 @@ pub mod messages {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
SendData(Vec<u8>),
|
RunCommand(OsString),
|
||||||
|
SendStdin(Vec<u8>, u64),
|
||||||
|
|
||||||
Cd(PathBuf),
|
Cd(PathBuf),
|
||||||
Ls(PathBuf),
|
Ls(PathBuf),
|
||||||
|
|
||||||
OpenTTY,
|
OpenTTY,
|
||||||
CloseTTY,
|
CloseTTY(u64),
|
||||||
|
SendRawData(Vec<u64>, u64),
|
||||||
|
|
||||||
StartUploadFile(PathBuf, u64),
|
StartUploadFile(PathBuf, u64),
|
||||||
SendFileSegment(u64, u64, Vec<u8>),
|
SendFileSegment(u64, u64, Vec<u64>),
|
||||||
|
|
||||||
StartDownloadFile(PathBuf, u64),
|
StartDownloadFile(PathBuf),
|
||||||
DownloadFileStatus(Result<(), Vec<u8>>),
|
DownloadFileStatus(Result<(), Vec<u64>>),
|
||||||
|
|
||||||
|
Disconnect,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@ -56,19 +60,22 @@ pub mod messages {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
// Connected(Capabilities, ed25519_dalek::PublicKey, ecies_ed25519::PublicKey),
|
AckRunCommand(u64),
|
||||||
SendData(Vec<u8>),
|
SendStdout(Vec<u8>, u64, u64),
|
||||||
|
CommandDone(u64),
|
||||||
|
|
||||||
CdDone,
|
CdDone,
|
||||||
LsResults(Vec<DirEntry>),
|
LsResults(Vec<DirEntry>),
|
||||||
|
|
||||||
OpenedTTY,
|
OpenedTTY(u64),
|
||||||
ClosedTTY,
|
ClosedTTY(u64),
|
||||||
|
SendRawData(Vec<u64>, u64),
|
||||||
|
|
||||||
UploadFileID(u64),
|
UploadFileID(u64),
|
||||||
UploadFileStatus(Result<(), Vec<u8>>),
|
UploadFileStatus(u64, Result<(), Vec<u64>>),
|
||||||
|
|
||||||
DownloadFileSegment(u64, u64, Vec<u8>),
|
StartDownloadFile(u64),
|
||||||
|
DownloadFileSegment(u64, u64, Vec<u64>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Copy)]
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Copy)]
|
||||||
@ -94,5 +101,6 @@ pub mod messages {
|
|||||||
pub root: bool,
|
pub root: bool,
|
||||||
pub userent: Option<String>,
|
pub userent: Option<String>,
|
||||||
pub transport: TransportType,
|
pub transport: TransportType,
|
||||||
|
pub hostname: Option<String>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
|||||||
return Err(std::io::Error::last_os_error())?;
|
return Err(std::io::Error::last_os_error())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let docker_container = false;
|
let docker_container = std::fs::read_to_string("/proc/1/cgroup")? != "0::/\n";
|
||||||
let docker_breakout = false;
|
let docker_breakout = false;
|
||||||
let uid = unsafe { libc::getuid() };
|
let uid = unsafe { libc::getuid() };
|
||||||
let root = uid == 0;
|
let root = uid == 0;
|
||||||
@ -76,6 +76,9 @@ fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
|||||||
TransportType::Udp
|
TransportType::Udp
|
||||||
};
|
};
|
||||||
let userent = get_username(uid)?;
|
let userent = get_username(uid)?;
|
||||||
|
let hostname = std::fs::read_to_string("/etc/hostname")
|
||||||
|
.map(|s| s.trim().to_string())
|
||||||
|
.ok();
|
||||||
|
|
||||||
Ok(Capabilities {
|
Ok(Capabilities {
|
||||||
operating_system: if cfg!(target_os = "linux") {
|
operating_system: if cfg!(target_os = "linux") {
|
||||||
@ -89,6 +92,7 @@ fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
|||||||
root,
|
root,
|
||||||
userent,
|
userent,
|
||||||
transport,
|
transport,
|
||||||
|
hostname,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +108,7 @@ fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
|||||||
root: userent.as_deref() == Some("Administrator"),
|
root: userent.as_deref() == Some("Administrator"),
|
||||||
userent,
|
userent,
|
||||||
transport: TransportType::Udp,
|
transport: TransportType::Udp,
|
||||||
|
hostname: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ struct ConnectionInformation {
|
|||||||
srcip: Ipv4Addr,
|
srcip: Ipv4Addr,
|
||||||
dstip: Ipv4Addr,
|
dstip: Ipv4Addr,
|
||||||
srcport: u16,
|
srcport: u16,
|
||||||
|
packet_sender: Sender<EthernetPacket>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectionInformation {
|
impl ConnectionInformation {
|
||||||
@ -79,6 +80,11 @@ impl ConnectionInformation {
|
|||||||
|
|
||||||
Ok(rmp_serde::from_slice(&data)?)
|
Ok(rmp_serde::from_slice(&data)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send(&self, packet: EthernetPacket) -> anyhow::Result<()> {
|
||||||
|
self.packet_sender.send(packet)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_connection_handler(
|
pub fn spawn_connection_handler(
|
||||||
@ -132,6 +138,7 @@ pub fn spawn_connection_handler(
|
|||||||
srcip: ip_pkt.source_ip(),
|
srcip: ip_pkt.source_ip(),
|
||||||
dstip: ip_pkt.dest_ip(),
|
dstip: ip_pkt.dest_ip(),
|
||||||
srcport: udp_pkt.srcport(),
|
srcport: udp_pkt.srcport(),
|
||||||
|
packet_sender,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let close = {
|
let close = {
|
||||||
@ -145,7 +152,7 @@ pub fn spawn_connection_handler(
|
|||||||
let (packet_handler_sender, packet_handler) = channel();
|
let (packet_handler_sender, packet_handler) = channel();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if let Err(e) = authenticate(capabilities, packet_handler, conninfo, packet_sender, close) {
|
if let Err(e) = authenticate(capabilities, packet_handler, conninfo, close) {
|
||||||
eprintln!("connection thread died: {e:?}");
|
eprintln!("connection thread died: {e:?}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -159,7 +166,6 @@ fn authenticate<F: Fn()>(
|
|||||||
capabilities: Arc<Capabilities>,
|
capabilities: Arc<Capabilities>,
|
||||||
packet_handler: Receiver<EthernetPacket>,
|
packet_handler: Receiver<EthernetPacket>,
|
||||||
conninfo: ConnectionInformation,
|
conninfo: ConnectionInformation,
|
||||||
packet_sender: Sender<EthernetPacket>,
|
|
||||||
close: F,
|
close: F,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
@ -169,15 +175,16 @@ fn authenticate<F: Fn()>(
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_pkt = conninfo.encrypt_and_sign(
|
conninfo.send(
|
||||||
|
conninfo.encrypt_and_sign(
|
||||||
&[
|
&[
|
||||||
&conninfo.local_sign_keypair.public.to_bytes(),
|
&conninfo.local_sign_keypair.public.to_bytes(),
|
||||||
&conninfo.local_enc_pubkey.to_bytes(),
|
&conninfo.local_enc_pubkey.to_bytes(),
|
||||||
&*(rmp_serde::to_vec(&*capabilities)?),
|
&*(rmp_serde::to_vec(&*capabilities)?),
|
||||||
]
|
]
|
||||||
.concat(),
|
.concat(),
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
packet_sender.send(next_pkt)?;
|
|
||||||
|
|
||||||
match packet_handler.recv_timeout(std::time::Duration::from_millis(250)) {
|
match packet_handler.recv_timeout(std::time::Duration::from_millis(250)) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
@ -204,14 +211,13 @@ fn authenticate<F: Fn()>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_full_connection(capabilities, packet_handler, conninfo, packet_sender, close)
|
handle_full_connection(capabilities, packet_handler, conninfo, close)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_full_connection<F>(
|
fn handle_full_connection<F>(
|
||||||
capabilities: Arc<Capabilities>,
|
capabilities: Arc<Capabilities>,
|
||||||
packet_handler: Receiver<EthernetPacket>,
|
packet_handler: Receiver<EthernetPacket>,
|
||||||
conninfo: ConnectionInformation,
|
conninfo: ConnectionInformation,
|
||||||
packet_sender: Sender<EthernetPacket>,
|
|
||||||
close: F,
|
close: F,
|
||||||
) -> anyhow::Result<()>
|
) -> anyhow::Result<()>
|
||||||
where
|
where
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user