diff --git a/.idea/e3pf.iml b/.idea/e3pf.iml index 7939757..2e9f75f 100644 --- a/.idea/e3pf.iml +++ b/.idea/e3pf.iml @@ -3,6 +3,8 @@ + + diff --git a/Cargo.lock b/Cargo.lock index 2bd3107..92c17b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -156,6 +205,49 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clap" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", + "once_cell", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -166,6 +258,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "colored" version = "2.0.0" @@ -325,6 +423,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fiat-crypto" version = "0.1.20" @@ -447,6 +566,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -465,6 +590,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -510,6 +641,29 @@ dependencies = [ "generic-array", ] +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itoa" version = "1.0.6" @@ -577,6 +731,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" + [[package]] name = "lock_api" version = "0.4.9" @@ -614,6 +774,24 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "ncpf" +version = "0.1.0" +dependencies = [ + "clap", + "libepf", + "tokio", +] + +[[package]] +name = "netcatpf" +version = "0.1.0" +dependencies = [ + "clap", + "libepf", + "tokio", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -837,6 +1015,20 @@ dependencies = [ "serde", ] +[[package]] +name = "rustix" +version = "0.37.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -968,6 +1160,12 @@ dependencies = [ "der", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" @@ -1110,6 +1308,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index f7f6097..40d12ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,6 @@ [workspace] members = [ - "libepf" + "libepf", + "ncpf", + "netcatpf" ] \ No newline at end of file diff --git a/ncpf/Cargo.toml b/ncpf/Cargo.toml new file mode 100644 index 0000000..c977193 --- /dev/null +++ b/ncpf/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ncpf" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libepf = { version = "0.1.0", path = "../libepf" } +clap = { version = "4.2", features = ["derive", "cargo"] } +tokio = { version = "1.28.0", features = ["rt-multi-thread", "macros", "net", "io-std"] } \ No newline at end of file diff --git a/ncpf/src/main.rs b/ncpf/src/main.rs new file mode 100644 index 0000000..6854c95 --- /dev/null +++ b/ncpf/src/main.rs @@ -0,0 +1,73 @@ +use std::error::Error; +use std::io::{stdin, Write}; +use std::net::{IpAddr, SocketAddr}; +use clap::{Parser}; +use tokio::io::AsyncReadExt; +use tokio::net::{TcpListener, TcpSocket}; +use tokio::select; +use libepf::ca_pool::load_ca_pool; +use libepf::handshake_stream::{ClientAuthentication, EpfClientHandshaker, EpfClientUpgradable, EpfStreamOps}; + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +pub struct Cli { + bind_ip: IpAddr, + bind_port: u16 +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let cli = Cli::parse(); + + let bind_addr = SocketAddr::new(cli.bind_ip, cli.bind_port); + + let tcp_stream = TcpSocket::new_v4()?.connect(bind_addr).await?; + + let ca_pool = load_ca_pool()?; + + let mut handshake_client = tcp_stream.upgrade(ClientAuthentication::Ephemeral).await; + handshake_client.handshake(ca_pool).await?; + let mut client = handshake_client.upgrade().await; + + let mut stdin = tokio::io::BufReader::new(tokio::io::stdin()); + let mut input = String::new(); + + loop { + select! { + packet_data = client.read() => { + match packet_data { + Ok(d) => std::io::stdout().write_all(&d).unwrap(), + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + }, + stdin_data = stdin.read_to_string(&mut input) => { + match stdin_data { + Ok(amt) => { + match client.write(input.as_bytes()).await { + Ok(_) => { + input = String::new(); + }, + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + if amt == 0 { + // EOF + break; + } + }, + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + } + } + } + + Ok(()) +} \ No newline at end of file diff --git a/netcatpf/Cargo.toml b/netcatpf/Cargo.toml new file mode 100644 index 0000000..e28bb62 --- /dev/null +++ b/netcatpf/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "netcatpf" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libepf = { version = "0.1.0", path = "../libepf" } +clap = { version = "4.2", features = ["derive", "cargo"] } +tokio = { version = "1.28.0", features = ["rt-multi-thread", "macros", "net", "io-std"] } \ No newline at end of file diff --git a/netcatpf/src/main.rs b/netcatpf/src/main.rs new file mode 100644 index 0000000..40ceb12 --- /dev/null +++ b/netcatpf/src/main.rs @@ -0,0 +1,88 @@ +use std::error::Error; +use std::fs; +use std::io::{stdin, Write}; +use std::net::{IpAddr, SocketAddr}; +use std::path::PathBuf; +use clap::{Parser}; +use tokio::io::AsyncReadExt; +use tokio::net::TcpListener; +use tokio::select; +use libepf::ca_pool::load_ca_pool; +use libepf::handshake_stream::{ClientAuthentication, EpfServerHandshaker, EpfServerUpgradable, EpfStreamOps}; +use libepf::pki::{EPFCertificate, EpfPkiSerializable, EpfPrivateKey}; + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +pub struct Cli { + bind_ip: IpAddr, + bind_port: u16, + certificate: PathBuf, + key: PathBuf +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let cli = Cli::parse(); + + // load cert + let cert_data = fs::read(cli.certificate)?; + let cert = EPFCertificate::from_pem(&cert_data)?; + + let private_key_data = fs::read(cli.key)?; + let private_key = EpfPrivateKey::from_pem(&private_key_data)?; + + let bind_addr = SocketAddr::new(cli.bind_ip, cli.bind_port); + + let listener = TcpListener::bind(bind_addr).await?; + + // get client + let (tcp_stream, _) = listener.accept().await?; + + let ca_pool = load_ca_pool()?; + + let mut handshake_server = tcp_stream.upgrade(cert, private_key).await; + handshake_server.handshake(ca_pool).await?; + let mut client = handshake_server.upgrade().await; + + let mut stdin = tokio::io::BufReader::new(tokio::io::stdin()); + let mut input = String::new(); + + loop { + select! { + packet_data = client.read() => { + match packet_data { + Ok(d) => std::io::stdout().write_all(&d).unwrap(), + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + }, + stdin_data = stdin.read_to_string(&mut input) => { + match stdin_data { + Ok(amt) => { + match client.write(input.as_bytes()).await { + Ok(_) => { + input = String::new(); + }, + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + if amt == 0 { + // EOF + break; + } + }, + Err(e) => { + println!("{}", e); + std::process::exit(1); + } + } + } + } + } + + Ok(()) +} \ No newline at end of file