This commit is contained in:
parent
69be9f7aca
commit
089def45d1
37 changed files with 2792 additions and 225 deletions
|
|
@ -8,9 +8,10 @@ name = "server"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
mtp = { version = "0.1.0", path = "../../", features = ["crypto", "host", "files"] }
|
||||
mtp = { version = "0.1.0", path = "../../", features = ["crypto", "host", "files", "pipes"] }
|
||||
rcgen = "0.14"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
serde_json = { version = "1" }
|
||||
hex = "0.4"
|
||||
base64 = "0.22"
|
||||
time = "0.3"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ mod keys;
|
|||
mod tls;
|
||||
|
||||
use mtp::host::{AuthenticationPolicy, HostConfig, MTPHost};
|
||||
|
||||
use mtp::type_map::TypeMap;
|
||||
use std::future::Future;
|
||||
use std::path::Path;
|
||||
|
|
@ -28,6 +27,54 @@ fn dev_cert_paths() -> (String, String) {
|
|||
(cert, key)
|
||||
}
|
||||
|
||||
async fn handle_pipe_loopback(
|
||||
conn: &mtp::host::MTPConnection,
|
||||
req: mtp::host::PipeRequest,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let pipe_id = req.id();
|
||||
println!(
|
||||
" [loopback] Pipe request: id={pipe_id} description={:?}",
|
||||
req.description()
|
||||
);
|
||||
|
||||
println!(" [loopback] Calling accept() for pipe {pipe_id} ...");
|
||||
let mut reader = req.accept().await?;
|
||||
println!(" [loopback] Pipe {pipe_id} accepted, reading data ...");
|
||||
|
||||
let mut buf = Vec::new();
|
||||
tokio::io::AsyncReadExt::read_to_end(&mut reader, &mut buf).await?;
|
||||
println!(
|
||||
" [loopback] Pipe {pipe_id} read {} bytes, creating return pipe ...",
|
||||
buf.len()
|
||||
);
|
||||
|
||||
let handle = conn.create_pipe("loopback").await?;
|
||||
println!(
|
||||
" [loopback] Return pipe created (id={}), waiting for client ...",
|
||||
handle.pipe_id()
|
||||
);
|
||||
|
||||
match handle.wait().await? {
|
||||
Some(mut writer) => {
|
||||
println!(
|
||||
" [loopback] Client accepted return pipe, writing {} bytes ...",
|
||||
buf.len()
|
||||
);
|
||||
tokio::io::AsyncWriteExt::write_all(&mut writer, &buf).await?;
|
||||
writer.finish().await?;
|
||||
println!(
|
||||
" [loopback] Pipe {pipe_id} loopback complete ({} bytes)",
|
||||
buf.len()
|
||||
);
|
||||
}
|
||||
None => {
|
||||
eprintln!(" [loopback] Return pipe denied by client for pipe {pipe_id}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (cert_path, key_path) = dev_cert_paths();
|
||||
|
|
@ -39,8 +86,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let (_host_id, host_keyring) = keys::load_or_generate_host_keys("host.mk")?;
|
||||
keys::export_host_public_keys(&host_keyring)?;
|
||||
|
||||
// The keyring is moved into the host config; keep a copy for decrypting the
|
||||
// demo payloads clients encrypt to our KEM public key.
|
||||
let decrypt_keyring = mtp::crypto::Keyring::from_bytes(&host_keyring.to_bytes())
|
||||
.expect("re-load host keyring for decryption");
|
||||
|
||||
|
|
@ -116,20 +161,47 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let tm: &TypeMap = conn.codec.registry().get(&conn.version).unwrap();
|
||||
|
||||
match conn.receiver.receive().await {
|
||||
Ok(msg) => {
|
||||
println!("Received: {msg}");
|
||||
let response = handlers::process_and_respond(
|
||||
&msg,
|
||||
tm,
|
||||
conn.client_public_key.as_ref(),
|
||||
&decrypt_keyring,
|
||||
);
|
||||
println!("Sending: {response}");
|
||||
conn.sender.send(&response).await?;
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Receive error: {e}");
|
||||
println!("Waiting for messages / pipe requests ...");
|
||||
loop {
|
||||
tokio::select! {
|
||||
biased;
|
||||
|
||||
pipe_req = conn.receive_pipe() => {
|
||||
match pipe_req {
|
||||
Ok(req) => {
|
||||
println!(" Pipe request: id={} desc={:?}", req.id(), req.description());
|
||||
if let Err(e) = handle_pipe_loopback(&conn, req).await {
|
||||
eprintln!(" Pipe loopback error: {e}");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Pipe channel closed: {e}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg = conn.receive() => {
|
||||
match msg {
|
||||
Ok(msg) => {
|
||||
println!("Received: {msg}");
|
||||
let response = handlers::process_and_respond(
|
||||
&msg,
|
||||
tm,
|
||||
conn.client_public_key.as_ref(),
|
||||
&decrypt_keyring,
|
||||
);
|
||||
println!("Sending: {response}");
|
||||
if let Err(e) = conn.sender.send(&response).await {
|
||||
eprintln!("Send error: {e}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Connection ended: {e}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use base64::Engine;
|
||||
use rcgen::{CertificateParams, ExtendedKeyUsagePurpose, IsCa, KeyPair, KeyUsagePurpose, SanType};
|
||||
use std::fs;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::path::Path;
|
||||
use time::{Duration, OffsetDateTime};
|
||||
|
||||
pub fn load_or_generate_tls(
|
||||
cert_path: &str,
|
||||
|
|
@ -19,8 +21,26 @@ pub fn load_or_generate_tls(
|
|||
if let Some(parent) = Path::new(key_path).parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let key_pair = rcgen::KeyPair::generate()?;
|
||||
let params = rcgen::CertificateParams::new(vec!["localhost".into(), "127.0.0.1".into()])?;
|
||||
|
||||
let key_pair = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256)?;
|
||||
|
||||
let mut params = CertificateParams::new(vec!["localhost".into()])?;
|
||||
params.not_before = OffsetDateTime::now_utc() - Duration::minutes(5);
|
||||
params.not_after = OffsetDateTime::now_utc() + Duration::days(13);
|
||||
|
||||
params
|
||||
.subject_alt_names
|
||||
.push(SanType::IpAddress(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))));
|
||||
params
|
||||
.subject_alt_names
|
||||
.push(SanType::IpAddress(IpAddr::V6(Ipv6Addr::new(
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
))));
|
||||
|
||||
params.key_usages = vec![KeyUsagePurpose::DigitalSignature];
|
||||
params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth];
|
||||
params.is_ca = IsCa::NoCa;
|
||||
|
||||
let cert = params.self_signed(&key_pair)?;
|
||||
|
||||
let cert_str = cert.pem();
|
||||
|
|
|
|||
Loading…
Reference in a new issue