#!/usr/bin/perl #***************************************************************************** # # Copyright (c) 2002-2006 Christian Belisle # Thierry Vignaud # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #***************************************************************************** use strict; use lib qw(/usr/lib/libDrakX); use common; use standalone; use vars qw($MODE %options); use interactive; use mygtk2 qw(gtknew gtkset); use ugtk2 qw(:helpers :wrappers :ask :create); use run_program; use security::level; use security::msec; use security::help; use security::l10n; #$MODE = 'basic'; #$0 =~ /draksec-firewall$/ and $MODE = 'firewall'; #$0 =~ /draksec-perms$/ and $MODE = 'perms'; #/^-?-(\S+)$/ and $options{$1} = 1 foreach @ARGV; my $in = 'interactive'->vnew('su'); $ugtk2::wm_icon = "/usr/share/mcc/themes/default/draksec-mdk.png"; my ($w, %fields); ############################ I18N ################################### my @help; my %translations = ( 'ALL' => N("ALL"), 'LOCAL' => N("LOCAL"), 'NONE' => N("NONE"), 'default' => N("Default"), 'ignore' => N("Ignore"), 'no' => N("No"), 'yes' => N("Yes"), ); my %inv_translations = reverse %translations; sub to_i18n { map { $translations{$_} || $_ } @_ } sub from_i18n { $inv_translations{$_[0]} || $_[0] } sub resize { gtkset($_[0], width => 50) } %fields = security::l10n::fields(); my %inv_fields = reverse %fields; # factorize this with rpmdrake and harddrake2 sub wait_msg { my $mainw = ugtk2->new(N("Please wait"), (modal => 1, transient => $w->{real_window})); $mainw->{window}->add(gtknew('WrappedLabel', text => $_[0])); $mainw->{rwindow}->show_all; gtkset_mousecursor_wait($mainw->{rwindow}->window); # ugly workaround for gtk+ not displaying subdialog contents: Glib::Timeout->add(300, sub { Gtk2->main_quit; 0 }); Gtk2->main; $mainw; } sub remove_wait_msg { $_[0]->destroy } sub basic_seclevel_explanations() { my $text = gtknew('TextView'); use Gtk2::Pango; my %common_opts = ('left-margin' => '10', 'right-margin' => '10'); gtktext_insert($text, ugtk2::markup_to_TextView_format(formatAlaTeX( #-PO: Do not alter the and tags. #-PO: Translate the security levels (Poor, Standard, High, Higher and Paranoid) in the same way, you translated these individuals words. #-PO: keep the double empty lines between sections, this is formatted a la LaTeX. N("Here, you can setup the security level and administrator of your machine. The 'Security Administrator' is the one who will receive security alerts if the 'Security Alerts' option is set. It can be a username or an email. The 'Security Level' menu allows you to select one of the six preconfigured security levels provided with msec. These levels range from 'poor' security and ease of use, to 'paranoid' config, suitable for very sensitive server applications: Poor: This is a totally unsafe but very easy to use security level. It should only be used for machines not connected to any network and that are not accessible to everybody. Standard: This is the standard security recommended for a computer that will be used to connect to the Internet as a client. High: There are already some restrictions, and more automatic checks are run every night. Higher: The security is now high enough to use the system as a server which can accept connections from many clients. If your machine is only a client on the Internet, you should choose a lower level. Paranoid: This is similar to the previous level, but the system is entirely closed and security features are at their maximum")), \%common_opts)); gtknew('ScrolledWindow', h_policy => 'never', child => $text); } sub new_nonedit_combo { my ($string_list, $o_default_value) = @_; gtknew('ComboBox', text => to_i18n($o_default_value), list => [ to_i18n(@$string_list) ]); } sub register_help_page { my ($domain) = @_; push @help, ([ [ $domain . "\n\n", { justification => 'center', scale => Gtk2::Pango->PANGO_SCALE_LARGE, weight => Gtk2::Pango->PANGO_WEIGHT_BOLD, }, ], [ N("Description of the fields:\n\n"), ], ], ); } sub register_help_entry { my ($label, $default, $opt) = @_; my $help = $security::help::help{$opt}; push @{$help[-1]}, ([ formatAlaTeX($label) . ":\n", { foreground => "royalblue3" }, ], [ join("\n", formatAlaTeX($help), N("(default value: %s)", map { s/ /, /g; $_ } to_i18n($default)), "\n") ] ); } my $msec = new security::msec; $w = ugtk2->new(N("Security Level and Checks")); my $window = $w->{window}; ############################ MAIN WINDOW ################################### # Set different options to Gtk2::Window unless ($::isEmbedded) { $w->{rwindow}->set_position('center'); $w->{rwindow}->set_title("DrakSec"); $window->set_size_request(598, 520); } # Connect the signals $window->signal_connect('delete_event', sub { $window->destroy }); $window->signal_connect('destroy', sub { ugtk2->exit }); $window->add(my $vbox = gtkshow(gtknew('VBox'))); # Create the notebook (for bookmarks at the top) my $notebook = create_notebook(); my $common_opts = { col_spacings => 10, row_spacings => 5, mcc => 1 }; ######################## BASIC OPTIONS PAGE ################################ my ($seclevel_entry, $secadmin_entry); $notebook->append_page(gtkshow(gtknew('VBox', children => [ 1, basic_seclevel_explanations(), 0, create_packtable($common_opts, [ do { my @sec_levels = security::level::get_common_list(); my $current_level = security::level::get_string(); push(@sec_levels, $current_level) unless member($current_level, @sec_levels); $seclevel_entry = new_nonedit_combo(\@sec_levels, $current_level); gtknew('Label_Left', text => N("Security Level:")), $seclevel_entry; } ], [ gtknew('Label_Left', text => N("Security Alerts:")), my $secadmin_check = gtksignal_connect(gtknew('CheckButton'), toggled => sub { $secadmin_entry->set_sensitive($_[0]->get_active); }) ], [ gtknew('Label_Left', text => N("Security Administrator:")), $secadmin_entry = Gtk2::Entry->new_with_text($msec->get_check_value("MAIL_USER")) ]) ])), gtknew('Label', text => N("Basic options"))); if ($msec->get_check_value("MAIL_WARN") eq "yes") { $secadmin_check->set_active(1); } else { $secadmin_entry->set_sensitive(0); } ######################### NETWORK & SYSTEM OPTIONS ######################### my @yesno_choices = qw(yes no default ignore); my @alllocal_choices = qw(ALL LOCAL NONE default); my @all_choices = (@yesno_choices, @alllocal_choices); my %options_values; foreach ([ 'network', N("Network Options") ], [ 'system', N("System Options") ]) { my ($domain, $label) = @$_; register_help_page($label); my %values; gtkappend_page($notebook, gtkshow(gtknew('VBox', children => [ 1, create_scrolled_window(create_packtable($common_opts, map { my $i = $_; my $entry; my $opt = $inv_fields{$i} || $i; my $default = $msec->get_function_default($opt); if (member($default, @all_choices)) { $values{$i} = new_nonedit_combo(member($default, @yesno_choices) ? \@yesno_choices : if_(member($default, @alllocal_choices), \@alllocal_choices)); $entry = $values{$i}->entry; } else { $values{$i} = gtknew('Entry'); $entry = $values{$i}; } $entry->set_text(to_i18n($msec->get_function_value($opt))); register_help_entry($i, $default, $opt); [ gtknew('Label_Left', line_wrap => 1, text => $i), resize($values{$i}) ]; } sort map { $fields{$_} || $_ } $msec->list_functions($domain), ), [ 'never', 'automatic' ], ), ]) ), gtknew('Label_Left', text => $label)); $options_values{$domain} = \%values; } ######################## PERIODIC CHECKS ################################### my %security_checks_value; my $check_string = N("Periodic Checks"); register_help_page($check_string); gtkappend_page($notebook, gtkshow(gtknew('VBox', children => [ 1, create_scrolled_window(create_packtable($common_opts, map { my $i = $_; my $opt = $inv_fields{$i} || $i; $security_checks_value{$i} = new_nonedit_combo([ 'yes', 'no', 'default' ], $msec->get_check_value($opt)); register_help_entry($i, $msec->get_check_default($opt), $opt); [ gtkshow(gtknew('Label_Left', line_wrap => 1, text => $i)), resize($security_checks_value{$i}) ]; } sort map { $fields{$_} || $_ } $msec->list_checks)) ])), gtknew('Label', text => $check_string)); ####################### OK CANCEL BUTTONS ################################## gtkpack_($vbox, 1, gtkshow($notebook), 0, create_okcancel(my $oc = { cancel_clicked => sub { ugtk2->exit(0) }, ok_clicked => sub { my $seclevel_value = $seclevel_entry->entry->get_text; my $secadmin_check_value = $secadmin_check->get_active; my $secadmin_value = $secadmin_entry->get_text; my $w; log::explanations("Configuring msec"); if ($seclevel_value ne security::level::get_string()) { $w = wait_msg(N("Please wait, setting security level...")); log::explanations(qq(Setting security level to "$seclevel_value")); security::level::set(security::level::from_string($seclevel_value)); remove_wait_msg($w); } $w = wait_msg(N("Please wait, setting security options...")); log::explanations(qq(Setting security administrator option to ") . bool2yesno($secadmin_check_value) . '"'); $msec->set_check('MAIL_WARN', bool2yesno($secadmin_check_value)); if ($secadmin_value ne $msec->get_check_value('MAIL_USER') && $secadmin_check_value) { log::explanations(qq(Setting security administrator contact to "$secadmin_value")); $msec->set_check('MAIL_USER', $secadmin_value); } log::explanations("Setting security periodic checks"); foreach my $key (keys %security_checks_value) { $msec->set_check($inv_fields{$key} || $key, from_i18n($security_checks_value{$key}->entry->get_text)); } $msec->apply_checks; foreach my $domain (keys %options_values) { log::explanations("Setting msec functions related to $domain"); foreach my $key (keys %{$options_values{$domain}}) { my $opt = $options_values{$domain}{$key}; $msec->set_function($inv_fields{$key} || $key, from_i18n($opt->get_text)); } } $msec->apply_functions; log::explanations("Applying msec changes"); run_program::run("/usr/sbin/msec"); remove_wait_msg($w); if ($secadmin_value ne $msec->get_check_value('CHKROOTKIT_CHECK')) { $in->do_pkgs->ensure_is_installed_if_available('chkrootkit', '/usr/sbin/chkrootkit'); } ugtk2->exit(0); } }, undef, undef, '', [ N("Help"), sub { my $text = gtknew('TextView'); create_dialog(N("Help"), gtktext_insert($text, [ # -1 b/c of main page: @{$help[$notebook->get_current_page-1]} ] ), { use_markup => 1, transient => $w->{real_window}, height => 400, width => 600, scroll => 1, }, ); } ], ), ); $notebook->signal_connect("switch-page" => sub { $oc->{buttons}{N("Help")}->set_sensitive($_[2]) }); $oc->{buttons}{N("Help")}->set_sensitive(0); $oc->{cancel}->can_default(1); $oc->{cancel}->grab_default; $in->do_pkgs->ensure_is_installed('msec', '/usr/sbin/msec'); $w->main; ugtk2->exit(0);