summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl-install/network/ifw.pm43
-rw-r--r--perl-install/standalone/drakids121
-rw-r--r--perl-install/standalone/net_applet65
3 files changed, 169 insertions, 60 deletions
diff --git a/perl-install/network/ifw.pm b/perl-install/network/ifw.pm
index 5be73cc59..8550ddcc5 100644
--- a/perl-install/network/ifw.pm
+++ b/perl-install/network/ifw.pm
@@ -2,6 +2,7 @@ package network::ifw;
use dbus_object;
use Socket;
+use common;
our @ISA = qw(dbus_object);
@@ -58,8 +59,9 @@ sub set_interactive {
}
sub get_reports {
- my ($o) = @_;
- $o->call_method('GetReports');
+ my ($o, $o_include_processed) = @_;
+ $o->call_method('GetReports',
+ Net::DBus::Binding::Value->new(&Net::DBus::Binding::Message::TYPE_UINT32, to_bool($o_include_processed)));
}
sub get_blacklist {
@@ -72,6 +74,21 @@ sub get_whitelist {
$o->call_method('GetWhitelist');
}
+sub clear_processed_reports {
+ my ($o) = @_;
+ $o->call_method('ClearProcessedReports');
+}
+
+sub send_alert_ack {
+ my ($o) = @_;
+ $o->call_method('SendAlertAck');
+}
+
+sub send_manage_request {
+ my ($o) = @_;
+ $o->call_method('SendManageRequest');
+}
+
sub format_date {
my ($timestamp) = @_;
require c;
@@ -106,4 +123,26 @@ sub resolve_address {
$hostname || $ip_addr;
}
+sub attack_to_hash {
+ my ($args) = @_;
+ my $attack = { mapn { $_[0] => $_[1] } [ 'timestamp', 'indev', 'prefix', 'sensor', 'protocol', 'addr', 'port', 'icmp_type', 'seq' ], $args };
+ $attack->{port} = unpack('S', pack('n', $attack->{port}));
+ $attack->{date} = format_date($attack->{timestamp});
+ $attack->{ip_addr} = get_ip_address($attack->{addr});
+ $attack->{hostname} = resolve_address($attack->{ip_addr});
+ $attack->{protocol} = get_protocol($attack->{protocol});
+ $attack->{service} = get_service($attack->{port});
+ $attack->{type} =
+ $attack->{prefix} eq 'SCAN' ? N("Port scanning")
+ : $attack->{prefix} eq 'SERV' ? N("Service attack")
+ : $attack->{prefix} eq 'PASS' ? N("Password cracking")
+ : undef;
+ $attack->{msg} =
+ $attack->{prefix} eq "SCAN" ? N("A port scanning attack has been attempted by %s.", $attack->{hostname})
+ : $attack->{prefix} eq "SERV" ? N("The %s service has been attacked by %s.", $attack->{service}, $attack->{hostname})
+ : $attack->{prefix} eq "PASS" ? N("A password cracking attack has been attempted by %s.", $attack->{hostname})
+ : undef;
+ $attack;
+}
+
1;
diff --git a/perl-install/standalone/drakids b/perl-install/standalone/drakids
index 52763432e..ee8f6733c 100644
--- a/perl-install/standalone/drakids
+++ b/perl-install/standalone/drakids
@@ -16,23 +16,11 @@ 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',
- );
+my $loglist = create_attack_list();
+$loglist->get_selection->set_mode('single');
+
+my $blacklist = create_attack_list();
$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("Allowed addresses") => 'text',
@@ -42,10 +30,15 @@ $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 $w = ugtk2->new(N("Interactive Firewall"),
+ icon => "/usr/lib/libDrakX/icons/drakfirewall.png");
+
my $ifw = network::ifw->new(dbus_object::system_bus(), sub {
my ($_con, $msg) = @_;
my $member = $msg->get_member;
- if ($member eq 'Blacklist') {
+ if ($member eq 'Attack') {
+ handle_log($msg->get_args_list);
+ } elsif ($member eq 'Blacklist') {
handle_blacklist($msg->get_args_list);
} elsif ($member eq 'Whitelist') {
handle_whitelist($msg->get_args_list);
@@ -53,14 +46,22 @@ my $ifw = network::ifw->new(dbus_object::system_bus(), sub {
clear_lists();
} elsif ($member eq 'Init') {
handle_init();
+ } elsif ($member eq 'ManageRequest') {
+ $w->{window}->present;
}
});
init_lists();
-$ugtk2::wm_icon = "/usr/lib/libDrakX/icons/drakfirewall.png";
-my $w = ugtk2->new(N("Interactive Firewall"));
gtkadd($w->{window},
gtknew('Notebook', children => [
+ gtknew('Label', text => N("Log")),
+ gtknew('VBox', spacing => 5, children => [
+ 1, gtknew('ScrolledWindow', width => 600, height => 400, child => $loglist),
+ 0, gtknew('HButtonBox', layout => 'edge', children_loose => [
+ gtknew('Button', text => N("Clear logs"), clicked => \&clear_log),
+ gtknew('Button', text => N("Quit"), clicked => sub { Gtk2->main_quit })
+ ]),
+ ]),
gtknew('Label', text => N("Blacklist")),
gtknew('VBox', spacing => 5, children => [
1, gtknew('ScrolledWindow', width => 600, height => 400, child => $blacklist),
@@ -108,6 +109,7 @@ sub init_blacklist() {
my @packets = $ifw->get_blacklist;
while (my @blacklist = splice(@packets, 0, 8)) {
handle_blacklist(@blacklist);
+ handle_log(@blacklist);
}
}
@@ -116,20 +118,7 @@ sub clear_blacklist() {
}
sub handle_blacklist {
- my ($timestamp, $indev, $prefix, $_sensor, $protocol, $addr, $port, $_icmp_type) = @_;
- push @{$blacklist->{data}}, [
- $addr,
- $timestamp,
- network::ifw::format_date($timestamp),
- network::ifw::resolve_address(network::ifw::get_ip_address($addr)),
- $prefix eq 'SCAN' ? N("Port scanning") :
- $prefix eq 'SERV' ? N("Service attack") :
- $prefix eq 'PASS' ? N("Password cracking") :
- '',
- network::ifw::get_service($port),
- $indev,
- network::ifw::get_protocol($protocol),
- ];
+ attack_list_add($blacklist, network::ifw::attack_to_hash(\@_));
}
sub get_selected_blacklist() {
@@ -183,13 +172,77 @@ sub unwhitelist {
sub init_lists() {
eval {
+ init_loglist();
init_blacklist();
init_whitelist();
};
- $@ and err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
+ $@ and print "$@\n", err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
}
sub clear_lists() {
+ clear_loglist();
clear_blacklist();
clear_whitelist();
}
+
+sub create_attack_list() {
+ my $attacklist = 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',
+ );
+ $attacklist->set_headers_clickable(1);
+ foreach (0, 1, 2) {
+ $attacklist->get_column($_)->signal_connect('clicked', \&sort_by_column, $attacklist->get_model);
+ #- sort on timestamp if Date column is clicked
+ #- sort columns include hidden columns while list columns don't
+ $attacklist->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2);
+ }
+ $attacklist;
+}
+
+sub attack_list_add {
+ my ($attacklist, $attack) = @_;
+ push @{$attacklist->{data}}, [
+ $attack->{addr},
+ $attack->{timestamp},
+ $attack->{date},
+ $attack->{hostname},
+ $attack->{type},
+ $attack->{service},
+ $attack->{indev},
+ $attack->{protocol},
+ ];
+}
+
+#- may throw an exception
+sub init_loglist() {
+ my @packets = $ifw->get_reports(1);
+ while (my @attack = splice(@packets, 0, 10)) {
+ handle_log(@attack);
+ }
+}
+
+sub clear_loglist() {
+ @{$loglist->{data}} = ();
+}
+
+sub handle_log {
+ attack_list_add($loglist, network::ifw::attack_to_hash(\@_));
+}
+
+sub clear_log {
+ eval {
+ $ifw->clear_processed_reports;
+ $ifw->send_alert_ack;
+ };
+ if (!$@) {
+ clear_loglist();
+ } else {
+ err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
+ }
+}
diff --git a/perl-install/standalone/net_applet b/perl-install/standalone/net_applet
index 0cfb4a978..12437f921 100644
--- a/perl-install/standalone/net_applet
+++ b/perl-install/standalone/net_applet
@@ -33,6 +33,8 @@ my $watched_interface;
my %pixbufs =
(
+ firewall => gtkcreate_pixbuf('/usr/lib/libDrakX/icons/drakfirewall.png'),
+ firewall_icon => gtkcreate_pixbuf('/usr/lib/libDrakX/icons/drakfirewall.png')->scale_simple(24, 24, 'hyper'),
state => { map { $_ => gtkcreate_pixbuf($_) } qw(connected disconnected) },
link_level => { map {
my $f = "./wifi-$_.png";
@@ -94,7 +96,7 @@ $eventbox->signal_connect(button_press_event => sub {
$icon->show_all;
-my ($dbus, $monitor, $ifw, $interactive_cb, @attacks_queue);
+my ($dbus, $monitor, $ifw, $interactive_cb, @attacks_queue, $ifw_alert);
eval { $dbus = dbus_object::system_bus() };
eval { $monitor = network::monitor->new($dbus) } if $dbus;
eval {
@@ -106,6 +108,8 @@ eval {
} elsif ($member eq 'Init') {
$ifw->attach_object;
checkNetworkForce();
+ } elsif ($member eq 'AlertAck') {
+ $ifw_alert = 0;
}
});
} if $dbus;
@@ -114,11 +118,13 @@ $bubble = Gtk2::NotificationBubble->new;
$bubble->attach($icon);
$bubble->signal_connect(timeout => sub {
#- on timeout, apply default policy
- exists $attacks_queue[0]{handled} or set_blacklist_verdict($attacks_queue[0]{seq}, undef);
+ set_blacklist_verdict($attacks_queue[0]{seq}, undef);
});
$bubble->signal_connect(clicked => sub {
- $attacks_queue[0]{handled} = 1;
$bubble->hide;
+ $ifw_alert = 0;
+ eval { $ifw->send_alert_ack };
+ update_tray_icon();
ask_attack_verdict($attacks_queue[0]);
});
@@ -157,7 +163,12 @@ sub run_drakroam() {
run_program::raw({ detach => 1 }, '/usr/sbin/drakroam') unless is_running('drakroam');
}
sub run_drakids() {
- run_program::raw({ detach => 1 }, '/usr/sbin/drakids') unless is_running('drakids');
+ $ifw_alert = 0;
+ if (is_running('drakids')) {
+ eval { $ifw->send_manage_request };
+ } else {
+ run_program::raw({ detach => 1 }, '/usr/sbin/drakids');
+ }
}
sub generate_wireless_menuitem {
my ($net) = @_;
@@ -234,14 +245,19 @@ sub go2State {
}
$menu->destroy;
}
- $menu = generate_menu($state_type, $interface);
+ $menu = generate_menu($interface);
}
}
+sub update_tray_icon() {
+ !$ifw_alert || $img->get_storage_type ne 'pixbuf' ?
+ $img->set_from_pixbuf($pixbufs{state}{$current_state eq 'connected' ? 'connected' : 'disconnected'}) :
+ $img->set_from_stock('gtk-dialog-warning', 'small-toolbar');
+}
sub generate_menu {
- my ($state_type, $interface) = @_;
+ my ($interface) = @_;
- $img->set_from_pixbuf($pixbufs{state}{$state_type eq 'connected' ? 'connected' : 'disconnected'});
- gtkset_tip(Gtk2::Tooltips->new, $eventbox, formatAlaTeX(common::sprintf_fixutf8(translate($tooltips{$state_type}), $interface)));
+ update_tray_icon();
+ gtkset_tip(Gtk2::Tooltips->new, $eventbox, formatAlaTeX(common::sprintf_fixutf8(translate($tooltips{$current_state}), $interface)));
my $menu = Gtk2::Menu->new;
my $create_item = sub {
@@ -271,15 +287,15 @@ sub generate_menu {
my $interactive;
eval { $interactive = $ifw->get_interactive };
- if ($state_type eq 'connected') {
+ if ($current_state eq 'connected') {
$menu->append($create_item->($_)) foreach qw(downNetwork monitorNetwork);
$menu->append($create_item->('monitorIFW')) if defined $interactive;
- } elsif ($state_type eq 'disconnected') {
+ } elsif ($current_state eq 'disconnected') {
$menu->append($create_item->('upNetwork'));
}
$menu->append($create_item->('confNetwork'));
- if ($state_type ne 'notconfigured') {
+ if ($current_state ne 'notconfigured') {
$menu->append($create_item->('wireless')) if $has_wireless;
push @settings, $create_item->('chooseInterface');
}
@@ -321,21 +337,13 @@ sub setAutoStart {
sub get_unprocessed_attacks() {
my @packets = eval { $ifw->get_reports };
- while (my @attack = splice(@packets, 0, 9)) {
+ while (my @attack = splice(@packets, 0, 10)) {
handle_attack(@attack);
}
}
sub handle_attack {
- my $attack = { mapn { $_[0] => $_[1] } [ 'seq', 'timestamp', 'indev', 'prefix', 'sensor', 'protocol', 'addr', 'port', 'icmp_type' ], \@_ };
- $attack->{ip_addr} = network::ifw::get_ip_address($attack->{addr});
- $attack->{hostname} = network::ifw::resolve_address($attack->{ip_addr});
- $attack->{protocol} = network::ifw::get_protocol($attack->{protocol});
- $attack->{service} = network::ifw::get_service($attack->{port});
- $attack->{msg} = $attack->{prefix} eq "SCAN" ? N("A port scanning attack has been attempted by %s.", $attack->{hostname})
- : $attack->{prefix} eq "SERV" ? N("The %s service has been attacked by %s.", $attack->{service}, $attack->{hostname})
- : $attack->{prefix} eq "PASS" ? N("A password cracking attack has been attempted by %s.", $attack->{hostname})
- : undef;
+ my $attack = network::ifw::attack_to_hash(\@_);
push @attacks_queue, $attack;
@attacks_queue == 1 and notify_attack($attacks_queue[0]);
}
@@ -359,15 +367,24 @@ sub notify_attack {
print "unhandled attack type, skipping\n";
return;
}
- $bubble->set(N("Interactive Firewall"), gtkcreate_img("/usr/lib/libDrakX/icons/drakfirewall.png"), $attack->{msg});
+ unless ($ifw_alert) {
+ $ifw_alert = 1;
+ update_tray_icon();
+ Glib::Timeout->add(1000, sub {
+ update_tray_icon();
+ $ifw_alert;
+ });
+ }
+ $bubble->set(N("Interactive Firewall"), Gtk2::Image->new_from_pixbuf($pixbufs{firewall}), $attack->{msg});
$bubble->show(5000);
+
}
sub ask_attack_verdict {
my ($attack) = @_;
my $w = ugtk2->new(N("Interactive Firewall: intrusion detected"),
- icon => "/usr/lib/libDrakX/icons/drakfirewall.png");
+ icon => "/usr/lib/libDrakX/icons/drakfirewall.png");
my ($yes, $no, $auto);
gtkadd($w->{window},
@@ -384,7 +401,7 @@ sub ask_attack_verdict {
gtknew('HBox', children => [
0, gtknew('Label', text => " "),
1, gtknew('VBox', children_loose => [
- N("Attack time: %s", network::ifw::format_date($attack->{timestamp})),
+ N("Attack time: %s", $attack->{date}),
N("Network interface: %s", $attack->{indev}),
N("Attack type: %s", $attack->{prefix}),
if_($attack->{protocol}, N("Protocol: %s", $attack->{protocol})),