From 1458e1b3e70006b498e9df5bd58a30a588b590f0 Mon Sep 17 00:00:00 2001 From: Navid Date: Tue, 29 Dec 2020 00:11:21 +0330 Subject: [PATCH] Refactor some code --- Cargo.toml | 2 +- README.md | 12 +- src/error.rs | 78 ------------ src/lib.rs | 275 ++++++++++++++++++++--------------------- tests/iptables_test.rs | 114 ++++++++--------- 5 files changed, 193 insertions(+), 288 deletions(-) delete mode 100644 src/error.rs diff --git a/Cargo.toml b/Cargo.toml index 5585009..8a142bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iptables" -version = "0.3.0" +version = "0.4.0" authors = ["Navid Fathollahzade ", "Pit Kleyersburg "] edition = "2018" description = "Rust bindings for iptables" diff --git a/README.md b/README.md index 1e9ecda..f283c67 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This crate provides bindings for [iptables](https://www.netfilter.org/projects/i ```toml [dependencies] -iptables = "0.3" +iptables = "0.4" ``` ## Getting started @@ -16,11 +16,11 @@ iptables = "0.3" ```rust let ipt = iptables::new(false).unwrap(); -assert_eq!(ipt.new_chain("nat", "NEWCHAINNAME").unwrap(), true); -assert_eq!(ipt.append("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -assert_eq!(ipt.exists("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -assert_eq!(ipt.delete("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -assert_eq!(ipt.delete_chain("nat", "NEWCHAINNAME").unwrap(), true); +assert!(ipt.new_chain("nat", "NEWCHAINNAME").is_ok()); +assert!(ipt.append("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok()); +assert!(ipt.exists("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap()); +assert!(ipt.delete("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok()); +assert!(ipt.delete_chain("nat", "NEWCHAINNAME").is_ok()); ``` For more information, please check the test file in `tests` folder. diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 1bd3757..0000000 --- a/src/error.rs +++ /dev/null @@ -1,78 +0,0 @@ -use std::{convert, error, fmt, io, num}; - -/// Defines the general error type of iptables crate -#[derive(Debug)] -pub enum IPTError { - Io(io::Error), - Regex(regex::Error), - Nix(nix::Error), - Parse(num::ParseIntError), - Other(&'static str), -} - -/// Defines the Result type of iptables crate -pub type IPTResult = Result; - -impl fmt::Display for IPTError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - IPTError::Io(ref err) => write!(f, "{}", err), - IPTError::Regex(ref err) => write!(f, "{}", err), - IPTError::Nix(ref err) => write!(f, "{}", err), - IPTError::Parse(ref err) => write!(f, "{}", err), - IPTError::Other(ref message) => write!(f, "{}", message), - } - } -} - -impl error::Error for IPTError { - fn description(&self) -> &str { - match *self { - IPTError::Io(ref err) => err.description(), - IPTError::Regex(ref err) => err.description(), - IPTError::Nix(ref err) => err.description(), - IPTError::Parse(ref err) => err.description(), - IPTError::Other(ref message) => message, - } - } - - fn cause(&self) -> Option<&dyn error::Error> { - match *self { - IPTError::Io(ref err) => Some(err), - IPTError::Regex(ref err) => Some(err), - IPTError::Nix(ref err) => Some(err), - IPTError::Parse(ref err) => Some(err), - _ => Some(self), - } - } -} - -impl convert::From for IPTError { - fn from(err: io::Error) -> Self { - IPTError::Io(err) - } -} - -impl convert::From for IPTError { - fn from(err: regex::Error) -> Self { - IPTError::Regex(err) - } -} - -impl convert::From for IPTError { - fn from(err: nix::Error) -> Self { - IPTError::Nix(err) - } -} - -impl convert::From for IPTError { - fn from(err: num::ParseIntError) -> Self { - IPTError::Parse(err) - } -} - -impl convert::From<&'static str> for IPTError { - fn from(err: &'static str) -> Self { - IPTError::Other(err) - } -} diff --git a/src/lib.rs b/src/lib.rs index 48a401d..50bd041 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,22 +6,18 @@ //! //! # Example //! ``` -//! fn main() { -//! let ipt = iptables::new(false).unwrap(); -//! assert_eq!(ipt.new_chain("nat", "NEWCHAINNAME").unwrap(), true); -//! assert_eq!(ipt.append("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -//! assert_eq!(ipt.exists("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -//! assert_eq!(ipt.delete("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap(), true); -//! assert_eq!(ipt.delete_chain("nat", "NEWCHAINNAME").unwrap(), true); -//! } +//! let ipt = iptables::new(false).unwrap(); +//! assert!(ipt.new_chain("nat", "NEWCHAINNAME").is_ok()); +//! assert!(ipt.append("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok()); +//! assert!(ipt.exists("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap()); +//! assert!(ipt.delete("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok()); +//! assert!(ipt.delete_chain("nat", "NEWCHAINNAME").is_ok()); //! ``` -pub mod error; - -use error::{IPTError, IPTResult}; use lazy_static::lazy_static; use nix::fcntl::{flock, FlockArg}; use regex::{Match, Regex}; +use std::error::Error; use std::ffi::OsStr; use std::fs::File; use std::os::unix::io::AsRawFd; @@ -58,14 +54,30 @@ impl SplitQuoted for str { } } -fn get_builtin_chains(table: &str) -> IPTResult<&[&str]> { +fn error_from_str(msg: &str) -> Box { + msg.into() +} + +fn output_to_result(output: Output) -> Result<(), Box> { + if !output.status.success() { + let msg = format!( + "iptables returned non-zero status code: {} - {}", + output.status.code().unwrap_or(-1), + String::from_utf8_lossy(output.stderr.as_slice()), + ); + return Err(error_from_str(msg.as_str())); + } + Ok(()) +} + +fn get_builtin_chains(table: &str) -> Result<&[&str], Box> { match table { "filter" => Ok(BUILTIN_CHAINS_FILTER), "mangle" => Ok(BUILTIN_CHAINS_MANGLE), "nat" => Ok(BUILTIN_CHAINS_NAT), "raw" => Ok(BUILTIN_CHAINS_RAW), "security" => Ok(BUILTIN_CHAINS_SECURITY), - _ => Err(IPTError::Other("given table is not supported by iptables")), + _ => Err(error_from_str("given table is not supported by iptables")), } } @@ -84,18 +96,18 @@ pub struct IPTables { /// Returns `None` because iptables only works on linux #[cfg(not(target_os = "linux"))] -pub fn new(is_ipv6: bool) -> IPTResult { +pub fn new(is_ipv6: bool) -> Result> { Err(IPTError::Other("iptables only works on Linux")) } /// Creates a new `IPTables` Result with the command of 'iptables' if `is_ipv6` is `false`, otherwise the command is 'ip6tables'. #[cfg(target_os = "linux")] -pub fn new(is_ipv6: bool) -> IPTResult { +pub fn new(is_ipv6: bool) -> Result> { let cmd = if is_ipv6 { "ip6tables" } else { "iptables" }; let version_output = Command::new(cmd).arg("--version").output()?; let re = Regex::new(r"v(\d+)\.(\d+)\.(\d+)")?; - let version_string = String::from_utf8_lossy(&version_output.stdout).into_owned(); + let version_string = String::from_utf8_lossy(version_output.stdout.as_slice()); let versions = re .captures(&version_string) .ok_or("invalid version number")?; @@ -128,140 +140,155 @@ pub fn new(is_ipv6: bool) -> IPTResult { impl IPTables { /// Get the default policy for a table/chain. - pub fn get_policy(&self, table: &str, chain: &str) -> IPTResult { + pub fn get_policy(&self, table: &str, chain: &str) -> Result> { let builtin_chains = get_builtin_chains(table)?; if !builtin_chains.iter().as_slice().contains(&chain) { - return Err(IPTError::Other( + return Err(error_from_str( "given chain is not a default chain in the given table, can't get policy", )); } - let output = - String::from_utf8_lossy(&self.run(&["-t", table, "-L", chain])?.stdout).into_owned(); - for item in output.trim().split("\n") { - let fields = item.split(" ").collect::>(); + let stdout = self.run(&["-t", table, "-L", chain])?.stdout; + let output = String::from_utf8_lossy(stdout.as_slice()); + for item in output.trim().split('\n') { + let fields = item.split(' ').collect::>(); if fields.len() > 1 && fields[0] == "Chain" && fields[1] == chain { return Ok(fields[3].replace(")", "")); } } - Err(IPTError::Other( + Err(error_from_str( "could not find the default policy for table and chain", )) } /// Set the default policy for a table/chain. - pub fn set_policy(&self, table: &str, chain: &str, policy: &str) -> IPTResult { + pub fn set_policy(&self, table: &str, chain: &str, policy: &str) -> Result<(), Box> { let builtin_chains = get_builtin_chains(table)?; if !builtin_chains.iter().as_slice().contains(&chain) { - return Err(IPTError::Other( + return Err(error_from_str( "given chain is not a default chain in the given table, can't set policy", )); } - match self.run(&["-t", table, "-P", chain, policy]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + self.run(&["-t", table, "-P", chain, policy]) + .and_then(output_to_result) } /// Executes a given `command` on the chain. /// Returns the command output if successful. - pub fn execute(&self, table: &str, command: &str) -> IPTResult { + pub fn execute(&self, table: &str, command: &str) -> Result> { self.run(&[&["-t", table], command.split_quoted().as_slice()].concat()) } /// Checks for the existence of the `rule` in the table/chain. /// Returns true if the rule exists. #[cfg(target_os = "linux")] - pub fn exists(&self, table: &str, chain: &str, rule: &str) -> IPTResult { + pub fn exists(&self, table: &str, chain: &str, rule: &str) -> Result> { if !self.has_check { return self.exists_old_version(table, chain, rule); } - match self.run(&[&["-t", table, "-C", chain], rule.split_quoted().as_slice()].concat()) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + self.run(&[&["-t", table, "-C", chain], rule.split_quoted().as_slice()].concat()) + .map(|output| output.status.success()) } /// Checks for the existence of the `chain` in the table. /// Returns true if the chain exists. #[cfg(target_os = "linux")] - pub fn chain_exists(&self, table: &str, chain: &str) -> IPTResult { - match self.run(&["-t", table, "-L", chain]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn chain_exists(&self, table: &str, chain: &str) -> Result> { + self.run(&["-t", table, "-L", chain]) + .map(|output| output.status.success()) + } + + fn exists_old_version( + &self, + table: &str, + chain: &str, + rule: &str, + ) -> Result> { + self.run(&["-t", table, "-S"]).map(|output| { + String::from_utf8_lossy(&output.stdout).contains(&format!("-A {} {}", chain, rule)) + }) } /// Inserts `rule` in the `position` to the table/chain. - /// Returns `true` if the rule is inserted. - pub fn insert(&self, table: &str, chain: &str, rule: &str, position: i32) -> IPTResult { - match self.run( + pub fn insert( + &self, + table: &str, + chain: &str, + rule: &str, + position: i32, + ) -> Result<(), Box> { + self.run( &[ &["-t", table, "-I", chain, &position.to_string()], rule.split_quoted().as_slice(), ] .concat(), - ) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + ) + .and_then(output_to_result) } /// Inserts `rule` in the `position` to the table/chain if it does not exist. - /// Returns `true` if the rule is inserted. pub fn insert_unique( &self, table: &str, chain: &str, rule: &str, position: i32, - ) -> IPTResult { + ) -> Result<(), Box> { if self.exists(table, chain, rule)? { - return Err(IPTError::Other("the rule exists in the table/chain")); + return Err(error_from_str("the rule exists in the table/chain")); } self.insert(table, chain, rule, position) } /// Replaces `rule` in the `position` to the table/chain. - /// Returns `true` if the rule is replaced. - pub fn replace(&self, table: &str, chain: &str, rule: &str, position: i32) -> IPTResult { - match self.run( + pub fn replace( + &self, + table: &str, + chain: &str, + rule: &str, + position: i32, + ) -> Result<(), Box> { + self.run( &[ &["-t", table, "-R", chain, &position.to_string()], rule.split_quoted().as_slice(), ] .concat(), - ) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + ) + .and_then(output_to_result) } /// Appends `rule` to the table/chain. - /// Returns `true` if the rule is appended. - pub fn append(&self, table: &str, chain: &str, rule: &str) -> IPTResult { - match self.run(&[&["-t", table, "-A", chain], rule.split_quoted().as_slice()].concat()) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn append(&self, table: &str, chain: &str, rule: &str) -> Result<(), Box> { + self.run(&[&["-t", table, "-A", chain], rule.split_quoted().as_slice()].concat()) + .and_then(output_to_result) } /// Appends `rule` to the table/chain if it does not exist. - /// Returns `true` if the rule is appended. - pub fn append_unique(&self, table: &str, chain: &str, rule: &str) -> IPTResult { + pub fn append_unique( + &self, + table: &str, + chain: &str, + rule: &str, + ) -> Result<(), Box> { if self.exists(table, chain, rule)? { - return Err(IPTError::Other("the rule exists in the table/chain")); + return Err(error_from_str("the rule exists in the table/chain")); } self.append(table, chain, rule) } /// Appends or replaces `rule` to the table/chain if it does not exist. - /// Returns `true` if the rule is appended or replaced. - pub fn append_replace(&self, table: &str, chain: &str, rule: &str) -> IPTResult { + pub fn append_replace( + &self, + table: &str, + chain: &str, + rule: &str, + ) -> Result<(), Box> { if self.exists(table, chain, rule)? { self.delete(table, chain, rule)?; } @@ -270,39 +297,37 @@ impl IPTables { } /// Deletes `rule` from the table/chain. - /// Returns `true` if the rule is deleted. - pub fn delete(&self, table: &str, chain: &str, rule: &str) -> IPTResult { - match self.run(&[&["-t", table, "-D", chain], rule.split_quoted().as_slice()].concat()) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn delete(&self, table: &str, chain: &str, rule: &str) -> Result<(), Box> { + self.run(&[&["-t", table, "-D", chain], rule.split_quoted().as_slice()].concat()) + .and_then(output_to_result) } /// Deletes all repetition of the `rule` from the table/chain. - /// Returns `true` if the rules are deleted. - pub fn delete_all(&self, table: &str, chain: &str, rule: &str) -> IPTResult { + pub fn delete_all(&self, table: &str, chain: &str, rule: &str) -> Result<(), Box> { while self.exists(table, chain, rule)? { self.delete(table, chain, rule)?; } - Ok(true) + + Ok(()) } /// Lists rules in the table/chain. - pub fn list(&self, table: &str, chain: &str) -> IPTResult> { + pub fn list(&self, table: &str, chain: &str) -> Result, Box> { self.get_list(&["-t", table, "-S", chain]) } /// Lists rules in the table. - pub fn list_table(&self, table: &str) -> IPTResult> { + pub fn list_table(&self, table: &str) -> Result, Box> { self.get_list(&["-t", table, "-S"]) } /// Lists the name of each chain in the table. - pub fn list_chains(&self, table: &str) -> IPTResult> { + pub fn list_chains(&self, table: &str) -> Result, Box> { let mut list = Vec::new(); - let output = String::from_utf8_lossy(&self.run(&["-t", table, "-S"])?.stdout).into_owned(); - for item in output.trim().split("\n") { - let fields = item.split(" ").collect::>(); + let stdout = self.run(&["-t", table, "-S"])?.stdout; + let output = String::from_utf8_lossy(stdout.as_slice()); + for item in output.trim().split('\n') { + let fields = item.split(' ').collect::>(); if fields.len() > 1 && (fields[0] == "-P" || fields[0] == "-N") { list.push(fields[1].to_string()); } @@ -311,69 +336,49 @@ impl IPTables { } /// Creates a new user-defined chain. - /// Returns `true` if the chain is created. - pub fn new_chain(&self, table: &str, chain: &str) -> IPTResult { - match self.run(&["-t", table, "-N", chain]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn new_chain(&self, table: &str, chain: &str) -> Result<(), Box> { + self.run(&["-t", table, "-N", chain]) + .and_then(output_to_result) } /// Flushes (deletes all rules) a chain. - /// Returns `true` if the chain is flushed. - pub fn flush_chain(&self, table: &str, chain: &str) -> IPTResult { - match self.run(&["-t", table, "-F", chain]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn flush_chain(&self, table: &str, chain: &str) -> Result<(), Box> { + self.run(&["-t", table, "-F", chain]) + .and_then(output_to_result) } /// Renames a chain in the table. - /// Returns `true` if the chain is renamed. - pub fn rename_chain(&self, table: &str, old_chain: &str, new_chain: &str) -> IPTResult { - match self.run(&["-t", table, "-E", old_chain, new_chain]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn rename_chain( + &self, + table: &str, + old_chain: &str, + new_chain: &str, + ) -> Result<(), Box> { + self.run(&["-t", table, "-E", old_chain, new_chain]) + .and_then(output_to_result) } /// Deletes a user-defined chain in the table. - /// Returns `true` if the chain is deleted. - pub fn delete_chain(&self, table: &str, chain: &str) -> IPTResult { - match self.run(&["-t", table, "-X", chain]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn delete_chain(&self, table: &str, chain: &str) -> Result<(), Box> { + self.run(&["-t", table, "-X", chain]) + .and_then(output_to_result) } /// Flushes all chains in a table. - /// Returns `true` if the chains are flushed. - pub fn flush_table(&self, table: &str) -> IPTResult { - match self.run(&["-t", table, "-F"]) { - Ok(output) => Ok(output.status.success()), - Err(err) => Err(err), - } + pub fn flush_table(&self, table: &str) -> Result<(), Box> { + self.run(&["-t", table, "-F"]).and_then(output_to_result) } - fn exists_old_version(&self, table: &str, chain: &str, rule: &str) -> IPTResult { - match self.run(&["-t", table, "-S"]) { - Ok(output) => Ok(String::from_utf8_lossy(&output.stdout) - .into_owned() - .contains(&format!("-A {} {}", chain, rule))), - Err(err) => Err(err), - } + fn get_list>(&self, args: &[S]) -> Result, Box> { + let stdout = self.run(args)?.stdout; + Ok(String::from_utf8_lossy(stdout.as_slice()) + .trim() + .split('\n') + .map(String::from) + .collect()) } - fn get_list>(&self, args: &[S]) -> IPTResult> { - let mut list = Vec::new(); - let output = String::from_utf8_lossy(&self.run(args)?.stdout).into_owned(); - for item in output.trim().split("\n") { - list.push(item.to_string()) - } - Ok(list) - } - - fn run>(&self, args: &[S]) -> IPTResult { + fn run>(&self, args: &[S]) -> Result> { let mut file_lock = None; let mut output_cmd = Command::new(self.cmd); @@ -396,20 +401,14 @@ impl IPTables { need_retry = true; } Err(e) => { - return Err(IPTError::Nix(e)); + return Err(Box::new(e)); } } } output = output_cmd.args(args).output()?; } - if !self.has_wait { - match file_lock { - Some(f) => drop(f), - None => (), - }; - } - + file_lock.map(|f| drop(f)); Ok(output) } } diff --git a/tests/iptables_test.rs b/tests/iptables_test.rs index 5f72b6e..f125ebb 100644 --- a/tests/iptables_test.rs +++ b/tests/iptables_test.rs @@ -31,116 +31,100 @@ fn test_old() { } fn nat(ipt: iptables::IPTables, old_name: &str, new_name: &str) { - assert_eq!(ipt.new_chain("nat", old_name).unwrap(), true); - assert_eq!(ipt.rename_chain("nat", old_name, new_name).unwrap(), true); - assert_eq!(ipt.append("nat", new_name, "-j ACCEPT").unwrap(), true); - assert_eq!(ipt.exists("nat", new_name, "-j ACCEPT").unwrap(), true); - assert_eq!(ipt.delete("nat", new_name, "-j ACCEPT").unwrap(), true); - assert_eq!(ipt.insert("nat", new_name, "-j ACCEPT", 1).unwrap(), true); - assert_eq!( - ipt.append( + assert!(ipt.new_chain("nat", old_name).is_ok()); + assert!(ipt.rename_chain("nat", old_name, new_name).is_ok()); + assert!(ipt.append("nat", new_name, "-j ACCEPT").is_ok()); + assert!(ipt.exists("nat", new_name, "-j ACCEPT").unwrap()); + assert!(ipt.delete("nat", new_name, "-j ACCEPT").is_ok()); + assert!(ipt.insert("nat", new_name, "-j ACCEPT", 1).is_ok()); + assert!(ipt + .append( "nat", new_name, "-m comment --comment \"double-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!( - ipt.exists( + .is_ok(),); + assert!(ipt + .exists( "nat", new_name, "-m comment --comment \"double-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!( - ipt.append( + .unwrap(),); + assert!(ipt + .append( "nat", new_name, "-m comment --comment 'single-quoted comment' -j ACCEPT" ) - .unwrap(), - true - ); + .is_ok(),); // The following `exists`-check has to use double-quotes, since the iptables output (if it // doesn't have the check-functionality) will use double quotes. - assert_eq!( - ipt.exists( + assert!(ipt + .exists( "nat", new_name, "-m comment --comment \"single-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!(ipt.flush_chain("nat", new_name).unwrap(), true); - assert_eq!(ipt.exists("nat", new_name, "-j ACCEPT").unwrap(), false); + .unwrap(),); + assert!(ipt.flush_chain("nat", new_name).is_ok()); + assert!(!ipt.exists("nat", new_name, "-j ACCEPT").unwrap()); assert!(ipt .execute("nat", &format!("-A {} -j ACCEPT", new_name)) .is_ok()); - assert_eq!(ipt.exists("nat", new_name, "-j ACCEPT").unwrap(), true); - assert_eq!(ipt.flush_chain("nat", new_name).unwrap(), true); - assert_eq!(ipt.chain_exists("nat", new_name).unwrap(), true); - assert_eq!(ipt.delete_chain("nat", new_name).unwrap(), true); - assert_eq!(ipt.chain_exists("nat", new_name).unwrap(), false); + assert!(ipt.exists("nat", new_name, "-j ACCEPT").unwrap()); + assert!(ipt.flush_chain("nat", new_name).is_ok()); + assert!(ipt.chain_exists("nat", new_name).unwrap()); + assert!(ipt.delete_chain("nat", new_name).is_ok()); + assert!(!ipt.chain_exists("nat", new_name).unwrap()); } fn filter(ipt: iptables::IPTables, name: &str) { - assert_eq!(ipt.new_chain("filter", name).unwrap(), true); - assert_eq!(ipt.insert("filter", name, "-j ACCEPT", 1).unwrap(), true); - assert_eq!(ipt.replace("filter", name, "-j DROP", 1).unwrap(), true); - assert_eq!(ipt.exists("filter", name, "-j DROP").unwrap(), true); - assert_eq!(ipt.exists("filter", name, "-j ACCEPT").unwrap(), false); - assert_eq!(ipt.delete("filter", name, "-j DROP").unwrap(), true); + assert!(ipt.new_chain("filter", name).is_ok()); + assert!(ipt.insert("filter", name, "-j ACCEPT", 1).is_ok()); + assert!(ipt.replace("filter", name, "-j DROP", 1).is_ok()); + assert!(ipt.exists("filter", name, "-j DROP").unwrap()); + assert!(!ipt.exists("filter", name, "-j ACCEPT").unwrap()); + assert!(ipt.delete("filter", name, "-j DROP").is_ok()); assert_eq!(ipt.list("filter", name).unwrap().len(), 1); assert!(ipt .execute("filter", &format!("-A {} -j ACCEPT", name)) .is_ok()); - assert_eq!(ipt.exists("filter", name, "-j ACCEPT").unwrap(), true); - assert_eq!( - ipt.append( + assert!(ipt.exists("filter", name, "-j ACCEPT").unwrap()); + assert!(ipt + .append( "filter", name, "-m comment --comment \"double-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!( - ipt.exists( + .is_ok(),); + assert!(ipt + .exists( "filter", name, "-m comment --comment \"double-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!( - ipt.append( + .unwrap()); + assert!(ipt + .append( "filter", name, "-m comment --comment 'single-quoted comment' -j ACCEPT" ) - .unwrap(), - true - ); + .is_ok(),); // The following `exists`-check has to use double-quotes, since the iptables output (if it // doesn't have the check-functionality) will use double quotes. - assert_eq!( - ipt.exists( + assert!(ipt + .exists( "filter", name, "-m comment --comment \"single-quoted comment\" -j ACCEPT" ) - .unwrap(), - true - ); - assert_eq!(ipt.flush_chain("filter", name).unwrap(), true); - assert_eq!(ipt.chain_exists("filter", name).unwrap(), true); - assert_eq!(ipt.delete_chain("filter", name).unwrap(), true); - assert_eq!(ipt.chain_exists("filter", name).unwrap(), false); + .unwrap(),); + assert!(ipt.flush_chain("filter", name).is_ok()); + assert!(ipt.chain_exists("filter", name).unwrap()); + assert!(ipt.delete_chain("filter", name).is_ok()); + assert!(!ipt.chain_exists("filter", name).unwrap()); } #[test] @@ -187,7 +171,7 @@ fn test_set_policy() { // If the following assertions fail or any other panic occurs, we still have to ensure not to // change the policy for the user. let result = panic::catch_unwind(|| { - assert_eq!(ipt.set_policy("mangle", "FORWARD", "DROP").unwrap(), true); + assert!(ipt.set_policy("mangle", "FORWARD", "DROP").is_ok()); assert_eq!(ipt.get_policy("mangle", "FORWARD").unwrap(), "DROP"); });