Skip to content

Commit

Permalink
firewall rules persistence
Browse files Browse the repository at this point in the history
  • Loading branch information
adgaultier committed Oct 10, 2024
1 parent 29b0632 commit 0bdca10
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 23 deletions.
35 changes: 35 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ show interface:
# Run oryx debug
run-debug:
echo "" > log-file
RUST_LOG=info cargo xtask run 2> log-file
RUST_LOG=info RUST_BACKTRACE=1 cargo xtask run 2> log-file

run:
cargo xtask run
Expand Down
4 changes: 3 additions & 1 deletion oryx-tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ kanal = "0.1.0-pre8"
mimalloc = "0.1"
clap = { version = "4", features = ["derive", "cargo"] }
network-types = "0.0.7"
uuid = { version = "1", default-features = false, features = ["v4"] }
uuid = { version = "1", default-features = false, features = ["v4","serde"] }
log = "0.4"
env_logger = "0.11"
serde_json = "1.0.128"
serde = {version = "1.0", features = ["derive"] }

[[bin]]
name = "oryx"
Expand Down
3 changes: 2 additions & 1 deletion oryx-tui/src/filter/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use ratatui::{
widgets::{Block, BorderType, Borders, Row, Table, TableState},
Frame,
};
use serde::{Deserialize, Serialize};

#[derive(Debug)]
pub struct TrafficDirectionFilter {
Expand All @@ -22,7 +23,7 @@ pub struct TrafficDirectionFilter {
pub terminate_egress: Arc<AtomicBool>,
}

#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum TrafficDirection {
Ingress,
Egress,
Expand Down
44 changes: 27 additions & 17 deletions oryx-tui/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,24 +191,34 @@ pub fn handle_key_events(
}

KeyCode::Char('s') => {
let app_packets = app.packets.lock().unwrap();
if app_packets.is_empty() {
Notification::send(
"There is no packets".to_string(),
NotificationLevel::Info,
event_sender,
)?;
if app.section.focused_section == FocusedSection::Firewall {
app.section
.firewall
.handle_keys(key_event, event_sender.clone())?
} else {
match export(&app_packets) {
Ok(_) => {
Notification::send(
"Packets exported to ~/oryx/capture file".to_string(),
NotificationLevel::Info,
event_sender,
)?;
}
Err(e) => {
Notification::send(e.to_string(), NotificationLevel::Error, event_sender)?;
let app_packets = app.packets.lock().unwrap();
if app_packets.is_empty() {
Notification::send(
"There is no packets".to_string(),
NotificationLevel::Info,
event_sender,
)?;
} else {
match export(&app_packets) {
Ok(_) => {
Notification::send(
"Packets exported to ~/oryx/capture file".to_string(),
NotificationLevel::Info,
event_sender,
)?;
}
Err(e) => {
Notification::send(
e.to_string(),
NotificationLevel::Error,
event_sender,
)?;
}
}
}
}
Expand Down
68 changes: 65 additions & 3 deletions oryx-tui/src/section/firewall.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::fmt::Display;
use crossterm::event::{Event, KeyCode, KeyEvent};
use log::info;
use oryx_common::MAX_FIREWALL_RULES;
use ratatui::{
layout::{Constraint, Direction, Flex, Layout, Margin, Rect},
Expand All @@ -8,7 +9,9 @@ use ratatui::{
widgets::{Block, Borders, Cell, Clear, HighlightSpacing, Padding, Row, Table, TableState},
Frame,
};
use std::{net::IpAddr, num::ParseIntError, str::FromStr};
use serde::{Deserialize, Serialize};
use serde_json;
use std::{fs, net::IpAddr, num::ParseIntError, os::unix::fs::chown, str::FromStr};
use tui_input::{backend::crossterm::EventHandler, Input};
use uuid;

Expand All @@ -20,7 +23,7 @@ pub enum FirewallSignal {
Kill,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FirewallRule {
id: uuid::Uuid,
name: String,
Expand All @@ -30,7 +33,7 @@ pub struct FirewallRule {
direction: TrafficDirection,
}

#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BlockedPort {
Single(u16),
All,
Expand Down Expand Up @@ -315,6 +318,42 @@ impl Firewall {
self.user_input = Some(UserInput::new());
}

pub fn save_rules(&self) -> AppResult<()> {
info!("saving rules");
info!("{:#?}", self.rules);

let json = serde_json::to_string(&self.rules).unwrap();

let uid = unsafe { libc::geteuid() };

let oryx_export_dir = dirs::home_dir().unwrap().join("oryx");

if !oryx_export_dir.exists() {
fs::create_dir(&oryx_export_dir)?;
chown(&oryx_export_dir, Some(uid), Some(uid))?;
}

let oryx_export_file = oryx_export_dir.join("firewall.json");
fs::write(oryx_export_file, json).expect("Could not save Firewall Rules");
info!("rules saved");
Ok(())
}

pub fn load_rules(&mut self) -> AppResult<()> {
info!("loading rules");
let oryx_export_file = dirs::home_dir().unwrap().join("oryx").join("firewall.json");
if oryx_export_file.exists() {
info!("EXISTS");
let json_string =
fs::read_to_string(oryx_export_file).expect("Could not load Firewall Rules");
let parsed_rules: Vec<FirewallRule> =
serde_json::from_str(&json_string).expect("Could not load Firewall Rules");
info!("rules loaded");
self.rules = parsed_rules;
}

Ok(())
}
fn validate_duplicate_rules(rules: &[FirewallRule], user_input: &UserInput) -> AppResult<()> {
if let Some(exiting_rule_with_same_ip) = rules.iter().find(|rule| {
rule.ip == IpAddr::from_str(user_input.ip.field.value()).unwrap()
Expand Down Expand Up @@ -411,6 +450,29 @@ impl Firewall {
key_event: KeyEvent,
sender: kanal::Sender<crate::event::Event>,
) -> AppResult<()> {
match key_event.code {
KeyCode::Char('s') => {
if let Err(e) = self.save_rules() {
Notification::send(
"Error saving rules",
crate::notification::NotificationLevel::Warning,
sender.clone(),
)?;
return Err(e);
}
}
KeyCode::Char('l') => {
if let Err(e) = self.load_rules() {
Notification::send(
"Error loading rules",
crate::notification::NotificationLevel::Warning,
sender.clone(),
)?;
return Err(e);
}
}
_ => {}
}
if let Some(user_input) = &mut self.user_input {
match key_event.code {
KeyCode::Esc => {
Expand Down

0 comments on commit 0bdca10

Please sign in to comment.