2022-10-16 19:42:44 +00:00
|
|
|
use std::{
|
2022-10-18 01:53:55 +00:00
|
|
|
collections::*,
|
2022-10-16 19:42:44 +00:00
|
|
|
net::{
|
2022-10-16 22:24:15 +00:00
|
|
|
Ipv4Addr,
|
|
|
|
SocketAddrV4,
|
2022-10-16 19:42:44 +00:00
|
|
|
},
|
2022-10-18 01:53:55 +00:00
|
|
|
sync::Arc,
|
2022-10-18 04:22:34 +00:00
|
|
|
time::Duration,
|
2022-10-18 01:53:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
use hyper::{
|
|
|
|
Body,
|
|
|
|
Method,
|
|
|
|
Request,
|
|
|
|
Response,
|
|
|
|
Server,
|
|
|
|
StatusCode,
|
|
|
|
service::{
|
|
|
|
make_service_fn,
|
|
|
|
service_fn,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
use tokio::{
|
|
|
|
net::UdpSocket,
|
|
|
|
sync::RwLock,
|
2022-10-16 19:42:44 +00:00
|
|
|
};
|
|
|
|
|
2022-10-16 22:24:15 +00:00
|
|
|
mod ip;
|
2022-10-18 04:22:34 +00:00
|
|
|
mod tlv;
|
2022-10-16 22:24:15 +00:00
|
|
|
|
|
|
|
fn main () -> Result <(), Error>
|
|
|
|
{
|
2022-10-16 19:42:44 +00:00
|
|
|
let mut args = std::env::args ();
|
|
|
|
let mut bail_unknown = true;
|
2022-10-16 22:24:15 +00:00
|
|
|
let mut last_unknown = None;
|
|
|
|
let mut name = ptth_diceware::passphrase ("_", 3);
|
|
|
|
let mut subcommand_count = 0;
|
|
|
|
let mut subcommand = None;
|
|
|
|
|
|
|
|
args.next ();
|
|
|
|
while let Some (arg) = args.next () {
|
|
|
|
if arg == "--ignore-unknown" {
|
|
|
|
bail_unknown = false;
|
|
|
|
}
|
|
|
|
if arg == "--name" {
|
|
|
|
name = args.next ().unwrap ().to_string ();
|
|
|
|
}
|
2022-10-18 01:53:55 +00:00
|
|
|
else if arg == "peer" {
|
|
|
|
subcommand = Some (Subcommand::Peer);
|
|
|
|
subcommand_count += 1;
|
|
|
|
}
|
|
|
|
else if arg == "receiver" {
|
|
|
|
subcommand = Some (Subcommand::Receiver);
|
|
|
|
subcommand_count += 1;
|
|
|
|
}
|
2022-10-16 22:24:15 +00:00
|
|
|
else if arg == "sender" {
|
|
|
|
subcommand = Some (Subcommand::Sender);
|
|
|
|
subcommand_count += 1;
|
|
|
|
}
|
|
|
|
else if arg == "spy" {
|
|
|
|
subcommand = Some (Subcommand::Spy);
|
|
|
|
subcommand_count += 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
last_unknown = Some (arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if bail_unknown {
|
|
|
|
if let Some (last_unknown) = last_unknown {
|
|
|
|
eprintln! ("Unknown argument `{}`", last_unknown);
|
|
|
|
return Err (Error::Args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if subcommand_count >= 2 {
|
|
|
|
eprintln! ("Detected {} subcommands in arguments", subcommand_count);
|
|
|
|
return Err (Error::Args)
|
|
|
|
}
|
|
|
|
|
|
|
|
let rt = tokio::runtime::Runtime::new ()?;
|
|
|
|
|
|
|
|
let params = Params::default ();
|
2022-10-16 19:42:44 +00:00
|
|
|
|
2022-10-16 22:24:15 +00:00
|
|
|
rt.block_on (async {
|
|
|
|
if let Some (cmd) = subcommand {
|
|
|
|
return match cmd {
|
2022-10-18 01:53:55 +00:00
|
|
|
Subcommand::Peer => peer (params).await,
|
|
|
|
Subcommand::Receiver => receiver (params).await,
|
2022-10-16 22:24:15 +00:00
|
|
|
Subcommand::Sender => sender (params).await,
|
|
|
|
Subcommand::Spy => spy (params),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
println! ("Name is `{}`", name);
|
|
|
|
|
|
|
|
Ok::<_, Error> (())
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok (())
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Subcommand {
|
2022-10-18 01:53:55 +00:00
|
|
|
Peer,
|
|
|
|
Receiver,
|
2022-10-16 22:24:15 +00:00
|
|
|
Sender,
|
|
|
|
Spy,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Params {
|
|
|
|
multicast_group: (Ipv4Addr, u16),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Params {
|
|
|
|
fn default () -> Self {
|
|
|
|
let multicast_group = (Ipv4Addr::new (225, 100, 99, 98), 9041);
|
2022-10-16 19:42:44 +00:00
|
|
|
|
2022-10-16 22:24:15 +00:00
|
|
|
Self {
|
|
|
|
multicast_group,
|
|
|
|
}
|
2022-10-16 19:42:44 +00:00
|
|
|
}
|
2022-10-16 22:24:15 +00:00
|
|
|
}
|
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
async fn peer (params: Params) -> Result <(), Error>
|
2022-10-16 22:24:15 +00:00
|
|
|
{
|
2022-10-18 04:22:34 +00:00
|
|
|
use rand::Rng;
|
|
|
|
|
|
|
|
let mut id = [0];
|
|
|
|
rand::thread_rng ().try_fill (&mut id).or (Err (Error::Rand))?;
|
2022-10-18 01:53:55 +00:00
|
|
|
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
|
|
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)).await?;
|
|
|
|
|
|
|
|
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
|
|
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
|
|
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
2022-10-16 22:24:15 +00:00
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
let peer = Peer {
|
2022-10-18 04:22:34 +00:00
|
|
|
id: id [0],
|
2022-10-18 01:53:55 +00:00
|
|
|
outbox: Outbox {
|
|
|
|
index: 1000,
|
|
|
|
messages: Default::default (),
|
|
|
|
}.into (),
|
|
|
|
params,
|
|
|
|
socket,
|
|
|
|
};
|
|
|
|
|
2022-10-18 04:22:34 +00:00
|
|
|
eprintln! ("Random peer ID is {}", peer.id);
|
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
let state = Arc::new (peer);
|
|
|
|
|
2022-10-18 04:22:34 +00:00
|
|
|
{
|
|
|
|
let state = Arc::clone (&state);
|
|
|
|
tokio::spawn (async move {
|
|
|
|
let mut interval = tokio::time::interval (Duration::from_secs (25));
|
|
|
|
interval.set_missed_tick_behavior (tokio::time::MissedTickBehavior::Skip);
|
|
|
|
|
|
|
|
loop {
|
|
|
|
interval.tick ().await;
|
|
|
|
|
|
|
|
state.send_multicast (&tlv::Message::IAmOnline { peer_id: state.id }).await.ok ();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let state = Arc::clone (&state);
|
|
|
|
tokio::spawn (async move {
|
|
|
|
loop {
|
|
|
|
let mut buf = vec! [0u8; 2048];
|
|
|
|
let (bytes_recved, addr) = match state.socket.recv_from (&mut buf).await
|
|
|
|
{
|
|
|
|
Err (_) => {
|
|
|
|
tokio::time::sleep (Duration::from_secs (10)).await;
|
|
|
|
continue;
|
|
|
|
},
|
|
|
|
Ok (x) => x,
|
|
|
|
};
|
|
|
|
let buf = &buf [0..bytes_recved];
|
|
|
|
|
|
|
|
let msg = match tlv::decode (buf) {
|
|
|
|
Err (_) => {
|
|
|
|
eprintln! ("ZAT4ERXR Couldn't decode message");
|
|
|
|
continue;
|
|
|
|
},
|
|
|
|
Ok (x) => x,
|
|
|
|
};
|
|
|
|
|
|
|
|
println! ("Received {:?}", msg);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
let make_svc = make_service_fn (|_conn| {
|
2022-10-18 04:22:34 +00:00
|
|
|
let state = Arc::clone (&state);
|
2022-10-18 01:53:55 +00:00
|
|
|
|
|
|
|
async {
|
|
|
|
Ok::<_, String> (service_fn (move |req| {
|
|
|
|
let state = state.clone ();
|
|
|
|
peer_handle_all (req, state)
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let addr = std::net::SocketAddr::from (([127, 0, 0, 1], multicast_port));
|
|
|
|
let server = Server::bind (&addr)
|
|
|
|
.serve (make_svc);
|
|
|
|
|
|
|
|
eprintln! ("Local UI on {}", addr);
|
|
|
|
|
|
|
|
server.await?;
|
|
|
|
|
|
|
|
Ok (())
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Peer {
|
2022-10-18 04:22:34 +00:00
|
|
|
id: u32,
|
2022-10-18 01:53:55 +00:00
|
|
|
outbox: RwLock <Outbox>,
|
|
|
|
params: Params,
|
|
|
|
socket: UdpSocket,
|
|
|
|
}
|
|
|
|
|
2022-10-18 04:22:34 +00:00
|
|
|
impl Peer {
|
|
|
|
async fn send_multicast (&self, msg: &tlv::Message) -> Result <(), Error>
|
|
|
|
{
|
|
|
|
let msg = tlv::encode (&msg)?;
|
|
|
|
self.socket.send_to (&msg, self.params.multicast_group).await?;
|
|
|
|
Ok (())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
struct Outbox {
|
|
|
|
index: u32,
|
|
|
|
messages: VecDeque <SentMessage>,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct SentMessage {
|
|
|
|
index: u32,
|
|
|
|
body: Vec <u8>,
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn peer_handle_all (req: Request <Body>, state: Arc <Peer>)
|
|
|
|
-> Result <Response <Body>, Error>
|
|
|
|
{
|
|
|
|
if req.method () == Method::POST {
|
|
|
|
if req.uri () == "/paste" {
|
|
|
|
let body = hyper::body::to_bytes (req.into_body ()).await?;
|
|
|
|
if body.len () > 1024 {
|
|
|
|
let resp = Response::builder ()
|
|
|
|
.status (StatusCode::BAD_REQUEST)
|
|
|
|
.body (Body::from ("Message body must be <= 1024 bytes"))?;
|
|
|
|
return Ok (resp);
|
|
|
|
}
|
|
|
|
let body = body.to_vec ();
|
|
|
|
|
|
|
|
let msg_index;
|
|
|
|
{
|
|
|
|
let mut outbox = state.outbox.write ().await;
|
|
|
|
let msg = SentMessage {
|
|
|
|
index: outbox.index,
|
|
|
|
body: body.clone (),
|
|
|
|
};
|
|
|
|
msg_index = msg.index;
|
|
|
|
outbox.messages.push_back (msg);
|
|
|
|
if outbox.messages.len () > 10 {
|
|
|
|
outbox.messages.pop_front ();
|
|
|
|
}
|
|
|
|
outbox.index += 1;
|
|
|
|
}
|
|
|
|
|
2022-10-18 04:22:34 +00:00
|
|
|
match state.send_multicast (&tlv::Message::IHaveMessage {
|
|
|
|
peer_id: state.id,
|
|
|
|
msg_index,
|
|
|
|
body,
|
|
|
|
}).await {
|
|
|
|
Ok (_) => (),
|
|
|
|
Err (_) => return Ok (
|
|
|
|
Response::builder ()
|
|
|
|
.status (StatusCode::BAD_REQUEST)
|
|
|
|
.body (Body::from ("Can't encode message"))?
|
|
|
|
),
|
|
|
|
}
|
2022-10-18 01:53:55 +00:00
|
|
|
|
|
|
|
return Ok (Response::new (format! ("Pasted message {}\n", msg_index).into ()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok (Response::new (":V\n".into ()))
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn receiver (params: Params) -> Result <(), Error>
|
|
|
|
{
|
|
|
|
let (multicast_addr, multicast_port) = params.multicast_group;
|
|
|
|
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)).await?;
|
|
|
|
|
|
|
|
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
|
|
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
|
|
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
|
|
|
|
|
|
loop {
|
|
|
|
let mut buf = vec! [0u8; 2048];
|
|
|
|
|
|
|
|
let (bytes_recved, remote_addr) = socket.recv_from (&mut buf).await?;
|
|
|
|
buf.truncate (bytes_recved);
|
|
|
|
|
|
|
|
println! ("Received {} bytes from {}", bytes_recved, remote_addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn sender (params: Params) -> Result <(), Error>
|
|
|
|
{
|
2022-10-16 22:24:15 +00:00
|
|
|
let (multicast_addr, multicast_port) = params.multicast_group;
|
2022-10-18 01:53:55 +00:00
|
|
|
let socket = tokio::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, 0)).await?;
|
2022-10-16 22:24:15 +00:00
|
|
|
|
|
|
|
socket.join_multicast_v4 (multicast_addr, Ipv4Addr::UNSPECIFIED)?;
|
|
|
|
eprintln! ("Multicast group is {:?}", params.multicast_group);
|
|
|
|
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
|
|
|
|
|
|
socket.send_to (&[], params.multicast_group).await?;
|
|
|
|
|
|
|
|
Ok (())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn spy (params: Params) -> Result <(), Error>
|
|
|
|
{
|
|
|
|
let (multicast_addr, multicast_port) = params.multicast_group;
|
2022-10-16 19:42:44 +00:00
|
|
|
|
2022-10-18 01:53:55 +00:00
|
|
|
let socket = match std::net::UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, multicast_port)) {
|
2022-10-16 22:24:15 +00:00
|
|
|
Ok (x) => x,
|
|
|
|
Err (e) => if e.kind () == std::io::ErrorKind::AddrInUse {
|
|
|
|
eprintln! ("Address in use. You can only run 1 instance of Insecure Chat at a time, even in spy mode.");
|
|
|
|
return Err (Error::AddrInUse);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Err (e.into ());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for bind_addr in ip::get_ips ()? {
|
|
|
|
socket.join_multicast_v4 (&multicast_addr, &bind_addr)?;
|
|
|
|
// eprintln! ("Joined multicast with {}", bind_addr);
|
|
|
|
}
|
|
|
|
eprintln! ("Multicast addr is {}", multicast_addr);
|
|
|
|
eprintln! ("Local addr is {}", socket.local_addr ()?);
|
|
|
|
|
|
|
|
loop {
|
|
|
|
let mut buf = vec! [0u8; 2048];
|
|
|
|
|
|
|
|
eprintln! ("Listening for UDP packets...");
|
|
|
|
let (bytes_recved, remote_addr) = socket.recv_from (&mut buf)?;
|
|
|
|
buf.truncate (bytes_recved);
|
|
|
|
|
|
|
|
println! ("Received {} bytes from {}", bytes_recved, remote_addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive (Debug, thiserror::Error)]
|
|
|
|
enum Error {
|
|
|
|
#[error ("Address in use")]
|
|
|
|
AddrInUse,
|
|
|
|
#[error ("CLI args")]
|
|
|
|
Args,
|
|
|
|
#[error (transparent)]
|
2022-10-18 01:53:55 +00:00
|
|
|
Hyper (#[from] hyper::Error),
|
|
|
|
#[error (transparent)]
|
|
|
|
HyperHttp (#[from] hyper::http::Error),
|
|
|
|
#[error (transparent)]
|
2022-10-16 22:24:15 +00:00
|
|
|
Io (#[from] std::io::Error),
|
|
|
|
#[error (transparent)]
|
|
|
|
Ip (#[from] ip::Error),
|
2022-10-18 04:22:34 +00:00
|
|
|
#[error ("Randomness")]
|
|
|
|
Rand,
|
|
|
|
#[error (transparent)]
|
|
|
|
Tlv (#[from] tlv::Error),
|
2022-10-16 19:42:44 +00:00
|
|
|
}
|