Skip to content

Commit

Permalink
Merge pull request #7: Ask user before receiving files
Browse files Browse the repository at this point in the history
This closes #1
  • Loading branch information
piegamesde authored Nov 10, 2020
2 parents 5388e77 + ba3e73d commit 29e7175
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 36 deletions.
3 changes: 2 additions & 1 deletion .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
unstable_features = true
edition = "2018"

# max_width = 80

match_block_trailing_comma = true
merge_imports = true
#merge_imports = true
format_code_in_doc_comments = true
4 changes: 3 additions & 1 deletion examples/test-file-rust2rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ async fn receive(code_rx: mpsc::Receiver<String>) {

let mut w = connector.connect_to_client().await;
info!("Got key: {}", &w.key);
transfer::receive_file(
let req = transfer::request_file(
&mut w,
&magic_wormhole::transit::DEFAULT_RELAY_SERVER
.parse()
.unwrap(),
)
.await
.unwrap();

req.resolve().await.unwrap();
}

async fn send(code_tx: mpsc::Sender<String>) {
Expand Down
51 changes: 45 additions & 6 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ async fn main() -> anyhow::Result<()> {
.parse()
.expect("TODO error handling");
CodeProvider::AllocateCode(numwords)
}
},
Some(code) => CodeProvider::SetCode(code.to_string()),
},
)
Expand Down Expand Up @@ -172,7 +172,7 @@ async fn main() -> anyhow::Result<()> {
.parse()
.expect("TODO error handling");
CodeProvider::AllocateCode(numwords)
}
},
Some(code) => CodeProvider::SetCode(code.to_string()),
},
)
Expand Down Expand Up @@ -268,17 +268,56 @@ async fn send_many(
} {
Ok(_) => {
info!("TOOD success message");
}
},
Err(e) => {
warn!("Send failed, {}", e);
}
},
}
}
// Ok(())
}

async fn receive(mut w: Wormhole, relay_server: &str) -> anyhow::Result<()> {
transfer::receive_file(&mut w, &relay_server.parse().unwrap()).await?;
use async_std::io;
use async_std::prelude::*;

Ok(())
let req = transfer::request_file(&mut w, &relay_server.parse().unwrap()).await?;

let mut stdout = io::stdout();
let stdin = io::stdin();

let answer = loop {
stdout
.write_fmt(format_args!(
"Receive file '{}' (size: {} bytes)? (y/N) ",
req.filename.display(),
req.filesize
))
.await
.unwrap();

stdout.flush().await.unwrap();

let mut answer = String::new();
stdin.read_line(&mut answer).await.unwrap();

match answer.chars().next() {
Some('y') | Some('Y') => break true,
Some('n') | Some('N') => break false,
_ => {
stdout
.write_fmt(format_args!("Please type y or n!\n"))
.await
.unwrap();
stdout.flush().await.unwrap();
continue;
},
};
};

if answer {
req.accept().await
} else {
req.reject().await
}
}
98 changes: 70 additions & 28 deletions src/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use sha2::{digest::FixedOutput, Digest, Sha256};
use sodiumoxide::crypto::secretbox;
use std::path::Path;
use std::path::PathBuf;
use transit::TransitConnector;
use transit::TransitType;

/// The App ID associated with this protocol.
pub const APPID: &str = "lothar.com/wormhole/text-or-file-xfer";
Expand Down Expand Up @@ -197,7 +199,7 @@ pub async fn send_file(
match fileack_msg {
PeerMessage::Answer(AnswerType::FileAck(msg)) => {
ensure!(msg == "ok", "file ack failed");
}
},
_ => bail!("did not receive file ack"),
}
}
Expand All @@ -215,7 +217,10 @@ pub async fn send_file(
.context("Could not send file")
}

pub async fn receive_file(wormhole: &mut Wormhole, relay_url: &RelayUrl) -> Result<()> {
pub async fn request_file<'a>(
wormhole: &'a mut Wormhole,
relay_url: &RelayUrl,
) -> Result<ReceiveRequest<'a>> {
let connector = transit::init(transit::Ability::all_abilities(), relay_url).await?;

// send the transit message
Expand All @@ -230,16 +235,16 @@ pub async fn receive_file(wormhole: &mut Wormhole, relay_url: &RelayUrl) -> Resu
PeerMessage::Transit(transit) => {
debug!("received transit message: {:?}", transit);
transit
}
},
PeerMessage::Error(err) => {
anyhow::bail!("Something went wrong on the other side: {}", err);
}
},
other => {
anyhow::bail!(
"Got an unexpected message type, is the other side all right? Got: '{:?}'",
other
);
}
},
};

// 3. receive file offer message from peer
Expand All @@ -255,31 +260,68 @@ pub async fn receive_file(wormhole: &mut Wormhole, relay_url: &RelayUrl) -> Resu
_ => bail!("unexpected message: {:?}", maybe_offer),
};

// send file ack.
// TODO ask upper layer to ack the file.
debug!("Sending ack");
wormhole
.tx
.send(
PeerMessage::new_file_ack("ok")
.serialize()
.as_bytes()
.to_vec(),
)
.await?;
let req = ReceiveRequest {
wormhole,
filename,
filesize,
connector,
other_side_ttype,
};

let mut transit = connector
.receiver_connect(
wormhole.key.derive_transit_key(&wormhole.appid),
Arc::try_unwrap(other_side_ttype).unwrap(),
)
.await?;
Ok(req)
}

debug!("Beginning file transfer");
// TODO here's the right position for applying the output directory and to check for malicious (relative) file paths
tcp_file_receive(&mut transit, &filename, filesize)
.await
.context("Could not receive file")
#[must_use]
pub struct ReceiveRequest<'a> {
wormhole: &'a mut Wormhole,
connector: TransitConnector,
pub filename: PathBuf,
pub filesize: u64,
other_side_ttype: Arc<transit::TransitType>,
}

impl<'a> ReceiveRequest<'a> {
pub async fn accept(self) -> Result<()> {
// send file ack.
debug!("Sending ack");
self.wormhole
.tx
.send(
PeerMessage::new_file_ack("ok")
.serialize()
.as_bytes()
.to_vec(),
)
.await?;

let mut transit = self
.connector
.receiver_connect(
self.wormhole.key.derive_transit_key(&self.wormhole.appid),
Arc::try_unwrap(self.other_side_ttype).unwrap(),
)
.await?;

debug!("Beginning file transfer");
// TODO here's the right position for applying the output directory and to check for malicious (relative) file paths
tcp_file_receive(&mut transit, &self.filename, self.filesize)
.await
.context("Could not receive file")
}

pub async fn reject(self) -> Result<()> {
self.wormhole
.tx
.send(
PeerMessage::new_error_message("transfer rejected")
.serialize()
.as_bytes()
.to_vec(),
)
.await?;

Ok(())
}
}

// encrypt and send the file to tcp stream and return the sha256 sum
Expand Down

0 comments on commit 29e7175

Please sign in to comment.