generated from PlexSheep/rs-base
docs: api docs for everyone
cargo devel CI / cargo CI (push) Successful in 1m32s
Details
cargo devel CI / cargo CI (push) Successful in 1m32s
Details
This commit is contained in:
parent
de7e046ae7
commit
bfa532cbd2
|
@ -1,3 +1,8 @@
|
||||||
|
//! Challenges and their common interface.
|
||||||
|
//!
|
||||||
|
//! This module is the core of the Wooly Vault application, as it defines the interface that all
|
||||||
|
//! challenges must implement, and contains the challenge modules themselves.
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
@ -8,17 +13,70 @@ pub mod c1;
|
||||||
pub mod c2;
|
pub mod c2;
|
||||||
pub mod c3;
|
pub mod c3;
|
||||||
|
|
||||||
|
/// Defines the behavior of a challenge.
|
||||||
|
///
|
||||||
|
/// Any type that implements this trait can be served as a challenge in the Wooly Vault application.
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Challenge
|
pub trait Challenge
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
/// Creates a new instance of the challenge with the given configuration and vault.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `config` - The configuration for the challenge.
|
||||||
|
/// * `vault` - The vault that holds the secret for the challenge.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A new instance of the challenge.
|
||||||
fn new(config: Config, vault: VaultRef) -> Self;
|
fn new(config: Config, vault: VaultRef) -> Self;
|
||||||
|
/// Returns a list of hints for the challenge.
|
||||||
|
///
|
||||||
|
/// A hint is a short text to be given to the contestants in case the host thinks they need
|
||||||
|
/// it. The first hint is the most vague, afterwards the hints become more and more helpful.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A vector of strings containing hints for the challenge.
|
||||||
fn hints() -> Vec<String>;
|
fn hints() -> Vec<String>;
|
||||||
|
/// Returns the solution to the challenge.
|
||||||
|
///
|
||||||
|
/// A solution is a short description of what has to be done to solve the challenge and get the
|
||||||
|
/// secret of the vault.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A string containing the solution to the challenge.
|
||||||
fn solution() -> String;
|
fn solution() -> String;
|
||||||
|
/// Starts the challenge and serves it to the contestants.
|
||||||
|
///
|
||||||
|
/// This method is asynchronous and returns a result indicating whether the challenge was
|
||||||
|
/// successful only after the challenge has ended.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A result indicating whether the challenge was successful ended.
|
||||||
async fn serve(self) -> anyhow::Result<()>;
|
async fn serve(self) -> anyhow::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Selects a challenge by index and serves it with the given configuration and vault.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `index` - The index of the challenge to select.
|
||||||
|
/// * `config` - The configuration for the challenge.
|
||||||
|
/// * `vault` - The vault that holds the secret for the challenge.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A result indicating whether the challenge has successfully ended.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an error if no challenge with the given index exists, or if the challenge that is being
|
||||||
|
/// served errors.
|
||||||
pub async fn select_and_start(index: u16, config: Config, vault: VaultRef) -> anyhow::Result<()> {
|
pub async fn select_and_start(index: u16, config: Config, vault: VaultRef) -> anyhow::Result<()> {
|
||||||
match index {
|
match index {
|
||||||
1 => c1::C1::new(config, vault).serve().await?,
|
1 => c1::C1::new(config, vault).serve().await?,
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
|
//! Common configuration options for the challenges.
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use libpt::cli::args::VerbosityLevel;
|
use libpt::cli::args::VerbosityLevel;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// The environment variable that can hold the secret for a challenge
|
||||||
pub const ENV_SECRET: &str = "WOOLY_SECRET";
|
pub const ENV_SECRET: &str = "WOOLY_SECRET";
|
||||||
|
|
||||||
/// Wooly Vault --- A few small hacking challenges
|
/// Wooly Vault --- A few small hacking challenges
|
||||||
|
@ -41,7 +45,6 @@ pub const ENV_SECRET: &str = "WOOLY_SECRET";
|
||||||
about,
|
about,
|
||||||
long_about,
|
long_about,
|
||||||
help_template = libpt::cli::args::HELP_TEMPLATE)]
|
help_template = libpt::cli::args::HELP_TEMPLATE)]
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Index of the challenge
|
/// Index of the challenge
|
||||||
pub challenge: u16,
|
pub challenge: u16,
|
||||||
|
@ -69,3 +72,24 @@ impl Debug for Config {
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
/// Load or input the secret
|
||||||
|
///
|
||||||
|
/// This will try to get the secret from the [`ENV_SECRET`] environment variable. If that
|
||||||
|
/// variable is not set, the user will be asked to input a secret manually.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// When the environment variable is not set and the reading from stdin fails.
|
||||||
|
pub fn 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -1,3 +1,19 @@
|
||||||
|
//! # Wooly Vault
|
||||||
|
//!
|
||||||
|
//! Wooly Vault is a set of smaller challenges for Rust hackers.
|
||||||
|
//!
|
||||||
|
//! A host may choose to open a challenge, set a secret and ask a contestant to try and solve the
|
||||||
|
//! challenge to get the secret. The contestant can then prove with the secret to the host that
|
||||||
|
//! they absolved the challenge.
|
||||||
|
//!
|
||||||
|
//! Wooly Vault has multiple challenges, and only one can be hosted per instance of this
|
||||||
|
//! application. The challenges all bind to a pre-set [Network Adress](crate::config::Config::addr).
|
||||||
|
//! The contestants can then connect to that adress with TCP. The first few challenges use raw TCP,
|
||||||
|
//! but some of the later ones are small HTTP webservices.
|
||||||
|
//!
|
||||||
|
//! Wooly Vault is programmed asynchronously with [tokio] to be able to handle many contestants at
|
||||||
|
//! once if needed.
|
||||||
|
|
||||||
pub mod challenge;
|
pub mod challenge;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod vault;
|
pub mod vault;
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -2,7 +2,6 @@ use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use libpt::log::{debug, info};
|
use libpt::log::{debug, info};
|
||||||
|
|
||||||
use wooly_vault::config::ENV_SECRET;
|
|
||||||
use wooly_vault::{challenge::select_and_start, config::Config, vault::Vault};
|
use wooly_vault::{challenge::select_and_start, config::Config, vault::Vault};
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
@ -16,27 +15,10 @@ async fn main() -> Result<()> {
|
||||||
debug!("logger active");
|
debug!("logger active");
|
||||||
info!("Configuration: {conf:?}");
|
info!("Configuration: {conf:?}");
|
||||||
|
|
||||||
let secret = get_secret()?;
|
let secret = Config::secret()?;
|
||||||
let v = Vault::new(&secret);
|
let v = Vault::new(&secret);
|
||||||
|
|
||||||
select_and_start(conf.challenge, conf, v).await?;
|
select_and_start(conf.challenge, conf, v).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
std::io::stdin().read_line(&mut buf)?;
|
|
||||||
Ok(buf.trim().parse()?)
|
|
||||||
}
|
|
||||||
|
|
25
src/vault.rs
25
src/vault.rs
|
@ -1,19 +1,44 @@
|
||||||
|
//! A module for managing and sharing secrets in the Wooly Vault application.
|
||||||
|
//!
|
||||||
|
//! This module provides a [`Vault`] struct that holds a secret and allows it to be shared safely
|
||||||
|
//! across the application using an [`Arc`] (Atomic Reference Counted) pointer.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// A type alias for an [`Arc`] pointer to a [`Vault`] instance.
|
||||||
|
///
|
||||||
|
/// This type is used to share a [`Vault`] instance across multiple parts of the application.
|
||||||
pub type VaultRef = Arc<Vault>;
|
pub type VaultRef = Arc<Vault>;
|
||||||
|
|
||||||
|
/// A struct that holds a secret and provides methods for accessing it.
|
||||||
|
///
|
||||||
|
/// The [`Vault`] struct is designed to be shared safely across the application using an [`Arc`] pointer.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Vault {
|
pub struct Vault {
|
||||||
|
/// The secret stored in the vault
|
||||||
secret: String,
|
secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vault {
|
impl Vault {
|
||||||
|
/// Creates a new [`Vault`] instance with the given secret.
|
||||||
|
///
|
||||||
|
/// Returns an [`Arc`] pointer to the new [`Vault`] instance.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A new [`Vault`] instance with the given secret.
|
||||||
pub fn new(secret: &str) -> VaultRef {
|
pub fn new(secret: &str) -> VaultRef {
|
||||||
let v = Self {
|
let v = Self {
|
||||||
secret: secret.to_string(),
|
secret: secret.to_string(),
|
||||||
};
|
};
|
||||||
Arc::new(v)
|
Arc::new(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the secret stored in the vault.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A reference to the secret stored in the vault.
|
||||||
pub fn secret(&self) -> &str {
|
pub fn secret(&self) -> &str {
|
||||||
&self.secret
|
&self.secret
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue