summaryrefslogtreecommitdiffstats
path: root/bin/net_applet
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.com>2007-05-25 15:39:46 +0000
committerOlivier Blin <oblin@mandriva.com>2007-05-25 15:39:46 +0000
commit1d37bfdbbe874abd6dcb5563eea19f531de09e1c (patch)
tree74845e43ed8fa59c7aaafd1a87efaa6b0c83c228 /bin/net_applet
parentc6ba983db7d5a82ee63599e775be0f8211447c72 (diff)
downloaddrakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.gz
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.bz2
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.xz
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.zip
sync with 2007.1 (because of SVN loss)2007.1
Diffstat (limited to 'bin/net_applet')
-rw-r--r--bin/net_applet489
1 files changed, 334 insertions, 155 deletions
diff --git a/bin/net_applet b/bin/net_applet
index a0c9efe..d4eb999 100644
--- a/bin/net_applet
+++ b/bin/net_applet
@@ -2,20 +2,26 @@
use strict;
use lib qw(/usr/lib/libDrakX);
+# i18n: IMPORTANT: to get correct namespace (drakx-net instead of libDrakX)
+BEGIN { unshift @::textdomains, 'drakx-net' }
use c;
use common;
use standalone;
use network::network;
use network::tools;
+use network::connection;
+use network::connection::ethernet;
+use network::vpn;
use run_program;
-use mygtk2 qw(gtknew);
+use mygtk2 qw(gtknew gtkset);
use dbus_object;
use network::ifw;
use network::monitor;
+use network::signal_strength;
use detect_devices;
+use modules;
use Gtk2::TrayIcon;
-use Gtk2::NotificationBubble;
use ugtk2 qw(:create :helpers :wrappers :dialogs);
@@ -24,33 +30,45 @@ shouldStart() or die "$onstartupfile should be set to TRUE or use net_applet --f
#- Allow multiple instances, but only one per user:
is_running('net_applet') and die "net_applet already running\n";
-my ($eventbox, $img, $bubble);
-my ($current_state, $current_interface, $menu, $wireless_device, $wireless_menu, $timeout, $update_timeout);
+my ($eventbox, $img);
+my ($current_state, $current_interface, $current_description, $simple_menu, $menu, $wireless_device, $timeout, $update_timeout);
add_icon_path("/usr/share/libDrakX/pixmaps/");
my $net = {};
+my $modules_conf = modules::any_conf->read;
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) },
+ firewall => gtknew('Pixbuf', file => 'drakfirewall.png'),
+ firewall_icon => gtknew('Pixbuf', file => 'drakfirewall.png')->scale_simple(24, 24, 'hyper'),
+ state => { map { $_ => gtknew('Pixbuf', file => $_) } qw(connected disconnected) },
link_level => { map {
- $_ => gtkcreate_pixbuf('wifi-' . sprintf('%03d', $_) . '.png')->scale_simple(24, 24, 'hyper');
+ $_ => gtknew('Pixbuf', file => 'wifi-' . sprintf('%03d', $_) . '.png')->scale_simple(24, 24, 'hyper');
} qw(20 40 60 80 100) },
- keyring => gtkcreate_pixbuf("/usr/share/pixmaps/keyring-small.png")->scale_simple(24, 24, 'hyper'), #- provided by usermode, required by drakxtools
+ encryption => { map {
+ $_ => gtknew('Pixbuf', file => "encryption-$_-24.png");
+ } qw(open weak strong) },
);
my %wireless_networks;
-my %tooltips =
- (
- connected => N_("Network is up on interface %s"),
- disconnected =>
- #-PO: keep the "Configure Network" substring synced with the "Configure Network" message below
- N_("Network is down on interface %s. Click on \"Configure Network\""),
- notconfigured => N_("You do not have any configured Internet connection.
-Run the \"%s\" assistant from the Mandriva Linux Control Center", N("Set up a new network interface (LAN, ISDN, ADSL, ...)")),
- );
+
+sub get_state_message {
+ my ($o_interface) = @_;
+ my $interface = $o_interface || $current_interface;
+ my $network = get_current_network();
+ formatAlaTeX(
+ $current_state eq 'connected' ?
+ N("Network is up on interface %s.", $interface) .
+ "\n\n" . N("IP address: %s", network::tools::get_interface_ip_address($net, $interface)) .
+ "\n\n" . N("Gateway: %s", [ network::tools::get_interface_status($interface) ]->[1]) .
+ ($network && "\n\n" . N("Connected to %s (link level: %d %%)", $network->{name}, $network->{signal_strength}))
+ : $current_state eq 'disconnected' ?
+ N("Network is down on interface %s.", $interface)
+ :
+ N("You do not have any configured Internet connection.
+Run the \"%s\" assistant from the Mandriva Linux Control Center", N("Set up a new network interface (LAN, ISDN, ADSL, ...)"))
+ );
+}
my %actions = (
'upNetwork' => { name => sub { N("Connect %s", $_[0]) }, launch => sub { network::tools::start_interface($_[0], 1) } },
@@ -58,7 +76,12 @@ my %actions = (
'monitorNetwork' => { name => N("Monitor Network"), launch => \&run_net_monitor },
'monitorIFW' => { name => N("Interactive Firewall"), launch => \&run_drakids },
'wireless' => { name => N("Manage wireless networks"), launch => sub { run_drakroam() } },
- 'confNetwork' => { name => N("Configure Network"), launch => sub { system("/usr/sbin/drakconnect --skip-wizard &") } },
+ 'drakvpn' => {
+ name => N("Manage VPN connections"), launch => sub {
+ run_program::raw({ detach => 1 }, '/usr/sbin/drakvpn');
+ },
+ },
+ 'confNetwork' => { name => N("Configure Network"), launch => sub { system("/usr/sbin/drakconnect &") } },
'chooseInterface' => {
name => N("Watched interface"),
choices => sub { N("Auto-detect"), sort keys %{$net->{ifcfg}} },
@@ -76,6 +99,12 @@ my %actions = (
my ($is_up, $_gw) = network::tools::get_interface_status($_[0]);
$is_up;
},
+ get_icon => sub {
+ my $ifcfg = $net->{ifcfg}{$_[0]};
+ require network::connection;
+ my $type = $ifcfg && network::connection->find_ifcfg_type($ifcfg);
+ $type && $type->get_type_icon;
+ },
launch => sub {
my ($is_up, $_gw) = network::tools::get_interface_status($_[0]);
if ($is_up) {
@@ -93,9 +122,18 @@ my %actions = (
launch => sub {
require run_program;
$net->{PROFILE} = $_[0];
- run_program::raw({ detach => 1 }, network::tools::wrap_command_for_root('/sbin/set-netprofile', $net->{PROFILE}));
+ run_program::raw({ detach => 1 }, common::wrap_command_for_root('/sbin/set-netprofile', $net->{PROFILE}));
}
},
+ 'chooseVPN' => {
+ name => N("VPN connection"),
+ header => "drakvpn",
+ choices => sub { map { $_->get_configured_connections } network::vpn::list_types },
+ allow_single_choice => 1,
+ format_choice => \&network::vpn::get_label,
+ choice_selected => sub { $_[0]->is_started },
+ launch => sub { require interactive; $_[0]->is_started ? $_[0]->stop : $_[0]->start(interactive->vnew) },
+ },
'help' => { name => N("Get Online Help"), launch => sub { system("drakhelp --id internet-connection &") } },
'quit' => { name => N("Quit"), launch => \&mainQuit },
);
@@ -107,7 +145,7 @@ gtkadd(my $icon = Gtk2::TrayIcon->new("Net_Applet"),
);
$icon->show_all;
-my ($dbus, $monitor, $ifw, $interactive_cb, @attacks_queue, $ifw_alert);
+my ($dbus, $monitor, $ifw, $interactive_cb, $ifw_alert);
eval { $dbus = dbus_object::system_bus() };
eval { $monitor = network::monitor->new($dbus) } if $dbus;
eval {
@@ -115,7 +153,9 @@ eval {
my ($_con, $msg) = @_;
my $member = $msg->get_member;
if ($member eq 'Attack') {
- handle_attack($msg->get_args_list);
+ handle_ifw_message($msg->get_args_list);
+ } elsif ($member eq 'Listen') {
+ handle_ifw_listen($msg->get_args_list);
} elsif ($member eq 'Init') {
$ifw->attach_object;
checkNetworkForce();
@@ -125,27 +165,24 @@ eval {
});
} if $dbus;
-$bubble = Gtk2::NotificationBubble->new;
-$bubble->attach($icon);
-$bubble->signal_connect(timeout => sub {
- set_verdict($attacks_queue[0], \&apply_verdict_ignore);
-});
-$bubble->signal_connect(clicked => sub {
- $bubble->hide;
- eval { $ifw->send_alert_ack };
- $ifw_alert = 0;
- update_tray_icon();
- ask_attack_verdict($attacks_queue[0]);
-});
+my $bubble_queue = Gtk2::NotificationBubble::Queue->new;
+$bubble_queue->{bubble}->attach($icon);
$eventbox->signal_connect(button_press_event => sub {
- $_[1]->button == 1 and ($ifw_alert ? run_drakids() : run_net_monitor());
- $_[1]->button == 3 && $menu and $menu->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time);
+ if ($_[1]->button == 1) {
+ if ($ifw_alert) {
+ run_drakids();
+ } elsif ($simple_menu) {
+ $simple_menu->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time);
+ }
+ } elsif ($_[1]->button == 3 && $menu) {
+ $menu->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time);
+ }
});
checkNetworkForce();
cronNetwork();
-get_unprocessed_attacks();
+get_unprocessed_ifw_messages();
$SIG{HUP} = sub {
print "received SIGHUP, reloading network configuration\n";
@@ -160,7 +197,7 @@ sub is_running {
my ($name) = @_;
any {
my ($ppid, $pid, $n) = /^\s*(\d+)\s+(\d+)\s+(.*)/;
- $pid != $$ && $n eq $name;
+ $ppid != 1 && $pid != $$ && $n eq $name;
} `ps -o '%P %p %c' -u $ENV{USER}`;
}
sub shouldStart() {
@@ -186,44 +223,57 @@ sub run_drakids() {
}
}
sub generate_wireless_menuitem {
- my ($wnet, $ap) = @_;
- $wnet->{menuitem} = Gtk2::CheckMenuItem->new;
- $wnet->{menuitem}->set_draw_as_radio(1);
- $wnet->{menuitem}->add(gtkpack_(gtkshow(Gtk2::HBox->new),
- 1, gtkset_alignment($wnet->{ssid_label} = Gtk2::Label->new, 0, 0),
- 0, $wnet->{keyring_image} = Gtk2::Image->new_from_pixbuf($pixbufs{keyring}),
- 0, $wnet->{level_image} = Gtk2::Image->new));
- $wnet->{activate} = $wnet->{menuitem}->signal_connect('activate' => sub {
+ my ($wnet) = @_;
+ my $menuitem = {};
+ $menuitem->{widget} = Gtk2::CheckMenuItem->new;
+ $menuitem->{widget}->set_draw_as_radio(1);
+ $menuitem->{widget}->add(gtkpack_(gtkshow(gtknew('HBox')),
+ 1, gtkset_alignment($menuitem->{label} = gtknew('Label'), 0, 0.5),
+ 0, $menuitem->{strength} = Gtk2::Image->new,
+ 0, $menuitem->{security} = Gtk2::Image->new,
+ ));
+ $menuitem->{activate} = $menuitem->{widget}->signal_connect('activate' => sub {
if (exists $wnet->{id}) {
eval { $monitor->select_network($wnet->{id}) };
$@ and err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
} else {
- run_drakroam($ap);
+ run_drakroam($wnet->{ap});
}
checkNetworkForce();
});
- undef $current_state; #- force menu redraw
+ update_wireless_item($menuitem, $wnet);
+ push @{$wnet->{menuitems}}, $menuitem;
+ return $menuitem->{widget};
}
sub update_wireless_item {
- my ($wnet, $ap_address) = @_;
- $wnet->{ssid_label}->set_text($wnet->{essid} || "[$ap_address]");
- $wnet->{keyring_image}->visible(to_bool($wnet->{flags}));
- $wnet->{level_image}->set_from_pixbuf($pixbufs{link_level}{$wnet->{approx_level}});
-
- $wnet->{menuitem}->signal_handler_block($wnet->{activate});
- $wnet->{menuitem}->set_active($wnet->{current});
- $wnet->{menuitem}->signal_handler_unblock($wnet->{activate});
+ my ($menuitem, $wnet) = @_;
+ $menuitem->{label}->set_text($wnet->{name});
+ $menuitem->{security}->set_from_pixbuf($pixbufs{encryption}{$wnet->{flags} =~ /WPA/i ? 'strong' : $wnet->{flags} =~ /WEP/i ? 'weak' : 'open'});
+ $menuitem->{strength}->set_from_pixbuf(network::signal_strength::get_strength_icon($wnet));
+
+ $menuitem->{widget}->signal_handler_block($menuitem->{activate});
+ $menuitem->{widget}->set_active($wnet->{current});
+ $menuitem->{widget}->signal_handler_unblock($menuitem->{activate});
}
sub checkWireless() {
$wireless_device or return;
- my ($networks) = network::monitor::list_wireless($monitor, $wireless_device);
+ my ($networks) = network::monitor::list_wireless($monitor);
+ my $force_applet_update;
foreach (keys %$networks) {
- my $wnet = $wireless_networks{$_} ||= {};
- put_in_hash($wnet, $networks->{$_});
- exists $wnet->{menuitem} or generate_wireless_menuitem($wnet, $_);
- update_wireless_item($wnet, $_);
+ exists $wireless_networks{$_} or $force_applet_update = 1;
+ put_in_hash($wireless_networks{$_} ||= {}, $networks->{$_});
+ }
+ if ($force_applet_update) {
+ undef $current_state;
+ } else {
+ foreach my $wnet (values %wireless_networks) {
+ my $is_valuable = exists $networks->{$wnet->{ap}};
+ foreach (@{$wnet->{menuitems}}) {
+ update_wireless_item($_, $wnet) if $is_valuable;
+ $_->{widget}->visible($is_valuable);
+ }
+ }
}
- $wireless_networks{$_}{menuitem}->visible(exists $networks->{$_}) foreach keys %wireless_networks;
}
sub checkNetwork() {
my ($gw_intf, $_is_up, $gw_address) = $watched_interface ?
@@ -249,85 +299,172 @@ sub cronNetwork() {
}
sub go2State {
my ($state_type, $interface) = @_;
- if ($current_state ne $state_type || $current_interface ne $interface) {
- $current_state = $state_type;
- $current_interface = $interface;
- $wireless_device = detect_devices::get_wireless_interface();
- if ($menu) {
- if (my $m = $wireless_menu && $wireless_menu->get_submenu) {
- $_->{menuitem}->get_parent and $m->remove($_->{menuitem}) foreach values %wireless_networks;
- }
- $menu->destroy;
+ my $need_update;
+ my ($old_interface, $old_description);
+ if ($current_interface ne $interface) {
+ my $card = find { $_->[0] eq $interface } network::connection::ethernet::get_eth_cards($modules_conf);
+ if ($state_type eq 'disconnected') {
+ $old_interface = $current_interface;
+ $old_description = $current_description;
}
- $menu = generate_menu($interface);
+ $current_description = $card && $card->[2];
+ $current_interface = $interface;
+ $need_update = 1;
+ }
+ if ($current_state ne $state_type) {
+ my $show = defined $current_state; # don't show bubble at applet startup
+ $current_state = $state_type;
+ $bubble_queue->add({
+ title => $old_description || $current_description || N("Network connection"),
+ pixbuf => get_state_pixbuf(),
+ message => get_state_message($old_interface || $current_interface),
+ }) if $show;
+ $need_update = 1;
+ }
+
+ update_applet() if $need_update;
+}
+
+sub get_current_network() {
+ detect_devices::is_wireless_interface($current_interface) && find { $_->{current} } values %wireless_networks;
+}
+
+sub get_state_pixbuf() {
+ my $pixbuf;
+ if ($current_state eq 'connected') {
+ my $wnet = get_current_network();
+ $pixbuf = $wnet ?
+ network::signal_strength::get_strength_icon($wnet) :
+ $pixbufs{state}{connected};
+ } else {
+ $pixbuf = $pixbufs{state}{disconnected};
}
+ $pixbuf;
}
+
sub update_tray_icon() {
if (!$ifw_alert || $img->get_storage_type ne 'pixbuf') {
- my $pixbuf;
- if ($current_state eq 'connected') {
- if (detect_devices::is_wireless_interface($current_interface)) {
- my $wnet = find { $_->{current} } values %wireless_networks;
- $pixbuf = $pixbufs{link_level}{$wnet->{approx_level}} if $wnet;
- }
- $pixbuf ||= $pixbufs{state}{connected};
- } else {
- $pixbuf = $pixbufs{state}{disconnected};
- }
- $img->set_from_pixbuf($pixbuf);
+ $img->set_from_pixbuf(get_state_pixbuf());
} else {
$img->set_from_stock('gtk-dialog-warning', 'small-toolbar');
}
}
-sub generate_menu {
- my ($interface) = @_;
+
+sub enable_ifw_alert() {
+ unless ($ifw_alert) {
+ $ifw_alert = 1;
+ update_tray_icon();
+ Glib::Timeout->add(1000, sub {
+ update_tray_icon();
+ $ifw_alert;
+ });
+ }
+}
+
+sub disable_ifw_alert() {
+ eval { $ifw->send_alert_ack };
+ $ifw_alert = 0;
+ update_tray_icon();
+}
+
+sub update_applet() {
+ $wireless_device = detect_devices::get_wireless_interface();
+
+ generate_simple_menu();
+ generate_menu();
update_tray_icon();
- gtkset_tip(Gtk2::Tooltips->new, $eventbox, formatAlaTeX(sprintf(translate($tooltips{$current_state}), $interface)));
-
- my $menu = Gtk2::Menu->new;
- my $create_item = sub {
- my ($action) = @_;
- my $name = ref($actions{$action}{name}) eq 'CODE' ? $actions{$action}{name}->($interface) : $actions{$action}{name};
- my $launch = $actions{$action}{launch};
- my @choices = exists $actions{$action}{choices} ? $actions{$action}{choices}->() : ();
- my $w;
- if (@choices == 0) {
- $w = gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($name)), activate => sub { $launch->($interface) });
- } elsif (@choices > 1) {
- my $selected = $actions{$action}{choice_selected};
- my $format = $actions{$action}{format_choice};
- $w = gtkshow(create_menu($name, map {
- my $choice = $_;
- my $w = gtkshow(gtkset_active(Gtk2::CheckMenuItem->new_with_label($format ? $format->($choice) : $choice), $selected->($choice)));
- gtksignal_connect($w, activate => sub { $launch->($choice) });
- $w->set_draw_as_radio(!$actions{$action}{use_checkbox});
- $w;
- } $actions{$action}{choices}->()));
- }
- #- don't add submenu if only one choice exists
+ gtkset_tip(Gtk2::Tooltips->new, $eventbox, get_state_message()); #gtkset($eventbox, tip => get_state_message());
+}
+
+sub create_menu_choices {
+ my ($action) = @_;
+ my @choices = $actions{$action}{choices}->();
+ #- don't add submenu if only zero or one choice exists
+ @choices > ($actions{$action}{allow_single_choice} ? 0 : 1) or return ();
+ my $selected = $actions{$action}{choice_selected};
+ my $format = $actions{$action}{format_choice};
+ my $get_icon = $actions{$action}{get_icon};
+ map {
+ my $choice = $_;
+ my $label = $format ? $format->($choice) : $choice;
+ my $w = gtkshow(gtkset_active(gtkadd(
+ Gtk2::CheckMenuItem->new,
+ gtknew('HBox', children => [
+ 1, gtkset_alignment(gtknew('Label', text => $label), 0, 0.5),
+ $get_icon ?
+ (0, gtknew('Image', file => $get_icon->($_))) :
+ (),
+ ])), $selected->($choice)));
+ gtksignal_connect($w, activate => sub { $actions{$action}{launch}->($choice) });
+ $w->set_draw_as_radio(!$actions{$action}{use_checkbox});
$w;
- };
+ } $actions{$action}{choices}->();
+}
+
+sub create_action_item {
+ my ($action) = @_;
+ my $name = ref($actions{$action}{name}) eq 'CODE' ? $actions{$action}{name}->($current_interface) : $actions{$action}{name};
+ if (exists $actions{$action}{choices}) {
+ gtkshow(create_menu($name,
+ if_($actions{$action}{header},
+ create_action_item($actions{$action}{header}),
+ gtkshow(Gtk2::SeparatorMenuItem->new),
+ ),
+ create_menu_choices($action),
+ ));
+ } else {
+ gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($name)), activate => sub { $actions{$action}{launch}->($current_interface) });
+ }
+}
+
+sub empty_menu {
+ my ($menu) = @_;
+ delete $_->{menuitems} foreach values %wireless_networks;
+ $menu->destroy if $menu;
+ Gtk2::Menu->new;
+}
+
+sub get_wireless_networks_sorted() {
+ sort {
+ $b->{signal_strength} <=> $a->{signal_strength} || $a->{name} cmp $b->{name};
+ } values %wireless_networks;
+}
+
+sub generate_simple_menu() {
+ $simple_menu = empty_menu($simple_menu);
+
+ if ($wireless_device) {
+ my @networks = get_wireless_networks_sorted();
+ my @valuable_networks = splice @networks, 0, 7;
+ gtkappend($simple_menu,
+ (map { generate_wireless_menuitem($_) } @valuable_networks),
+ (@networks ? create_menu(N("More networks"), map { generate_wireless_menuitem($_) } @networks) : ()),
+ Gtk2::SeparatorMenuItem->new,
+ );
+ }
+ gtkappend($simple_menu, create_menu_choices('setInterface'));
+}
+
+sub generate_menu() {
+ $menu = empty_menu($menu);
my (@settings);
my $interactive;
eval { $interactive = $ifw->get_interactive };
if ($current_state eq 'connected') {
- $menu->append($create_item->($_)) foreach qw(downNetwork monitorNetwork);
+ $menu->append(create_action_item($_)) foreach qw(downNetwork monitorNetwork);
} elsif ($current_state eq 'disconnected') {
- $menu->append($create_item->('upNetwork'));
+ $menu->append(create_action_item('upNetwork'));
}
- $menu->append($create_item->('monitorIFW')) if $current_state ne 'notconfigured' && defined $interactive;
+ $menu->append(create_action_item('monitorIFW')) if $current_state ne 'notconfigured' && defined $interactive;
- $menu->append($create_item->('confNetwork'));
+ $menu->append(create_action_item('confNetwork'));
- if ($current_state ne 'notconfigured') {
- $menu->append($create_item->('wireless')) if $wireless_device;
- push @settings, $create_item->('chooseInterface');
- }
+ push @settings, create_action_item('chooseInterface') if $current_state ne 'notconfigured';
- push @settings, $create_item->('chooseProfile');
+ push @settings, create_action_item('chooseProfile');
if (defined $interactive) {
$interactive_cb = gtkshow(gtksignal_connect(gtkset_active(Gtk2::CheckMenuItem->new_with_label(N("Interactive Firewall automatic mode")),
!$interactive),
@@ -338,13 +475,18 @@ sub generate_menu {
toggled => sub { setAutoStart(uc(bool2text($_[0]->get_active))) }));
$menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));
- $wireless_device and $menu->append(gtkshow($wireless_menu = create_menu(N("Wireless networks"),
- map { $_->{menuitem} } values %wireless_networks)));
- if (my $set = $current_state ne 'notconfigured' && $create_item->('setInterface')) { $menu->append($set) }
- $menu->append(gtkshow(create_menu(N("Settings"), grep { $_ } @settings)));
+ if ($current_state ne 'notconfigured' && $wireless_device) {
+ $menu->append(gtkshow(create_menu(N("Wireless networks"),
+ create_action_item('wireless'),
+ gtkshow(Gtk2::SeparatorMenuItem->new),
+ map { generate_wireless_menuitem($_) } get_wireless_networks_sorted())));
+ }
+ if (my $vpn = create_action_item('chooseVPN')) { $menu->append($vpn) }
+ if (my $set = $current_state ne 'notconfigured' && create_action_item('setInterface')) { $menu->append($set) }
+ $menu->append(gtkshow(create_menu(N("Settings"), @settings)));
$menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));
- $menu->append($create_item->('help'));
- $menu->append($create_item->('quit'));
+ $menu->append(create_action_item('help'));
+ $menu->append(create_action_item('quit'));
$menu;
}
sub mainQuit() {
@@ -363,27 +505,17 @@ sub setAutoStart {
);
}
-sub get_unprocessed_attacks() {
+sub get_unprocessed_ifw_messages() {
my @packets = eval { $ifw->get_reports };
- while (my @attack = splice(@packets, 0, 10)) {
- handle_attack(@attack);
+ while (my @ifw_message = splice(@packets, 0, 10)) {
+ handle_ifw_message(@ifw_message);
}
}
-sub handle_attack {
- my $attack = network::ifw::attack_to_hash(\@_);
- push @attacks_queue, $attack;
- @attacks_queue == 1 and notify_attack($attacks_queue[0]);
-}
-
sub set_verdict {
my ($attack, $apply_verdict) = @_;
eval { $apply_verdict->($attack) };
$@ and err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
-
- shift @attacks_queue;
- #- wait for some time so that the new bubble is noticeable
- @attacks_queue and Glib::Timeout->add(500, sub { notify_attack($attacks_queue[0]); 0 });
}
sub apply_verdict_blacklist {
@@ -402,33 +534,40 @@ sub apply_verdict_whitelist {
apply_verdict_ignore($attack);
}
-sub notify_attack {
- my ($attack) = @_;
+sub handle_ifw_message {
+ my $attack = network::ifw::attack_to_hash(\@_);
unless ($attack->{msg}) {
print "unhandled attack type, skipping\n";
return;
}
- 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);
+ enable_ifw_alert();
+ $bubble_queue->add({
+ title => N("Interactive Firewall"),
+ pixbuf => $pixbufs{firewall},
+ message => $attack->{msg},
+ timeout => sub {
+ set_verdict($attack, \&apply_verdict_ignore);
+ },
+ clicked => sub {
+ disable_ifw_alert();
+ ask_attack_verdict($attack);
+ },
+ });
}
sub ask_attack_verdict {
my ($attack) = @_;
my $w = ugtk2->new(N("Interactive Firewall: intrusion detected"),
- icon => "/usr/lib/libDrakX/icons/drakfirewall.png");
+ icon => "drakfirewall.png");
my ($blacklist, $whitelist, $ignore, $auto);
my $update_automatic_mode = sub { $auto->get_active and $interactive_cb->set_active(1) };
-
+ my $set_verdict = sub {
+ my ($verdict) = @_;
+ set_verdict($attack, $verdict);
+ $bubble_queue->process_next;
+ };
gtkadd($w->{window},
gtknew('VBox', spacing => 5, children_loose => [
gtknew('HBox', children => [
@@ -467,23 +606,63 @@ sub ask_attack_verdict {
$blacklist = gtknew('Button', text => N("Blacklist"), clicked => sub {
$w->destroy;
$update_automatic_mode->();
- set_verdict($attack, \&apply_verdict_blacklist);
+ $set_verdict->(\&apply_verdict_blacklist);
}),
$whitelist = gtknew('Button', text => N("Whitelist"), clicked => sub {
$w->destroy;
$update_automatic_mode->();
- set_verdict($attack, \&apply_verdict_whitelist);
+ $set_verdict->(\&apply_verdict_whitelist);
}),
$ignore = gtknew('Button', text => N("Ignore"), clicked => sub {
$w->destroy;
- set_verdict($attack, \&apply_verdict_ignore);
+ $set_verdict->(\&apply_verdict_ignore);
}),
]),
]));
eval { $auto->set_active(!$ifw->get_interactive) };
$blacklist->grab_focus;
gtksignal_connect($w->{window}, delete_event => sub {
- set_verdict($attack, \&apply_verdict_ignore);
+ $set_verdict->(\&apply_verdict_ignore);
});
$w->{window}->show_all;
}
+
+sub handle_ifw_listen {
+ my $listen = network::ifw::parse_listen_message(\@_);
+ enable_ifw_alert();
+ $bubble_queue->add({
+ title => N("Interactive Firewall: new service"),
+ pixbuf => $pixbufs{firewall},
+ message => $listen->{message},
+ clicked => sub {
+ disable_ifw_alert();
+ ask_listen_verdict($listen);
+ },
+ });
+}
+
+sub ask_listen_verdict {
+ my ($listen) = @_;
+
+ my $w = ugtk2->new(N("Interactive Firewall: new service"), icon => "drakfirewall.png");
+ my $set_verdict = sub {
+ $bubble_queue->process_next;
+ };
+ gtkadd($w->{window},
+ gtknew('VBox', spacing => 5, children_loose => [
+ gtknew('HBox', children => [
+ 0, Gtk2::Image->new_from_stock('gtk-dialog-warning', 'dialog'),
+ 1, gtknew('VBox', children => [
+ 0, $listen->{message},
+ 0, N("Do you want to open this service?"),
+ ])
+ ]),
+ gtknew('CheckButton', text => N("Remember this answer"), toggled => sub {}),
+ gtknew('HButtonBox', layout => 'edge', children_loose => [
+ gtknew('Button', text => N("Allow"), clicked => sub { $w->destroy; $set_verdict->(1) }),
+ gtknew('Button', text => N("Block"), clicked => sub { $w->destroy; $set_verdict->(0) }),
+ ]),
+ ]));
+ gtksignal_connect($w->{window}, delete_event => sub { $set_verdict->() });
+ $w->{window}->show_all;
+}