generated from PlexSheep/rs-base
feat: proper cli
cargo devel CI / cargo CI (push) Successful in 2m16s
Details
cargo devel CI / cargo CI (push) Successful in 2m16s
Details
This commit is contained in:
parent
19b81e2631
commit
f00aa8b4e9
14
Cargo.toml
14
Cargo.toml
|
@ -14,5 +14,15 @@ repository = "https://git.cscherr.de/PlexSheep/wooly-vault"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
async-trait = "0.1.82"
|
async-trait = "0.1.82"
|
||||||
libpt = { version = "0.6.0", features = ["log"] }
|
clap = { version = "4.5.17", features = ["derive"] }
|
||||||
tokio = { version = "1.40.0", features = ["macros", "net", "time", "io-util", "rt", "sync"] }
|
libpt = { version = "0.7.1", features = ["cli", "log"] }
|
||||||
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
|
serde_json = "1.0.128"
|
||||||
|
tokio = { version = "1.40.0", features = [
|
||||||
|
"macros",
|
||||||
|
"net",
|
||||||
|
"time",
|
||||||
|
"io-util",
|
||||||
|
"rt",
|
||||||
|
"sync",
|
||||||
|
] }
|
||||||
|
|
|
@ -4,8 +4,9 @@ use tokio::io::AsyncWriteExt;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
use super::Challenge;
|
use super::Challenge;
|
||||||
|
use crate::config::Config;
|
||||||
use crate::has_won;
|
use crate::has_won;
|
||||||
use crate::vault::{Config, VaultRef};
|
use crate::vault::VaultRef;
|
||||||
|
|
||||||
pub struct C1 {
|
pub struct C1 {
|
||||||
config: Config,
|
config: Config,
|
||||||
|
@ -19,9 +20,15 @@ impl Challenge for C1 {
|
||||||
fn new(config: Config, vault: VaultRef) -> Self {
|
fn new(config: Config, vault: VaultRef) -> Self {
|
||||||
Self { config, vault }
|
Self { config, vault }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hints() -> Vec<String> {
|
fn hints() -> Vec<String> {
|
||||||
vec![String::from("TCP connect to 1337")]
|
vec![String::from("TCP connect to 1337.")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn solution() -> String {
|
||||||
|
String::from("Connect by TCP, then the secret will be sent to you.")
|
||||||
|
}
|
||||||
|
|
||||||
async fn serve(self) -> anyhow::Result<()> {
|
async fn serve(self) -> anyhow::Result<()> {
|
||||||
info!("serving challenge 1");
|
info!("serving challenge 1");
|
||||||
let listener = TcpListener::bind(self.config.addr).await?;
|
let listener = TcpListener::bind(self.config.addr).await?;
|
||||||
|
|
|
@ -5,8 +5,9 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
|
||||||
use super::Challenge;
|
use super::Challenge;
|
||||||
|
use crate::config::Config;
|
||||||
use crate::has_won;
|
use crate::has_won;
|
||||||
use crate::vault::{Config, VaultRef};
|
use crate::vault::VaultRef;
|
||||||
|
|
||||||
pub struct C2 {
|
pub struct C2 {
|
||||||
config: Config,
|
config: Config,
|
||||||
|
@ -37,11 +38,17 @@ impl Challenge for C2 {
|
||||||
fn new(config: Config, vault: VaultRef) -> Self {
|
fn new(config: Config, vault: VaultRef) -> Self {
|
||||||
Self { config, vault }
|
Self { config, vault }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hints() -> Vec<String> {
|
fn hints() -> Vec<String> {
|
||||||
vec![String::from(
|
vec![String::from(
|
||||||
"TCP connect to 1337 and give me a special u16",
|
"TCP connect to 1337 and give me a special u16",
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn solution() -> String {
|
||||||
|
String::from("Connect by TCP, send 1337 as bytes (not text).")
|
||||||
|
}
|
||||||
|
|
||||||
async fn serve(self) -> anyhow::Result<()> {
|
async fn serve(self) -> anyhow::Result<()> {
|
||||||
info!("serving challenge 2");
|
info!("serving challenge 2");
|
||||||
let listener = TcpListener::bind(self.config.addr).await?;
|
let listener = TcpListener::bind(self.config.addr).await?;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::vault::{Config, VaultRef};
|
use crate::config::Config;
|
||||||
|
use crate::vault::VaultRef;
|
||||||
|
|
||||||
pub mod c1;
|
pub mod c1;
|
||||||
pub mod c2;
|
pub mod c2;
|
||||||
|
@ -13,6 +14,7 @@ where
|
||||||
{
|
{
|
||||||
fn new(config: Config, vault: VaultRef) -> Self;
|
fn new(config: Config, vault: VaultRef) -> Self;
|
||||||
fn hints() -> Vec<String>;
|
fn hints() -> Vec<String>;
|
||||||
|
fn solution() -> String;
|
||||||
async fn serve(self) -> anyhow::Result<()>;
|
async fn serve(self) -> anyhow::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use clap::Parser;
|
||||||
|
use libpt::cli::args::VerbosityLevel;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
pub const ENV_SECRET: &str = "WOOLY_SECRET";
|
||||||
|
|
||||||
|
/// Wooly Vault --- A few small hacking challenges
|
||||||
|
///
|
||||||
|
/// # Configuration
|
||||||
|
/// Each challenge requires some basic information to host:
|
||||||
|
///
|
||||||
|
/// * secret - a string that if found signifies that the challenge was solved
|
||||||
|
///
|
||||||
|
/// * addr - the network adress plus port the challenge should run on
|
||||||
|
///
|
||||||
|
/// * verbosity - how verbose the logging should be
|
||||||
|
///
|
||||||
|
/// * challenge - which challenge to host (there are a few)
|
||||||
|
///
|
||||||
|
/// The secret cannot be inputted with a command line argument, because the arguments can often be
|
||||||
|
/// seen in the process view. You may either specify a secret in the 'WOOLY_SECRET' environment
|
||||||
|
/// variable or input it interactively on start.
|
||||||
|
///
|
||||||
|
/// # Challenges
|
||||||
|
///
|
||||||
|
/// There are a number of challenges:
|
||||||
|
///
|
||||||
|
/// 1. Connect by TCP
|
||||||
|
///
|
||||||
|
/// 2. Connect by TCP and send a special u16
|
||||||
|
#[derive(Parser, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||||
|
#[command(
|
||||||
|
author,
|
||||||
|
version,
|
||||||
|
about,
|
||||||
|
long_about,
|
||||||
|
help_template = libpt::cli::args::HELP_TEMPLATE)]
|
||||||
|
|
||||||
|
pub struct Config {
|
||||||
|
/// Index of the challenge
|
||||||
|
pub challenge: u16,
|
||||||
|
/// Network address to host the challenge on
|
||||||
|
pub addr: SocketAddr,
|
||||||
|
#[command(flatten)]
|
||||||
|
pub verbosity: VerbosityLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
challenge: 1,
|
||||||
|
addr: SocketAddr::from_str("127.0.0.1:1337").unwrap(),
|
||||||
|
verbosity: VerbosityLevel::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Config {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Config")
|
||||||
|
.field("addr", &self.addr)
|
||||||
|
.field("verbosity", &self.verbosity.level())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod challenge;
|
pub mod challenge;
|
||||||
|
pub mod config;
|
||||||
pub mod vault;
|
pub mod vault;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -1,30 +1,41 @@
|
||||||
use wooly_vault::challenge::select_and_start;
|
use anyhow::Result;
|
||||||
use wooly_vault::vault::{Config, Vault};
|
use clap::Parser;
|
||||||
|
use libpt::log::{debug, info};
|
||||||
|
|
||||||
|
use wooly_vault::config::ENV_SECRET;
|
||||||
|
use wooly_vault::{challenge::select_and_start, config::Config, vault::Vault};
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
let conf = Config::parse();
|
||||||
|
|
||||||
let _logger = libpt::log::Logger::builder()
|
let _logger = libpt::log::Logger::builder()
|
||||||
.set_level(libpt::log::Level::TRACE)
|
.set_level(conf.verbosity.level())
|
||||||
.display_time(false)
|
.display_time(false)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
debug!("logger active");
|
||||||
|
info!("Configuration: {conf:?}");
|
||||||
|
|
||||||
println!("Input the secret and press enter");
|
let secret = get_secret()?;
|
||||||
let mut buf: String = String::new();
|
let v = Vault::new(&secret);
|
||||||
std::io::stdin().read_line(&mut buf)?;
|
|
||||||
let secret = buf.trim();
|
|
||||||
|
|
||||||
let conf = Config::default();
|
select_and_start(conf.challenge, conf, v).await?;
|
||||||
|
|
||||||
let v = Vault::new(secret);
|
|
||||||
|
|
||||||
println!("What challenge to serve?");
|
|
||||||
let i = select_challenge()?;
|
|
||||||
select_and_start(i, conf, v).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_challenge() -> anyhow::Result<u16> {
|
fn get_secret() -> Result<String> {
|
||||||
|
if let Ok(v) = std::env::var(ENV_SECRET) {
|
||||||
|
return Ok(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Input the secret and press enter");
|
||||||
|
let mut buf: String = String::new();
|
||||||
|
std::io::stdin().read_line(&mut buf)?;
|
||||||
|
Ok(buf.trim().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_challenge() -> Result<u16> {
|
||||||
let mut buf: String = String::new();
|
let mut buf: String = String::new();
|
||||||
std::io::stdin().read_line(&mut buf)?;
|
std::io::stdin().read_line(&mut buf)?;
|
||||||
Ok(buf.trim().parse()?)
|
Ok(buf.trim().parse()?)
|
||||||
|
|
15
src/vault.rs
15
src/vault.rs
|
@ -1,22 +1,7 @@
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub type VaultRef = Arc<Vault>;
|
pub type VaultRef = Arc<Vault>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
|
||||||
pub struct Config {
|
|
||||||
pub addr: SocketAddr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
addr: SocketAddr::from_str("127.0.0.1:1337").unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Vault {
|
pub struct Vault {
|
||||||
secret: String,
|
secret: String,
|
||||||
|
|
Loading…
Reference in New Issue