From 7fe4715014243068cfb9762621d186adf09c2d4a Mon Sep 17 00:00:00 2001 From: glyph Date: Tue, 14 Dec 2021 16:13:27 +0200 Subject: [PATCH] bump version and switch to rust 2021 --- Cargo.lock | 2 +- peach-network/Cargo.toml | 4 +- peach-network/README.md | 2 +- peach-network/src/error.rs | 21 ++++++---- peach-network/src/network.rs | 80 ++++++++++++++++-------------------- 5 files changed, 52 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c48e7d0..3c51b87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2532,7 +2532,7 @@ dependencies = [ [[package]] name = "peach-network" -version = "0.3.0" +version = "0.4.0" dependencies = [ "get_if_addrs", "miniserde", diff --git a/peach-network/Cargo.toml b/peach-network/Cargo.toml index 44987c7..3913ce2 100644 --- a/peach-network/Cargo.toml +++ b/peach-network/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "peach-network" -version = "0.3.0" +version = "0.4.0" authors = ["Andrew Reid "] -edition = "2018" +edition = "2021" description = "Query and configure network interfaces." homepage = "https://opencollective.com/peachcloud" repository = "ihttps://git.coopcloud.tech/PeachCloud/peach-workspace/src/branch/main/peach-network" diff --git a/peach-network/README.md b/peach-network/README.md index 4b2ea7c..e3a887d 100644 --- a/peach-network/README.md +++ b/peach-network/README.md @@ -1,6 +1,6 @@ # peach-network -![Generic badge](https://img.shields.io/badge/version-0.3.0-.svg) +![Generic badge](https://img.shields.io/badge/version-0.4.0-.svg) Network interface state query and modification library. diff --git a/peach-network/src/error.rs b/peach-network/src/error.rs index f66db36..efb468d 100644 --- a/peach-network/src/error.rs +++ b/peach-network/src/error.rs @@ -156,10 +156,13 @@ pub enum NetworkError { /// Interface. iface: String, }, - /// Failed to start ap0 service. - StartAp0(IoError), - /// Failed to start wlan0 service. - StartWlan0(IoError), + /// Failed to start systemctl service for a network interface. + StartInterface { + /// Underlying error source. + source: IoError, + /// Interface. + iface: String, + }, /// Failed to execute wpa-ctrl command. WpaCtrl(WpaError), } @@ -196,8 +199,7 @@ impl std::error::Error for NetworkError { NetworkError::WlanOperstate(ref source) => Some(source), NetworkError::Save => None, NetworkError::Connect { .. } => None, - NetworkError::StartWlan0(ref source) => Some(source), - NetworkError::StartAp0(ref source) => Some(source), + NetworkError::StartInterface { ref source, .. } => Some(source), NetworkError::WpaCtrl(ref source) => Some(source), } } @@ -332,8 +334,11 @@ impl std::fmt::Display for NetworkError { id, iface ) } - NetworkError::StartWlan0(_) => write!(f, "Failed to start ap0 service"), - NetworkError::StartAp0(_) => write!(f, "Failed to start wlan0 service"), + NetworkError::StartInterface { ref iface, .. } => write!( + f, + "Failed to start systemctl service for {} interface", + iface + ), NetworkError::WpaCtrl(_) => write!(f, "WpaCtrl command failed"), } } diff --git a/peach-network/src/network.rs b/peach-network/src/network.rs index 1a0874d..c8aff0c 100644 --- a/peach-network/src/network.rs +++ b/peach-network/src/network.rs @@ -11,7 +11,7 @@ //! Switching between client mode and access point mode is achieved by making //! system calls to systemd (via `systemctl`). Further networking functionality //! is provided by making system calls to retrieve interface state and write -//! access point credentials to `wpa_supplicant-wlan0.conf`. +//! access point credentials to `wpa_supplicant-.conf`. use std::{ fs::OpenOptions, @@ -478,36 +478,22 @@ pub fn traffic(iface: &str) -> Result, NetworkError> { /* SET - Methods for modifying state */ -/// Activate wireless access point. +/// Start network interface service. /// -/// A `systemctl `command is invoked which starts the `ap0` interface service. -/// If the command executes successfully, an `Ok` `Result` type is returned. -/// In the event of an error, a `NetworkError` is returned in the `Result`. -pub fn activate_ap() -> Result<(), NetworkError> { - // start the ap0 interface service +/// A `systemctl `command is invoked which starts the service for the given +/// network interface. If the command executes successfully, an `Ok` `Result` +/// type is returned. In the event of an error, a `NetworkError` is returned +/// in the `Result`. +pub fn start_iface_service(iface: String) -> Result<(), NetworkError> { + let iface_service = format!("wpa_supplicant@{}.service", &iface); + + // start the interface service Command::new("sudo") .arg("/usr/bin/systemctl") .arg("start") - .arg("wpa_supplicant@ap0.service") + .arg(iface_service) .output() - .map_err(NetworkError::StartAp0)?; - - Ok(()) -} - -/// Activate wireless client. -/// -/// A `systemctl` command is invoked which starts the `wlan0` interface service. -/// If the command executes successfully, an `Ok` `Result` type is returned. -/// In the event of an error, a `NetworkError` is returned in the `Result`. -pub fn activate_client() -> Result<(), NetworkError> { - // start the wlan0 interface service - Command::new("sudo") - .arg("/usr/bin/systemctl") - .arg("start") - .arg("wpa_supplicant@wlan0.service") - .output() - .map_err(NetworkError::StartWlan0)?; + .map_err(|source| NetworkError::StartInterface { source, iface })?; Ok(()) } @@ -516,13 +502,15 @@ pub fn activate_client() -> Result<(), NetworkError> { /// /// # Arguments /// +/// * `wlan_iface` - A local wireless interface. /// * `wifi` - An instance of the `WiFi` `struct` with fields `ssid` and `pass` /// /// If configuration parameters are successfully generated from the provided -/// SSID and password and appended to `wpa_supplicant-wlan0.conf`, an `Ok` -/// `Result` type is returned. In the event of an error, a `NetworkError` is -/// returned in the `Result`. -pub fn add(wifi: &WiFi) -> Result<(), NetworkError> { +/// SSID and password and appended to `wpa_supplicant-.conf` (where +/// `` is the provided interface parameter), an `Ok` `Result` type +/// is returned. In the event of an error, a `NetworkError` is returned in the +/// `Result`. +pub fn add(wlan_iface: String, wifi: &WiFi) -> Result<(), NetworkError> { // generate configuration based on provided ssid & password let output = Command::new("wpa_passphrase") .arg(&wifi.ssid) @@ -538,12 +526,12 @@ pub fn add(wifi: &WiFi) -> Result<(), NetworkError> { let mut wpa_details = "\n".as_bytes().to_vec(); wpa_details.extend(&*(output.stdout)); - // append wpa_passphrase output to wpa_supplicant-wlan0.conf if successful + let wlan_config = format!("/etc/wpa_supplicant/wpa_supplicant-{}.conf", wlan_iface); + + // append wpa_passphrase output to wpa_supplicant-.conf if successful if output.status.success() { // open file in append mode - let file = OpenOptions::new() - .append(true) - .open("/etc/wpa_supplicant/wpa_supplicant-wlan0.conf"); + let file = OpenOptions::new().append(true).open(wlan_config); let _file = match file { // if file exists & open succeeds, write wifi configuration @@ -563,33 +551,35 @@ pub fn add(wifi: &WiFi) -> Result<(), NetworkError> { } } -/// Deploy the access point if the `wlan0` interface is `up` without an active +/// Deploy an access point if the wireless interface is `up` without an active /// connection. /// -/// The status of the `wlan0` service and the state of the `wlan0` interface +/// The status of the wireless service and the state of the wireless interface /// are checked. If the service is active but the interface is down (ie. not /// currently connected to an access point), then the access point is activated /// by calling the `activate_ap()` function. -pub fn check_iface() -> Result<(), NetworkError> { +pub fn check_iface(wlan_iface: String, ap_iface: String) -> Result<(), NetworkError> { + let wpa_service = format!("wpa_supplicant@{}.service", &wlan_iface); + // returns 0 if the service is currently active - let wlan0_status = Command::new("/usr/bin/systemctl") + let wlan_status = Command::new("/usr/bin/systemctl") .arg("is-active") - .arg("wpa_supplicant@wlan0.service") + .arg(wpa_service) .status() .map_err(NetworkError::WlanState)?; - // returns the current state of the wlan0 interface - let iface_state = state("wlan0")?; + // returns the current state of the wlan interface + let iface_state = state(&wlan_iface)?; // returns down if the interface is not currently connected to an ap - let wlan0_state = match iface_state { + let wlan_state = match iface_state { Some(state) => state, None => "error".to_string(), }; - // if wlan0 is active but not connected, start the ap0 service - if wlan0_status.success() && wlan0_state == "down" { - activate_ap()? + // if wlan is active but not connected, start the ap service + if wlan_status.success() && wlan_state == "down" { + start_iface_service(ap_iface)? } Ok(())