summaryrefslogtreecommitdiffstats
path: root/bin/drakvpn
diff options
context:
space:
mode:
Diffstat (limited to 'bin/drakvpn')
-rw-r--r--bin/drakvpn1136
1 files changed, 1136 insertions, 0 deletions
diff --git a/bin/drakvpn b/bin/drakvpn
new file mode 100644
index 0000000..09ddae8
--- /dev/null
+++ b/bin/drakvpn
@@ -0,0 +1,1136 @@
+#!/usr/bin/perl
+
+#
+# author Florin Grad (florin@mandrakesoft.com)
+#
+# Copyright 2005 Mandriva
+#
+# 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 lib qw(/usr/lib/libDrakX);
+
+use standalone; #- warning, standalone must be loaded very first, for 'explanations'
+
+use common;
+use detect_devices;
+use interactive;
+use network::network;
+use log;
+use c;
+use network::netconnect;
+use network::shorewall;
+use network::ipsec;
+use Data::Dumper;
+
+$::isInstall and die "Not supported during install.\n";
+
+
+local $_ = join '', @ARGV;
+
+$::Wizard_pix_up = "drakvpn.png";
+$ugtk2::wm_icon = "drakvpn";
+
+my $direct = /-direct/;
+
+my ($kernel_version) = c::kernel_version() =~ /(...)/;
+log::l("[drakvpn] kernel_version $kernel_version");
+
+$kernel_version >= 2.4 or fatal_quit(N("Sorry, we support only 2.4 and above kernels."));
+
+my $tunnels_file = "/etc/shorewall/tunnels";
+my $ipsec_conf = "";
+my $racoon_conf = "/etc/racoon/racoon.conf";
+my $proc_version = "";
+my $ipsec_package = "";
+
+my $in = interactive->vnew('su');
+my $shorewall = network::shorewall::read($in);
+my @section_names;
+
+if ($kernel_version > 2.5) {
+ $ipsec_conf = "/etc/ipsec.conf";
+} else {
+ $ipsec_conf = "/etc/freeswan/ipsec.conf";
+}
+my $ipsec = network::ipsec::read_ipsec_conf($ipsec_conf,$kernel_version);
+my $racoon = network::ipsec::read_racoon_conf($racoon_conf);
+
+#print network::ipsec::display_ipsec_conf($ipsec_conf,$ipsec,$kernel_version);
+
+$::Wizard_title = N("DrakVPN");
+
+$in->isa('interactive::gtk') and $::isWizard = 1;
+
+my $wait_configuring;
+
+sub fatal_quit ($) {
+ log::l("[drakvpn] FATAL: $_[0]");
+ undef $wait_configuring;
+ $in->ask_warn('', $_[0]);
+ quit_global($in, -1);
+}
+
+begin:
+
+#- **********************************
+#- * 0th step: verify if we are already set up
+
+if ($shorewall && any { !/^\s*(?:#|\n)/ } cat_($tunnels_file)) {
+ $::Wizard_no_previous = 1;
+
+ if (!$shorewall->{disabled}) {
+ my $r = $in->ask_from_list_(N("The VPN connection is enabled."),
+N("The setup of a VPN connection has already been done.
+
+It's currently enabled.
+
+What would you like to do?"),
+ [ N_("disable"), N_("reconfigure"), N_("dismiss") ]) or quit_global($in, 0);
+ # FIXME: reconfigure is not handled
+ if ($r eq "disable") {
+ if (!$::testing) {
+ my $_wait_disabl = $in->wait_message('', N("Disabling VPN..."));
+ network::ipsec::stop_daemons();
+ }
+ foreach ($ipsec_conf, $tunnels_file) {
+ if (-f $_) { rename($_, "$_.drakvpndisable") or die "Could not rename $_ to $_.drakvpndisable" }
+ }
+ network::ipsec::sys("/etc/init.d/shorewall restart >/dev/null");
+ log::l("[drakvpn] Disabled");
+ $::Wizard_finished = 1;
+ $in->ask_okcancel('', N("The VPN connection is now disabled."));
+ quit_global($in, 0);
+ }
+ if ($r eq "dismiss") {
+ quit_global($in, 0);
+ }
+ } else {
+ my $r = $in->ask_from_list_(N("VPN connection currently disabled"),
+N("The setup of a VPN connection has already been done.
+
+It's currently disabled.
+
+What would you like to do?"),
+ [ N_("enable"), N_("reconfigure"), N_("dismiss") ]);
+ # FIXME: reconfigure is not handled
+ if ($r eq "enable") {
+ foreach ($ipsec_conf, $tunnels_file) {
+ rename($_, "$_.old") if -f $_;
+ rename("$_.drakvpndisable", $_) or die "Could not find configuration. Please reconfigure.";
+ }
+ {
+ my $_wait_enabl = $in->wait_message('', N("Enabling VPN..."));
+ network::ipsec::start_daemons();
+ }
+ log::l("[drakvpn] Enabled");
+ }
+ $::Wizard_finished = 1;
+ $in->ask_okcancel('', N("The VPN connection is now enabled."));
+ quit_global($in, 0);
+ if ($r eq "dismiss") {
+ quit_global($in, 0);
+ }
+ }
+ }
+
+#- **********************************
+#- * 1st step: detect/setup
+step_ask_confirm:
+
+$::Wizard_no_previous = 1;
+
+$direct or $in->ask_okcancel(N("Simple VPN setup."),
+N("You are about to configure your computer to use a VPN connection.
+
+With this feature, computers on your local private network and computers
+on some other remote private networks, can share resources, through
+their respective firewalls, over the Internet, in a secure manner.
+
+The communication over the Internet is encrypted. The local and remote
+computers look as if they were on the same network.
+
+Make sure you have configured your Network/Internet access using
+drakconnect before going any further."), 1) or goto begin;
+
+undef $::Wizard_no_previous;
+
+if ($kernel_version < 2.5) {
+ system("/sbin/modprobe ipsec") if -e "/sbin/modprobe";
+ $proc_version = cat_("/proc/net/ipsec_version") if -e "/proc/net/ipsec_version";
+ if ($proc_version =~ /super/i) {
+ $ipsec_package = "super-freeswan";
+ } else {
+ $ipsec_package = "freeswan";
+ }
+} else {
+ $ipsec_package = "ipsec-tools";
+ $proc_version = "ipsec native";
+}
+
+$direct or $in->ask_okcancel(N("Simple VPN setup."),
+N("VPN connection.
+
+This program is based on the following projects:
+ - FreeSwan: \t\t\thttp://www.freeswan.org/
+ - Super-FreeSwan: \t\thttp://www.freeswan.ca/
+ - ipsec-tools: \t\t\thttp://ipsec-tools.sourceforge.net/
+ - ipsec-howto: \t\thttp://www.ipsec-howto.org
+ - the docs and man pages coming with the %s package
+
+Please read AT LEAST the ipsec-howto docs
+before going any further.",$ipsec_package)) or goto begin;
+
+$direct or $in->ask_okcancel(N("Kernel module."),
+N("The kernel needs to have ipsec support.
+
+You're running a %s kernel version.
+
+This kernel has '%s' support.", $kernel_version, $proc_version)) or goto begin;
+
+step_detectsetup:
+
+#my @configured_devices = map { /ifcfg-(\S+)/ } glob('/etc/sysconfig/network-scripts/ifcfg*');
+
+my %aliased_devices;
+/^\s*alias\s+(eth[0-9])\s+(\S+)/ and $aliased_devices{$1} = $2 foreach cat_("/etc/modules.conf");
+
+#- **********************************
+#- * 2nd step: configure
+
+#$wait_configuring = $in->wait_message(N("Configuring..."),
+# N("Configuring scripts, installing software, starting servers..."));
+
+#- if the kernel has super-freeswan support, remove the freeswan package
+#- and vice-versa
+#- if you're using e kernel 2.5 and above with native ipsec support, remove
+#- both freeswan and super-freeswan packages
+
+if (!$::testing && $ipsec_package =~ /super/i && $kernel_version < 2.5) {
+ log::l("[drakvpn] removing the freeswan package");
+ $in->do_pkgs->remove("freeswan") if -e "/etc/freeswan/ipsec.d/policies/clear";
+ log::l("[drakvpn] removing the ipsec-tools package");
+ $in->do_pkgs->remove("ipsec-tools") if -e "/sbin/setkey";
+ $in->do_pkgs->remove("libipsec-tools0") if -e "/lib/libipsec.so.0";
+} elsif (!$::testing && $kernel_version < 2.5) {
+ log::l("[drakvpn] removing the $ipsec_package package");
+ $in->do_pkgs->remove("super-freeswan") if -e "/usr/lib/ipsec/auto.advroute";
+ log::l("[drakvpn] removing the ipsec-tools package");
+ $in->do_pkgs->remove("ipsec-tools") if -e "/sbin/setkey";
+ $in->do_pkgs->remove("libipsec-tools0") if -e "/sbin/setkey";
+} else {
+ log::l("[drakvpn] removing the freeswan AND the super-freeswan packages");
+ $in->do_pkgs->remove("freeswan") if -e "/etc/freeswan/ipsec.d/policies/clear";
+ $in->do_pkgs->remove("super-freeswan-doc") if -e "/usr/sbin/ipsec";
+ $in->do_pkgs->remove("super-freeswan") if -e "/usr/lib/ipsec/auto.advroute";
+}
+
+
+#- install and setup the RPM packages, if needed
+
+my %rpm2file;
+log::l("[drakvpn] install the $ipsec_package and the shorewall rpm packages");
+if (!$::testing && $ipsec_package =~ /ipsec-tools/i) {
+ %rpm2file = ($ipsec_package => '/sbin/setkey',
+ shorewall => '/sbin/shorewall');
+} else {
+ %rpm2file = ($ipsec_package => '/usr/sbin/ipsec',
+ shorewall => '/sbin/shorewall');
+}
+
+#- first: try to install all in one step, if needed
+if (! ($ipsec_package =~ /super/i && -e "/usr/lib/ipsec/auto.advroute" ||
+ $ipsec_package =~ /^freeswan/i && -e "/etc/freeswan/ipsec.d/policies/clear" ||
+ $ipsec_package =~ /ipsec-tools/i && -e "/sbin/setkey")) {
+
+ my @needed_to_install = grep { !-e $rpm2file{$_} } keys %rpm2file;
+ @needed_to_install and $in->do_pkgs->install(@needed_to_install) if !$::testing;
+ #- second: try one by one if failure detected
+ if (!$::testing && any { !-e $rpm2file{$_} } keys %rpm2file) {
+ foreach (keys %rpm2file) {
+ -e $rpm2file{$_} or $in->do_pkgs->install($_);
+ -e $rpm2file{$_} or fatal_quit(N("Problems installing package %s", $_));
+ }
+ }
+}
+
+undef $wait_configuring;
+
+#- configure the $ipsec_conf file
+#- Add, Remove config|conn entries
+
+step_configuration:
+
+my $c;
+
+my %messages = (ipsec => N("Security Policies"), racoon => N("IKE daemon racoon"));
+
+if ($kernel_version > 2.5) {
+ $in->ask_from(N("Configuration file"),
+N("Configuration step!
+
+You need to define the Security Policies and then to
+configure the automatic key exchange (IKE) daemon.
+The KAME IKE daemon we're using is called 'racoon'.
+
+What would you like to configure?\n"),
+ [ { val => \$c, type => "list", list => [ keys %messages ], format => sub { $messages{$_[0]} } } ]) or goto step_detectsetup;
+
+} else {
+$in->ask_okcancel(N("Configuration file"),
+N("Next, we will configure the %s file.\n
+
+Simply click on Next.\n", $ipsec_conf)) or goto step_detectsetup;
+
+ $c = "configure";
+}
+
+#-------------------------------------------------------------------
+#---------------------- configure ipsec_conf -----------------------
+#-------------------------------------------------------------------
+
+if ($c eq "ipsec" || $c eq "configure") {
+
+step_configure_ipsec_conf:
+
+@section_names = network::ipsec::get_section_names_ipsec_conf($ipsec,$kernel_version) if $ipsec;
+
+my $choice = $section_names[0];
+my $d = $in->ask_from_list_(N("%s entries", $ipsec_conf),
+N("The %s file contents
+is divided into sections.\n
+You can now:\n
+ - display, add, edit, or remove sections, then
+ - commit the changes
+
+What would you like to do?\n", $ipsec_conf),
+ [ N_("_:display here is a verb\nDisplay"), N_("Add"), N_("Edit"), N_("Remove"), N_("Commit") ]) or goto step_configuration;
+
+my $existing_section = "";
+
+#- display $ipsec_conf -------------------------
+
+step_display_ipsec_conf:
+
+if ($d eq "display $ipsec_conf" || $d eq "_:display here is a verb\nDisplay") {
+ my $ipsec_exists = 0;
+ foreach my $key (keys %$ipsec) {
+ $ipsec_exists = 1 if $ipsec->{$key};
+ }
+ if ($ipsec_exists) {
+ $in->ask_okcancel(N("_:display here is a verb\nDisplay configuration"),
+ network::ipsec::display_ipsec_conf($ipsec,$kernel_version));
+ goto step_configure_ipsec_conf;
+ } else {
+$in->ask_okcancel(N("_:display here is a verb\nDisplay configuration"),
+N("The %s file does not exist.\n
+This must be a new configuration.\n
+You'll have to go back and choose 'add'.\n", $ipsec_conf));
+ goto step_configure_ipsec_conf;
+ }
+
+#- add ---------------------
+
+} elsif ($d eq "Add") {
+
+step_add_section:
+
+if ($kernel_version < 2.5) {
+
+#- add ---- kernel 2.4 part -------------------------------
+
+my $e = $in->ask_from_list_(N("ipsec.conf entries"),
+N("The %s file contains different sections.\n
+Here is its skeleton: 'config setup'
+ 'conn default'
+ 'normal1'
+ 'normal2' \n
+You can now add one of these sections.\n
+Choose the section you would like to add.\n", $ipsec_conf),
+ [ N_("config setup"), N_("conn %default"), N_("normal conn"), N_("dismiss") ]) or goto step_configure_ipsec_conf;
+ if ($e eq "config setup") {
+
+ $existing_section = network::ipsec::already_existing_section_ipsec_conf("config setup", $ipsec, $kernel_version);
+
+ if ($existing_section eq "already existing") {
+$in->ask_okcancel(N("Exists!"),
+N("A section with this name already exists.
+The section names have to be unique.\n
+You'll have to go back and add another section
+or change its name.\n"));
+ goto step_add_section;
+}
+
+ my $config_setup = {
+ 1 => [ "config", "setup" ],
+ 2 => [ "interfaces", "%defaultroute" ],
+ 3 => [ "klipsdebug", "none" ],
+ 4 => [ "plutodebug", "none" ],
+ 5 => [ "plutoload", "%search" ],
+ 6 => [ "plutostart", "%search" ],
+ 7 => [ "uniqueids", "yes" ],
+ };
+ $in->ask_from('',
+N("This section has to be on top of your
+%s file.\n
+Make sure all other sections follow this config
+setup section.\n
+Choose continue or previous when you are done.\n", $ipsec_conf),
+ [ { label => N("interfaces"), val => \$config_setup->{2}[1], type => 'entry' },
+ { label => N("klipsdebug"), val => \$config_setup->{3}[1], type => 'entry' },
+ { label => N("plutodebug"), val => \$config_setup->{4}[1], type => 'entry' },
+ { label => N("plutoload"), val => \$config_setup->{5}[1], type => 'entry' },
+ { label => N("plutostart"), val => \$config_setup->{6}[1], type => 'entry' },
+ { label => N("uniqueids"), val => \$config_setup->{7}[1], type => 'entry' },
+ ]
+) or goto step_configure_ipsec_conf;
+
+ network::ipsec::add_section_ipsec_conf($config_setup, $ipsec);
+
+ goto step_configure_ipsec_conf;
+
+ } elsif ($e eq "conn %default") {
+
+ $existing_section = network::ipsec::already_existing_section_ipsec_conf("conn %default", $ipsec, $kernel_version);
+
+ if ($existing_section eq "already existing") {
+$in->ask_okcancel(N("Exists!"),
+N("A section with this name already exists.
+The section names have to be unique.\n
+You'll have to go back and add another section
+or change its name.\n"));
+ goto step_add_section;
+}
+
+ my $conn_default = {
+ 1 => [ "conn", "%default" ],
+ 2 => [ "pfs", "yes" ],
+ 3 => [ "keyingtries", "1" ],
+ 4 => [ "compress", "yes" ],
+ 5 => [ "disablearrivalcheck", "no" ],
+ 6 => [ "left", "" ],
+ 7 => [ "leftcert", "" ],
+ 8 => [ "leftrsasigkey", "%cert" ],
+ 9 => [ "leftsubnet", "" ],
+ 10 => [ "leftnexthop", "" ],
+ };
+ $in->ask_from('',
+N("This is the first section after the config
+setup one.\n
+Here you define the default settings.
+All the other sections will follow this one.
+The left settings are optional. If do not define
+them here, globally, you can define them in each
+section.\n",),
+ [ { label => N("PFS"), val => \$conn_default->{2}[1], type => 'entry' },
+ { label => N("keyingtries"), val => \$conn_default->{3}[1], type => 'entry' },
+ { label => N("compress"), val => \$conn_default->{4}[1], type => 'entry' },
+ { label => N("disablearrivalcheck"), val => \$conn_default->{5}[1], type => 'entry' },
+ { label => N("left"), val => \$conn_default->{6}[1], type => 'entry' },
+ { label => N("leftcert"), val => \$conn_default->{7}[1], type => 'entry' },
+ { label => N("leftrsasigkey"), val => \$conn_default->{8}[1], type => 'entry' },
+ { label => N("leftsubnet"), val => \$conn_default->{9}[1], type => 'entry' },
+ { label => N("leftnexthop"), val => \$conn_default->{10}[1], type => 'entry' },
+ ]
+) or goto step_configure_ipsec_conf;
+
+ network::ipsec::add_section_ipsec_conf($conn_default, $ipsec);
+
+ goto step_configure_ipsec_conf;
+
+ } elsif ($e eq "normal conn") {
+
+
+ my $normal_conn = {
+ 1 => [ "conn", "my-connection" ],
+ 2 => [ "authby", "rsasig" ],
+ 3 => [ "auto", "start" ],
+ 4 => [ "left", "" ],
+ 5 => [ "leftcert", "" ],
+ 6 => [ "leftrsasigkey", "%cert" ],
+ 7 => [ "leftsubnet", "" ],
+ 8 => [ "leftnexthop", "" ],
+ 9 => [ "right", "" ],
+ 10 => [ "rightcert", "" ],
+ 11 => [ "rightrsasigkey", "%cert" ],
+ 12 => [ "rightsubnet", "" ],
+ 13 => [ "rightnexthop", "" ],
+ };
+
+step_add_normal_conn:
+ $in->ask_from('',
+N("Your %s file has several sections, or connections.\n
+You can now add a new section.
+Choose continue when you are done to write the data.\n", $ipsec_conf),
+ [ { label => N("section name"), val => \$normal_conn->{1}[1], type => 'entry' },
+ { label => N("authby"), val => \$normal_conn->{2}[1], type => 'entry' },
+ { label => N("auto"), val => \$normal_conn->{3}[1], type => 'entry' },
+ { label => N("left"), val => \$normal_conn->{4}[1], type => 'entry' },
+ { label => N("leftcert"), val => \$normal_conn->{5}[1], type => 'entry' },
+ { label => N("leftrsasigkey"), val => \$normal_conn->{6}[1], type => 'entry' },
+ { label => N("leftsubnet"), val => \$normal_conn->{7}[1], type => 'entry' },
+ { label => N("leftnexthop"), val => \$normal_conn->{8}[1], type => 'entry' },
+ { label => N("right"), val => \$normal_conn->{9}[1], type => 'entry' },
+ { label => N("rightcert"), val => \$normal_conn->{10}[1], type => 'entry' },
+ { label => N("rightrsasigkey"), val => \$normal_conn->{11}[1], type => 'entry' },
+ { label => N("rightsubnet"), val => \$normal_conn->{12}[1], type => 'entry' },
+ { label => N("rightnexthop"), val => \$normal_conn->{13}[1], type => 'entry' },
+ ]
+) or goto step_configure_ipsec_conf;
+
+ $existing_section = network::ipsec::already_existing_section_ipsec_conf($normal_conn->{1}[0] . " " . $normal_conn->{1}[1], $ipsec, $kernel_version);
+
+ if ($existing_section eq "already existing") {
+$in->ask_okcancel(N("Exists!"),
+N("A section with this name already exists.
+The section names have to be unique.\n
+You'll have to go back and add another section
+or change the name of the section.\n"));
+ goto step_add_normal_conn;
+}
+
+ network::ipsec::add_section_ipsec_conf($normal_conn, $ipsec);
+
+ goto step_configure_ipsec_conf;
+
+ }
+
+} else {
+
+#- add ---- kernel 2.6 part -------------------------------
+
+ my $section = { command => 'spdadd',
+ src_range => 'src_network_address',
+ dst_range => 'dest_network_address',
+ upperspec => 'any',
+ flag => '-P',
+ direction => 'in or out',
+ ipsec => 'ipsec',
+ protocol => 'esp',
+ mode => 'tunnel',
+ src_dest => 'source-destination',
+ level => 'require' };
+
+step_add_section_ipsec_conf_k26:
+
+ ask_info3('',
+N("Add a Security Policy.\n
+You can now add a Security Policy.\n
+Choose continue when you are done to write the data.\n"), $section) or goto step_configure_ipsec_conf;
+
+# $existing_section = network::ipsec::already_existing_section_ipsec_conf($section->{src_dest}, $ipsec, $kernel_version);
+#
+# if ($existing_section eq "already existing") {
+#$in->ask_okcancel(N("Exists!"),
+#N("A section with this name already exists.
+#The section names have to be unique.\n
+#You'll have to go back and add another section
+#or change the name of the section.\n"));
+# goto step_add_section_ipsec_conf_k26;
+#};
+
+ if (!$ipsec->{1}) {
+ put_in_hash($ipsec, { max(keys %$ipsec) + 1 => "#!/sbin/setkey -f" });
+ put_in_hash($ipsec, { max(keys %$ipsec) + 1 => "flush;" });
+ put_in_hash($ipsec, { max(keys %$ipsec) + 1 => "spdflush;" });
+ }
+
+ network::ipsec::add_section_ipsec_conf($section, $ipsec);
+
+ @section_names = network::ipsec::get_section_names_ipsec_conf($ipsec,$kernel_version);
+
+ goto step_configure_ipsec_conf;
+}
+
+#- edit ---------------------
+
+} elsif ($d eq "Edit") {
+
+step_edit_ipsec_conf:
+$in->ask_from(N("Edit section"),
+N("Your %s file has several sections or connections.\n
+You can choose here below the one you want to edit
+and then click on next.\n", $ipsec_conf),
+ [ { val => \$choice, list => \@section_names, label => N("Section names"), sort => 0, not_edit => 0 } ])
+ or goto step_configure_ipsec_conf;
+
+my $number = network::ipsec::matched_section_key_number_ipsec_conf($choice,$ipsec,$kernel_version);
+
+#- edit ---- kernel 2.4 part -------------------------------
+
+if ($kernel_version < 2.5) {
+if ($choice =~ /^version|block|private|clear|packet/) {
+
+$in->ask_okcancel(N("Can not edit!"),
+N("You cannot edit this section.\n
+This section is mandatory for Freeswan 2.X.
+One has to specify version 2.0 on the top
+of the %s file, and eventually, disable or
+enable the opportunistic encryption.\n",$ipsec_conf));
+ goto step_edit_ipsec_conf;
+
+} elsif ($choice =~ /^config setup/) {
+ $in->ask_from('',
+N("Your %s file has several sections.\n
+You can now edit the config setup section entries.
+Choose continue when you are done to write the data.\n", $ipsec_conf),
+
+[ network::ipsec::dynamic_list($number, $ipsec) ]
+
+) or goto step_configure_ipsec_conf;
+
+ goto step_configure_ipsec_conf;
+} elsif ($choice =~ /^conn %default/) {
+ $in->ask_from('',
+N("Your %s file has several sections or connections.\n
+You can now edit the default section entries.
+Choose continue when you are done to write the data.\n", $ipsec_conf),
+
+[ network::ipsec::dynamic_list($number, $ipsec) ]
+
+) or goto step_configure_ipsec_conf;
+
+ goto step_configure_ipsec_conf;
+
+} elsif ($choice =~ /^conn/) {
+
+ $in->ask_from('',
+N("Your %s file has several sections or connections.\n
+You can now edit the normal section entries.\n
+Choose continue when you are done to write the data.\n", $ipsec_conf),
+
+[ network::ipsec::dynamic_list($number, $ipsec) ]
+
+) or goto step_configure_ipsec_conf;
+
+ goto step_configure_ipsec_conf;
+
+} else {
+
+ goto step_configure_ipsec_conf;
+
+}
+
+#- edit ---- kernel 2.6 part -------------------------------
+
+} else {
+
+ ask_info3('',
+N("Edit a Security Policy.\n
+You can now edit a Security Policy.\n
+Choose continue when you are done to write the data.\n"), $ipsec->{$number}) or goto step_configure_ipsec_conf;
+
+goto step_configure_ipsec_conf;
+
+}
+
+#- remove ---------------------
+
+} elsif ($d eq "Remove") {
+$in->ask_from(N("Remove section"),
+N("Your %s file has several sections or connections.\n
+You can choose here below the one you want to remove
+and then click on next.\n", $ipsec_conf),
+ [ { val => \$choice, list => \@section_names, label => N("Section names"), sort => 0, not_edit => 0 } ]);
+
+ network::ipsec::remove_section_ipsec_conf($choice,$ipsec,$kernel_version);
+
+ @section_names = network::ipsec::get_section_names_ipsec_conf($ipsec,$kernel_version) if $ipsec;
+
+ goto step_configure_ipsec_conf;
+
+#- continue and write ---------------------
+
+} elsif ($d eq "Commit") {
+ log::l("[drakvpn] Modify the $ipsec_conf file");
+ network::ipsec::write_ipsec_conf($ipsec_conf, $ipsec,$kernel_version);
+ }
+#-------------------------------------------------------------------
+#---------------------- configure racoon_conf -----------------------
+#-------------------------------------------------------------------
+
+} elsif ($c eq "racoon") {
+
+step_configure_racoon_conf:
+
+@section_names = network::ipsec::get_section_names_racoon_conf($racoon) if $racoon;
+
+my $choice = $section_names[0];
+my $d = $in->ask_from_list_(N("%s entries", $racoon_conf),
+N("The racoon.conf file configuration.\n
+The contents of this file is divided into sections.
+You can now:
+ - display \t\t (display the file contents)
+ - add \t\t (add one section)
+ - edit \t\t\t (modify parameters of an existing section)
+ - remove \t\t (remove an existing section)
+ - commit \t\t (writes the changes to the real file)"),
+ [ N_("_:display here is a verb\nDisplay"), N_("Add"), N_("Edit"), N_("Remove"), N_("Commit") ]) or goto step_configuration;
+
+
+#- display $racoon_conf -------------------------
+
+step_display_racoon_conf:
+
+if ($d eq "_:display here is a verb\nDisplay") {
+
+ my $racoon_exists = 0;
+ foreach my $key (keys %$racoon) {
+ $racoon_exists = 1 if $racoon->{$key};
+ }
+
+ if ($racoon_exists) {
+ $in->ask_okcancel(N("_:display here is a verb\nDisplay configuration"),
+ network::ipsec::display_racoon_conf($racoon));
+ goto step_configure_racoon_conf;
+ } else {
+$in->ask_okcancel(N("_:display here is a verb\nDisplay configuration"),
+N("The %s file does not exist\n
+This must be a new configuration.\n
+You'll have to go back and choose configure.\n", $racoon_conf));
+ goto step_configure_racoon_conf;
+ }
+
+#- add $racoon_conf ------------------------------
+
+} elsif ($d eq "Add") {
+
+step_add_section_racoon:
+
+#my $existing_section = "";
+
+my $e = $in->ask_from_list_(N("racoonf.conf entries"),
+N("The 'add' sections step.\n
+Here below is the racoon.conf file skeleton:
+\t'path'
+\t'remote'
+\t'sainfo' \n
+Choose the section you would like to add.\n"),
+ [ N_("path"), N_("remote"), N_("sainfo"), N_("dismiss") ]) or goto step_configure_racoon_conf;
+if ($e eq "path") {
+
+ my $path_section = {
+ 1 => [ 'path', 'path_type', '"/etc/racoon/certs"' ],
+ };
+
+ $in->ask_from('',
+N("The 'add path' section step.\n
+The path sections have to be on top of your racoon.conf file.\n
+Put your mouse over the certificate entry to obtain online help."),
+ [ { label => N("path type"),
+ val => \$path_section->{1}[1],
+ list => [ 'certificate', 'pre_shared_key', 'include' ],
+ help =>
+N("path include path: specifies a path to include
+a file. See File Inclusion.
+ Example: path include '/etc/racoon'
+
+path pre_shared_key file: specifies a file containing
+pre-shared key(s) for various ID(s). See Pre-shared key File.
+ Example: path pre_shared_key '/etc/racoon/psk.txt' ;
+
+path certificate path: racoon(8) will search this directory
+if a certificate or certificate request is received.
+ Example: path certificate '/etc/cert' ;
+
+File Inclusion: include file
+other configuration files can be included.
+ Example: include \"remote.conf\" ;
+
+Pre-shared key File: Pre-shared key file defines a pair
+of the identifier and the shared secret key which are used at
+Pre-shared key authentication method in phase 1."),
+},
+ { label => N("real file"), val => \$path_section->{1}[2], type => 'entry' },
+ ]
+) or goto step_configure_racoon_conf;
+
+network::ipsec::add_section_racoon_conf($path_section, $racoon);
+} elsif ($e eq "remote") {
+ my $main_remote_section = { 1 => [ 'remote', 'address' ],
+ 2 => [ 'exchange_mode', 'aggressive,main' ],
+ 3 => [ 'generate_policy', 'on' ],
+ 4 => [ 'passive', 'on' ],
+ 5 => [ 'certificate_type', 'x509', '"my_certificate.pem"', '"my_private_key.pem"' ],
+ 6 => [ 'peers_certfile', '"remote.public"' ],
+ 7 => [ 'verify_cert', 'on' ],
+ 8 => [ 'my_identifier', 'asn1dn' ],
+ 9 => [ 'peers_identifier', 'asn1dn' ]
+ };
+ my $proposal_remote_section = { 1 => [ 'proposal' ],
+ 2 => [ 'encryption_algorithm', '3des' ],
+ 3 => [ 'hash_algorithm', 'md5' ],
+ 4 => [ 'authentication_method', 'rsasig' ],
+ 5 => [ 'dh_group', 'modp1024' ]
+ };
+ ask_info2('',
+N("Make sure you already have the path sections
+on the top of your racoon.conf file.
+
+You can now choose the remote settings.
+Choose continue or previous when you are done.\n"), $main_remote_section, $proposal_remote_section) or goto step_configure_racoon_conf;
+
+network::ipsec::add_section_racoon_conf($main_remote_section, $racoon);
+network::ipsec::add_section_racoon_conf($proposal_remote_section, $racoon);
+} elsif ($e eq "sainfo") {
+ my $sainfo_section = { 1 => [ 'sainfo', 'address', '192.168.100.2', 'any', 'address', '10.0.0.2', 'any' ],
+ 2 => [ 'pfs_group', '1' ],
+ 3 => [ 'lifetime', 'time', '30', 'sec' ],
+ 4 => [ 'encryption_algorithm', '3des' ],
+ 5 => [ 'authentication_algorithm', 'hmac_sha1' ],
+ 6 => [ 'compression_algorithm', 'deflate' ],
+ };
+ ask_info('',
+N("Make sure you already have the path sections
+on the top of your %s file.
+
+You can now choose the sainfo settings.
+Choose continue or previous when you are done.\n", $racoon_conf), $sainfo_section) or goto step_configure_racoon_conf;
+
+network::ipsec::add_section_racoon_conf($sainfo_section, $racoon);
+}
+
+@section_names = network::ipsec::get_section_names_racoon_conf($racoon) if $racoon;
+
+goto step_configure_racoon_conf;
+
+#- edit $racoon_conf -----------------------------
+
+} elsif ($d eq "Edit") {
+$in->ask_from(N("Edit section"),
+N("Your %s file has several sections or connections.
+
+You can choose here in the list below the one you want
+to edit and then click on next.\n", $racoon_conf),
+ [ { val => \$choice, list => \@section_names, label => N("Section names"), sort => 0, not_edit => 0 } ])
+ or goto step_configure_racoon_conf;
+
+my $number = network::ipsec::matched_section_key_number_racoon_conf($choice,$racoon);
+
+if ($choice =~ /^remote/) {
+ ask_info2('',
+N("Your %s file has several sections.\n
+
+You can now edit the remote section entries.
+
+Choose continue when you are done to write the data.\n", $racoon_conf), $racoon->{$number}, $racoon->{$number+2})
+ or goto step_configure_racoon_conf;
+
+} elsif ($choice =~ /^sainfo/) {
+ ask_info('',
+N("Your %s file has several sections.
+
+You can now edit the sainfo section entries.
+
+Choose continue when you are done to write the data.", $racoon_conf), $racoon->{$number}) or goto step_configure_racoon_conf;
+
+} elsif ($choice =~ /^path/) {
+ $in->ask_from('',
+N("This section has to be on top of your
+%s file.\n
+Make sure all other sections follow these path
+sections.\n
+You can now edit the path entries.
+
+Choose continue or previous when you are done.\n", $racoon_conf),
+ [ { label => N("path_type"), val => \$racoon->{$number}{1}[1], list => [ 'certificate', 'pre_shared_key', 'include' ] },
+ { label => N("real file"), val => \$racoon->{$number}{1}[2], type => 'entry' },
+ ]
+) or goto step_configure_racoon_conf;
+}
+
+goto step_configure_racoon_conf;
+
+#- remove $racoon_conf ---------------------------
+
+} elsif ($d eq "Remove") {
+$in->ask_from(N("Remove section"),
+N("Your %s file has several sections or connections.\n
+You can choose here below the one you want to remove
+and then click on next.\n", $racoon_conf),
+ [ { val => \$choice, list => \@section_names, label => N("Section names"), sort => 0, not_edit => 0 } ]);
+
+my $number = network::ipsec::matched_section_key_number_racoon_conf($choice,$racoon);
+network::ipsec::remove_section_racoon_conf($choice,$racoon,$number);
+ @section_names = network::ipsec::get_section_names_racoon_conf($racoon) if $racoon;
+
+ goto step_configure_racoon_conf;
+
+#- write $racoon_conf and continue ---------------
+} elsif ($d eq "Commit") {
+ log::l("[drakvpn] Modify the $racoon_conf file");
+ network::ipsec::write_racoon_conf($racoon_conf, $racoon);
+}
+}
+
+#- start the daemons
+network::ipsec::start_daemons();
+
+#- bye-bye message
+
+undef $wait_configuring;
+
+$::Wizard_no_previous = 1;
+$::Wizard_finished = 1;
+
+$in->ask_okcancel(N("Congratulations!"),
+N("Everything has been configured.\n
+You may now share resources through the Internet,
+in a secure way, using a VPN connection.
+
+You should make sure that that the tunnels shorewall
+section is configured."));
+
+log::l("[drakvpn] Installation complete, exiting");
+quit_global($in, 0);
+
+sub quit_global {
+ my ($in, $exitcode) = @_;
+ $in->exit($exitcode);
+ goto begin;
+}
+
+
+sub ask_info {
+ my ($title, $text, $data) = @_;
+ $in->ask_from($title, $text,
+ [ { label => N("Sainfo source address"), val => \$data->{1}[2], type => 'entry',
+ help => N("sainfo (source_id destination_id | anonymous) { statements }
+defines the parameters of the IKE phase 2
+(IPsec-SA establishment).
+
+source_id and destination_id are constructed like:
+
+ address address [/ prefix] [[port]] ul_proto
+
+Examples: \n
+sainfo anonymous (accepts connections from anywhere)
+ leave blank this entry if you want anonymous
+
+sainfo address 203.178.141.209 any address 203.178.141.218 any
+ 203.178.141.209 is the source address
+
+sainfo address 172.16.1.0/24 any address 172.16.2.0/24 any
+ 172.16.1.0/24 is the source address") },
+ { label => N("Sainfo source protocol"), val => \$data->{1}[3], type => 'entry',
+ help => N("sainfo (source_id destination_id | anonymous) { statements }
+defines the parameters of the IKE phase 2
+(IPsec-SA establishment).
+
+source_id and destination_id are constructed like:
+
+ address address [/ prefix] [[port]] ul_proto
+
+Examples: \n
+sainfo anonymous (accepts connections from anywhere)
+ leave blank this entry if you want anonymous
+
+sainfo address 203.178.141.209 any address 203.178.141.218 any
+ the first 'any' allows any protocol for the source") },
+ { label => N("Sainfo destination address"), val => \$data->{1}[5], type => 'entry',
+ help => N("sainfo (source_id destination_id | anonymous) { statements }
+defines the parameters of the IKE phase 2
+(IPsec-SA establishment).
+
+source_id and destination_id are constructed like:
+
+ address address [/ prefix] [[port]] ul_proto
+
+Examples: \n
+sainfo anonymous (accepts connections from anywhere)
+ leave blank this entry if you want anonymous
+
+sainfo address 203.178.141.209 any address 203.178.141.218 any
+ 203.178.141.218 is the destination address
+
+sainfo address 172.16.1.0/24 any address 172.16.2.0/24 any
+ 172.16.2.0/24 is the destination address") },
+ { label => N("Sainfo destination protocol"), val => \$data->{1}[6], type => 'entry',
+ help => N("sainfo (source_id destination_id | anonymous) { statements }
+defines the parameters of the IKE phase 2
+(IPsec-SA establishment).
+
+source_id and destination_id are constructed like:
+
+ address address [/ prefix] [[port]] ul_proto
+
+Examples: \n
+sainfo anonymous (accepts connections from anywhere)
+ leave blank this entry if you want anonymous
+
+sainfo address 203.178.141.209 any address 203.178.141.218 any
+ the last 'any' allows any protocol for the destination") },
+ { label => N("PFS group"), val => \$data->{2}[1],
+ list => [ qw(modp768 modp1024 modp1536 1 2 5) ],
+ help => N("define the group of Diffie-Hellman exponentiations.
+If you do not require PFS then you can omit this directive.
+Any proposal will be accepted if you do not specify one.
+group is one of the following: modp768, modp1024, modp1536.
+Or you can define 1, 2, or 5 as the DH group number.") },
+ { label => N("Lifetime number"), val => \$data->{3}[2], type => 'entry',
+ help => N("define a lifetime of a certain time which will be pro-
+posed in the phase 1 negotiations. Any proposal will be
+accepted, and the attribute(s) will not be proposed to
+the peer if you do not specify it(them). They can be
+individually specified in each proposal.
+
+Examples: \n
+ lifetime time 1 min; # sec,min,hour
+ lifetime time 1 min; # sec,min,hour
+ lifetime time 30 sec;
+ lifetime time 30 sec;
+ lifetime time 60 sec;
+ lifetime time 12 hour;
+
+So, here, the lifetime numbers are 1, 1, 30, 30, 60 and 12.
+") },
+ { label => N("Lifetime unit"), val => \$data->{3}[3],
+ list => [ qw(sec min hour) ],
+ help => N("define a lifetime of a certain time which will be pro-
+posed in the phase 1 negotiations. Any proposal will be
+accepted, and the attribute(s) will not be proposed to
+the peer if you do not specify it(them). They can be
+individually specified in each proposal.
+
+Examples: \n
+ lifetime time 1 min; # sec,min,hour
+ lifetime time 1 min; # sec,min,hour
+ lifetime time 30 sec;
+ lifetime time 30 sec;
+ lifetime time 60 sec;
+ lifetime time 12 hour;
+
+So, here, the lifetime units are 'min', 'min', 'sec', 'sec', 'sec' and 'hour'.
+") },
+ { label => N("Encryption algorithm"), val => \$data->{4}[1],
+ list => [ qw(des 3des des_iv64 des_iv32 rc5 rc4 idea 3idea cast128 blowfish null_enc twofish rijndae) ] },
+ { label => N("Authentication algorithm"), val => \$data->{5}[1],
+ list => [ qw(des 3des des_iv64 des_iv32 hmac_md5 hmac_sha1 non_auth) ] },
+ { label => N("Compression algorithm"), val => \$data->{6}[1],
+ list => [ N_("deflate") ], format => \&translate, allow_empty_list => 1 }
+
+]) }
+
+sub ask_info2 {
+ my ($title, $text, $main_remote_section, $proposal_remote_section) = @_;
+ $in->ask_from($title, $text,,
+ [ { label => N("Remote"), val => \$main_remote_section->{1}[1], type => 'entry',
+ help => N("remote (address | anonymous) [[port]] { statements }
+specifies the parameters for IKE phase 1 for each remote node.
+The default port is 500. If anonymous is specified, the state-
+ments apply to all peers which do not match any other remote
+directive.\n
+Examples: \n
+remote anonymous
+remote ::1 [8000]") },
+ { label => N("Exchange mode"), val => \$main_remote_section->{2}[1],
+ list => [ qw(main,agressive agressive,main) ],
+ help => N("defines the exchange mode for phase 1 when racoon is the
+initiator. Also it means the acceptable exchange mode
+when racoon is responder. More than one mode can be
+specified by separating them with a comma. All of the
+modes are acceptable. The first exchange mode is what
+racoon uses when it is the initiator.\n") },
+ { label => N("Generate policy"), val => \$main_remote_section->{3}[1],
+ list => [ N_("off"), N_("on") ], format => \&translate,
+ help => N("This directive is for the responder. Therefore you
+should set passive on in order that racoon(8) only
+becomes a responder. If the responder does not have any
+policy in SPD during phase 2 negotiation, and the direc-
+tive is set on, then racoon(8) will choice the first pro-
+posal in the SA payload from the initiator, and generate
+policy entries from the proposal. It is useful to nego-
+tiate with the client which is allocated IP address
+dynamically. Note that inappropriate policy might be
+installed into the responder's SPD by the initiator. So
+that other communication might fail if such policies
+installed due to some policy mismatches between the ini-
+tiator and the responder. This directive is ignored in
+the initiator case. The default value is off.") },
+ { label => N("Passive"), val => \$main_remote_section->{4}[1],
+ list => [ N_("off"), N_("on") ], format => \&translate,
+ help => N("If you do not want to initiate the negotiation, set this
+to on. The default value is off. It is useful for a
+server.") },
+ { label => N("Certificate type"), val => \$main_remote_section->{5}[1],
+ list => [ 'x509' ], allow_empty_list => 1 },
+ { label => N("My certfile"), val => \$main_remote_section->{5}[2], type => 'entry',
+ help => N("Name of the certificate") },
+ { label => N("My private key"), val => \$main_remote_section->{5}[3], type => 'entry',
+ help => N("Name of the private key") },
+ { label => N("Peers certfile"), val => \$main_remote_section->{6}[1], type => 'entry',
+ help => N("Name of the peers certificate") },
+ { label => N("Verify cert"), val => \$main_remote_section->{7}[1],
+ list => [ N_("off"), N_("on") ], format => \&translate,
+ help => N("If you do not want to verify the peer's certificate for
+some reason, set this to off. The default is on.") },
+ { label => N("My identifier"), val => \$main_remote_section->{8}[1], type => 'entry',
+ help => N("specifies the identifier sent to the remote host and the
+type to use in the phase 1 negotiation. address, FQDN,
+user_fqdn, keyid and asn1dn can be used as an idtype.
+they are used like:
+ my_identifier address [address];
+ the type is the IP address. This is the default
+ type if you do not specify an identifier to use.
+ my_identifier user_fqdn string;
+ the type is a USER_FQDN (user fully-qualified
+ domain name).
+ my_identifier FQDN string;
+ the type is a FQDN (fully-qualified domain name).
+ my_identifier keyid file;
+ the type is a KEY_ID.
+ my_identifier asn1dn [string];
+ the type is an ASN.1 distinguished name. If
+ string is omitted, racoon(8) will get DN from
+ Subject field in the certificate.\n
+Examples: \n
+my_identifier user_fqdn \"myemail\@mydomain.com\"") },
+ { label => N("Peers identifier"), val => \$main_remote_section->{9}[1], type => 'entry' },
+ { label => N("Proposal"), val => \$proposal_remote_section->{1}[0], list => [ 'proposal' ], allow_empty_list => 1 },
+ { label => N("Encryption algorithm"), val => \$proposal_remote_section->{2}[1], list => [ qw(des 3des blowfish cast128) ],
+ help => N("specify the encryption algorithm used for the
+phase 1 negotiation. This directive must be defined.
+algorithm is one of the following:
+
+DES, 3DES, blowfish, cast128 for oakley.
+
+For other transforms, this statement should not be used.") },
+ { label => N("Hash algorithm"), val => \$proposal_remote_section->{3}[1], type => 'entry' },
+ { label => N("Authentication method"), val => \$proposal_remote_section->{4}[1], type => 'entry' },
+ { label => N("DH group"), val => \$proposal_remote_section->{5}[1], list => [ qw(modp768 modp1024 modp1536 1 2 5) ], },
+ ]);
+}
+
+sub ask_info3 {
+ my ($title, $text, $section) = @_;
+ $in->ask_from($title, $text,,
+ [ { label => N("Command"), val => \$section->{command}, list => [ 'spdadd' ], allow_empty_list => 1 },
+ { label => N("Source IP range"), val => \$section->{src_range}, type => 'entry' },
+ { label => N("Destination IP range"), val => \$section->{dst_range}, type => 'entry' },
+ { label => N("Upper-layer protocol"), val => \$section->{upperspec}, list => [ N_("any") ],
+ format => \&translate, allow_empty_list => 1 },
+ { label => N("Flag"), val => \$section->{flag}, list => [ '-P' ], allow_empty_list => 1 },
+ { label => N("Direction"), val => \$section->{direction}, list => [ 'in', 'out' ] },
+ { label => N("IPsec policy"), val => \$section->{ipsec}, list => [ N_("ipsec"), N_("discard"), N_("none") ],
+ format => \&translate },
+ { label => N("Protocol"), val => \$section->{protocol}, list => [ 'esp', 'ah', 'ipcomp' ] },
+ { label => N("Mode"), val => \$section->{mode}, list => [ N_("tunnel"), N_("transport"), N_("any") ],
+ format => \&translate },
+ { label => N("Source/destination"), val => \$section->{src_dest}, type => 'entry' },
+ { label => N("Level"), val => \$section->{level}, list => [ N_("require"), N_("default"), N_("use"), N_("unique") ],
+ format => \&translate },
+ ]);
+}
+