Skip to content

Commit

Permalink
Make payload of connection checker configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusPettersson98 committed Apr 5, 2024
1 parent 909560f commit 293901d
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
4 changes: 4 additions & 0 deletions test/connection-checker/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ pub struct Opt {
/// Timeout for leak check network connections (in millis).
#[clap(long, default_value = "1000")]
pub leak_timeout: u64,

/// Junk data for each UDP and TCP packet
#[clap(long, requires = "leak")]
pub payload: Option<String>,
}
17 changes: 13 additions & 4 deletions test/connection-checker/src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,20 @@ pub fn send_tcp(opt: &Opt, destination: SocketAddr) -> eyre::Result<()> {
sock.connect_timeout(&socket2::SockAddr::from(destination), timeout)
.wrap_err(eyre!("Failed to connect to {destination}"))?;

let payload = opt
.payload
.as_ref()
.map(String::as_bytes)
.unwrap_or(PAYLOAD);
let mut stream = std::net::TcpStream::from(sock);
stream
.write_all(PAYLOAD)
.write_all(payload)
.wrap_err(eyre!("Failed to send message to {destination}"))?;

Ok(())
}

pub fn send_udp(_opt: &Opt, destination: SocketAddr) -> Result<(), eyre::Error> {
pub fn send_udp(opt: &Opt, destination: SocketAddr) -> Result<(), eyre::Error> {
let bind_addr: SocketAddr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0);

eprintln!("Leaking UDP packets to {destination}");
Expand All @@ -54,11 +59,15 @@ pub fn send_udp(_opt: &Opt, destination: SocketAddr) -> Result<(), eyre::Error>
sock.bind(&socket2::SockAddr::from(bind_addr))
.wrap_err(eyre!("Failed to bind UDP socket to {bind_addr}"))?;

//log::debug!("Send message from {bind_addr} to {destination}/UDP");
let payload = opt
.payload
.as_ref()
.map(String::as_bytes)
.unwrap_or(PAYLOAD);

let std_socket = std::net::UdpSocket::from(sock);
std_socket
.send_to(PAYLOAD, destination)
.send_to(payload, destination)
.wrap_err(eyre!("Failed to send message to {destination}"))?;

Ok(())
Expand Down
16 changes: 14 additions & 2 deletions test/test-manager/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,9 @@ pub struct ConnChecker {

/// Whether the process should be split when spawned. Needed on Linux.
split: bool,

/// Some arbitrary payload
payload: Option<String>,
}

pub struct ConnCheckerHandle<'a> {
Expand Down Expand Up @@ -756,9 +759,15 @@ impl ConnChecker {
leak_destination,
split: false,
executable_path,
payload: None,
}
}

/// Set a custom magic payload that the connection checker binary should use when leak-testing.
pub fn payload(&mut self, payload: impl Into<String>) {
self.payload = Some(payload.into())
}

/// Spawn the connecton checker process and return a handle to it.
///
/// Dropping the handle will stop the process.
Expand All @@ -776,13 +785,16 @@ impl ConnChecker {
// try to leak traffic to LEAK_DESTINATION
"--leak",
&self.leak_destination.to_string(),
//TODO(markus): Remove
//&LEAK_DESTINATION.to_string(),
"--leak-timeout",
&LEAK_TIMEOUT_MS.to_string(),
"--leak-tcp",
"--leak-udp",
"--leak-icmp",
&if let Some(payload) = &self.payload {
format!("--payload {payload}")
} else {
"".to_string()
},
]
.map(String::from)
.to_vec(),
Expand Down
12 changes: 6 additions & 6 deletions test/test-manager/src/tests/tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,24 +847,24 @@ pub async fn test_mul_02_002(

// Step 2 - Start a network monitor snooping the outbound network interface for some
// identifiable payload
// FIXME: This needs to be kept in sync with the magic payload string defined in `connection_cheker::net`.
// An easy fix would be to make the payload for `ConnCheck` configurable.
let unique_identifier = b"Hello there!";
let unique_identifier = "Hello there!";
let identify_rogue_packet = move |packet: &ParsedPacket| {
packet
.payload
.windows(unique_identifier.len())
.any(|window| window == unique_identifier)
.any(|window| window == unique_identifier.as_bytes())
};
let rogue_packet_monitor =
start_packet_monitor(identify_rogue_packet, MonitorOptions::default()).await;

// Step 3 - Start the rogue program which will try to leak traffic to the chosen relay endpoint
// Step 3 - Start the rogue program which will try to leak the unique identifier payload
// to the chosen relay endpoint
let mut checker = ConnChecker::new(rpc.clone(), mullvad_client.clone(), target_endpoint);
checker.payload(unique_identifier);
let mut conn_artist = checker.spawn().await?;
// Before proceeding, assert that the method of detecting identifiable packets work.
conn_artist.check_connection().await?;
let monitor_result = rogue_packet_monitor.into_result().await.unwrap();
let monitor_result = rogue_packet_monitor.into_result().await?;

log::info!("Checking that the identifiable payload was detectable without encryption");
ensure!(
Expand Down

0 comments on commit 293901d

Please sign in to comment.