Files
bonknet/bonknet_server/src/bin/server.rs

299 lines
12 KiB
Rust

use std::io::{Error, ErrorKind};
use std::sync::Arc;
use futures::{SinkExt, StreamExt};
use tokio::net::TcpStream;
use tokio_rustls::rustls::ClientConfig;
use tokio_rustls::rustls::pki_types::ServerName;
use tokio_rustls::TlsConnector;
use tokio_util::codec::{Framed, LengthDelimitedCodec};
use libbonknet::*;
use libbonknet::servermsg::*;
use libbonknet::cert::*;
use uuid::Uuid;
use tracing::{error, info};
async fn datastream(tlsconfig: Arc<ClientConfig>, conn_id: Uuid) -> std::io::Result<()> {
let connector = TlsConnector::from(tlsconfig);
let dnsname = ServerName::try_from("localhost").unwrap();
let stream = TcpStream::connect("localhost:2541").await?;
let stream = connector.connect(dnsname, stream).await?;
let mut transport = Framed::new(stream, LengthDelimitedCodec::new());
let msg = FromServerConnTypeMessage::OpenDataStream(conn_id);
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
match transport.next().await {
None => panic!("None in the transport"),
Some(item) => match item {
Ok(buf) => {
use ToPeerDataStream::*;
let msg: ToPeerDataStream = rmp_serde::from_slice(&buf).unwrap();
match msg {
OkDataStreamRequestAccepted => {
info!("Data Stream Accepted. Waiting for Open...");
}
Refused => {
error!("Refused");
return Err(Error::new(ErrorKind::ConnectionRefused, "Refused"));
}
other => {
error!("Unexpected response: {:?}", other);
return Err(Error::new(ErrorKind::ConnectionRefused, "Unexpected response"));
}
}
}
Err(e) => {
error!("Error: {:?}", e);
return Err(e);
}
}
}
match transport.next().await {
None => panic!("None in the transport"),
Some(item) => match item {
Ok(buf) => {
use ToPeerDataStream::*;
let msg: ToPeerDataStream = rmp_serde::from_slice(&buf).unwrap();
match msg {
OkDataStreamOpen => {
info!("Data Stream Open!. Connecting Streams.");
}
Revoked => {
error!("Data Stream Revoked!");
return Err(Error::new(ErrorKind::ConnectionAborted, "Revoked"));
}
Refused => {
error!("Refused");
return Err(Error::new(ErrorKind::ConnectionRefused, "Refused"));
}
other => {
error!("Unexpected response: {:?}", other);
return Err(Error::new(ErrorKind::ConnectionRefused, "Unexpected response"));
}
}
}
Err(e) => {
error!("Error: {:?}", e);
return Err(e);
}
}
}
// Initialize outbound stream
let mut inbound = transport.into_inner();
let mut outbound = TcpStream::connect("127.0.0.1:22").await?;
match tokio::io::copy_bidirectional(&mut inbound, &mut outbound).await {
Ok(bytes_copied) => info!("{bytes_copied:?}"),
Err(e) => error!("Error during copy: {e}"),
}
Ok(())
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
// Tracing Subscriber
let subscriber = tracing_subscriber::FmtSubscriber::new();
tracing::subscriber::set_global_default(subscriber).unwrap();
// Server Name
let my_name = "cicciopizza";
// Load Identity files
let guestserver_ident = LeafCertPair::load_from_file("certs_pem/guestserver.pem").unwrap();
let broker_root = BrokerRootCerts::load_from_file("certs_pem/broker_root_ca_cert.pem").unwrap();
// Load TLS Config
let guest_cert_chain = guestserver_ident.fullchain();
let tlsconfig = ClientConfig::builder()
.with_root_certificates(broker_root.to_rootcertstore())
// .with_no_client_auth();
.with_client_auth_cert(guest_cert_chain, guestserver_ident.clone_key().into())
.unwrap();
let connector = TlsConnector::from(Arc::new(tlsconfig));
let dnsname = ServerName::try_from("localhost").unwrap();
let stream = TcpStream::connect("localhost:2541").await?;
let stream = connector.connect(dnsname, stream).await?;
let mut transport = Framed::new(stream, LengthDelimitedCodec::new());
let msg = FromGuestServerMessage::Announce { name: my_name.into() };
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
// TODO: Remove this two mutable option
let mut myserver_leaf: Option<LeafCertPair> = None;
match transport.next().await {
None => {
panic!("None in the transport");
}
Some(item) => match item {
Ok(buf) => {
use libbonknet::servermsg::ToGuestServerMessage::*;
let msg: ToGuestServerMessage = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
OkAnnounce(payload) => {
info!("Ok Announce");
myserver_leaf = Some(payload.parse());
}
FailedNameAlreadyOccupied => {
error!("Failed Announce, name already occupied");
return Ok(());
}
}
}
Err(e) => {
error!("Error: {:?}", e);
}
}
}
transport.close().await.unwrap();
if let Some(server_leaf) = myserver_leaf {
let tlsconfig = Arc::new(ClientConfig::builder()
.with_root_certificates(broker_root.to_rootcertstore())
.with_client_auth_cert(server_leaf.fullchain(), server_leaf.clone_key().into())
.unwrap());
let connector = TlsConnector::from(Arc::clone(&tlsconfig));
let dnsname = ServerName::try_from("localhost").unwrap();
let stream = TcpStream::connect("localhost:2541").await?;
let stream = connector.connect(dnsname, stream).await?;
let mut transport = Framed::new(stream, LengthDelimitedCodec::new());
let msg = FromServerConnTypeMessage::SendCommand;
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
match transport.next().await {
None => {
panic!("None in the transport");
}
Some(item) => match item {
Ok(buf) => {
use libbonknet::servermsg::ToServerConnTypeReply;
use libbonknet::servermsg::ToServerConnTypeReply::*;
let msg: ToServerConnTypeReply = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
OkSendCommand => {
info!("Stream set in SendCommand mode");
}
GenericFailure => {
panic!("Generic Failure during SendCommand");
}
others => {
panic!("Unexpected Message type: {:?}", others);
}
}
}
Err(e) => {
info!("Disconnection: {:?}", e);
}
}
}
// Begin WhoAmI
let msg = FromServerCommandMessage::WhoAmI;
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
match transport.next().await {
None => {
panic!("None in the transport");
}
Some(item) => match item {
Ok(buf) => {
use libbonknet::servermsg::ToServerCommandReply;
use libbonknet::servermsg::ToServerCommandReply::*;
let msg: ToServerCommandReply = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
YouAre { name } => {
info!("I am {}", name);
}
GenericFailure => {
panic!("Generic failure during WhoAmI");
}
_ => {
panic!("Unexpected reply");
}
}
}
Err(e) => {
info!("Disconnection: {:?}", e);
}
}
}
transport.close().await.expect("Error during transport stream close");
// Start Subscribe Stream
let connector = TlsConnector::from(Arc::clone(&tlsconfig));
let dnsname = ServerName::try_from("localhost").unwrap();
let stream = TcpStream::connect("localhost:2541").await?;
let stream = connector.connect(dnsname, stream).await?;
let mut transport = Framed::new(stream, LengthDelimitedCodec::new());
let msg = FromServerConnTypeMessage::Subscribe;
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
match transport.next().await {
None => {
panic!("None in the transport");
}
Some(item) => match item {
Ok(buf) => {
use libbonknet::servermsg::ToServerConnTypeReply;
use libbonknet::servermsg::ToServerConnTypeReply::*;
let msg: ToServerConnTypeReply = rmp_serde::from_slice(&buf).unwrap();
info!("{:?}", msg);
match msg {
OkSubscribe => {
info!("Stream set in Subscribe mode");
}
GenericFailure => {
panic!("Generic Failure during SendCommand");
}
others => {
panic!("Unexpected Message type: {:?}", others);
}
}
}
Err(e) => {
info!("Disconnection: {:?}", e);
}
}
}
// Subscribe consume
loop {
match transport.next().await {
None => {
info!("Empty Buffer");
}
Some(item) => {
let mut out: Option<FromServerReply> = None;
match item {
Ok(buf) => {
use libbonknet::servermsg::ToServerMessage;
use libbonknet::servermsg::ToServerMessage::*;
let msg: ToServerMessage = rmp_serde::from_slice(&buf).unwrap();
match msg {
Msg { reply_id, body } => {
use libbonknet::servermsg::FromServerReplyBody;
use libbonknet::servermsg::ToServerMessageBody::*;
match body {
Request { conn_id } => {
info!("I'm required with Connection ID {}", conn_id);
out = Some(FromServerReply::Msg {
reply_id,
body: FromServerReplyBody::RequestAccepted,
});
// TODO: SPAWN DATASTREAM
tokio::spawn(datastream(tlsconfig.clone(), conn_id));
}
}
}
Ping => {
info!("Ping!");
out = Some(FromServerReply::Pong);
}
}
}
Err(e) => {
error!("Error: {:?}", e);
}
}
if let Some(msg) = out {
transport.send(rmp_serde::to_vec(&msg).unwrap().into()).await.unwrap();
}
}
}
}
}
Ok(())
}