Compare commits

..

No commits in common. "a9bbd29f9f76f8960b15b62e577444f0b05feb4d" and "69b9bc9824767b4fc525d41444f991a42d23f3cd" have entirely different histories.

5 changed files with 9 additions and 101 deletions

View file

@ -334,7 +334,6 @@ async fn spawn_ssh(
cmd.arg("sudo"); cmd.arg("sudo");
} }
cmd.arg(format!("FWD_LOG={log_filter}")) cmd.arg(format!("FWD_LOG={log_filter}"))
.arg("FWD_SEND_ANONYMOUS=1")
.arg("fwd") .arg("fwd")
.arg("--server"); .arg("--server");

View file

@ -127,11 +127,6 @@ impl Listener {
} }
} }
#[cfg(test)]
pub fn state_ref(&self) -> std::sync::Arc<std::sync::Mutex<State>> {
self.state.clone()
}
pub fn enabled(&self) -> bool { pub fn enabled(&self) -> bool {
self.state() == State::Enabled self.state() == State::Enabled
} }
@ -159,8 +154,8 @@ impl Listener {
*self.state.lock().unwrap() *self.state.lock().unwrap()
} }
pub fn toggle_enabled(&mut self, socks_port: Option<u16>) { pub fn set_enabled(&mut self, socks_port: Option<u16>, enabled: bool) {
if self.state() == State::Disabled { if enabled {
self.state = State::Enabled.boxed(); self.state = State::Enabled.boxed();
self.start(socks_port); self.start(socks_port);
} else { } else {
@ -440,7 +435,7 @@ impl UI {
fn enable_disable_port(&mut self, port: u16) { fn enable_disable_port(&mut self, port: u16) {
if let Some(listener) = self.ports.get_mut(&port) { if let Some(listener) = self.ports.get_mut(&port) {
listener.toggle_enabled(self.socks_port); listener.set_enabled(self.socks_port, !listener.enabled());
} }
} }
@ -1183,72 +1178,4 @@ mod tests {
drop(sender); drop(sender);
} }
#[test]
fn empty_port_desc_disabled_on_refresh() {
let (sender, receiver) = mpsc::channel(64);
let config = ServerConfig::default();
let mut ui = UI::new(receiver, config);
ui.handle_internal_event(Some(UIEvent::Ports(vec![PortDesc {
port: 8080,
desc: "".to_string(),
}])));
let listener = ui.ports.get(&8080).unwrap();
assert_eq!(listener.state(), State::Disabled);
// Just do it again, make sure we haven't broken the refresh path.
ui.handle_internal_event(Some(UIEvent::Ports(vec![PortDesc {
port: 8080,
desc: "".to_string(),
}])));
let listener = ui.ports.get(&8080).unwrap();
assert_eq!(listener.state(), State::Disabled);
drop(sender);
}
#[test]
fn state_toggle_enable_disable() {
let (sender, receiver) = mpsc::channel(64);
let config = ServerConfig::default();
let mut ui = UI::new(receiver, config);
ui.handle_internal_event(Some(UIEvent::Ports(vec![PortDesc {
port: 8080,
desc: "rando".to_string(),
}])));
let listener = ui.ports.get_mut(&8080).unwrap();
assert_eq!(listener.state(), State::Enabled);
// Enabled -> Disabled
ui.enable_disable_port(8080); // FLIP!
let listener = ui.ports.get(&8080).unwrap();
assert_eq!(listener.state(), State::Disabled);
// Disabled -> Enabled
ui.enable_disable_port(8080); // FLIP!
let listener = ui.ports.get(&8080).unwrap();
assert_eq!(listener.state(), State::Enabled);
{
// Oh no it broke!
let state = listener.state_ref();
let mut sg = state.lock().unwrap();
*sg = State::Broken;
}
let listener = ui.ports.get_mut(&8080).unwrap();
assert_eq!(listener.state(), State::Broken);
// Broken -> Disabled
ui.enable_disable_port(8080);
let listener = ui.ports.get_mut(&8080).unwrap();
assert_eq!(listener.state(), State::Disabled);
drop(sender);
}
} }

View file

@ -24,15 +24,6 @@ async fn server_loop<Reader: AsyncRead + Unpin>(
reader: &mut MessageReader<Reader>, reader: &mut MessageReader<Reader>,
writer: &mut mpsc::Sender<Message>, writer: &mut mpsc::Sender<Message>,
) -> Result<()> { ) -> Result<()> {
// NOTE: The client needs to opt in to getting anonymous ports because it
// does not feel safe to automatically enable port forwarding by default
// for random system ports. The way we keep it from being unsafe is that
// the client leaves anonymous ports disabled by default. Older clients
// did not do this, and so we cannot send older clients anonymous ports.
let send_anonymous = std::env::var("FWD_SEND_ANONYMOUS")
.map(|v| v == "1")
.unwrap_or(false);
// The first message we send must be an announcement. // The first message we send must be an announcement.
writer.send(Message::Hello(0, 2, vec![])).await?; writer.send(Message::Hello(0, 2, vec![])).await?;
let mut version_reported = false; let mut version_reported = false;
@ -55,7 +46,7 @@ async fn server_loop<Reader: AsyncRead + Unpin>(
version_reported = true; version_reported = true;
} }
let ports = match refresh::get_entries(send_anonymous).await { let ports = match refresh::get_entries().await {
Ok(ports) => ports, Ok(ports) => ports,
Err(e) => { Err(e) => {
error!("Error scanning: {:?}", e); error!("Error scanning: {:?}", e);

View file

@ -12,7 +12,7 @@ mod procfs;
#[cfg(unix)] #[cfg(unix)]
mod docker; mod docker;
pub async fn get_entries(_send_anonymous: bool) -> Result<Vec<PortDesc>> { pub async fn get_entries() -> Result<Vec<PortDesc>> {
#[cfg_attr(not(target_os = "linux"), allow(unused_mut))] #[cfg_attr(not(target_os = "linux"), allow(unused_mut))]
let mut attempts = 0; let mut attempts = 0;
@ -35,7 +35,7 @@ pub async fn get_entries(_send_anonymous: bool) -> Result<Vec<PortDesc>> {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {
attempts += 1; attempts += 1;
match procfs::get_entries(_send_anonymous) { match procfs::get_entries() {
Ok(m) => { Ok(m) => {
for (p, d) in m { for (p, d) in m {
result.entry(p).or_insert(d); result.entry(p).or_insert(d);

View file

@ -4,7 +4,7 @@ use std::collections::HashMap;
use crate::message::PortDesc; use crate::message::PortDesc;
pub fn get_entries(send_anonymous: bool) -> Result<HashMap<u16, PortDesc>> { pub fn get_entries() -> Result<HashMap<u16, PortDesc>> {
let all_procs = procfs::process::all_processes()?; let all_procs = procfs::process::all_processes()?;
// build up a map between socket inodes and process stat info. Ignore any // build up a map between socket inodes and process stat info. Ignore any
@ -38,21 +38,12 @@ pub fn get_entries(send_anonymous: bool) -> Result<HashMap<u16, PortDesc>> {
|| tcp_entry.local_address.ip().is_unspecified()) || tcp_entry.local_address.ip().is_unspecified())
&& !h.contains_key(&tcp_entry.local_address.port()) && !h.contains_key(&tcp_entry.local_address.port())
{ {
// If the process is not one that we can identify, then we return if let Some(cmd) = map.get(&tcp_entry.inode) {
// the port but leave the description empty so that it can be
// identified by the client as "anonymous".
let desc = if let Some(cmd) = map.get(&tcp_entry.inode) {
cmd.clone()
} else {
String::new()
};
if send_anonymous || !desc.is_empty() {
h.insert( h.insert(
tcp_entry.local_address.port(), tcp_entry.local_address.port(),
PortDesc { PortDesc {
port: tcp_entry.local_address.port(), port: tcp_entry.local_address.port(),
desc, desc: cmd.clone(),
}, },
); );
} }