Struct portal_lib::Portal
source · pub struct Portal {
pub id: String,
pub direction: Direction,
pub exchange: PortalKeyExchange,
pub state: Option<Spake2<Ed25519Group>>,
/* private fields */
}
Expand description
The primary interface into the library.
Fields§
§id: String
§direction: Direction
§exchange: PortalKeyExchange
§state: Option<Spake2<Ed25519Group>>
Implementations§
source§impl Portal
impl Portal
sourcepub fn init(
direction: Direction,
id: String,
password: String
) -> Result<Portal, Box<dyn Error>>
pub fn init( direction: Direction, id: String, password: String ) -> Result<Portal, Box<dyn Error>>
Initialize a new portal request
Example
use portal_lib::{Portal,Direction};
// the shared password should be secret and hard to guess/crack
// see the portal-client as an example of potential usage
let id = String::from("my client ID");
let password = String::from("testpasswd");
let portal = Portal::init(Direction::Receiver, id, password).unwrap();
sourcepub fn handshake<P: Read + Write>(
&mut self,
peer: &mut P
) -> Result<(), Box<dyn Error>>
pub fn handshake<P: Read + Write>( &mut self, peer: &mut P ) -> Result<(), Box<dyn Error>>
Negotiate a secure connection over the insecure channel by performing the portal handshake. Subsequent communication will be encrypted.
Example
use std::net::TcpStream;
use portal_lib::{Portal,Direction};
let mut portal = Portal::init(Direction::Sender, "id".into(), "password".into()).unwrap();
let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
// conduct the handshake with the peer
portal.handshake(&mut stream).unwrap();
sourcepub fn outgoing<'a, W>(
&mut self,
peer: &mut W,
info: &'a TransferInfo
) -> Result<impl Iterator<Item = (&'a PathBuf, &'a Metadata)>, Box<dyn Error>>where
W: Write,
pub fn outgoing<'a, W>( &mut self, peer: &mut W, info: &'a TransferInfo ) -> Result<impl Iterator<Item = (&'a PathBuf, &'a Metadata)>, Box<dyn Error>>where W: Write,
As the sender, communicate a TransferInfo struct to the receiver so that they may confirm/deny the transfer. Returns an iterator over the fullpath + Metadata to pass to send_file(). Allows the user to send multiple files in one session.
Example
use std::path::Path;
use std::error::Error;
use std::net::TcpStream;
use portal_lib::{Portal, Direction, TransferInfoBuilder};
fn my_send() -> Result<(), Box<dyn Error>> {
// Securely generate/exchange ID & Password with peer out-of-band
let id = String::from("id");
let password = String::from("password");
// Connect to the relay
let mut portal = Portal::init(Direction::Sender,"id".into(), "password".into())?;
let mut stream = TcpStream::connect("127.0.0.1:34254")?;
// The handshake must be performed first, otherwise
// there is no shared key to encrypt the file with
portal.handshake(&mut stream)?;
// Add any files/directories
let info = TransferInfoBuilder::new()
.add_file(Path::new("/etc/passwd"))?
.finalize();
// Optional: implement a custom callback to display how much
// has been transferred
fn progress(transferred: usize) {
println!("sent {:?} bytes", transferred);
}
// Send every file in TransferInfo
for (fullpath, metadata) in portal.outgoing(&mut stream, &info)? {
portal.send_file(&mut stream, fullpath, Some(progress))?;
}
Ok(())
}
sourcepub fn incoming<R, V>(
&mut self,
peer: &mut R,
verify: Option<V>
) -> Result<impl Iterator<Item = Metadata>, Box<dyn Error>>where
R: Read,
V: Fn(&TransferInfo) -> bool,
pub fn incoming<R, V>( &mut self, peer: &mut R, verify: Option<V> ) -> Result<impl Iterator<Item = Metadata>, Box<dyn Error>>where R: Read, V: Fn(&TransferInfo) -> bool,
As the receiver, receive a TransferInfo struct which will be passed to your optional verify callback. And may be used to confirm/deny the transfer. Returns an iterator over the Metadata of incoming files.
Example
use std::path::Path;
use std::error::Error;
use std::net::TcpStream;
use portal_lib::{Portal, Direction, TransferInfo};
fn my_recv() -> Result<(), Box<dyn Error>> {
// Securely generate/exchange ID & Password with peer out-of-band
let id = String::from("id");
let password = String::from("password");
// Connect to the relay
let mut portal = Portal::init(Direction::Sender, id, password)?;
let mut stream = TcpStream::connect("127.0.0.1:34254")?;
// The handshake must be performed first, otherwise
// there is no shared key to encrypt the file with
portal.handshake(&mut stream)?;
// Optional: User callback to confirm/deny a transfer. If
// none is provided, this will default accept the incoming file.
// Return true to accept, false to reject the transfer.
fn confirm_download(_info: &TransferInfo) -> bool { true }
// Optional: implement a custom callback to display how much
// has been transferred
fn progress(transferred: usize) {
println!("received {:?} bytes", transferred);
}
// Decide where downloads should go
let my_downloads = Path::new("/tmp");
// Receive every file in TransferInfo
for metadata in portal.incoming(&mut stream, Some(confirm_download))? {
portal.recv_file(&mut stream, my_downloads, Some(&metadata), Some(progress))?;
}
Ok(())
}
sourcepub fn send_file<W, D>(
&mut self,
peer: &mut W,
path: &PathBuf,
callback: Option<D>
) -> Result<usize, Box<dyn Error>>where
W: Write,
D: Fn(usize),
pub fn send_file<W, D>( &mut self, peer: &mut W, path: &PathBuf, callback: Option<D> ) -> Result<usize, Box<dyn Error>>where W: Write, D: Fn(usize),
Send a given file over the portal. Must be called after performing the handshake or this method will return an error.
Example
use std::path::Path;
use std::net::TcpStream;
use portal_lib::{Portal,Direction};
let mut portal = Portal::init(Direction::Sender,"id".into(), "password".into()).unwrap();
let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
// The handshake must be performed first, otherwise
// there is no shared key to encrypt the file with
portal.handshake(&mut stream);
// Optional: implement a custom callback to display how much
// has been transferred
fn progress(transferred: usize) {
println!("sent {:?} bytes", transferred);
}
// Begin sending the file
let file = Path::new("/etc/passwd").to_path_buf();
portal.send_file(&mut stream, &file, Some(progress));
sourcepub fn recv_file<R, D>(
&mut self,
peer: &mut R,
outdir: &Path,
expected: Option<&Metadata>,
display: Option<D>
) -> Result<Metadata, Box<dyn Error>>where
R: Read,
D: Fn(usize),
pub fn recv_file<R, D>( &mut self, peer: &mut R, outdir: &Path, expected: Option<&Metadata>, display: Option<D> ) -> Result<Metadata, Box<dyn Error>>where R: Read, D: Fn(usize),
Receive the next file over the portal. Must be called after performing the handshake or this method will return an error.
Example
use std::path::Path;
use std::net::TcpStream;
use portal_lib::{Portal,Direction};
let mut portal = Portal::init(Direction::Sender,"id".into(), "password".into()).unwrap();
let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
// The handshake must be performed first, otherwise
// there is no shared key to encrypt the file with
portal.handshake(&mut stream);
// Optional: implement a custom callback to display how much
// has been transferred
fn progress(transferred: usize) {
println!("received {:?} bytes", transferred);
}
// Begin receiving the file into /tmp
portal.recv_file(&mut stream, Path::new("/tmp"), None, Some(progress));
sourcepub fn get_direction(&self) -> Direction
pub fn get_direction(&self) -> Direction
Returns a copy of the Portal::Direction associated with this Portal request
sourcepub fn set_direction(&mut self, direction: Direction)
pub fn set_direction(&mut self, direction: Direction)
Sets the Portal::Direction associated with this Poral request
sourcepub fn get_id(&self) -> &String
pub fn get_id(&self) -> &String
Returns a reference to the ID associated with this Portal request