Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed wg set config error on non-linux devices and upgraded all deps #345

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
850 changes: 506 additions & 344 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions boringtun-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@
name = "boringtun-cli"
description = "an implementation of the WireGuard® protocol designed for portability and speed"
version = "0.5.2"
authors = ["Noah Kennedy <[email protected]>", "Andy Grover <[email protected]>", "Jeff Hiner <[email protected]>"]
authors = [
"Noah Kennedy <[email protected]>",
"Andy Grover <[email protected]>",
"Jeff Hiner <[email protected]>",
]
license = "BSD-3-Clause"
repository = "https://github.com/cloudflare/boringtun"
documentation = "https://docs.rs/boringtun/0.5.2/boringtun/"
edition = "2021"

[dependencies]
daemonize = "0.4.1"
clap = { version = "3.1.6", features = ["env"] }
tracing = "0.1.31"
tracing-subscriber = "0.3.9"
tracing-appender = "0.2.1"
daemonize = "0.5.0"
clap = { version = "4.2.7", features = ["env"] }
tracing = "0.1.37"
tracing-subscriber = "0.3.17"
tracing-appender = "0.2.2"

[dependencies.boringtun]
version = "0.5.2"
path = "../boringtun"
features = ["device"]
features = ["device"]
96 changes: 50 additions & 46 deletions boringtun-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause

extern crate daemonize;
use boringtun::device::drop_privileges::drop_privileges;
use boringtun::device::{DeviceConfig, DeviceHandle};
use clap::{Arg, Command};
use clap::{Arg, ArgAction, Command};
use daemonize::Daemonize;
use std::fs::File;
use std::os::unix::net::UnixDatagram;
use std::process::exit;
use tracing::Level;

fn check_tun_name(_v: String) -> Result<(), String> {
fn check_tun_name(_v: &str) -> Result<String, String> {
#[cfg(any(target_os = "macos", target_os = "ios"))]
{
if boringtun::device::tun::parse_utun_name(&_v).is_ok() {
Ok(())
if boringtun::device::tun::parse_utun_name(_v).is_ok() {
Ok(_v.to_string())
} else {
Err("Tunnel name must have the format 'utun[0-9]+', use 'utun' for automatic assignment".to_owned())
}
}
#[cfg(not(target_os = "macos"))]
{
Ok(())
Ok(_v.to_string())
}
}

Expand All @@ -32,40 +33,39 @@ fn main() {
.args(&[
Arg::new("INTERFACE_NAME")
.required(true)
.takes_value(true)
.validator(|tunname| check_tun_name(tunname.to_string()))
.value_name("INTERFACE")
.value_parser(check_tun_name)
.help("The name of the created interface"),
Arg::new("foreground")
.long("foreground")
.short('f')
.action(ArgAction::SetTrue)
.help("Run and log in the foreground"),
Arg::new("threads")
.takes_value(true)
.long("threads")
.short('t')
.env("WG_THREADS")
.value_parser(clap::value_parser!(usize))
.help("Number of OS threads to use")
.default_value("4"),
Arg::new("verbosity")
.takes_value(true)
.long("verbosity")
.short('v')
.env("WG_LOG_LEVEL")
.possible_values(["error", "info", "debug", "trace"])
.value_parser(clap::value_parser!(Level))
.help("Log verbosity")
.default_value("error"),
Arg::new("uapi-fd")
.long("uapi-fd")
.env("WG_UAPI_FD")
.value_parser(clap::value_parser!(i32))
.help("File descriptor for the user API")
.default_value("-1"),
Arg::new("tun-fd")
.long("tun-fd")
.env("WG_TUN_FD")
.help("File descriptor for an already-existing TUN device")
.default_value("-1"),
.help("File descriptor for an already-existing TUN device"),
Arg::new("log")
.takes_value(true)
.long("log")
.short('l')
.env("WG_LOG_FILE")
Expand All @@ -74,65 +74,70 @@ fn main() {
Arg::new("disable-drop-privileges")
.long("disable-drop-privileges")
.env("WG_SUDO")
.value_parser(|v: &str| -> Result<bool, String> {
if v == "true" || v == "1" {
Ok(true)
} else {
Ok(false)
}
})
.action(ArgAction::SetTrue)
.help("Do not drop sudo privileges"),
Arg::new("disable-connected-udp")
.long("disable-connected-udp")
.action(ArgAction::SetTrue)
.help("Disable connected UDP sockets to each peer"),
#[cfg(target_os = "linux")]
Arg::new("disable-multi-queue")
.long("disable-multi-queue")
.action(ArgAction::SetTrue)
.help("Disable using multiple queues for the tunnel interface"),
])
.get_matches();

let background = !matches.is_present("foreground");
let background = !matches.get_flag("foreground");
#[cfg(target_os = "linux")]
let uapi_fd: i32 = matches.value_of_t("uapi-fd").unwrap_or_else(|e| e.exit());
let tun_fd: isize = matches.value_of_t("tun-fd").unwrap_or_else(|e| e.exit());
let mut tun_name = matches.value_of("INTERFACE_NAME").unwrap();
if tun_fd >= 0 {
tun_name = matches.value_of("tun-fd").unwrap();
}
let n_threads: usize = matches.value_of_t("threads").unwrap_or_else(|e| e.exit());
let log_level: Level = matches.value_of_t("verbosity").unwrap_or_else(|e| e.exit());
let uapi_fd: i32 = *matches.get_one::<i32>("uapi-fd").unwrap();
let tun_name = if let Some(tun_name) = matches.get_one::<String>("tun-fd") {
tun_name
} else {
matches
.get_one::<String>("INTERFACE_NAME")
.expect("provide interface name")
};
let n_threads: usize = *matches.get_one::<usize>("threads").unwrap();
let log_level: Level = *matches.get_one::<Level>("verbosity").unwrap();

// Create a socketpair to communicate between forked processes
let (sock1, sock2) = UnixDatagram::pair().unwrap();
let _ = sock1.set_nonblocking(true);

let _guard;

if background {
let log = matches.value_of("log").unwrap();
let log = matches.get_one::<String>("log").unwrap();

let log_file =
File::create(log).unwrap_or_else(|_| panic!("Could not create log file {}", log));

let (non_blocking, guard) = tracing_appender::non_blocking(log_file);

_guard = guard;

tracing_subscriber::fmt()
.with_max_level(log_level)
.with_writer(non_blocking)
.with_writer(log_file)
.with_ansi(false)
.init();

let daemonize = Daemonize::new()
.working_directory("/tmp")
.exit_action(move || {
let daemonize = Daemonize::new().working_directory("/tmp");
match daemonize.execute() {
daemonize::Outcome::Parent(Ok(parent)) => {
let mut b = [0u8; 1];
if sock2.recv(&mut b).is_ok() && b[0] == 1 {
println!("BoringTun started successfully");
tracing::info!("BoringTun daemonized successfully!");
exit(parent.first_child_exit_code);
} else {
eprintln!("BoringTun failed to start");
tracing::error!("BoringTun failed to start");
exit(1);
};
});

match daemonize.start() {
Ok(_) => tracing::info!("BoringTun started successfully"),
Err(e) => {
}
daemonize::Outcome::Child(Ok(_)) => {}
daemonize::Outcome::Parent(Err(e)) | daemonize::Outcome::Child(Err(e)) => {
tracing::error!(error = ?e);
exit(1);
}
Expand All @@ -143,14 +148,13 @@ fn main() {
.with_max_level(log_level)
.init();
}

let config = DeviceConfig {
n_threads,
#[cfg(target_os = "linux")]
uapi_fd,
use_connected_socket: !matches.is_present("disable-connected-udp"),
use_connected_socket: !matches.get_flag("disable-connected-udp"),
#[cfg(target_os = "linux")]
use_multi_queue: !matches.is_present("disable-multi-queue"),
use_multi_queue: !matches.get_flag("disable-multi-queue"),
};

let mut device_handle: DeviceHandle = match DeviceHandle::new(tun_name, config) {
Expand All @@ -163,19 +167,19 @@ fn main() {
}
};

if !matches.is_present("disable-drop-privileges") {
if !matches.get_flag("disable-drop-privileges") {
if let Err(e) = drop_privileges() {
tracing::error!(message = "Failed to drop privileges", error = ?e);
sock1.send(&[0]).unwrap();
exit(1);
}
}

tracing::info!("BoringTun started successfully");

// Notify parent that tunnel initialization succeeded
sock1.send(&[1]).unwrap();
drop(sock1);

tracing::info!("BoringTun started successfully");

device_handle.wait();
}
36 changes: 18 additions & 18 deletions boringtun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name = "boringtun"
description = "an implementation of the WireGuard® protocol designed for portability and speed"
version = "0.5.2"
authors = [
"Noah Kennedy <[email protected]>",
"Andy Grover <[email protected]>",
"Jeff Hiner <[email protected]>",
"Noah Kennedy <[email protected]>",
"Andy Grover <[email protected]>",
"Jeff Hiner <[email protected]>",
]
license = "BSD-3-Clause"
repository = "https://github.com/cloudflare/boringtun"
Expand All @@ -21,40 +21,40 @@ ffi-bindings = ["tracing-subscriber"]
mock-instant = ["mock_instant"]

[dependencies]
base64 = "0.13"
base64 = "0.21"
hex = "0.4"
untrusted = "0.9.0"
libc = "0.2"
parking_lot = "0.12"
tracing = "0.1.29"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3", features = ["fmt"], optional = true }
ip_network = "0.4.1"
ip_network_table = "0.2.0"
ring = "0.16"
x25519-dalek = { version = "=2.0.0-rc.2", features = [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= is probably intentional to avoid bugs like this one: webrtc-rs/webrtc#432

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was part of cargo upgrade process and it wasn't intentional, but this repository provides Cargo.lock and builds can be predictable by cargo build --frozen/--locked. Please let me know if that enforcement should be added.

"reusable_secrets",
"static_secrets",
x25519-dalek = { version = "2.0.0-rc.2", features = [
"reusable_secrets",
"static_secrets",
] }
rand_core = { version = "0.6.3", features = ["getrandom"] }
chacha20poly1305 = "0.10.0-pre.1"
aead = "0.5.0-pre.2"
rand_core = { version = "0.6.4", features = ["getrandom"] }
chacha20poly1305 = "0.10.1"
aead = "0.5.2"
blake2 = "0.10"
hmac = "0.12"
jni = { version = "0.19.0", optional = true }
mock_instant = { version = "0.2", optional = true }
socket2 = { version = "0.4.7", features = ["all"], optional = true }
mock_instant = { version = "0.3", optional = true }
socket2 = { version = "0.5.3", features = ["all"], optional = true }
thiserror = { version = "1", optional = true }

[target.'cfg(unix)'.dependencies]
nix = { version = "0.25", default-features = false, features = [
"time",
"user",
nix = { version = "0.26", default-features = false, features = [
"time",
"user",
] }

[dev-dependencies]
etherparse = "0.12"
etherparse = "0.13"
tracing-subscriber = "0.3"
criterion = { version = "0.3.5", features = ["html_reports"] }
criterion = { version = "0.4.0", features = ["html_reports"] }

[lib]
crate-type = ["staticlib", "cdylib", "rlib"]
Expand Down
4 changes: 2 additions & 2 deletions boringtun/benches/crypto_benches/chacha20poly1305_benching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn bench_chacha20poly1305(c: &mut Criterion) {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];

let mut rng = OsRng::default();
let mut rng = OsRng;

rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);
Expand All @@ -65,7 +65,7 @@ pub fn bench_chacha20poly1305(c: &mut Criterion) {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];

let mut rng = OsRng::default();
let mut rng = OsRng;

rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);
Expand Down
27 changes: 15 additions & 12 deletions boringtun/src/device/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,21 @@ fn api_set(reader: &mut BufReader<&UnixStream>, d: &mut LockReadGuard<Device>) -
},
Err(_) => return EINVAL,
},
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
"fwmark" => match val.parse::<u32>() {
Ok(mark) => match device.set_fwmark(mark) {
Ok(()) => {}
Err(_) => return EADDRINUSE,
},
Err(_) => return EINVAL,
},
"fwmark" =>
{
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
match val.parse::<u32>() {
Ok(mark) => match device.set_fwmark(mark) {
Ok(()) => {}
Err(_) => return EADDRINUSE,
},
Err(_) => return EINVAL,
}
}
"replace_peers" => match val.parse::<bool>() {
Ok(true) => device.clear_peers(),
Ok(false) => {}
Expand Down
4 changes: 2 additions & 2 deletions boringtun/src/device/dev_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<T> Lock<T> {
impl<T: ?Sized> Lock<T> {
/// Acquire a read lock
pub fn read(&self) -> LockReadGuard<T> {
let (ref lock, ref cvar) = &self.wants_write;
let (lock, cvar) = &self.wants_write;
let mut wants_write = lock.lock();
while *wants_write {
// We have a writer and we want to wait for it to go away
Expand Down Expand Up @@ -90,7 +90,7 @@ impl<'a, T: ?Sized> LockReadGuard<'a, T> {
}));

// Finally signal other threads
let (ref lock, ref cvar) = &self.wants_write;
let (lock, cvar) = &self.wants_write;
let mut wants_write = lock.lock();
*wants_write = false;
cvar.notify_all();
Expand Down
Loading