Update to modern code
This commit is contained in:
parent
63eba4dc37
commit
a838a94ce9
6 changed files with 493 additions and 512 deletions
916
Cargo.lock
generated
916
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -21,7 +21,7 @@ codegen-units = 1
|
||||||
debug = 1
|
debug = 1
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "4.0.0-beta.4", features = [ "rustls" ] }
|
actix-web = { version = "4.0.0-beta.8", features = [ "rustls" ] }
|
||||||
arc-swap = "1"
|
arc-swap = "1"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
@ -29,7 +29,7 @@ bincode = "1"
|
||||||
bytes = { version = "1", features = [ "serde" ] }
|
bytes = { version = "1", features = [ "serde" ] }
|
||||||
chacha20 = "0.7"
|
chacha20 = "0.7"
|
||||||
chrono = { version = "0.4", features = [ "serde" ] }
|
chrono = { version = "0.4", features = [ "serde" ] }
|
||||||
clap = { version = "3.0.0-beta.2", features = [ "wrap_help" ] }
|
clap = { version = "3.0.0-beta.4", features = [ "wrap_help" ] }
|
||||||
ctrlc = "3"
|
ctrlc = "3"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
flate2 = { version = "1", features = [ "tokio" ] }
|
flate2 = { version = "1", features = [ "tokio" ] }
|
||||||
|
@ -44,7 +44,8 @@ parking_lot = "0.11"
|
||||||
prometheus = { version = "0.12", features = [ "process" ] }
|
prometheus = { version = "0.12", features = [ "process" ] }
|
||||||
redis = "0.21"
|
redis = "0.21"
|
||||||
reqwest = { version = "0.11", default_features = false, features = [ "json", "stream", "rustls-tls" ] }
|
reqwest = { version = "0.11", default_features = false, features = [ "json", "stream", "rustls-tls" ] }
|
||||||
rustls = "0.19"
|
rustls = "0.20"
|
||||||
|
rustls-pemfile = "0.2"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use clap::{crate_authors, crate_description, crate_version, Clap};
|
use clap::{crate_authors, crate_description, crate_version, Parser};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -301,7 +301,7 @@ struct YamlExtendedOptions {
|
||||||
redis_url: Option<Url>,
|
redis_url: Option<Url>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Clone)]
|
#[derive(Parser, Clone)]
|
||||||
#[clap(version = crate_version!(), author = crate_authors!(), about = crate_description!())]
|
#[clap(version = crate_version!(), author = crate_authors!(), about = crate_description!())]
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
/// The port to listen on.
|
/// The port to listen on.
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -22,7 +22,9 @@ use config::Config;
|
||||||
use maxminddb::geoip2;
|
use maxminddb::geoip2;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use redis::Client as RedisClient;
|
use redis::Client as RedisClient;
|
||||||
use rustls::{NoClientAuth, ServerConfig};
|
|
||||||
|
use rustls::server::NoClientAuth;
|
||||||
|
use rustls::ServerConfig;
|
||||||
use sodiumoxide::crypto::stream::xchacha20::gen_key;
|
use sodiumoxide::crypto::stream::xchacha20::gen_key;
|
||||||
use state::{RwLockServerState, ServerState};
|
use state::{RwLockServerState, ServerState};
|
||||||
use stop::send_stop;
|
use stop::send_stop;
|
||||||
|
@ -239,11 +241,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
server.bind(bind_address)?.run().await?;
|
server.bind(bind_address)?.run().await?;
|
||||||
} else {
|
} else {
|
||||||
// Rustls only supports TLS 1.2 and 1.3.
|
// Rustls only supports TLS 1.2 and 1.3.
|
||||||
let tls_config = {
|
let tls_config = ServerConfig::builder()
|
||||||
let mut tls_config = ServerConfig::new(NoClientAuth::new());
|
.with_safe_defaults()
|
||||||
tls_config.cert_resolver = Arc::new(DynamicServerCert);
|
.with_client_cert_verifier(NoClientAuth::new())
|
||||||
tls_config
|
.with_cert_resolver(Arc::new(DynamicServerCert));
|
||||||
};
|
|
||||||
|
|
||||||
server.bind_rustls(bind_address, tls_config)?.run().await?;
|
server.bind_rustls(bind_address, tls_config)?.run().await?;
|
||||||
}
|
}
|
||||||
|
|
27
src/ping.rs
27
src/ping.rs
|
@ -2,9 +2,9 @@ use std::net::{IpAddr, SocketAddr};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::{io::BufReader, sync::Arc};
|
use std::{io::BufReader, sync::Arc};
|
||||||
|
|
||||||
use rustls::internal::pemfile::{certs, rsa_private_keys};
|
use rustls::sign::{CertifiedKey, RsaSigningKey, SigningKey};
|
||||||
use rustls::sign::{RSASigningKey, SigningKey};
|
use rustls::{Certificate, PrivateKey};
|
||||||
use rustls::Certificate;
|
use rustls_pemfile::{certs, rsa_private_keys};
|
||||||
use serde::de::{MapAccess, Visitor};
|
use serde::de::{MapAccess, Visitor};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_repr::Deserialize_repr;
|
use serde_repr::Deserialize_repr;
|
||||||
|
@ -15,8 +15,8 @@ use url::Url;
|
||||||
use crate::client::HTTP_CLIENT;
|
use crate::client::HTTP_CLIENT;
|
||||||
use crate::config::{ClientSecret, Config};
|
use crate::config::{ClientSecret, Config};
|
||||||
use crate::state::{
|
use crate::state::{
|
||||||
RwLockServerState, PREVIOUSLY_COMPROMISED, PREVIOUSLY_PAUSED, TLS_CERTS,
|
RwLockServerState, CERTIFIED_KEY, PREVIOUSLY_COMPROMISED, PREVIOUSLY_PAUSED,
|
||||||
TLS_PREVIOUSLY_CREATED, TLS_SIGNING_KEY,
|
TLS_PREVIOUSLY_CREATED,
|
||||||
};
|
};
|
||||||
use crate::units::{Bytes, BytesPerSecond, Port};
|
use crate::units::{Bytes, BytesPerSecond, Port};
|
||||||
use crate::CLIENT_API_VERSION;
|
use crate::CLIENT_API_VERSION;
|
||||||
|
@ -104,7 +104,7 @@ pub enum ErrorCode {
|
||||||
|
|
||||||
pub struct Tls {
|
pub struct Tls {
|
||||||
pub created_at: String,
|
pub created_at: String,
|
||||||
pub priv_key: Arc<Box<dyn SigningKey>>,
|
pub priv_key: Arc<RsaSigningKey>,
|
||||||
pub certs: Vec<Certificate>,
|
pub certs: Vec<Certificate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,8 @@ impl<'de> Deserialize<'de> for Tls {
|
||||||
priv_key = rsa_private_keys(&mut BufReader::new(value.as_bytes()))
|
priv_key = rsa_private_keys(&mut BufReader::new(value.as_bytes()))
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|mut v| {
|
.and_then(|mut v| {
|
||||||
v.pop().and_then(|key| RSASigningKey::new(&key).ok())
|
v.pop()
|
||||||
|
.and_then(|key| RsaSigningKey::new(&PrivateKey(key)).ok())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
"certificate" => {
|
"certificate" => {
|
||||||
|
@ -150,8 +151,8 @@ impl<'de> Deserialize<'de> for Tls {
|
||||||
match (created_at, priv_key, certificates) {
|
match (created_at, priv_key, certificates) {
|
||||||
(Some(created_at), Some(priv_key), Some(certificates)) => Ok(Tls {
|
(Some(created_at), Some(priv_key), Some(certificates)) => Ok(Tls {
|
||||||
created_at,
|
created_at,
|
||||||
priv_key: Arc::new(Box::new(priv_key)),
|
priv_key: Arc::new(priv_key),
|
||||||
certs: certificates,
|
certs: certificates.into_iter().map(Certificate).collect(),
|
||||||
}),
|
}),
|
||||||
_ => Err(serde::de::Error::custom("Could not deserialize tls info")),
|
_ => Err(serde::de::Error::custom("Could not deserialize tls info")),
|
||||||
}
|
}
|
||||||
|
@ -213,8 +214,12 @@ pub async fn update_server_state(
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.swap(Arc::new(tls.created_at));
|
.swap(Arc::new(tls.created_at));
|
||||||
TLS_SIGNING_KEY.get().unwrap().swap(tls.priv_key);
|
CERTIFIED_KEY.store(Some(Arc::new(CertifiedKey {
|
||||||
TLS_CERTS.get().unwrap().swap(Arc::new(tls.certs));
|
cert: tls.certs.clone(),
|
||||||
|
key: Arc::clone(&tls.priv_key) as Arc<dyn SigningKey>,
|
||||||
|
ocsp: None,
|
||||||
|
sct_list: None,
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
let previously_compromised = PREVIOUSLY_COMPROMISED.load(Ordering::Acquire);
|
let previously_compromised = PREVIOUSLY_COMPROMISED.load(Ordering::Acquire);
|
||||||
|
|
38
src/state.rs
38
src/state.rs
|
@ -1,15 +1,16 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::client::HTTP_CLIENT;
|
use crate::client::HTTP_CLIENT;
|
||||||
use crate::config::{ClientSecret, Config, OFFLINE_MODE};
|
use crate::config::{ClientSecret, Config, OFFLINE_MODE};
|
||||||
use crate::ping::{Request, Response, CONTROL_CENTER_PING_URL};
|
use crate::ping::{Request, Response, CONTROL_CENTER_PING_URL};
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::{ArcSwap, ArcSwapOption};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rustls::sign::{CertifiedKey, SigningKey};
|
use rustls::server::{ClientHello, ResolvesServerCert};
|
||||||
|
use rustls::sign::{CertifiedKey, RsaSigningKey, SigningKey};
|
||||||
use rustls::Certificate;
|
use rustls::Certificate;
|
||||||
use rustls::{ClientHello, ResolvesServerCert};
|
|
||||||
use sodiumoxide::crypto::box_::{PrecomputedKey, PRECOMPUTEDKEYBYTES};
|
use sodiumoxide::crypto::box_::{PrecomputedKey, PRECOMPUTEDKEYBYTES};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
@ -26,8 +27,10 @@ pub static PREVIOUSLY_PAUSED: AtomicBool = AtomicBool::new(false);
|
||||||
pub static PREVIOUSLY_COMPROMISED: AtomicBool = AtomicBool::new(false);
|
pub static PREVIOUSLY_COMPROMISED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
pub static TLS_PREVIOUSLY_CREATED: OnceCell<ArcSwap<String>> = OnceCell::new();
|
pub static TLS_PREVIOUSLY_CREATED: OnceCell<ArcSwap<String>> = OnceCell::new();
|
||||||
pub static TLS_SIGNING_KEY: OnceCell<ArcSwap<Box<dyn SigningKey>>> = OnceCell::new();
|
static TLS_SIGNING_KEY: OnceCell<ArcSwap<RsaSigningKey>> = OnceCell::new();
|
||||||
pub static TLS_CERTS: OnceCell<ArcSwap<Vec<Certificate>>> = OnceCell::new();
|
static TLS_CERTS: OnceCell<ArcSwap<Vec<Certificate>>> = OnceCell::new();
|
||||||
|
|
||||||
|
pub static CERTIFIED_KEY: ArcSwapOption<CertifiedKey> = ArcSwapOption::const_empty();
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ServerInitError {
|
pub enum ServerInitError {
|
||||||
|
@ -91,6 +94,14 @@ impl ServerState {
|
||||||
info!("This client's URL has been set to {}", resp.url);
|
info!("This client's URL has been set to {}", resp.url);
|
||||||
|
|
||||||
let tls = resp.tls.unwrap();
|
let tls = resp.tls.unwrap();
|
||||||
|
|
||||||
|
CERTIFIED_KEY.store(Some(Arc::new(CertifiedKey {
|
||||||
|
cert: tls.certs.clone(),
|
||||||
|
key: Arc::clone(&tls.priv_key) as Arc<dyn SigningKey>,
|
||||||
|
ocsp: None,
|
||||||
|
sct_list: None,
|
||||||
|
})));
|
||||||
|
|
||||||
std::mem::drop(
|
std::mem::drop(
|
||||||
TLS_PREVIOUSLY_CREATED.set(ArcSwap::from_pointee(tls.created_at)),
|
TLS_PREVIOUSLY_CREATED.set(ArcSwap::from_pointee(tls.created_at)),
|
||||||
);
|
);
|
||||||
|
@ -146,22 +157,9 @@ pub struct RwLockServerState(pub RwLock<ServerState>);
|
||||||
pub struct DynamicServerCert;
|
pub struct DynamicServerCert;
|
||||||
|
|
||||||
impl ResolvesServerCert for DynamicServerCert {
|
impl ResolvesServerCert for DynamicServerCert {
|
||||||
fn resolve(&self, _: ClientHello) -> Option<CertifiedKey> {
|
fn resolve(&self, _: ClientHello) -> Option<Arc<CertifiedKey>> {
|
||||||
// TODO: wait for actix-web to use a new version of rustls so we can
|
// TODO: wait for actix-web to use a new version of rustls so we can
|
||||||
// remove cloning the certs all the time
|
// remove cloning the certs all the time
|
||||||
Some(CertifiedKey {
|
CERTIFIED_KEY.load_full()
|
||||||
cert: TLS_CERTS
|
|
||||||
.get()
|
|
||||||
.expect("tls cert to exist")
|
|
||||||
.load()
|
|
||||||
.as_ref()
|
|
||||||
.clone(),
|
|
||||||
key: TLS_SIGNING_KEY
|
|
||||||
.get()
|
|
||||||
.expect("tls signing key to exist")
|
|
||||||
.load_full(),
|
|
||||||
ocsp: None,
|
|
||||||
sct_list: None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue