//! ## SSLRelay //! Library for relaying TCP traffic as well as TLS encrypted TCP traffic. //! This Library allows you to implement callback functions for upstream and downstream traffic. //! These callbacks can R/W the data from a stream(Blocking) or only R the data(Non-Blocking). //!``` //!pub trait HandlerCallbacks { //! fn ds_b_callback(&mut self, _in_data: Vec) -> CallbackRet {CallbackRet::Relay(_in_data)} //! fn ds_nb_callback(&self, _in_data: Vec){} //! fn us_b_callback(&mut self, _in_data: Vec) -> CallbackRet {CallbackRet::Relay(_in_data)} //! fn us_nb_callback(&self, _in_data: Vec){} //!} //!``` //! The blocking callbacks return an enum called CallbackRet with four different variants. //! The variants control the flow of the tcp stream. //!``` //! pub enum CallbackRet { //! Relay(Vec),// Relay data //! Spoof(Vec),// Skip relaying and send data back //! Shutdown,// Shutdown TCP connection //! Freeze,// Dont send data (pretend as if stream never was recieved) //! } //! ``` //! ## Example (basic.rs) //! ``` //! use sslrelay::{self, RelayConfig, HandlerCallbacks, CallbackRet, TCPDataType, TLSConfig}; //! //! // Handler object //! #[derive(Clone)] // Must have Clone trait implemented. //! struct Handler; //! //! /* //! Callback traits that can be used to read or inject data //! into data upstream or downstream. //! */ //! impl HandlerCallbacks for Handler { //! //! // DownStream non blocking callback (Read Only) //! fn ds_nb_callback(&self, _in_data: Vec) { //! println!("[CALLBACK] Down Stream Non Blocking CallBack!"); //! } //! //! // DownStream blocking callback (Read & Write) //! fn ds_b_callback(&mut self, _in_data: Vec) -> CallbackRet { //! println!("[CALLBACK] Down Stream Blocking CallBack!"); //! CallbackRet::Relay(_in_data) //! } //! //! // UpStream non blocking callback (Read Only) //! fn us_nb_callback(&self, _in_data: Vec) { //! println!("[CALLBACK] Up Stream Non Blocking CallBack!"); //! } //! //! // UpStream blocking callback (Read & Write) //! fn us_b_callback(&mut self, _in_data: Vec) -> CallbackRet { //! println!("[CALLBACK] Up Stream Blocking CallBack!"); //! CallbackRet::Relay(_in_data) //! } //! } //! //! fn main() { //! //! // Create new SSLRelay object //! let mut relay = sslrelay::SSLRelay::new( //! Handler, //! RelayConfig { //! downstream_data_type: TCPDataType::TLS, //! upstream_data_type: TCPDataType::TLS, //! bind_host: "0.0.0.0".to_string(), //! bind_port: "443".to_string(), //! remote_host: "remote.com".to_string(), //! remote_port: "443".to_string(), //! tls_config: TLSConfig::FILE{ //! certificate_path: "./tls.crt".to_string(), //! private_key_path: "./tls.key".to_string(), //! }, //! } //! ); //! //! // Start listening //! relay.start(); //! } //! ``` use openssl::{ x509::X509, pkey::PKey, ssl::{ SslVerifyMode, SslConnector, SslAcceptor, SslStream, SslFiletype, SslMethod, } }; use std::net::{ TcpListener, TcpStream, Shutdown }; use std::sync::{ Arc, Mutex }; use std::{ thread }; use std::{ path::Path, time::Duration, }; use std::io::{ self, Read, Write }; use std::sync::mpsc::{ self, Receiver, Sender }; mod data; mod tcp; mod relay; #[derive(Debug)] enum FullDuplexTcpState { DownStreamWrite(Vec), UpStreamWrite(Vec), DownStreamShutDown, UpStreamShutDown, } #[derive(Debug)] enum DataPipe { DataWrite(Vec), Shutdown, } enum DataStreamType { RAW(TcpStream), TLS(SslStream), } /// Specifies the upstream or downstream data type (TLS or RAW). #[derive(Copy, Clone)] pub enum TCPDataType { TLS, RAW, } /// TLSConfig is used to specify TLS options. /// FILE is for specifying a path to a certificate and private key. /// DATA is for passing the certificate and private key bytes directly. /// NONE is for when you are not using TLS on the listening/downstream side of the relay. #[derive(Clone)] pub enum TLSConfig { FILE {certificate_path: String, private_key_path: String}, DATA {certificate: Vec, private_key: Vec}, NONE, } /// Relay Config structure for passing into the SSLRelay::new() config parameter. #[derive(Clone)] pub struct RelayConfig { pub downstream_data_type: TCPDataType, pub upstream_data_type: TCPDataType, pub bind_host: String, pub bind_port: String, pub remote_host: String, pub remote_port: String, pub tls_config: TLSConfig, } /// CallbackRet for blocking callback functions #[derive(Debug)] pub enum CallbackRet { Relay(Vec),// Relay data Spoof(Vec),// Skip relaying and send data back Shutdown,// Shutdown TCP connection Freeze,// Dont send data (pretend as if stream never was recieved) } /// Callback functions a user may or may not implement. pub trait HandlerCallbacks { fn ds_b_callback(&mut self, _in_data: Vec) -> CallbackRet {CallbackRet::Relay(_in_data)} fn ds_nb_callback(&self, _in_data: Vec){} fn us_b_callback(&mut self, _in_data: Vec) -> CallbackRet {CallbackRet::Relay(_in_data)} fn us_nb_callback(&self, _in_data: Vec){} } /// The main SSLRelay object. #[derive(Clone)] pub struct SSLRelay where H: HandlerCallbacks + std::marker::Sync + std::marker::Send + Clone + 'static, { config: RelayConfig, handlers: Option>, } #[allow(dead_code)] struct FullDuplexTcp where H: HandlerCallbacks + std::marker::Sync + std::marker::Send + Clone + 'static, { remote_host: String, remote_port: String, ds_inner_m: Arc>>, us_inner_m: Arc>>, inner_handlers: InnerHandlers, } #[derive(Clone)] struct InnerHandlers where H: HandlerCallbacks + std::marker::Sync + std::marker::Send + Clone + 'static, { cb: H } struct DownStreamInner { ds_stream: DataStreamType, internal_data_buffer: Vec, } struct UpStreamInner { us_stream: DataStreamType, internal_data_buffer: Vec }