certtool + fix ncpf/netcatpf
This commit is contained in:
parent
d8ca1bbb90
commit
cbe8dee8a3
|
@ -2,6 +2,7 @@
|
|||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/certtoolpf/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/libepf/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/ncpf/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/netcatpf/src" isTestSource="false" />
|
||||
|
|
|
@ -149,6 +149,16 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "certtoolpf"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"inquire",
|
||||
"libepf",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -296,6 +306,31 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -399,6 +434,12 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30"
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "2.2.1"
|
||||
|
@ -641,6 +682,22 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inquire"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4bf420bd01f298a3ed8f57af9babedb296b4edfc1dbd8b159cee883aa90edaa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm",
|
||||
"dyn-clone",
|
||||
"lazy_static",
|
||||
"newline-converter",
|
||||
"thiserror",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.10"
|
||||
|
@ -792,6 +849,15 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "newline-converter"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -1106,6 +1172,36 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.1.0"
|
||||
|
@ -1212,6 +1308,26 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
|
@ -1292,6 +1408,12 @@ version = "1.0.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
members = [
|
||||
"libepf",
|
||||
"ncpf",
|
||||
"netcatpf"
|
||||
"netcatpf",
|
||||
"certtoolpf"
|
||||
]
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "certtoolpf"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
inquire = "0.6.1"
|
||||
libepf = { version = "0.1.0", path = "../libepf" }
|
||||
clap = { version = "4", features = ["derive", "cargo"] }
|
||||
rand = "0.8.5"
|
|
@ -0,0 +1,328 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use clap::{Parser, Subcommand};
|
||||
use inquire::{Confirm, Select, Text};
|
||||
use rand::rngs::OsRng;
|
||||
use libepf::ca_pool::load_ca_pool;
|
||||
use libepf::pki::{EPFCertificate, EPFCertificateDetails, EpfPkiCertificateOps, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Generate a public and private keypair
|
||||
GenerateKeypair {
|
||||
#[arg(short = 'p', long)]
|
||||
out_public_key: PathBuf,
|
||||
#[arg(short = 'k', long)]
|
||||
out_private_key: PathBuf
|
||||
},
|
||||
/// Create a new **unsigned** certificate
|
||||
CreateCertificate {
|
||||
#[arg(short, long)]
|
||||
output: PathBuf,
|
||||
#[arg(short, long)]
|
||||
public_key: PathBuf
|
||||
},
|
||||
/// Dump information about the certificate
|
||||
DumpCertificate {
|
||||
cert: PathBuf
|
||||
},
|
||||
/// Verify the certificate
|
||||
VerifyCertificate {
|
||||
cert: PathBuf
|
||||
},
|
||||
/// Sign the certificate using the given private key
|
||||
SignCertificate {
|
||||
cert: PathBuf,
|
||||
#[arg(short, long)]
|
||||
key: PathBuf,
|
||||
#[arg(short, long)]
|
||||
output: PathBuf
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Cli::parse();
|
||||
|
||||
if let Some(subcommand) = args.command {
|
||||
match subcommand {
|
||||
Commands::GenerateKeypair { out_private_key, out_public_key } => {
|
||||
let private_key = EpfPrivateKey::generate(&mut OsRng);
|
||||
let public_key = private_key.verifying_key();
|
||||
|
||||
let private_key_pem = match private_key.as_pem() {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Error while serializing private key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let public_key_pem = match public_key.as_pem() {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Error while serializing public key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
match std::fs::write(out_private_key, private_key_pem) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error saving private key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
match std::fs::write(out_public_key, public_key_pem) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error saving public key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
},
|
||||
Commands::CreateCertificate { output, public_key } => {
|
||||
// load public key
|
||||
let public_key_pem = match fs::read(public_key) {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Unable to load public key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let public_key = match EpfPublicKey::from_pem(&public_key_pem) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
println!("Error parsing public key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let name = match Text::new("Certificate name?").prompt() {
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let options = vec!["1 day", "1 week", "1 month", "6 months", "1 year", "2 years", "5 years", "10 years", "Forever"];
|
||||
let expires_in = match Select::new("How long should the certificate be valid for?", options).prompt() {
|
||||
Ok(expires_in) => expires_in,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let expires_in = match expires_in {
|
||||
"1 day" => 60 * 60 * 24,
|
||||
"1 week" => 60 * 60 * 24 * 7,
|
||||
"1 month" => 60 * 60 * 24 * 7 * 4,
|
||||
"6 months" => 60 * 60 * 24 * 7 * 4 * 6,
|
||||
"1 year" => 60 * 60 * 24 * 7 * 4 * 6 * 2,
|
||||
"2 years" => 60 * 60 * 24 * 7 * 4 * 6 * 2 * 2,
|
||||
"5 years" => 60 * 60 * 24 * 7 * 4 * 6 * 2 * 5,
|
||||
"10 years" => 60 * 60 * 24 * 7 * 4 * 6 * 2 * 10,
|
||||
"Forever" => 60 * 60 * 24 * 7 * 4 * 6 * 2 * 100000, // 100,000 years
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let add_claims = match Confirm::new("Would you like to add additional claims to the certificate?").with_default(false).prompt() {
|
||||
Ok(ac) => ac,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let mut claims = HashMap::new();
|
||||
|
||||
if add_claims {
|
||||
loop {
|
||||
let name = match Text::new("Claim name:").prompt() {
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let value = match Text::new("Claim value:").prompt() {
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
claims.insert(name, value);
|
||||
let add_another = match Confirm::new("Would you like to add additional claims to the certificate?").with_default(true).prompt() {
|
||||
Ok(ac) => ac,
|
||||
Err(e) => {
|
||||
println!("Error with prompt: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
if !add_another {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name,
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs(),
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs() + expires_in,
|
||||
public_key: public_key.to_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims,
|
||||
},
|
||||
fingerprint: "".to_string(),
|
||||
signature: [0u8; 64],
|
||||
};
|
||||
match cert.recalculate_fingerprint() {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error calculating certificate fingerprint: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
let cert_pem = match cert.as_pem() {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Error serializing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
match fs::write(output, cert_pem) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error saving certificate: {}", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
Commands::DumpCertificate { cert } => {
|
||||
// load cert
|
||||
let cert_pem = match fs::read(cert) {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Unable to load certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let cert = match EPFCertificate::from_pem(&cert_pem) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
println!("Error parsing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
println!("{}", cert);
|
||||
},
|
||||
Commands::SignCertificate { cert, key, output }=> {
|
||||
// load cert
|
||||
let cert_pem = match fs::read(cert) {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Unable to load certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let mut cert = match EPFCertificate::from_pem(&cert_pem) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
println!("Error parsing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// load key
|
||||
let key_pem = match fs::read(key) {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Unable to load private key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let key = match EpfPrivateKey::from_pem(&key_pem) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
println!("Error parsing private key: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
match cert.sign(&key) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error signing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
let cert_pem = match cert.as_pem() {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Error serializing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
match fs::write(output, cert_pem) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("Error saving certificate: {}", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
Commands::VerifyCertificate { cert } => {
|
||||
// load cert
|
||||
let cert_pem = match fs::read(cert) {
|
||||
Ok(pem) => pem,
|
||||
Err(e) => {
|
||||
println!("Unable to load certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let cert = match EPFCertificate::from_pem(&cert_pem) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
println!("Error parsing certificate: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let ca_pool = match load_ca_pool() {
|
||||
Ok(pool) => pool,
|
||||
Err(e) => {
|
||||
println!("Unable to load trusted certs pool: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
match cert.verify(&ca_pool) {
|
||||
Ok(trusted) => {
|
||||
if !trusted {
|
||||
println!("Certificate valid but not trusted");
|
||||
std::process::exit(3);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Certificate invalid: {}", e);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
println!("No subcommand specified. Run with -h/--help for help.");
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ pub fn load_ca_pool() -> Result<EpfCaPool, Box<dyn Error>> {
|
|||
|
||||
for entry in fs::read_dir("/etc/e3pf/certs")? {
|
||||
let entry = entry?;
|
||||
if entry.path().extension() == Some(OsStr::new(".pem")) {
|
||||
if entry.path().extension() == Some(OsStr::new("pem")) {
|
||||
cert_strings.push(fs::read_to_string(entry.path())?);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ impl Display for EPFCertificate {
|
|||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
"\t\tIssuer Fingerprint: {}",
|
||||
"\t\tIssuer Public Key: {}",
|
||||
hex::encode(self.details.issuer_public_key)
|
||||
)?;
|
||||
writeln!(f, "\t}}")?;
|
||||
|
|
|
@ -7,19 +7,20 @@ use tokio::net::{TcpSocket};
|
|||
use tokio::select;
|
||||
use libepf::ca_pool::load_ca_pool;
|
||||
use libepf::handshake_stream::{ClientAuthentication, EpfClientHandshaker, EpfClientUpgradable, EpfStreamOps};
|
||||
use std::io;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
bind_ip: IpAddr,
|
||||
bind_port: u16
|
||||
connect_ip: IpAddr,
|
||||
connect_port: u16
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
let bind_addr = SocketAddr::new(cli.bind_ip, cli.bind_port);
|
||||
let bind_addr = SocketAddr::new(cli.connect_ip, cli.connect_port);
|
||||
|
||||
let tcp_stream = TcpSocket::new_v4()?.connect(bind_addr).await?;
|
||||
|
||||
|
@ -30,7 +31,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
let mut client = handshake_client.upgrade().await;
|
||||
|
||||
let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
|
||||
let mut input = String::new();
|
||||
let mut input = [0u8; 32767];
|
||||
|
||||
loop {
|
||||
select! {
|
||||
|
@ -38,23 +39,37 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
match packet_data {
|
||||
Ok(d) => std::io::stdout().write_all(&d).unwrap(),
|
||||
Err(e) => {
|
||||
match e.downcast_ref::<io::Error>() {
|
||||
Some(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
|
||||
std::process::exit(0);
|
||||
},
|
||||
Some(_) | None => {
|
||||
println!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
stdin_data = stdin.read_to_string(&mut input) => {
|
||||
stdin_data = stdin.read(&mut input) => {
|
||||
match stdin_data {
|
||||
Ok(amt) => {
|
||||
match client.write(input.as_bytes()).await {
|
||||
match client.write(&input[..amt]).await {
|
||||
Ok(_) => {
|
||||
input = String::new();
|
||||
input = [0u8; 32767];
|
||||
},
|
||||
Err(e) => {
|
||||
match e.downcast_ref::<io::Error>() {
|
||||
Some(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
|
||||
std::process::exit(0);
|
||||
},
|
||||
Some(_) | None => {
|
||||
println!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if amt == 0 {
|
||||
// EOF
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::{fs, io};
|
||||
use std::io::{Write};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::path::PathBuf;
|
||||
|
@ -17,7 +17,7 @@ pub struct Cli {
|
|||
bind_ip: IpAddr,
|
||||
bind_port: u16,
|
||||
certificate: PathBuf,
|
||||
key: PathBuf
|
||||
key: PathBuf,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -45,7 +45,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
let mut client = handshake_server.upgrade().await;
|
||||
|
||||
let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
|
||||
let mut input = String::new();
|
||||
let mut input = [0u8; 32767];
|
||||
|
||||
loop {
|
||||
select! {
|
||||
|
@ -53,23 +53,37 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
match packet_data {
|
||||
Ok(d) => std::io::stdout().write_all(&d).unwrap(),
|
||||
Err(e) => {
|
||||
match e.downcast_ref::<io::Error>() {
|
||||
Some(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
|
||||
std::process::exit(0);
|
||||
},
|
||||
Some(_) | None => {
|
||||
println!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
stdin_data = stdin.read_to_string(&mut input) => {
|
||||
stdin_data = stdin.read(&mut input) => {
|
||||
match stdin_data {
|
||||
Ok(amt) => {
|
||||
match client.write(input.as_bytes()).await {
|
||||
match client.write(&input[..amt]).await {
|
||||
Ok(_) => {
|
||||
input = String::new();
|
||||
input = [0u8; 32767];
|
||||
},
|
||||
Err(e) => {
|
||||
match e.downcast_ref::<io::Error>() {
|
||||
Some(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
|
||||
std::process::exit(0);
|
||||
},
|
||||
Some(_) | None => {
|
||||
println!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if amt == 0 {
|
||||
// EOF
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue