From 92b858884c5091e54a66d59aa81ca7535c333793 Mon Sep 17 00:00:00 2001 From: Kevin Yue Date: Fri, 10 May 2024 10:26:45 -0400 Subject: [PATCH] fix: check executable for file --- crates/common/src/vpn_utils.rs | 19 ++++++++++++++++--- crates/openconnect/src/vpn.rs | 28 ++++++++++++---------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/crates/common/src/vpn_utils.rs b/crates/common/src/vpn_utils.rs index c6342ad..5366154 100644 --- a/crates/common/src/vpn_utils.rs +++ b/crates/common/src/vpn_utils.rs @@ -1,7 +1,6 @@ -use is_executable::IsExecutable; -use std::path::Path; +use std::{io, path::Path}; -pub use is_executable::is_executable; +use is_executable::IsExecutable; const VPNC_SCRIPT_LOCATIONS: [&str; 6] = [ "/usr/local/share/vpnc-scripts/vpnc-script", @@ -39,3 +38,17 @@ pub fn find_vpnc_script() -> Option { pub fn find_csd_wrapper() -> Option { find_executable(&CSD_WRAPPER_LOCATIONS) } + +/// If file exists, check if it is executable +pub fn check_executable(file: &str) -> Result<(), io::Error> { + let path = Path::new(file); + + if path.exists() && !path.is_executable() { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + format!("{} is not executable", file), + )); + } + + Ok(()) +} diff --git a/crates/openconnect/src/vpn.rs b/crates/openconnect/src/vpn.rs index 5ba8781..e5f3280 100644 --- a/crates/openconnect/src/vpn.rs +++ b/crates/openconnect/src/vpn.rs @@ -4,7 +4,7 @@ use std::{ sync::{Arc, RwLock}, }; -use common::vpn_utils::{find_vpnc_script, is_executable}; +use common::vpn_utils::{check_executable, find_vpnc_script}; use log::info; use crate::ffi; @@ -80,23 +80,23 @@ impl Vpn { } #[derive(Debug)] -pub struct VpnError<'a> { - message: &'a str, +pub struct VpnError { + message: String, } -impl<'a> VpnError<'a> { - fn new(message: &'a str) -> Self { +impl VpnError { + fn new(message: String) -> Self { Self { message } } } -impl fmt::Display for VpnError<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl fmt::Display for VpnError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.message) } } -impl std::error::Error for VpnError<'_> {} +impl std::error::Error for VpnError {} pub struct VpnBuilder { server: String, @@ -159,21 +159,17 @@ impl VpnBuilder { self } - pub fn build(self) -> Result> { + pub fn build(self) -> Result { let script = match self.script { Some(script) => { - if !is_executable(&script) { - return Err(VpnError::new("vpnc script is not executable")); - } + check_executable(&script).map_err(|e| VpnError::new(e.to_string()))?; script } - None => find_vpnc_script().ok_or_else(|| VpnError::new("Failed to find vpnc-script"))?, + None => find_vpnc_script().ok_or_else(|| VpnError::new(String::from("Failed to find vpnc-script")))?, }; if let Some(csd_wrapper) = &self.csd_wrapper { - if !is_executable(csd_wrapper) { - return Err(VpnError::new("CSD wrapper is not executable")); - } + check_executable(csd_wrapper).map_err(|e| VpnError::new(e.to_string()))?; } let user_agent = self.user_agent.unwrap_or_default();