Compare commits
No commits in common. "master" and "220905" have entirely different histories.
1602
Cargo.lock
generated
1602
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
43
Cargo.toml
43
Cargo.toml
@ -5,28 +5,27 @@ edition = "2021"
|
|||||||
description = "TCP-over-HTTP solution"
|
description = "TCP-over-HTTP solution"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.4", features = ["derive", "env"] }
|
clap = { version = "3.2.18", features = ["derive", "env"] }
|
||||||
log = "0.4.21"
|
log = "0.4.17"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.9.0"
|
||||||
actix = "0.13.3"
|
actix = "0.13.0"
|
||||||
actix-web = { version = "4.5.1", features = ["rustls-0_21"] }
|
actix-web = { version = "4", features = ["rustls"] }
|
||||||
actix-web-actors = "4.3.0"
|
actix-web-actors = "4.1.0"
|
||||||
actix-tls = "3.3.0"
|
actix-tls = "3.0.3"
|
||||||
serde = { version = "1.0.200", features = ["derive"] }
|
serde = { version = "1.0.144", features = ["derive"] }
|
||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
futures = "0.3.30"
|
futures = "0.3.24"
|
||||||
webpki = "0.22.4"
|
webpki = "0.22.0"
|
||||||
x509-parser = "0.16.0"
|
x509-parser = "0.14.0"
|
||||||
pem = "3.0.4"
|
pem = "1.1.0"
|
||||||
reqwest = { version = "0.12.4", features = ["json", "rustls-tls"], default-features = false }
|
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features = false }
|
||||||
tokio-tungstenite = { version = "0.20.0", features = ["__rustls-tls", "rustls-tls-native-roots"] }
|
tokio-tungstenite = { version = "0.17.2", features = ["__rustls-tls", "rustls-tls-native-roots"] }
|
||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.0"
|
||||||
hyper-rustls = { version = "0.23.2", features = ["rustls-native-certs"] }
|
hyper-rustls = { version = "0.23.0", features = ["rustls-native-certs"] }
|
||||||
bytes = "1.6.0"
|
bytes = "1.2.1"
|
||||||
rustls-pemfile = "2.0.0"
|
rustls-pemfile = "1.0.1"
|
||||||
rustls = { version = "0.21.0", features = ["dangerous_configuration"] }
|
rustls = "0.20.6"
|
||||||
rustls-native-certs = "0.6.3"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
mktemp = "0.5.1"
|
mktemp = "0.4.1"
|
@ -1,9 +1,3 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"matchUpdateTypes": ["major", "minor", "patch"],
|
|
||||||
"automerge": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,16 @@ use std::error::Error;
|
|||||||
use std::io::{Cursor, ErrorKind};
|
use std::io::{Cursor, ErrorKind};
|
||||||
|
|
||||||
use rustls::{Certificate, PrivateKey};
|
use rustls::{Certificate, PrivateKey};
|
||||||
use rustls_pemfile::Item;
|
use rustls_pemfile::{read_one, Item};
|
||||||
|
|
||||||
/// Parse PEM certificates bytes into a [`rustls::Certificate`] structure
|
/// Parse PEM certificates bytes into a [`rustls::Certificate`] structure
|
||||||
///
|
///
|
||||||
/// An error is returned if not any certificate could be found
|
/// An error is returned if not any certificate could be found
|
||||||
pub fn parse_pem_certificates(certs: &[u8]) -> Result<Vec<Certificate>, Box<dyn Error>> {
|
pub fn parse_pem_certificates(certs: &[u8]) -> Result<Vec<Certificate>, Box<dyn Error>> {
|
||||||
let certs = rustls_pemfile::certs(&mut Cursor::new(certs))
|
let certs = rustls_pemfile::certs(&mut Cursor::new(certs))?
|
||||||
.map(|c| c.map(|c| Certificate(c.to_vec())))
|
.into_iter()
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.map(Certificate)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if certs.is_empty() {
|
if certs.is_empty() {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
@ -25,7 +26,7 @@ pub fn parse_pem_certificates(certs: &[u8]) -> Result<Vec<Certificate>, Box<dyn
|
|||||||
|
|
||||||
/// Parse PEM private key bytes into a [`rustls::PrivateKey`] structure
|
/// Parse PEM private key bytes into a [`rustls::PrivateKey`] structure
|
||||||
pub fn parse_pem_private_key(privkey: &[u8]) -> Result<PrivateKey, Box<dyn Error>> {
|
pub fn parse_pem_private_key(privkey: &[u8]) -> Result<PrivateKey, Box<dyn Error>> {
|
||||||
let key = match rustls_pemfile::read_one(&mut Cursor::new(privkey))? {
|
let key = match read_one(&mut Cursor::new(privkey))? {
|
||||||
None => {
|
None => {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
@ -33,8 +34,8 @@ pub fn parse_pem_private_key(privkey: &[u8]) -> Result<PrivateKey, Box<dyn Error
|
|||||||
))?;
|
))?;
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
Some(Item::Pkcs8Key(key)) => key.secret_pkcs8_der().to_vec(),
|
Some(Item::PKCS8Key(key)) => key,
|
||||||
Some(Item::Pkcs1Key(key)) => key.secret_pkcs1_der().to_vec(),
|
Some(Item::RSAKey(key)) => key,
|
||||||
_ => {
|
_ => {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
|
@ -93,7 +93,7 @@ fn load_pem_file(path: &Option<String>, name: &str) -> std::io::Result<Option<Ve
|
|||||||
None => None,
|
None => None,
|
||||||
Some(p) => Some(
|
Some(p) => Some(
|
||||||
std::fs::read(p)
|
std::fs::read(p)
|
||||||
.map_err(|e| encpasulate_error(e, format!("Failed to load {name}!")))?,
|
.map_err(|e| encpasulate_error(e, format!("Failed to load {}!", name)))?,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ pub async fn run_app(mut args: ClientConfig) -> std::io::Result<()> {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to fetch relay configuration from server! {e}"),
|
format!("Failed to fetch relay configuration from server! {}", e),
|
||||||
))?;
|
))?;
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
|
use hyper_rustls::ConfigBuilderExt;
|
||||||
use rustls::RootCertStore;
|
use rustls::RootCertStore;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
@ -41,17 +42,7 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc<ClientCon
|
|||||||
let config = rustls::ClientConfig::builder().with_safe_defaults();
|
let config = rustls::ClientConfig::builder().with_safe_defaults();
|
||||||
|
|
||||||
let config = match conf.get_root_certificate() {
|
let config = match conf.get_root_certificate() {
|
||||||
None => {
|
None => config.with_native_roots(),
|
||||||
// Perform a connection over TLS
|
|
||||||
let mut roots = RootCertStore::empty();
|
|
||||||
for cert in rustls_native_certs::load_native_certs()
|
|
||||||
.expect("Failed to load native certificates")
|
|
||||||
{
|
|
||||||
roots.add(&rustls::Certificate(cert.0)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
config.with_root_certificates(roots)
|
|
||||||
}
|
|
||||||
Some(cert) => {
|
Some(cert) => {
|
||||||
log::debug!("Using custom root certificates");
|
log::debug!("Using custom root certificates");
|
||||||
let mut store = RootCertStore::empty();
|
let mut store = RootCertStore::empty();
|
||||||
@ -74,14 +65,14 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc<ClientCon
|
|||||||
.expect("Failed to parse client auth private key!");
|
.expect("Failed to parse client auth private key!");
|
||||||
|
|
||||||
config
|
config
|
||||||
.with_client_auth_cert(certs, key)
|
.with_single_cert(certs, key)
|
||||||
.expect("Failed to set client certificate!")
|
.expect("Failed to set client certificate!")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let connector = tokio_tungstenite::Connector::Rustls(Arc::new(config));
|
let connector = tokio_tungstenite::Connector::Rustls(Arc::new(config));
|
||||||
|
|
||||||
let (ws_stream, _) =
|
let (ws_stream, _) =
|
||||||
tokio_tungstenite::connect_async_tls_with_config(ws_url, None, false, Some(connector))
|
tokio_tungstenite::connect_async_tls_with_config(ws_url, None, Some(connector))
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to server relay!");
|
.expect("Failed to connect to server relay!");
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(tls_conf) = tls_config {
|
if let Some(tls_conf) = tls_config {
|
||||||
server.bind_rustls_021(&args.listen_address, tls_conf)?
|
server.bind_rustls(&args.listen_address, tls_conf)?
|
||||||
} else {
|
} else {
|
||||||
server.bind(&args.listen_address)?
|
server.bind(&args.listen_address)?
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use rustls::internal::msgs::enums::AlertDescription;
|
||||||
use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier};
|
use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier};
|
||||||
use rustls::{AlertDescription, Certificate, DistinguishedName, Error, RootCertStore};
|
use rustls::{Certificate, DistinguishedNames, Error, RootCertStore};
|
||||||
use x509_parser::prelude::{CertificateRevocationList, FromDer, X509Certificate};
|
use x509_parser::prelude::{CertificateRevocationList, FromDer, X509Certificate};
|
||||||
|
|
||||||
use crate::base::cert_utils::parse_pem_certificates;
|
use crate::base::cert_utils::parse_pem_certificates;
|
||||||
@ -54,13 +55,13 @@ impl CustomCertClientVerifier {
|
|||||||
let parsed_crl = pem::parse(crl_file)
|
let parsed_crl = pem::parse(crl_file)
|
||||||
.map_err(|e| encpasulate_error(e, "Failed to decode CRL file!"))?;
|
.map_err(|e| encpasulate_error(e, "Failed to decode CRL file!"))?;
|
||||||
|
|
||||||
Some(parsed_crl.into_contents())
|
Some(parsed_crl.contents)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
upstream_cert_verifier: Box::new(Arc::new(AllowAnyAuthenticatedClient::new(store))),
|
upstream_cert_verifier: Box::new(AllowAnyAuthenticatedClient::new(store)),
|
||||||
crl,
|
crl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -71,12 +72,12 @@ impl ClientCertVerifier for CustomCertClientVerifier {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_auth_mandatory(&self) -> bool {
|
fn client_auth_mandatory(&self) -> Option<bool> {
|
||||||
true
|
Some(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
|
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
|
||||||
&[]
|
Some(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_client_cert(
|
fn verify_client_cert(
|
||||||
|
Loading…
Reference in New Issue
Block a user