Signed-off-by: Avril <flanchan@cumallover.me>
master
Avril 4 years ago
parent c228e99dcc
commit 1e5a19570a
Signed by: flanchan
GPG Key ID: 284488987C31F630

181
Cargo.lock generated

@ -113,6 +113,12 @@ dependencies = [
"safemem", "safemem",
] ]
[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]] [[package]]
name = "byte-tools" name = "byte-tools"
version = "0.3.1" version = "0.3.1"
@ -131,6 +137,12 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "cc"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -171,15 +183,56 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[package]]
name = "crypto-mac"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca"
dependencies = [
"generic-array 0.14.4",
"subtle",
]
[[package]]
name = "cryptohelpers"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cfc491baaffd7cbd6acc02ebd23564760d83a2c17e1a47e6a04a8d5a86e7fb5"
dependencies = [
"crc",
"getrandom",
"hex-literal",
"hmac",
"libc",
"openssl",
"pbkdf2",
"serde",
"serde_derive",
"sha2",
"tokio",
]
[[package]] [[package]]
name = "datse" name = "datse"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"color-eyre", "color-eyre",
"cryptohelpers",
"futures", "futures",
"lazy_static",
"log", "log",
"pretty_env_logger", "pretty_env_logger",
"tokio", "tokio",
"uuid",
"warp", "warp",
] ]
@ -242,6 +295,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.0.0" version = "1.0.0"
@ -465,6 +533,22 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex-literal"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
[[package]]
name = "hmac"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff"
dependencies = [
"crypto-mac",
"digest 0.9.0",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.1" version = "0.2.1"
@ -778,12 +862,54 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
dependencies = [
"bitflags",
"cfg-if 0.1.10",
"foreign-types",
"lazy_static",
"libc",
"openssl-sys",
]
[[package]]
name = "openssl-sys"
version = "0.9.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
dependencies = [
"autocfg 1.0.1",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "owo-colors" name = "owo-colors"
version = "1.1.3" version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a1250cdd103eef6bd542b5ae82989f931fc00a41a27f60377338241594410f3" checksum = "7a1250cdd103eef6bd542b5ae82989f931fc00a41a27f60377338241594410f3"
[[package]]
name = "pbkdf2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170d73bf11f39b4ce1809aabc95bf5c33564cdc16fc3200ddda17a5f6e5e48b"
dependencies = [
"base64",
"crypto-mac",
"hmac",
"rand 0.7.3",
"rand_core 0.5.1",
"sha2",
"subtle",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@ -842,6 +968,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.10" version = "0.2.10"
@ -1112,6 +1244,20 @@ name = "serde"
version = "1.0.117" version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
@ -1161,6 +1307,19 @@ dependencies = [
"opaque-debug 0.3.0", "opaque-debug 0.3.0",
] ]
[[package]]
name = "sha2"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8"
dependencies = [
"block-buffer 0.9.0",
"cfg-if 1.0.0",
"cpuid-bool",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.2.2" version = "1.2.2"
@ -1188,6 +1347,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "subtle"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.48" version = "1.0.48"
@ -1453,6 +1618,22 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
[[package]]
name = "uuid"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
dependencies = [
"rand 0.7.3",
"serde",
]
[[package]]
name = "vcpkg"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.2" version = "0.9.2"

@ -21,8 +21,11 @@ client = []
[dependencies] [dependencies]
color-eyre = {version = "0.5", default-features=false} color-eyre = {version = "0.5", default-features=false}
cryptohelpers = {version = "1.5.1", features= ["sha256", "rsa", "serde"]}
futures = "0.3.8" futures = "0.3.8"
lazy_static = "1.4.0"
log = "0.4.11" log = "0.4.11"
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
tokio = {version = "0.2", features = ["full"]} tokio = {version = "0.2", features = ["full"]}
uuid = {version = "0.8.1", features = ["v4","serde"]}
warp = "0.2.5" warp = "0.2.5"

@ -0,0 +1,23 @@
//! Arg parsing error
use super::*;
use std::{
error,
fmt,
};
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
Unknown,
}
impl error::Error for Error{}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
_ => write!(f, "unknown error"),
}
}
}

@ -8,19 +8,21 @@ pub enum Operation
#[cfg(feature="client")] Client(client::Config), #[cfg(feature="client")] Client(client::Config),
Help, Help,
} }
/// Name of the program
#[derive(Debug)] pub fn program() -> &'static str
pub struct Error;
pub fn parse_args() -> impl Future<Output = Result<Operation, Error>>
{ {
parse(std::env::args().skip(1)) lazy_static!{
static ref NAME: String = std::env::args().next().unwrap();
}
&NAME[..]
} }
async fn parse<T, I>(args: I) -> Result<Operation, Error> /// Attempt to parse the args
where I: IntoIterator<Item = T>, pub fn parse_args() -> impl Future<Output = Result<Operation, Error>>
T: Into<String>
{ {
let mut args = args.into_iter().map(Into::into); parse::parse(std::env::args().skip(1))
todo!()
} }
mod parse;
mod error;
pub use error::Error;

@ -0,0 +1,10 @@
//! Parse args
use super::*;
pub async fn parse<T, I>(args: I) -> Result<Operation, Error>
where I: IntoIterator<Item = T>,
T: Into<String>
{
let mut args = args.into_iter().map(Into::into);
todo!()
}

@ -3,6 +3,7 @@
#[macro_use] extern crate log; #[macro_use] extern crate log;
use color_eyre::{ use color_eyre::{
eyre::{ eyre::{
self, eyre, self, eyre,
@ -10,10 +11,10 @@ use color_eyre::{
}, },
SectionExt as _, SectionExt as _,
}; };
use futures::{ use futures::{
prelude::*, prelude::*,
}; };
use lazy_static::lazy_static;
fn install() -> eyre::Result<()> fn install() -> eyre::Result<()>
{ {

@ -6,6 +6,8 @@ pub struct Config
} }
mod state;
#[cfg(feature="server-http")] pub mod web; #[cfg(feature="server-http")] pub mod web;
#[cfg(feature="server-tcp")] pub mod tcp; #[cfg(feature="server-tcp")] pub mod tcp;

@ -0,0 +1,8 @@
//! Server state
use super::*;
#[derive(Debug, Clone)]
pub struct ServerState
{
}

@ -0,0 +1,31 @@
//! Authentication
use super::*;
pub struct Sha256Hash(pub sha256::Sha256Hash);
type RsaSignature = rsa::Signature;
impl str::FromStr for Sha256Hash
{
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
todo!() //read encoded base64(?)/hex into `Signature`
}
}
pub async fn auth_req(who: source::IpAddr, state: Arc<state::State>) -> Result<(), Infallible>
{
Ok(())
}
pub async fn auth_key(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, num: usize, body: Bytes) -> Result<(), Infallible>
{
Ok(())
}
pub async fn auth_pass(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, passhash: sha256::Sha256Hash) -> Result<(), Infallible>
{
Ok(())
}

@ -0,0 +1,74 @@
use std::{
net::{
IpAddr,
AddrParseError,
},
str,
error,
fmt,
};
#[derive(Debug)]
pub struct XFormatError;
impl error::Error for XFormatError{}
impl fmt::Display for XFormatError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "X-Forwarded-For was not in the correct format")
}
}
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Default)]
pub struct XForwardedFor(Vec<IpAddr>);
impl XForwardedFor
{
pub fn new() -> Self
{
Self(Vec::new())
}
pub fn single(ip: impl Into<IpAddr>) -> Self
{
Self(vec![ip.into()])
}
pub fn addrs(&self) -> &[IpAddr]
{
&self.0[..]
}
pub fn into_first(self) -> Option<IpAddr>
{
self.0.into_iter().next()
}
pub fn into_addrs(self) -> Vec<IpAddr>
{
self.0
}
}
impl str::FromStr for XForwardedFor
{
type Err = XFormatError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut output = Vec::new();
for next in s.split(',')
{
output.push(next.trim().parse()?)
}
Ok(Self(output))
}
}
impl From<AddrParseError> for XFormatError
{
#[inline(always)] fn from(_: AddrParseError) -> Self
{
Self
}
}

@ -1,2 +1,80 @@
//! datse server over HTTP //! datse server over HTTP
use super::*; use super::*;
use warp::{
Filter,
hyper::body::Bytes,
};
use std::{
str,
sync::Arc,
convert::Infallible,
};
use cryptohelpers::{
sha256,
rsa,
};
/// Web server config
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Config
{
}
pub mod settings;
mod state;
mod source;
mod forwarded_list;
mod auth;
/// Main entry point for web server
pub async fn main(state: server::state::ServerState, cfg: settings::Settings) -> eyre::Result<()>
{
let state = Arc::new(state::State::new(state, cfg.clone()));
let state = warp::any().map(move || state.clone());
// Extract the client IP or fail with custom rejection
let client_ip = warp::addr::remote()
.and(warp::header("X-Forwarded-For"))
.map(source::extract(cfg.trust_x_forwarded_for))
.and_then(|req: Result<std::net::IpAddr, _>| async move {req.map_err(warp::reject::custom)});
let auth = {
let req = warp::path("req")
.and(client_ip.clone()).and(state.clone()); //TODO
let resp = {
let resp_auth_with_state = warp::post()
.and(client_ip.clone()).and(state.clone())
.and(warp::path::param().map(|req_id: uuid::Uuid| req_id));
let resp_auth_key = resp_auth_with_state.clone()
.and(warp::path("si")
.and(warp::path::param().map(|num: usize| std::cmp::max(1, num))
.or(warp::path::end().map(|| 1usize)).unify()))
.and(warp::body::content_length_limit(cfg.max_body_len.0))
.and(warp::body::bytes())
.and_then(auth::auth_key);
// -- Paths --
let resp_auth_pass = resp_auth_with_state
.and(warp::path::param().map(|hash: auth::Sha256Hash| hash.0))
.and_then(auth::auth_pass);
let resp = warp::path("resp")
.and(resp_auth_key
.or(resp_auth_pass));
// /resp/<req_id>/pw/<passwd hash>
// /resp/<req_id>/si[/<num of sigs in body>]
resp
};
warp::path("auth").and(req)
};
todo!()
}

@ -0,0 +1,28 @@
//! Settings for web server
//!
//! Usually derived from config
use super::*;
const DEFAULT_MAX_BODY_LEN_ARESP: u64 = 1024 * 4; // 4KB
const DEFAULT_MAX_BODY_LEN: u64 = 1024 * 1024 * 4; // 4MB
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Settings
{
/// First is max body len for auth responses, 2nd is for data.
pub max_body_len: (u64, u64),
pub trust_x_forwarded_for: bool,
}
impl Default for Settings
{
#[inline]
fn default() -> Self
{
Self {
max_body_len: (DEFAULT_MAX_BODY_LEN_ARESP, DEFAULT_MAX_BODY_LEN),
trust_x_forwarded_for: false,
}
}
}

@ -0,0 +1,58 @@
//! Contains info about the requester
use super::*;
use std::net::{
SocketAddr,
};
use std::{fmt,error};
use forwarded_list::XForwardedFor;
#[derive(Debug)]
pub struct Requester
{
source: Option<SocketAddr>,
x_forwarded_for: XForwardedFor,
}
pub use std::net::IpAddr;
impl Requester
{
pub fn new(source: Option<SocketAddr>, x_forwarded_for: XForwardedFor) -> Result<Self, NoIpError>
{
if source.is_none() && x_forwarded_for.addrs().len() == 0 {
Err(NoIpError)
} else {
Ok(Self{
source,
x_forwarded_for,
})
}
}
}
#[derive(Debug)]
pub struct NoIpError;
impl warp::reject::Reject for NoIpError{}
impl error::Error for NoIpError{}
impl fmt::Display for NoIpError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "no remote host IP address could be found")
}
}
/// Extract the IP using the specified settings for trusting the `X-Forwarded-For` header.
pub fn extract(trust_x: bool) -> impl Fn(Option<SocketAddr>, XForwardedFor) -> Result<IpAddr,NoIpError> + Clone
{
move |opt, x| {
if trust_x {
x.into_first().ok_or(NoIpError)
} else {
opt.map(|x| x.ip()).ok_or(NoIpError)
}
}
}

@ -0,0 +1,30 @@
//! Web server state
use super::*;
use tokio::{
sync::{
RwLock,
},
};
#[derive(Debug)]
pub struct State
{
backend: RwLock<server::state::ServerState>,
settings: settings::Settings,
}
impl State
{
pub fn new(backend: server::state::ServerState, settings: settings::Settings) -> Self
{
Self {
backend: RwLock::new(backend),
settings,
}
}
pub fn cfg(&self) -> &settings::Settings
{
&self.settings
}
}
Loading…
Cancel
Save