Skip to content

Commit

Permalink
edit firewall rules
Browse files Browse the repository at this point in the history
  • Loading branch information
pythops committed Oct 5, 2024
1 parent 8faecd7 commit 988887a
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 28 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions oryx-tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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"] }

[[bin]]
name = "oryx"
Expand Down
7 changes: 5 additions & 2 deletions oryx-tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ impl App {
let packets = Arc::new(Mutex::new(Vec::with_capacity(AppPacket::LEN * 1024 * 1024)));

let (sender, receiver) = kanal::unbounded();

let (firewall_ingress_sender, firewall_egress_receiver) = kanal::unbounded();

thread::spawn({
let packets = packets.clone();
move || loop {
Expand All @@ -73,11 +76,11 @@ impl App {
Self {
running: true,
help: Help::new(),
filter: Filter::new(),
filter: Filter::new(firewall_egress_receiver),
start_sniffing: false,
packets: packets.clone(),
notifications: Vec::new(),
section: Section::new(packets.clone()),
section: Section::new(packets.clone(), firewall_ingress_sender),
data_channel_sender: sender,
is_editing: false,
active_popup: None,
Expand Down
3 changes: 2 additions & 1 deletion oryx-tui/src/ebpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use oryx_common::{protocols::Protocol, RawPacket};
use crate::{
event::Event,
notification::{Notification, NotificationLevel},
section::firewall::FirewallRule,
};
use mio::{event::Source, unix::SourceFd, Events, Interest, Poll, Registry, Token};

Expand Down Expand Up @@ -67,7 +68,7 @@ impl Ebpf {
notification_sender: kanal::Sender<Event>,
data_sender: kanal::Sender<[u8; RawPacket::LEN]>,
filter_channel_receiver: kanal::Receiver<(Protocol, bool)>,
_firewall_channel_receiver: kanal::Receiver<(Protocol, bool)>,
_firewall_ingress_receiver: kanal::Receiver<FirewallRule>,
terminate: Arc<AtomicBool>,
) {
thread::spawn({
Expand Down
18 changes: 8 additions & 10 deletions oryx-tui/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use ratatui::{
use transport::TransportFilter;
use tui_big_text::{BigText, PixelSize};

use crate::{app::AppResult, ebpf::Ebpf, event::Event, interface::Interface};
use crate::{
app::AppResult, ebpf::Ebpf, event::Event, interface::Interface, section::firewall::FirewallRule,
};

#[derive(Debug, Clone)]
pub struct Channels {
Expand Down Expand Up @@ -89,16 +91,11 @@ pub struct Filter {
pub filter_chans: IoChans,
pub firewall_chans: IoChans,
pub focused_block: FocusedBlock,
}

impl Default for Filter {
fn default() -> Self {
Self::new()
}
pub firewall_ingress_receiver: kanal::Receiver<FirewallRule>,
}

impl Filter {
pub fn new() -> Self {
pub fn new(firewall_ingress_receiver: kanal::Receiver<FirewallRule>) -> Self {
Self {
interface: Interface::new(),
network: NetworkFilter::new(),
Expand All @@ -108,6 +105,7 @@ impl Filter {
filter_chans: IoChans::new(),
firewall_chans: IoChans::new(),
focused_block: FocusedBlock::Interface,
firewall_ingress_receiver,
}
}

Expand Down Expand Up @@ -135,7 +133,7 @@ impl Filter {
notification_sender.clone(),
data_sender.clone(),
self.filter_chans.ingress.receiver.clone(),
self.firewall_chans.ingress.receiver.clone(),
self.firewall_ingress_receiver.clone(),
self.traffic_direction.terminate_ingress.clone(),
);
}
Expand Down Expand Up @@ -317,7 +315,7 @@ impl Filter {
notification_sender.clone(),
data_sender.clone(),
self.filter_chans.ingress.receiver.clone(),
self.firewall_chans.ingress.receiver.clone(),
self.firewall_ingress_receiver.clone(),
self.traffic_direction.terminate_ingress.clone(),
);
}
Expand Down
2 changes: 1 addition & 1 deletion oryx-tui/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub fn handle_key_events(
}
}

KeyCode::Char('n') => {
KeyCode::Char('n') | KeyCode::Char('e') => {
if app.section.focused_section == FocusedSection::Firewall {
app.is_editing = true;
app.section.handle_keys(key_event)?;
Expand Down
9 changes: 6 additions & 3 deletions oryx-tui/src/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::sync::{Arc, Mutex};

use alert::Alert;
use crossterm::event::{KeyCode, KeyEvent};
use firewall::Firewall;
use firewall::{Firewall, FirewallRule};

use inspection::Inspection;
use ratatui::{
Expand Down Expand Up @@ -39,13 +39,16 @@ pub struct Section {
}

impl Section {
pub fn new(packets: Arc<Mutex<Vec<AppPacket>>>) -> Self {
pub fn new(
packets: Arc<Mutex<Vec<AppPacket>>>,
firewall_ingress_sender: kanal::Sender<FirewallRule>,
) -> Self {
Self {
focused_section: FocusedSection::Inspection,
inspection: Inspection::new(packets.clone()),
stats: Stats::new(packets.clone()),
alert: Alert::new(packets.clone()),
firewall: Firewall::new(),
firewall: Firewall::new(firewall_ingress_sender),
}
}
fn title_span(&self, header_section: FocusedSection) -> Span {
Expand Down
62 changes: 51 additions & 11 deletions oryx-tui/src/section/firewall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use ratatui::{
};
use std::{net::IpAddr, str::FromStr};
use tui_input::{backend::crossterm::EventHandler, Input};
use uuid;

use crate::app::AppResult;

#[derive(Debug, Clone)]
pub struct FirewallRule {
id: uuid::Uuid,
name: String,
enabled: bool,
ip: IpAddr,
Expand All @@ -28,6 +30,7 @@ pub enum FocusedInput {

#[derive(Debug, Clone)]
struct UserInput {
id: Option<uuid::Uuid>,
pub name: UserInputField,
pub ip: UserInputField,
pub port: UserInputField,
Expand All @@ -43,6 +46,7 @@ struct UserInputField {
impl UserInput {
pub fn new() -> Self {
Self {
id: None,
name: UserInputField::default(),
ip: UserInputField::default(),
port: UserInputField::default(),
Expand Down Expand Up @@ -187,7 +191,7 @@ impl UserInput {
.highlight_spacing(HighlightSpacing::Always)
.block(
Block::default()
.title(" New Firewall Rule ")
.title(" Firewall Rule ")
.title_alignment(ratatui::layout::Alignment::Center)
.borders(Borders::all())
.border_type(ratatui::widgets::BorderType::Thick)
Expand All @@ -200,19 +204,21 @@ impl UserInput {
}
}

#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone)]
pub struct Firewall {
rules: Vec<FirewallRule>,
state: TableState,
user_input: Option<UserInput>,
ingress_sender: kanal::Sender<FirewallRule>,
}

impl Firewall {
pub fn new() -> Self {
pub fn new(ingress_sender: kanal::Sender<FirewallRule>) -> Self {
Self {
rules: Vec::new(),
state: TableState::default(),
user_input: None,
ingress_sender,
}
}

Expand All @@ -235,14 +241,22 @@ impl Firewall {
if let Some(user_input) = &mut self.user_input {
user_input.validate()?;

let rule = FirewallRule {
name: user_input.name.field.value().to_lowercase(),
ip: IpAddr::from_str(user_input.ip.field.value()).unwrap(),
port: u16::from_str(user_input.port.field.value()).unwrap(),
enabled: false,
};
self.rules.push(rule);
self.user_input = None;
if let Some(id) = user_input.id {
let rule = self.rules.iter_mut().find(|rule| rule.id == id).unwrap();
rule.name = user_input.name.field.to_string();
rule.ip = IpAddr::from_str(user_input.ip.field.value()).unwrap();
rule.port = u16::from_str(user_input.port.field.value()).unwrap();
} else {
let rule = FirewallRule {
id: uuid::Uuid::new_v4(),
name: user_input.name.field.value().to_lowercase(),
ip: IpAddr::from_str(user_input.ip.field.value()).unwrap(),
port: u16::from_str(user_input.port.field.value()).unwrap(),
enabled: false,
};
self.rules.push(rule);
self.user_input = None;
}
}
}

Expand Down Expand Up @@ -277,6 +291,32 @@ impl Firewall {
KeyCode::Char(' ') => {
if let Some(index) = self.state.selected() {
self.rules[index].enabled = !self.rules[index].enabled;
self.ingress_sender.send(self.rules[index].clone())?
}
}

KeyCode::Char('e') => {
if let Some(index) = self.state.selected() {
let rule = self.rules[index].clone();

let user_input = UserInput {
id: Some(rule.id),
name: UserInputField {
field: Input::from(rule.name),
error: None,
},
ip: UserInputField {
field: Input::from(rule.ip.to_string()),
error: None,
},
port: UserInputField {
field: Input::from(rule.port.to_string()),
error: None,
},
focus_input: FocusedInput::Name,
};

self.user_input = Some(user_input);
}
}

Expand Down

0 comments on commit 988887a

Please sign in to comment.