Use the real structure with Server-Broker-Client instead of Client-Server-Requester previously used in Bonk v1

This commit is contained in:
2024-02-12 17:33:56 +01:00
parent 7ee40b7dbe
commit 857b9171af
11 changed files with 604 additions and 157 deletions

200
bonknet_broker/src/main.rs Normal file
View File

@@ -0,0 +1,200 @@
use actix::prelude::*;
use std::collections::HashMap;
use std::sync::Arc;
use libbonknet::{load_cert, load_prkey, FromServerMessage, RequiredReplyValues, FromGuestServerMessage};
use rustls::{RootCertStore, ServerConfig};
use rustls::server::WebPkiClientVerifier;
use actix_tls::accept::rustls_0_22::{Acceptor as RustlsAcceptor, TlsStream};
use actix_server::Server;
use actix_rt::net::TcpStream;
use actix_service::{ServiceFactoryExt as _};
use futures_util::{StreamExt};
use thiserror::Error;
use tokio_util::codec::{Framed, LengthDelimitedCodec};
use tracing::{info, error};
#[derive(Error, Debug)]
enum DBError {
#[error("Certificate is already registered with name {0}")]
CertAlreadyRegistered(String),
// #[error("Generic Failure")]
// GenericFailure,
}
#[derive(Message)]
#[rtype(result = "Result<(), DBError>")]
struct RegisterServer {
cert: Vec<u8>,
name: String,
}
// TODO: Move into Sqlite DB with unique check on col1 and col2!!!! Right now name is not unique
struct ServerCertDB {
db: HashMap<Vec<u8>, String>, // Cert to Name
}
impl Actor for ServerCertDB {
type Context = Context<Self>;
}
impl Handler<RegisterServer> for ServerCertDB {
type Result = Result<(), DBError>;
fn handle(&mut self, msg: RegisterServer, _ctx: &mut Self::Context) -> Self::Result {
match self.db.get(&msg.cert) {
None => {
self.db.insert(msg.cert, msg.name);
Ok(())
}
Some(name) => {
Err(DBError::CertAlreadyRegistered(name.clone()))
}
}
}
}
struct GuestServerConnection {
stream: TlsStream<TcpStream>,
}
impl Actor for GuestServerConnection {
type Context = Context<Self>;
}
struct ServerConnection<T: 'static> {
stream: Framed<TlsStream<TcpStream>, T>,
name: String
}
impl<T> ServerConnection<T> {
fn new(stream: TlsStream<TcpStream>, codec: T) -> Self {
let stream = Framed::new(stream, codec);
ServerConnection {
stream,
name: "Polnareffland1".into(),
}
}
}
impl<T> Actor for ServerConnection<T> {
type Context = Context<Self>;
}
#[actix_rt::main]
async fn main() {
// Tracing Subscriber
let subscriber = tracing_subscriber::FmtSubscriber::new();
tracing::subscriber::set_global_default(subscriber).unwrap();
// BROKER CERTS
let broker_root_cert_der = load_cert("certs/broker_root_cert.pem").unwrap();
let broker_cert_der = load_cert("certs/broker_cert.pem").unwrap();
let broker_prkey_der = load_prkey("certs/broker_key.pem").unwrap();
// SERVER ROOT
let server_root_cert_der = load_cert("certs/server_root_cert.pem").unwrap();
// GUESTSERVER ROOT
let guestserver_root_cert_der = load_cert("certs/guestserver_root_cert.pem").unwrap();
// CLIENT ROOT
let client_root_cert_der = load_cert("certs/client_root_cert.pem").unwrap();
// Client Verifier
let mut broker_root_store = RootCertStore::empty();
broker_root_store.add(server_root_cert_der.clone()).unwrap();
broker_root_store.add(client_root_cert_der.clone()).unwrap();
broker_root_store.add(guestserver_root_cert_der.clone()).unwrap();
let server_verifier = WebPkiClientVerifier::builder(Arc::new(broker_root_store)).build().unwrap();
// Configure TLS
let server_tlsconfig = ServerConfig::builder()
// .with_no_client_auth()
.with_client_cert_verifier(server_verifier)
.with_single_cert(vec![broker_cert_der.clone(), broker_root_cert_der.clone()], broker_prkey_der.into())
.unwrap();
let server_acceptor = RustlsAcceptor::new(server_tlsconfig);
let server_root_cert_der = Arc::new(server_root_cert_der);
let client_root_cert_der = Arc::new(client_root_cert_der);
let guestserver_root_cert_der = Arc::new(guestserver_root_cert_der);
Server::build()
.bind("server-command", ("localhost", 2541), move || {
let server_root_cert_der = Arc::clone(&server_root_cert_der);
let client_root_cert_der = Arc::clone(&client_root_cert_der);
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
let _server_db_addr = ServerCertDB {
db: HashMap::new(),
}.start();
// Set up TLS service factory
server_acceptor
.clone()
.map_err(|err| println!("Rustls error: {:?}", err))
.and_then(move |stream: TlsStream<TcpStream>| {
let server_root_cert_der = Arc::clone(&server_root_cert_der);
let client_root_cert_der = Arc::clone(&client_root_cert_der);
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
async move {
let peer_cert_der = stream.get_ref().1.peer_certificates().unwrap().last().unwrap().clone();
if peer_cert_der == *server_root_cert_der {
info!("Server connection");
let framed = Framed::new(stream, LengthDelimitedCodec::new());
framed.for_each(|item| async move {
match item {
Ok(buf) => {
use FromServerMessage::*;
let msg: FromServerMessage = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
RequiredReply(v) => match v {
RequiredReplyValues::Ok => {
info!("Required Reply OK")
}
RequiredReplyValues::GenericFailure { .. } => {
info!("Required Reply Generic Failure")
}
}
ChangeName { name } => {
info!("Requested Change Name to Name {}", name);
}
WhoAmI => {
info!("Requested WhoAmI");
}
}
},
Err(e) => {
info!("Disconnection: {:?}", e);
}
}
}).await;
info!("Disconnection!");
} else if peer_cert_der == *guestserver_root_cert_der {
info!("GuestServer connection");
let framed = Framed::new(stream, LengthDelimitedCodec::new());
framed.for_each(|item| async move {
match item {
Ok(buf) => {
use FromGuestServerMessage::*;
let msg: FromGuestServerMessage = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
Announce { name } => {
info!("Announced with name {}", name);
}
}
}
Err(e) => {
info!("Disconnection: {:?}", e);
}
}
}).await;
} else if peer_cert_der == *client_root_cert_der {
info!("Client connection");
} else {
error!("Unknown Root Certificate");
}
Ok(())
}
})
}).unwrap()
.workers(1)
.run()
.await
.unwrap();
}