sigchat prepare tls connection to provisioning server

This commit is contained in:
nworbnhoj 2023-12-12 06:44:02 +11:00
parent 2be426131c
commit b094402bf3
2 changed files with 126 additions and 3 deletions

View file

@ -1,11 +1,13 @@
mod group_permission;
mod link_state;
mod signal_ws;
mod trust_mode;
use crate::Account;
use crate::{Account, DEFAULT_DEVICE_NAME, DEFAULT_HOST_NAME};
use group_permission::GroupPermission;
use link_state::LinkState;
use std::io::Error;
use signal_ws::SignalWS;
pub use trust_mode::TrustMode;
// Structure modeled on signal-cli by AsamK <asamk@gmx.de> and contributors - https://github.com/AsamK/signal-cli.
@ -14,8 +16,9 @@ pub use trust_mode::TrustMode;
#[allow(dead_code)]
pub struct Manager {
account:Account,
account: Account,
trust_mode: TrustMode,
websocket: Option<SignalWS>,
log_verbose: bool,
log_scrub: bool,
log_send: bool,
@ -32,6 +35,7 @@ impl Manager {
Manager {
account,
trust_mode,
websocket: None,
log_verbose: false,
log_scrub: false,
log_send: false,
@ -128,7 +132,24 @@ impl Manager {
///
#[allow(dead_code)]
pub fn link(&mut self, name: Option<&str>, host: Option<&str>) -> Result<bool, Error> {
todo!();
// insert default values as required
let name = name.unwrap_or(DEFAULT_DEVICE_NAME);
let host = host.unwrap_or(DEFAULT_HOST_NAME);
match SignalWS::provision(&host) {
Ok(ws) => {
if let Some(prior_ws) = &mut self.websocket {
prior_ws.close();
}
self.websocket = Some(ws);
log::info!("websocket established to link {name} at {host}");
log::warn!("Manager.link() not fully implemented.");
}
Err(e) => {
log::info!("failed to connect to server: {}", e);
Err(e)
}
}
}
/// Link another device to this device. Only works, if this is the primary device.

View file

@ -0,0 +1,102 @@
use rustls::{ClientConnection, StreamOwned};
use std::io::{Error, ErrorKind};
use std::net::TcpStream;
use tls::Tls;
const PROVISIONING_PATH: &str = "/provisioning/";
const REGISTRATION_PATH: &str = "/v1/registration";
#[allow(dead_code)]
pub enum SignalWS {
Message {
ws: WebSocket<StreamOwned<ClientConnection, TcpStream>>,
},
Provision {
ws: WebSocket<StreamOwned<ClientConnection, TcpStream>>,
},
Register {
ws: WebSocket<StreamOwned<ClientConnection, TcpStream>>,
},
}
impl SignalWS {
#[allow(dead_code)]
pub fn message(_host: &str) -> Result<Self, Error> {
todo!();
}
pub fn provision(host: &str) -> Result<Self, Error> {
let server = format!("wss://{host}{}", PROVISIONING_PATH);
// let mut conn = client_connection(&server);
match SignalWS::connect(server) {
Ok(ws) => Ok(Self::Provision { ws }),
Err(e) => Err(e),
}
}
#[allow(dead_code)]
pub fn register(host: &str) -> Result<Self, Error> {
let server = format!("wss://{host}{}", REGISTRATION_PATH);
// let mut conn = client_connection(&server);
match SignalWS::connect(server) {
Ok(ws) => Ok(Self::Register { ws }),
Err(e) => Err(e),
}
}
pub fn close(&mut self) {
match self {
SignalWS::Message { ws, .. }
| SignalWS::Provision { ws, .. }
| SignalWS::Register { ws, .. } => {
ws.close(None)
.unwrap_or_else(|e| log::warn!("failed to close websocket: {e}"));
// TODO close properly https://docs.rs/tungstenite/0.20.1/tungstenite/protocol/struct.WebSocket.html
ws.flush()
.unwrap_or_else(|e| log::warn!("failed to flush websocket: {e}"));
}
}
}
/// Make a websocket connection to host server
///
/// # Arguments
/// * `server` - server
///
/// # Returns
///
fn connect(
server: String,
) -> Result<WebSocket<StreamOwned<ClientConnection, TcpStream>>, Error> {
log::info!("connecting websocket");
match url::Url::parse(&server) {
Ok(url) => {
let host = url.host_str().expect("failed to extract host from url");
match TcpStream::connect((host, 443)) {
Ok(sock) => {
log::info!("tcp connected");
let xtls = Tls::new();
match xtls.stream(host, sock) {
Ok(tls_stream) => {
log::info!("tls configured");
log::info!("WEBSOCKET NOT IMPLEMENTED YET");
}
Err(e) => {
log::warn!("failed to configure tls: {e}");
Err(e)
}
}
}
Err(e) => {
log::warn!("failed to connect tcp: {e}");
Err(e)
}
}
}
Err(e) => {
log::info!("failed to parse server url: {e}");
Err(Error::new(ErrorKind::InvalidData, e))
}
}
}
}