mirror of
https://github.com/MercuryWorkshop/epoxy-tls.git
synced 2025-05-12 14:00:01 -04:00
add to simple wisp client
This commit is contained in:
parent
577ce71b89
commit
24ccd8d393
7 changed files with 82 additions and 9 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1952,12 +1952,14 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"clap",
|
"clap",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
|
"ed25519-dalek",
|
||||||
"fastwebsockets",
|
"fastwebsockets",
|
||||||
"futures",
|
"futures",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"humantime",
|
"humantime",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
|
"sha2",
|
||||||
"simple_moving_average",
|
"simple_moving_average",
|
||||||
"tokio",
|
"tokio",
|
||||||
"wisp-mux",
|
"wisp-mux",
|
||||||
|
|
|
@ -7,7 +7,7 @@ use log::LevelFilter;
|
||||||
use regex::RegexSet;
|
use regex::RegexSet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wisp_mux::extensions::{
|
use wisp_mux::extensions::{
|
||||||
cert::CertAuthProtocolExtensionBuilder,
|
cert::{CertAuthProtocolExtension, CertAuthProtocolExtensionBuilder},
|
||||||
motd::MotdProtocolExtensionBuilder,
|
motd::MotdProtocolExtensionBuilder,
|
||||||
password::{PasswordProtocolExtension, PasswordProtocolExtensionBuilder},
|
password::{PasswordProtocolExtension, PasswordProtocolExtensionBuilder},
|
||||||
udp::UdpProtocolExtensionBuilder,
|
udp::UdpProtocolExtensionBuilder,
|
||||||
|
@ -304,6 +304,7 @@ impl WispConfig {
|
||||||
get_certificates_from_paths(self.certificate_extension_keys.clone())
|
get_certificates_from_paths(self.certificate_extension_keys.clone())
|
||||||
.await?,
|
.await?,
|
||||||
)));
|
)));
|
||||||
|
required_extensions.push(CertAuthProtocolExtension::ID);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,9 +179,7 @@ async fn handle_stream(
|
||||||
let id = muxstream.stream_id;
|
let id = muxstream.stream_id;
|
||||||
let (mut rx, mut tx) = muxstream.into_io().into_asyncrw().into_split();
|
let (mut rx, mut tx) = muxstream.into_io().into_asyncrw().into_split();
|
||||||
|
|
||||||
match twisp::handle_twisp(id, &mut rx, &mut tx, twisp_map.clone(), pty, cmd)
|
match twisp::handle_twisp(id, &mut rx, &mut tx, twisp_map.clone(), pty, cmd).await {
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let _ = closer.close(CloseReason::Voluntary).await;
|
let _ = closer.close(CloseReason::Voluntary).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,14 @@ atomic-counter = "1.0.1"
|
||||||
bytes = "1.7.1"
|
bytes = "1.7.1"
|
||||||
clap = { version = "4.5.16", features = ["cargo", "derive"] }
|
clap = { version = "4.5.16", features = ["cargo", "derive"] }
|
||||||
console-subscriber = { version = "0.4.0", optional = true }
|
console-subscriber = { version = "0.4.0", optional = true }
|
||||||
|
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
|
||||||
fastwebsockets = { version = "0.8.0", features = ["unstable-split", "upgrade"] }
|
fastwebsockets = { version = "0.8.0", features = ["unstable-split", "upgrade"] }
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
http-body-util = "0.1.2"
|
http-body-util = "0.1.2"
|
||||||
humantime = "2.1.0"
|
humantime = "2.1.0"
|
||||||
hyper = { version = "1.4.1", features = ["http1", "client"] }
|
hyper = { version = "1.4.1", features = ["http1", "client"] }
|
||||||
hyper-util = { version = "0.1.7", features = ["tokio"] }
|
hyper-util = { version = "0.1.7", features = ["tokio"] }
|
||||||
|
sha2 = "0.10.8"
|
||||||
simple_moving_average = "1.0.2"
|
simple_moving_average = "1.0.2"
|
||||||
tokio = { version = "1.39.3", features = ["full"] }
|
tokio = { version = "1.39.3", features = ["full"] }
|
||||||
wisp-mux = { path = "../wisp", features = ["fastwebsockets"]}
|
wisp-mux = { path = "../wisp", features = ["fastwebsockets"]}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use atomic_counter::{AtomicCounter, RelaxedCounter};
|
use atomic_counter::{AtomicCounter, RelaxedCounter};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use ed25519_dalek::pkcs8::DecodePrivateKey;
|
||||||
use fastwebsockets::handshake;
|
use fastwebsockets::handshake;
|
||||||
use futures::future::select_all;
|
use futures::future::select_all;
|
||||||
use http_body_util::Empty;
|
use http_body_util::Empty;
|
||||||
|
@ -10,12 +11,14 @@ use hyper::{
|
||||||
Request, Uri,
|
Request, Uri,
|
||||||
};
|
};
|
||||||
use hyper_util::rt::TokioIo;
|
use hyper_util::rt::TokioIo;
|
||||||
|
use sha2::{Digest, Sha512};
|
||||||
use simple_moving_average::{SingleSumSMA, SMA};
|
use simple_moving_average::{SingleSumSMA, SMA};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
future::Future,
|
future::Future,
|
||||||
io::{stdout, Cursor, IsTerminal, Write},
|
io::{stdout, Cursor, IsTerminal, Write},
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
|
path::PathBuf,
|
||||||
process::{abort, exit},
|
process::{abort, exit},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
@ -29,6 +32,8 @@ use tokio::{
|
||||||
};
|
};
|
||||||
use wisp_mux::{
|
use wisp_mux::{
|
||||||
extensions::{
|
extensions::{
|
||||||
|
cert::{CertAuthProtocolExtension, CertAuthProtocolExtensionBuilder, SigningKey},
|
||||||
|
motd::{MotdProtocolExtension, MotdProtocolExtensionBuilder},
|
||||||
password::{PasswordProtocolExtension, PasswordProtocolExtensionBuilder},
|
password::{PasswordProtocolExtension, PasswordProtocolExtensionBuilder},
|
||||||
udp::{UdpProtocolExtension, UdpProtocolExtensionBuilder},
|
udp::{UdpProtocolExtension, UdpProtocolExtensionBuilder},
|
||||||
ProtocolExtensionBuilder,
|
ProtocolExtensionBuilder,
|
||||||
|
@ -92,11 +97,28 @@ struct Cli {
|
||||||
/// Usernames and passwords are sent in plaintext!!
|
/// Usernames and passwords are sent in plaintext!!
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
auth: Option<String>,
|
auth: Option<String>,
|
||||||
|
/// Enable certauth
|
||||||
|
#[arg(long)]
|
||||||
|
certauth: Option<PathBuf>,
|
||||||
|
/// Enable motd parsing
|
||||||
|
#[arg(long)]
|
||||||
|
motd: bool,
|
||||||
/// Make a Wisp V2 connection
|
/// Make a Wisp V2 connection
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
wisp_v2: bool,
|
wisp_v2: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_cert(path: PathBuf) -> Result<SigningKey, Box<dyn Error + Sync + Send>> {
|
||||||
|
let data = tokio::fs::read_to_string(path).await?;
|
||||||
|
let signer = ed25519_dalek::SigningKey::from_pkcs8_pem(&data)?;
|
||||||
|
let binary_key = signer.verifying_key().to_bytes();
|
||||||
|
|
||||||
|
let mut hasher = Sha512::new();
|
||||||
|
hasher.update(binary_key);
|
||||||
|
let hash: [u8; 64] = hasher.finalize().into();
|
||||||
|
Ok(SigningKey::new_ed25519(Arc::new(signer), hash))
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread")]
|
#[tokio::main(flavor = "multi_thread")]
|
||||||
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
#[cfg(feature = "tokio-console")]
|
#[cfg(feature = "tokio-console")]
|
||||||
|
@ -153,10 +175,19 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
extensions.push(Box::new(UdpProtocolExtensionBuilder));
|
extensions.push(Box::new(UdpProtocolExtensionBuilder));
|
||||||
extension_ids.push(UdpProtocolExtension::ID);
|
extension_ids.push(UdpProtocolExtension::ID);
|
||||||
}
|
}
|
||||||
|
if opts.motd {
|
||||||
|
extensions.push(Box::new(MotdProtocolExtensionBuilder::Client));
|
||||||
|
}
|
||||||
if let Some(auth) = auth {
|
if let Some(auth) = auth {
|
||||||
extensions.push(Box::new(auth));
|
extensions.push(Box::new(auth));
|
||||||
extension_ids.push(PasswordProtocolExtension::ID);
|
extension_ids.push(PasswordProtocolExtension::ID);
|
||||||
}
|
}
|
||||||
|
if let Some(certauth) = opts.certauth {
|
||||||
|
let key = get_cert(certauth).await?;
|
||||||
|
let extension = CertAuthProtocolExtensionBuilder::new_client(key);
|
||||||
|
extensions.push(Box::new(extension));
|
||||||
|
extension_ids.push(CertAuthProtocolExtension::ID);
|
||||||
|
}
|
||||||
|
|
||||||
let (mux, fut) = if !opts.wisp_v2 {
|
let (mux, fut) = if !opts.wisp_v2 {
|
||||||
ClientMux::create(rx, tx, None)
|
ClientMux::create(rx, tx, None)
|
||||||
|
@ -169,9 +200,19 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
.await?
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let motd_extension = mux
|
||||||
|
.supported_extensions
|
||||||
|
.iter()
|
||||||
|
.find_map(|x| x.downcast_ref::<MotdProtocolExtension>());
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"connected and created ClientMux, was downgraded {}, extensions supported {:?}\n",
|
"connected and created ClientMux, was downgraded {}, extensions supported {:?}, motd {:?}\n\n",
|
||||||
mux.downgraded, mux.supported_extension_ids
|
mux.downgraded,
|
||||||
|
mux.supported_extensions
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.get_id())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
motd_extension.map(|x| x.motd.clone())
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut threads = Vec::with_capacity((opts.streams * 2) + 3);
|
let mut threads = Vec::with_capacity((opts.streams * 2) + 3);
|
||||||
|
|
|
@ -74,7 +74,10 @@ pub struct VerifyKey {
|
||||||
|
|
||||||
impl VerifyKey {
|
impl VerifyKey {
|
||||||
/// Create a new ED25519 verification key.
|
/// Create a new ED25519 verification key.
|
||||||
pub fn new_ed25519(verifier: Arc<dyn Verifier<Signature> + Sync + Send>, hash: [u8; 64]) -> Self {
|
pub fn new_ed25519(
|
||||||
|
verifier: Arc<dyn Verifier<Signature> + Sync + Send>,
|
||||||
|
hash: [u8; 64],
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cert_type: SupportedCertificateTypes::Ed25519,
|
cert_type: SupportedCertificateTypes::Ed25519,
|
||||||
hash,
|
hash,
|
||||||
|
@ -314,9 +317,9 @@ impl ProtocolExtensionBuilder for CertAuthProtocolExtensionBuilder {
|
||||||
fn build_to_extension(&mut self, _: Role) -> Result<AnyProtocolExtension, WispError> {
|
fn build_to_extension(&mut self, _: Role) -> Result<AnyProtocolExtension, WispError> {
|
||||||
match self {
|
match self {
|
||||||
Self::ServerBeforeChallenge { verifiers } => {
|
Self::ServerBeforeChallenge { verifiers } => {
|
||||||
let mut challenge = BytesMut::with_capacity(64);
|
let mut challenge = [0u8; 64];
|
||||||
getrandom::getrandom(&mut challenge).map_err(CertAuthError::from)?;
|
getrandom::getrandom(&mut challenge).map_err(CertAuthError::from)?;
|
||||||
let challenge = challenge.freeze();
|
let challenge = Bytes::from(challenge.to_vec());
|
||||||
|
|
||||||
*self = Self::ServerAfterChallenge {
|
*self = Self::ServerAfterChallenge {
|
||||||
verifiers: verifiers.to_vec(),
|
verifiers: verifiers.to_vec(),
|
||||||
|
|
|
@ -32,6 +32,16 @@ impl AnyProtocolExtension {
|
||||||
pub fn downcast<T: ProtocolExtension>(self) -> Result<Box<T>, Self> {
|
pub fn downcast<T: ProtocolExtension>(self) -> Result<Box<T>, Self> {
|
||||||
self.0.__downcast().map_err(Self)
|
self.0.__downcast().map_err(Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Downcast the protocol extension.
|
||||||
|
pub fn downcast_ref<T: ProtocolExtension>(&self) -> Option<&T> {
|
||||||
|
self.0.__downcast_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Downcast the protocol extension.
|
||||||
|
pub fn downcast_mut<T: ProtocolExtension>(&mut self) -> Option<&mut T> {
|
||||||
|
self.0.__downcast_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for AnyProtocolExtension {
|
impl Deref for AnyProtocolExtension {
|
||||||
|
@ -126,6 +136,22 @@ impl dyn ProtocolExtension {
|
||||||
Err(self)
|
Err(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn __downcast_ref<T: ProtocolExtension>(&self) -> Option<&T> {
|
||||||
|
if self.__is::<T>() {
|
||||||
|
unsafe { Some(&*(self as *const dyn ProtocolExtension as *const T)) }
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __downcast_mut<T: ProtocolExtension>(&mut self) -> Option<&mut T> {
|
||||||
|
if self.__is::<T>() {
|
||||||
|
unsafe { Some(&mut *(self as *mut dyn ProtocolExtension as *mut T)) }
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to build a Wisp protocol extension from a payload.
|
/// Trait to build a Wisp protocol extension from a payload.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue