contego/src/main.rs
einisto 35fb797c95 Key-based authentication & critical fix to server's async behaviour
* 8 character long alphanumeric key authentication (server-side)
* Modified integration test to skip the previously mentioned key authentication
* Fixed a previously made typo, which caused the server to await until a single
  client's connection was done
* Simplified the structure of client.rs & server.rs a lot, also improved comments
* Confirm client's connection request with SYN
* Version bump, v0.2.0 => v0.3.0
2022-07-29 17:24:20 +03:00

88 lines
2.8 KiB
Rust

use clap::Parser;
use fragilebyte::{client, server};
use std::{error::Error, path::PathBuf, process::exit, str::FromStr};
use tokio;
#[derive(Parser, Debug)]
#[clap(author, about, version, long_about = None)]
struct Args {
#[clap(short = 't', long, value_parser)]
/// Server's address when connecting as a client
target: Option<String>,
#[clap(short = 'k', long, value_parser)]
/// Alphanumeric 8 characters long key required to establish a connection to the host
key: Option<String>,
#[clap(default_value_t = 8080u16, short = 'p', long, value_parser = validate_arg::<u16>)]
/// Port where the service is hosted
port: u16,
#[clap(default_value_t = 8192usize, short = 'b', long, value_parser = validate_arg::<usize>)]
/// Buffersize used in the file transfer (bytes)
buffersize: usize,
#[clap(default_value_t = false, long, action)]
/// Run only in the local network
localhost: bool,
#[clap(default_value_t = 30, long, value_parser = validate_arg::<u64>)]
/// Seconds of inactivity after which the server closes itself
timeout: u64,
#[clap(short = 'f', long, value_parser)]
/// Path to the folder where the files are outputted as a client or
/// served from as a server [default: './output' / './data']
fileroot: Option<PathBuf>,
#[clap(default_value_t = false, short = 'a', long, action)]
/// Automatically download every available file from the host (skips stdin)
all: bool,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
match args.target {
Some(addr) => {
// Client
let fileroot = match args.fileroot {
Some(n) => n,
None => PathBuf::from("./output"),
};
let access_key = match args.key {
Some(n) => n,
None => {
eprintln!("[-] Access key required as a client, please try again");
exit(0x0100);
}
};
client::connect(addr, fileroot, access_key, args.all)
.await
.expect("Error initializing client");
}
None => {
// Server
let fileroot = match args.fileroot {
Some(n) => n,
None => PathBuf::from("./data"),
};
server::listen(
args.port,
fileroot,
args.buffersize,
args.localhost,
args.timeout,
false,
)
.await
.expect("Error initializing server");
}
}
Ok(())
}
fn validate_arg<T: FromStr>(value: &str) -> Result<T, String> {
match value.parse::<T>() {
Ok(n) => Ok(n),
Err(_) => Err(format!("Invalid argument: {}", value)),
}
}