#!/usr/bin/perl use strict; use lib qw(/usr/lib/libDrakX); use common; use Socket; use mygtk2 qw(gtknew); use POSIX qw(strftime); use network::activefw; use Gtk2::SimpleList; use ugtk2 qw(:create :helpers :wrappers); my $blacklist = Gtk2::SimpleList->new(addr => 'hidden', timestamp => 'hidden', N("Date") => 'text', N("Attacker") => 'text', N("Attack type") => 'text', N("Service") => 'text', N("Network interface") => 'text', N("Protocol") => 'text', ); $blacklist->get_selection->set_mode('multiple'); $blacklist->set_headers_clickable(1); foreach (0, 1, 2) { $blacklist->get_column($_)->signal_connect('clicked', \&sort_by_column, $blacklist->get_model); #- sort on timestamp if Date column is clicked #- sort columns include hidden columns while list columns don't $blacklist->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2); } my $whitelist = Gtk2::SimpleList->new(addr => 'hidden', N("Attacker") => 'text', ); $whitelist->get_selection->set_mode('multiple'); $whitelist->set_headers_clickable(1); $whitelist->get_column(0)->signal_connect('clicked', \&sort_by_column, $whitelist->get_model); $whitelist->get_column(0)->set_sort_column_id(0); my $activefw = network::activefw->new(sub { my ($_con, $msg) = @_; my $member = $msg->get_member; if ($member eq 'Blacklist') { handle_blacklist($msg->get_args_list); } elsif ($member eq 'Whitelist') { handle_whitelist($msg->get_args_list); } elsif ($member eq 'Clear') { clear_lists(); } elsif ($member eq 'Init') { handle_init(); } }); init_lists(); $ugtk2::wm_icon = "/usr/lib/libDrakX/icons/drakfirewall.png"; my $w = ugtk2->new(N("Active Firewall")); gtkpack($w->{window}, gtknew('Notebook', children => [ gtknew('Label', text => N("Blacklist")), gtknew('VBox', spacing => 5, children => [ 1, gtknew('ScrolledWindow', width => 600, height => 400, child => $blacklist), 0, gtknew('HButtonBox', layout => 'edge', children_loose => [ gtknew('Button', text => N("Remove from blacklist"), clicked => sub { unblacklist(get_selected_blacklist()) }), gtknew('Button', text => N("Move to whitelist"), clicked => sub { whitelist(get_selected_blacklist()) }), gtknew('Button', text => N("Quit"), clicked => sub { Gtk2->main_quit }) ]), ]), gtknew('Label', text => N("Whitelist")), gtknew('VBox', spacing => 5, children => [ 1, gtknew('ScrolledWindow', width => 600, height => 400, child => $whitelist), 0, gtknew('HButtonBox', layout => 'edge', children_loose => [ gtknew('Button', text => N("Remove from whitelist"), clicked => sub { unwhitelist(get_selected_whitelist()) }), gtknew('Button', text => N("Quit"), clicked => sub { Gtk2->main_quit }) ]), ]), ]), ); $w->show; Gtk2->main; ugtk2::exit(0); sub sort_by_column { my ($column, $model) = @_; my $col_id = $column->get_sort_column_id; my ($old_id, $old_order) = $model->get_sort_column_id; $model->set_sort_column_id($col_id, $old_id == $col_id && $old_order ne 'descending' ? 'ascending' : 'descending'); } sub handle_init { $activefw->attach_daemon; init_lists(); } sub list_remove_addr { my ($list, @addr) = @_; #- workaround buggy Gtk2::SimpleList array abstraction, it corrupts references foreach (0 .. $#{$list}) { member($list->[$_][0], @addr) and splice @$list, $_, 1; } } sub init_blacklist { my @packets = $activefw->get_blacklist; while (my @blacklist = splice(@packets, 0, 8)) { handle_blacklist(@blacklist); } } sub clear_blacklist { @{$blacklist->{data}} = (); } sub handle_blacklist { my ($timestamp, $indev, $prefix, $sensor, $protocol, $addr, $port, $icmp_type) = @_; push @{$blacklist->{data}}, [ $addr, $timestamp, network::activefw::format_date($timestamp), network::activefw::resolve_address(network::activefw::get_ip_address($addr)), $prefix eq 'SCAN' ? N("Port scanning") : $prefix eq 'SERV' ? N("Service attack") : $prefix eq 'PASS' ? N("Password cracking") : '', network::activefw::get_service($port) || '', $indev, $protocol || '', ]; } sub get_selected_blacklist { uniq(map { $blacklist->{data}[$_][0] } $blacklist->get_selected_indices); } sub unblacklist { my @addr = @_; $activefw->unblacklist($_) foreach @addr; #- delete from the list even if the above calls were unsuccessful list_remove_addr($blacklist->{data}, @addr); } sub init_whitelist { handle_whitelist($_) foreach $activefw->get_whitelist; } sub clear_whitelist { @{$whitelist->{data}} = (); } sub handle_whitelist { my ($addr) = @_; push @{$whitelist->{data}}, [ $addr, network::activefw::resolve_address(network::activefw::get_ip_address($addr)) ]; } sub get_selected_whitelist { uniq(map { $whitelist->{data}[$_][0] } $whitelist->get_selected_indices); } sub whitelist { my @addr = @_; unblacklist(@addr); $activefw->whitelist($_) foreach @addr; } sub unwhitelist { my @addr = @_; $activefw->unwhitelist($_) foreach @addr; #- delete from the list even if the above calls were unsuccessful list_remove_addr($whitelist->{data}, @addr); } sub init_lists { init_blacklist(); init_whitelist(); } sub clear_lists { clear_blacklist(); clear_whitelist(); }