This commit is contained in:
Mike Dilger 2023-10-26 19:41:10 +13:00
parent b64ef9c3e9
commit 8701ae69dd
5 changed files with 74 additions and 19 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target
/tls/

View File

@ -2,6 +2,8 @@ Config(
data_directory: "./sample",
ip_address: "127.0.0.1",
port: 8080,
certchain_pem_path: "tls/fullchain.pem",
key_pem_path: "tls/privkey.pem",
name: None,
description: None,
public_key_hex: None,

View File

@ -5,6 +5,8 @@ pub struct Config {
pub data_directory: String,
pub ip_address: String,
pub port: u16,
pub certchain_pem_path: String,
pub key_pem_path: String,
pub name: Option<String>,
pub description: Option<String>,
pub public_key_hex: Option<String>,
@ -16,6 +18,8 @@ impl Default for Config {
data_directory: "/tmp".to_string(),
ip_address: "127.0.0.1".to_string(),
port: 80,
certchain_pem_path: "./tls/fullchain.pem".to_string(),
key_pem_path: "./tls/privkey.pem".to_string(),
name: None,
description: None,
public_key_hex: None,

View File

@ -67,6 +67,13 @@ pub enum Error {
#[error("LMDB: {0}")]
Lmdb(#[from] heed::Error),
#[error("Private Key Not Found")]
NoPrivateKey,
// Rustls
#[error("TLS: {0}")]
Rustls(#[from] tokio_rustls::rustls::Error),
// Filter is underspecified
#[error("Filter is underspecified. Scrapers are not allowed")]
Scraper,

View File

@ -12,11 +12,14 @@ use crate::error::Error;
use crate::globals::GLOBALS;
use crate::store::Store;
use hyper::{Body, Request, Response};
use rustls::{Certificate, PrivateKey};
use std::env;
use std::error::Error as StdError;
use std::fs::OpenOptions;
use std::io::Read;
use std::fs::{File, OpenOptions};
use std::io::{BufReader, Read};
use std::sync::Arc;
use tokio::net::TcpListener;
use tokio_rustls::{rustls, TlsAcceptor};
#[tokio::main]
async fn main() -> Result<(), Error> {
@ -41,6 +44,35 @@ async fn main() -> Result<(), Error> {
let store = Store::new(&config.data_directory)?;
let _ = GLOBALS.store.set(store);
// TLS setup
let tls_acceptor = {
let certs: Vec<Certificate> =
rustls_pemfile::certs(&mut BufReader::new(File::open(&config.certchain_pem_path)?))?
.drain(..)
.map(Certificate)
.collect();
let mut keys: Vec<PrivateKey> = rustls_pemfile::pkcs8_private_keys(&mut BufReader::new(
File::open(&config.key_pem_path)?,
))?
.drain(..)
.rev()
.map(PrivateKey)
.collect();
let key = match keys.pop() {
Some(k) => k,
None => return Err(Error::NoPrivateKey),
};
let tls_config = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, key)?;
TlsAcceptor::from(Arc::new(tls_config))
};
// Bind listener to port
let listener = TcpListener::bind((&*config.ip_address, config.port)).await?;
log::info!("Running on {}:{}", config.ip_address, config.port);
@ -56,24 +88,33 @@ async fn main() -> Result<(), Error> {
loop {
let (tcp_stream, peer_addr) = listener.accept().await?;
let connection =
http_server.serve_connection(tcp_stream, hyper::service::service_fn(handle_request));
let acceptor = tls_acceptor.clone();
let http_server_clone = http_server.clone();
tokio::spawn(async move {
// If our service exits with an error, log the error
if let Err(he) = connection.await {
if let Some(src) = he.source() {
if &*format!("{}", src) == "Transport endpoint is not connected (os error 107)"
{
// do nothing
} else {
// Print in detail
log::info!("{:?}", src);
}
} else {
// Print in less detail
let e: Error = he.into();
log::info!("{}", e);
match acceptor.accept(tcp_stream).await {
Err(e) => log::error!("{}", e),
Ok(tls_stream) => {
let connection = http_server_clone
.serve_connection(tls_stream, hyper::service::service_fn(handle_request));
tokio::spawn(async move {
// If our service exits with an error, log the error
if let Err(he) = connection.await {
if let Some(src) = he.source() {
if &*format!("{}", src)
== "Transport endpoint is not connected (os error 107)"
{
// do nothing
} else {
// Print in detail
log::info!("{:?}", src);
}
} else {
// Print in less detail
let e: Error = he.into();
log::info!("{}", e);
}
}
});
}
}
});