summaryrefslogtreecommitdiffstats
path: root/perl-install
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install')
-rw-r--r--perl-install/network/ipsec.pm781
-rw-r--r--perl-install/standalone/drakvpn943
2 files changed, 1724 insertions, 0 deletions
diff --git a/perl-install/network/ipsec.pm b/perl-install/network/ipsec.pm
new file mode 100644
index 000000000..3cdd9a43f
--- /dev/null
+++ b/perl-install/network/ipsec.pm
@@ -0,0 +1,781 @@
+package network::ipsec;
+
+
+
+use detect_devices;
+use network::netconnect;
+use run_program;
+use common;
+use log;
+use Data::Dumper;
+
+#- debugg functions ----------
+sub recreate_ipsec_conf {
+ my ($ipsec, $kernel_version) = @_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ print "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
+ foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
+ if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
+ print "\t$ipsec->{$key1}{$key2}[0]\n";
+ } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(conn|config|version)/) {
+ print "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
+ } else {
+ print "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n";
+ };
+ }
+ }
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (! $ipsec->{$key1}{secure_policy}) {
+ print "$ipsec->{$key1}\n";
+ } else {
+ print $ipsec->{$key1}{secure_policy} . " " .
+ $ipsec->{$key1}{src_range} . " " .
+ $ipsec->{$key1}{dst_range} . " " .
+ $ipsec->{$key1}{upperspec} . " " .
+ $ipsec->{$key1}{flag} . " " .
+ $ipsec->{$key1}{direction} . " " .
+ $ipsec->{$key1}{ipsec} . "\n\t" .
+ $ipsec->{$key1}{protocol} . "/" .
+ $ipsec->{$key1}{mode} . "/" .
+ $ipsec->{$key1}{src_dest} . "/" .
+ $ipsec->{$key1}{level} . ";\n"
+ };
+ }
+ }
+}
+
+sub recreate_racoon_conf {
+ my ($racoon) = @_;
+ my $in_a_section = "n";
+ my $in_a_proposal_section = "n";
+ foreach my $key1 (ikeys %$racoon) {
+ if ($in_a_proposal_section eq "y") {
+ print "\t}\n}\n$racoon->{$key1}\n" if ! $racoon->{$key1}{1};
+ } elsif ($in_a_section eq "y") {
+ print "}\n$racoon->{$key1}\n" if ! $racoon->{$key1}{1};
+ } else {
+ print "$racoon->{$key1}\n" if ! $racoon->{$key1}{1};
+ };
+ $in_a_section = "n";
+ $in_a_proposal_section = "n";
+ foreach my $key2 (ikeys %{$racoon->{$key1}}) {
+ if ($racoon->{$key1}{$key2}[0] =~ /^path/) {
+ print "$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1] $racoon->{$key1}{$key2}[2];\n";
+ } elsif ($racoon->{$key1}{$key2}[0] =~ /^remote/) {
+ $in_a_section = "y";
+ $in_a_proposal_section = "n";
+ print "$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1] {\n";
+ } elsif ($racoon->{$key1}{$key2}[0] =~ /^sainfo/) {
+ $in_a_section = "y";
+ $in_a_proposal_section = "n";
+ print "$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1] $racoon->{$key1}{$key2}[2] $racoon->{$key1}{$key2}[3] $racoon->{$key1}{$key2}[4] $racoon->{$key1}{$key2}[5] $racoon->{$key1}{$key2}[6] {\n";
+ } elsif ($racoon->{$key1}{$key2}[0] =~ /^proposal /) {
+ $in_a_proposal_section = "y";
+ print "\t$racoon->{$key1}{$key2}[0] {\n";
+ } elsif ($in_a_section eq "y" && $racoon->{$key1}{$key2}[0] =~ /^certificate_type/) {
+ print "\t$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1] $racoon->{$key1}{$key2}[2] $racoon->{$key1}{$key2}[3];\n";
+ } elsif ($in_a_section eq "y" && $racoon->{$key1}{$key2}[0] =~ /^#/) {
+ print "\t$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1]\n";
+ } elsif ($in_a_section eq "y") {
+ print "\t$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1];\n";
+ } elsif ($in_a_proposal_section eq "y" && $racoon->{$key1}{$key2}[0] =~ /^#/) {
+ print "\t\t$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1]\n";
+ } elsif ($in_a_proposal_section eq "y") {
+ print "\t\t$racoon->{$key1}{$key2}[0] $racoon->{$key1}{$key2}[1];\n";
+ }
+ }
+ }
+
+print "}\n";
+}
+
+sub recreate_ipsec_conf1_k24 {
+ my ($ipsec) = @_;
+ foreach my $key1 (ikeys %$ipsec) {
+ print "$key1-->$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
+ foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
+ if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
+ print "\t$key2-->$ipsec->{$key1}{$key2}[0]\n";
+ } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(conn|config|version)/) {
+ print "$key1-->$key2-->$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
+ } else {
+ print "\t$key2-->$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n";
+ };
+ }
+ }
+}
+#- end of debug functions --------
+
+sub sys { system(@_) == 0 or log::l("[drakvpn] Warning, sys failed for $_[0]") }
+
+sub start_daemons () {
+ return if $::testing;
+ log::explanations("Starting daemons");
+ if (-e "/etc/rc.d/init.d/ipsec") {
+ system("/etc/rc.d/init.d/ipsec status >/dev/null") == 0 and sys("/etc/rc.d/init.d/ipsec stop");
+ sys("/etc/rc.d/init.d/$_ start >/dev/null"), sys("/sbin/chkconfig --level 345 $_ on") foreach 'ipsec';
+ } else {
+
+ };
+ sys("/etc/rc.d/init.d/$_ start >/dev/null"), sys("/sbin/chkconfig --level 345 $_ on") foreach 'shorewall';
+}
+
+sub stop_daemons () {
+ return if $::testing;
+ log::explanations("Stopping daemons");
+ if (-e "/etc/rc.d/init.d/ipsec") {
+ foreach (qw(ipsec)) {
+ system("/etc/rc.d/init.d/$_ status >/dev/null 2>/dev/null") == 0 and sys("/etc/rc.d/init.d/$_ stop");
+ };
+ sys("/sbin/chkconfig --level 345 $_ off") && -e "/etc/rc.d/init.d/$_" foreach 'ipsec';
+ };
+ system("/etc/rc.d/init.d/shorewall status >/dev/null 2>/dev/null") == 0 and sys("/etc/rc.d/init.d/shorewall stop >/dev/null");
+
+}
+
+sub set_config_file {
+ my ($file, @l) = @_;
+
+ my $done;
+ substInFile {
+ if (!$done && (/^#LAST LINE/ || eof)) {
+ $_ = join('', map { join("\t", @$_) . "\n" } @l) . $_;
+ $done = 1;
+ } else {
+ $_ = '' if /^[^#]/;
+ }
+ } "$::prefix/$file";
+}
+
+sub get_config_file {
+ my ($file) = @_;
+ map { [ split ' ' ] } grep { !/^#/ } cat_("$::prefix/$file");
+}
+
+
+#-------------------------------------------------------------------
+#---------------------- configure racoon_conf -----------------------
+#-------------------------------------------------------------------
+
+sub read_racoon_conf {
+ my ($racoon_conf) = @_;
+ my %conf;
+ my $nb = 0; #total number
+ my $i = 0; #nb within a section
+ my $in_a_section = "n";
+ my @line1;
+ my $line = "";
+ local $_;
+ open(my $LIST, "< $racoon_conf");
+ while (<$LIST>) {
+ chomp($_);
+ $line = $_;
+ $in_a_section = "n" if $line =~ /}/ && $line !~ /^#/;
+ $line =~ s/^\s+|\s*;|\s*{//g if $line !~ /^#/;
+ $line =~ /(.*)#(.*)/ if $line !~ /^#/; #- define before and after comment
+# print "--line-->$line\n";
+ my $data_part = $1;
+ my $comment_part = "#".$2;
+ if ($data_part) {
+ $data_part =~ s/,//g;
+# print "@@".$data_part."->".$comment_part."\n";
+ @line1 = split /\s+/,$data_part;
+ @line1 = (@line1, $comment_part) if $comment_part;
+ } else {
+ @line1 = split /\s+/,$line;
+ }
+ if (!$line && $in_a_section eq "n") {
+ $nb++;
+ put_in_hash(\%conf, { $nb => $line });
+ $in_a_section = "n";
+ } elsif (!$line && $in_a_section eq "y") {
+ put_in_hash($conf{$nb} ||= {}, { $i => [ '' ] });
+ $i++;
+ } elsif ($line =~ /^path/) {
+ $i=1;
+ $nb++;
+ put_in_hash($conf{$nb} ||= {}, { $i => [@line1] });
+ $in_a_section = "n";
+ $i++;
+ } elsif ($line =~ /^#|^{|^}/) {
+ if ($in_a_section eq "y") {
+ put_in_hash($conf{$nb} ||= {}, { $i => [$line] });
+ $i++;
+ } else {
+ $nb++;
+ put_in_hash(\%conf, { $nb => $line });
+ $in_a_section = "n";
+ };
+ } elsif ($line =~ /^sainfo|^remote|^listen|^timer|^padding/ && $in_a_section eq "n") {
+ $i=1;
+ $nb++;
+ put_in_hash($conf{$nb} ||= {}, { $i => [@line1] });
+ $in_a_section = "y";
+ $i++;
+ } elsif ($line eq "proposal" && $in_a_section eq "y") {
+ $i=1;
+ $nb++;
+ put_in_hash($conf{$nb} ||= {}, { $i => [@line1] });
+ $in_a_section = "y";
+ $i++;
+ } else {
+ put_in_hash($conf{$nb} ||= {}, { $i => [@line1] });
+ $i++;
+ };
+ };
+
+\%conf;
+}
+
+sub display_racoon_conf {
+ my ($racoon) = @_;
+ my $display = "";
+ my $prefix_to_simple_line = "";
+ foreach my $key1 (ikeys %$racoon) {
+ if (!$racoon->{$key1}{1}) {
+ $display .= $prefix_to_simple_line . $racoon->{$key1} . "\n";
+ $prefix_to_simple_line = "";
+ } else {
+ foreach my $key2 (ikeys %{$racoon->{$key1}}) {
+ $key2 > 1 ? my $pt = $racoon->{$key1}{$key2-1}[0] : my $pt = $racoon->{$key1}{1}[0];
+ my $t = $racoon->{$key1}{1}[0];
+ my $f = $racoon->{$key1}{$key2}[0];
+ my $list_length = scalar @{$racoon->{$key1}{$key2}};
+ my $already_read = 0;
+ my $line = "";
+
+ for (my $i = 0; $i <= $list_length-1; $i++) {
+
+ my $c = $racoon->{$key1}{$key2}[$i];
+ my $n = $racoon->{$key1}{$key2}[$i+1];
+
+ if ($c =~ /^path|^log|^timer|^listen|^padding|^remote|^proposal|^sainfo/) {
+ $line .= "$c ";
+ } elsif ($i == $list_length-2 && $n =~ /^#/) {
+ $line .= "$c; ";
+ } elsif ($i == $list_length-1) {
+ if ($f =~ /^#|^$|^timer|^listen|^padding|^remote|^proposal\s+|^sainfo/) {
+ $line .= $c;
+ } elsif ($c =~ /^#/) {
+ $line .= "\t$c";
+ } else {
+ $line .= "$c;";
+ }
+ } else {
+ $line .= "$c ";
+ }
+
+ $already_read = 1;
+ }
+
+ if ($f =~ /^timer|^listen|^padding|^remote|^sainfo/) {
+ $line .= " {";
+ $prefix_to_simple_line = "";
+ } elsif ($f eq "proposal") {
+ $line = "\t" . $line . " {";
+ } elsif ($t eq "proposal") {
+ $line = "\t\t" . $line if $line ne "proposal";
+ $prefix_to_simple_line = "\t";
+ } else {
+ $line = "\t" . $line if $t !~ /^path|^log/;
+ $prefix_to_simple_line = "";
+ }
+ $display .= "$line\n";
+ }
+ }
+ }
+
+$display;
+
+}
+
+sub write_racoon_conf {
+ my ($racoon_conf, $racoon) = @_;
+ my $display = "";
+ my $prefix_to_simple_line = "";
+ foreach my $key1 (ikeys %$racoon) {
+ if (!$racoon->{$key1}{1}) {
+ $display .= $prefix_to_simple_line . $racoon->{$key1} . "\n";
+ $prefix_to_simple_line = "";
+ } else {
+ foreach my $key2 (ikeys %{$racoon->{$key1}}) {
+ $key2 > 1 ? my $pt = $racoon->{$key1}{$key2-1}[0] : my $pt = $racoon->{$key1}{1}[0];
+ my $t = $racoon->{$key1}{1}[0];
+ my $f = $racoon->{$key1}{$key2}[0];
+ my $list_length = scalar @{$racoon->{$key1}{$key2}};
+ my $already_read = 0;
+ my $line = "";
+
+ for (my $i = 0; $i <= $list_length-1; $i++) {
+
+ my $c = $racoon->{$key1}{$key2}[$i];
+ my $n = $racoon->{$key1}{$key2}[$i+1];
+
+ if ($c =~ /^path|^log|^timer|^listen|^padding|^remote|^proposal|^sainfo/) {
+ $line .= "$c ";
+ } elsif ($i == $list_length-2 && $n =~ /^#/) {
+ $line .= "$c; ";
+ } elsif ($i == $list_length-1) {
+ if ($f =~ /^#|^$|^timer|^listen|^padding|^remote|^proposal\s+|^sainfo/) {
+ $line .= $c;
+ } elsif ($c =~ /^#/) {
+ $line .= "\t$c";
+ } else {
+ $line .= "$c;";
+ }
+ } else {
+ $line .= "$c ";
+ }
+
+ $already_read = 1;
+ }
+
+ if ($f =~ /^timer|^listen|^padding|^remote|^sainfo/) {
+ $line .= " {";
+ $prefix_to_simple_line = "";
+ } elsif ($f eq "proposal") {
+ $line = "\t" . $line . " {";
+ } elsif ($t eq "proposal") {
+ $line = "\t\t" . $line if $line ne "proposal";
+ $prefix_to_simple_line = "\t";
+ } else {
+ $line = "\t" . $line if $t !~ /^path|^log/;
+ $prefix_to_simple_line = "";
+ }
+ $display .= "$line\n";
+ }
+ }
+ }
+
+open(my $ADD, "> $racoon_conf") or die "Can't open the $racoon_conf file for writing";
+ print $ADD "$display\n";
+
+}
+
+sub get_section_names_racoon_conf {
+ my ($racoon_conf, $racoon) = @_;
+ my @section_names;
+
+ if (-e $racoon_conf) {
+ foreach my $key1 (ikeys %$racoon) {
+ if (!$racoon->{$key1}{1}) {
+ next;
+ } else {
+ my $list_length = scalar @{$racoon->{$key1}{1}};
+ my $section_title = "";
+ my $separator = "";
+ for (my $i = 0; $i <= $list_length-1; $i++) {
+ my $s = $racoon->{$key1}{1}[$i];
+ if ($s !~ /^#|^proposal/) {
+ $section_title .= $separator . $s;
+ $separator = " ";
+ };
+ }
+ push(@section_names, $section_title) if $section_title ne "";
+ }
+ }
+
+ @section_names;
+
+ }
+}
+
+sub add_section_racoon_conf {
+ my ($new_section, $racoon) = @_;
+ put_in_hash($racoon, { max(keys %$racoon) + 1 => '' });
+ put_in_hash($racoon, { max(keys %$racoon) + 1 => $new_section });
+ put_in_hash($racoon, { max(keys %$racoon) + 1 => '}' }) if $new_section->{1}[0] !~ /^path|^remote/;
+ put_in_hash($racoon, { max(keys %$racoon) + 1 => '' }) if $new_section->{1}[0] =~ /^proposal/;
+ put_in_hash($racoon, { max(keys %$racoon) + 1 => '}' }) if $new_section->{1}[0] =~ /^proposal/;
+}
+
+sub matched_section_key_number_racoon_conf {
+ my ($section_name, $racoon) = @_;
+ foreach my $key1 (ikeys %$racoon) {
+ if (!$racoon->{$key1}{1}) {
+ next;
+ } else {
+ my $list_length = scalar @{$racoon->{$key1}{1}};
+ my $section_title = "";
+ my $separator = "";
+ for (my $i = 0; $i <= $list_length-1; $i++) {
+ my $s = $racoon->{$key1}{1}[$i];
+ if ($s !~ /^#|^proposal/) {
+ $section_title .= $separator . $s;
+ $separator = " ";
+ };
+ };
+ if ($section_title eq $section_name) {
+ return $key1;
+ };
+ }
+ }
+
+}
+
+sub already_existing_section_racoon_conf {
+ my ($section_name, $racoon, $racoon_conf) = @_;
+ if (-e $racoon_conf) {
+ foreach my $key1 (ikeys %$racoon) {
+ if (!$racoon->{$key1}{1}) {
+ next;
+ } elsif (find {
+ my $list_length = scalar @{$racoon->{$key1}{1}};
+ my $section_title = "";
+ my $separator = "";
+ for (my $i = 0; $i <= $list_length-1; $i++) {
+ my $s = $racoon->{$key1}{1}[$i];
+ if ($s !~ /^#|^proposal/) {
+ $section_title .= $separator . $s;
+ $separator = " ";
+ };
+ }
+
+ $section_title eq $section_name;
+
+ } ikeys %{$racoon->{$key1}}) {
+
+ return "already existing";
+ }
+ }
+ }
+
+}
+
+sub remove_section_racoon_conf {
+ my ($section_name, $racoon, $k) = @_;
+ if ($section_name =~ /^remote/) {
+
+ delete $racoon->{$k};
+ my $proposal_removed = "n";
+ delete $racoon->{$k+1};
+ delete $racoon->{$k+2}; #- remove assoc }
+ delete $racoon->{$k+3}; #- remove assoc }
+
+ } elsif ($section_name =~ /^path/) {
+
+ delete $racoon->{$k};
+ delete $racoon->{$k+1} if $racoon->{$k+1}{1} eq "";
+
+ } else {
+
+ delete $racoon->{$k};
+ delete $racoon->{$k+1} if $racoon->{$k+1}{1} eq "";
+ delete $racoon->{$k+2} if $racoon->{$k+2}{1} eq ""; #- remove assoc }
+
+ }
+
+}
+
+#-------------------------------------------------------------------
+#---------------------- configure ipsec_conf -----------------------
+#-------------------------------------------------------------------
+
+sub read_ipsec_conf {
+ my ($ipsec_conf, $kernel_version) = @_;
+ my %conf;
+ my $nb = 0; #total number
+ my $i = 0; #nb within a connexion
+ my $in_a_conn = "n";
+ my $line = "";
+ my @line1;
+ local $_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ open(my $LIST, "< $ipsec_conf"); #or die "Can't open the $ipsec_conf file for reading";
+ while (<$LIST>) {
+ chomp($_);
+ $line = $_;
+ $line =~ s/^\s+//;
+ if (!$line) {
+ $nb++;
+ put_in_hash(\%conf, { $nb => $line });
+ $in_a_conn = "n";
+ } elsif ($line =~ /^#/) {
+ if ($in_a_conn eq "y") {
+ put_in_hash($conf{$nb} ||= {}, { $i => [$line] });
+ $i++;
+ } else {
+ $nb++;
+ put_in_hash(\%conf, { $nb => $line });
+ $in_a_conn = "n";
+ };
+ } elsif ($line =~ /^conn|^config|^version/ && $in_a_conn eq "n") {
+ @line1 = split /\s+/,$line;
+ $i=1;
+ $nb++;
+ put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
+ $in_a_conn = "y" if $line !~ /^version/;
+ $i++;
+ } elsif ($line =~ /^conn|^config|^version/ && $in_a_conn eq "y") {
+ @line1 = split /\s+/,$line;
+ $i=1;
+ $nb++;
+ put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
+ $i++;
+ } else {
+ @line1 = split /=/,$line;
+ put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
+ $i++;
+ };
+ };
+
+ } else {
+ #- kernel 2.6 part -------------------------------
+ my @mylist;
+ my $myline = "";
+ open(my $LIST, "< $ipsec_conf"); #or die "Can't open the $ipsec_conf file for reading";
+ while (<$LIST>) {
+ chomp($_);
+ $myline = $_;
+ $myline =~ s/^\s+//;
+ if ($myline =~ /^spdadd/) {
+ @mylist = split /\s+/,$myline;
+ $in_a_conn = "y";
+ $nb++;
+ next;
+ } elsif ($in_a_conn eq "y") {
+ @mylist = (@mylist, split '\s+|/',$myline);
+ put_in_hash(\%conf, { $nb => { secure_policy => $mylist[0],
+ src_range => $mylist[1],
+ dst_range => $mylist[2],
+ upperspec => $mylist[3],
+ flag => $mylist[4],
+ direction => $mylist[5],
+ ipsec => $mylist[6],
+ protocol => $mylist[7],
+ mode => $mylist[8],
+ src_dest => $mylist[9],
+ level => $mylist[10] } });
+ $in_a_conn = "n";
+ } else {
+ $nb++;
+ put_in_hash(\%conf, { $nb => $myline });
+ };
+ };
+
+ };
+
+ \%conf;
+}
+
+sub write_ipsec_conf {
+ my ($ipsec_conf, $ipsec, $kernel_version) = @_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ open(my $ADD, "> $ipsec_conf") or die "Can't open the $ipsec_conf file for writing";
+ foreach my $key1 (ikeys %$ipsec) {
+ print $ADD "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
+ foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
+ if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
+ print $ADD "\t$ipsec->{$key1}{$key2}[0]\n";
+ } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
+ print $ADD "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
+ } else {
+ print $ADD "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n" if $ipsec->{$key1}{$key2}[0] && $ipsec->{$key1}{$key2}[1];
+ };
+ }
+ }
+ } else {
+ #- kernel 2.6 part -------------------------------
+ my $display = "";
+ foreach my $key1 (ikeys %$ipsec) {
+ if (! $ipsec->{$key1}{secure_policy}) {
+ $display .= "$ipsec->{$key1}\n";
+ } else {
+ $display .= $ipsec->{$key1}{secure_policy} . " " .
+ $ipsec->{$key1}{src_range} . " " .
+ $ipsec->{$key1}{dst_range} . " " .
+ $ipsec->{$key1}{upperspec} . " " .
+ $ipsec->{$key1}{flag} . " " .
+ $ipsec->{$key1}{direction} . " " .
+ $ipsec->{$key1}{ipsec} . "\n\t" .
+ $ipsec->{$key1}{protocol} . "/" .
+ $ipsec->{$key1}{mode} . "/" .
+ $ipsec->{$key1}{src_dest} . "/" .
+ $ipsec->{$key1}{level} . ";\n"
+ };
+ }
+ open(my $ADD, "> $ipsec_conf") or die "Can't open the $ipsec_conf file for writing";
+ print $ADD $display;
+ }
+}
+
+sub display_ipsec_conf {
+ my ($ipsec_conf, $ipsec, $kernel_version) = @_;
+ my $display = "";
+
+ if (! -e $ipsec_conf) {
+ $display = "There is no $ipsec_conf file\n";
+ } elsif ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ $display .= "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
+ foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
+ if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
+ $display .= "\t$ipsec->{$key1}{$key2}[0]\n";
+ } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
+ $display .= "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
+ } else {
+ $display .= "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n";
+ };
+ }
+ }
+
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (! $ipsec->{$key1}{secure_policy}) {
+ $display .= "$ipsec->{$key1}\n";
+ } else {
+ $display .= $ipsec->{$key1}{secure_policy} . " " .
+ $ipsec->{$key1}{src_range} . " " .
+ $ipsec->{$key1}{dst_range} . " " .
+ $ipsec->{$key1}{upperspec} . " " .
+ $ipsec->{$key1}{flag} . " " .
+ $ipsec->{$key1}{direction} . " " .
+ $ipsec->{$key1}{ipsec} . "\n\t" .
+ $ipsec->{$key1}{protocol} . "/" .
+ $ipsec->{$key1}{mode} . "/" .
+ $ipsec->{$key1}{src_dest} . "/" .
+ $ipsec->{$key1}{level} . ";\n";
+ };
+ }
+
+ }
+
+ $display;
+
+}
+
+sub get_section_names_ipsec_conf {
+ my ($ipsec_conf, $ipsec, $kernel_version) = @_;
+ my @section_names;
+
+ if (-e $ipsec_conf) {
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
+ if ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
+ push(@section_names, "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]");
+ };
+ }
+ }
+
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if ($ipsec->{$key1}{secure_policy} =~ m/(^spdadd)/) {
+ push(@section_names, "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}");
+ };
+ }
+ }
+
+ @section_names;
+
+ }
+}
+
+sub remove_section_ipsec_conf {
+ my ($section_name, $ipsec, $kernel_version) = @_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = $ipsec->{$key1}{$_}[0];
+ $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
+ $section_name eq "$s $ipsec->{$key1}{$_}[1]";
+ } ikeys %{$ipsec->{$key1}}) {
+ delete $ipsec->{$key1};
+ }
+ }
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
+ $s !~ /^#/ && $ipsec->{$key1}{src_range} && $section_name eq $s;
+ } ikeys %{$ipsec->{$key1}}) {
+ delete $ipsec->{$key1-1};
+ delete $ipsec->{$key1};
+ }
+ }
+ }
+}
+
+sub add_section_ipsec_conf {
+ my ($new_section, $ipsec) = @_;
+ put_in_hash($ipsec, { max(keys %$ipsec) + 1 => '' });
+ put_in_hash($ipsec, { max(keys %$ipsec) + 1 => $new_section });
+}
+
+sub already_existing_section_ipsec_conf {
+ my ($section_name, $ipsec, $kernel_version) = @_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = $ipsec->{$key1}{$_}[0];
+ $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
+ $section_name eq "$s $ipsec->{$key1}{$_}[1]";
+ } ikeys %{$ipsec->{$key1}}) {
+ return "already existing";
+ }
+ }
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
+ $s !~ /^#/ && $ipsec->{$key1}{src_range} &&
+ $section_name eq $s;
+ } ikeys %{$ipsec->{$key1}}) {
+ return "already existing";
+ }
+ }
+ };
+ return "no";
+}
+
+#- returns the reference to the dynamical list for editing
+sub dynamic_list {
+ my ($number, $ipsec) = @_;
+ my @list = map { { label => N("%s=", $ipsec->{$number}{$_}[0]),
+ val => \$ipsec->{$number}{$_}[1] } } ikeys %{$ipsec->{$number}};
+
+ @list;
+}
+
+#- returns the hash key number of $section_name
+sub matched_section_key_number_ipsec_conf {
+ my ($section_name, $ipsec, $kernel_version) = @_;
+ if ($kernel_version < 2.5) {
+ #- kernel 2.4 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = $ipsec->{$key1}{$_}[0];
+ $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
+ $section_name eq "$s $ipsec->{$key1}{$_}[1]";
+ } ikeys %{$ipsec->{$key1}}) {
+ return $key1;
+ }
+ }
+ } else {
+ #- kernel 2.6 part -------------------------------
+ foreach my $key1 (ikeys %$ipsec) {
+ if (find {
+ my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
+ $s !~ /^#/ && $ipsec->{$key1}{src_range} &&
+ $section_name eq $s;
+ } ikeys %{$ipsec->{$key1}}) {
+ return $key1;
+ }
+ }
+ }
+}
+1
diff --git a/perl-install/standalone/drakvpn b/perl-install/standalone/drakvpn
new file mode 100644
index 000000000..f3d4a703f
--- /dev/null
+++ b/perl-install/standalone/drakvpn
@@ -0,0 +1,943 @@
+#!/usr/bin/perl
+
+#
+# author Florin Grad (florin@mandrakesoft.com)
+#
+# Copyright 2004 MandrakeSoft
+#
+# 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 = "wiz_drakgw.png";
+$::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, 'silent');
+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);
+
+$::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 && -f "/etc/shorewall/tunnels") {
+ $::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);
+ 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") ]);
+ 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:
+
+undef $::Wizard_no_previous;
+
+$::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 ressources, 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;
+
+$::direct or $in->ask_okcancel(N("Simple VPN setup."),
+N("VPN connection.
+
+This program is based on the following projects:
+
+ - FreeSwan: http://www.freeswan.org/
+ - Super-FreeSwan: http://www.freeswan.ca/
+ - ipsec-tools: http://ipsec-tools.sourceforge.net/
+ - ipsec-howto: http://www.ipsec-howto.org
+
+Please read the at lest the ipsec-howto docs before
+going any further."), 1) or goto begin;
+
+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("Kernel module."),
+N("The running kernel need to have ipsec support.\n
+The kernels 2.4 until 2.5 need to be compiled with
+Freeswan or Super/FreeSwan.
+The kernels 2.5 and above have native ipsec support.\n
+The running kernel version is %s and it has support for:
+%s", $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");
+
+my $card_netconnect = network::netconnect::get_net_device() || "eth0";
+defined $card_netconnect and log::l("[drakvpn] Information from netconnect: ignore card $card_netconnect");
+
+ $in->ask_from('',
+ N("Please enter the name of the interface connected to the internet.
+
+Examples:
+ ppp+ for modem or DSL connections,
+ eth0, or eth1 for cable connection,
+ ippp+ for a isdn connection.
+"),
+ [ { label => N("Net Device"), val => \$card_netconnect, list => [ detect_devices::getNet() ], not_edit => 0 } ])
+ or goto step_ask_confirm;
+
+#- **********************************
+#- * 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;
+
+if ($kernel_version > 2.5) {
+ $c = $in->ask_from_list_(N("Configuration file"),
+N("Welcome to the
+%s and %s
+files configuration step.
+
+You can now configure the sections of these files.
+
+Which file would you like to configure ?\n", $ipsec_conf, $racoon_conf),
+ [ N("configure %s", $ipsec_conf), N("configure %s", $racoon_conf) ]) 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 "configure $ipsec_conf" || $c eq "configure") {
+
+step_configure_ipsec_conf:
+
+@section_names = network::ipsec::get_section_names_ipsec_conf($ipsec_conf,$ipsec,$kernel_version) if -e $ipsec_conf;
+
+my $choice = $section_names[0] if $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\n
+
+What would you like to do ?\n", $ipsec_conf),
+ [ N_("display"), 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") {
+ if (-e $ipsec_conf) {
+ $in->ask_okcancel(N("Display configuration"),
+ network::ipsec::display_ipsec_conf($ipsec_conf,$ipsec,$kernel_version));
+ goto step_configure_ipsec_conf;
+ } else {
+$in->ask_okcancel(N("Display 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", $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 section 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 don't 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 = { secure_policy => '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:
+
+ $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("secure_policy = "), val => \$section->{secure_policy}, list => [ 'spdadd', 'spdadd' ] },
+ { label => N("src_range = "), val => \$section->{src_range}, type => 'entry' },
+ { label => N("dst_range = "), val => \$section->{dst_range}, type => 'entry' },
+ { label => N("upperspec = "), val => \$section->{upperspec}, list => [ 'any', 'any' ] },
+ { label => N("flag = "), val => \$section->{flag}, list => [ '-P', '-P' ] },
+ { label => N("direction = "), val => \$section->{direction}, list => [ 'in', 'out' ] },
+ { label => N("ipsec = "), val => \$section->{ipsec}, list => [ 'ipsec', 'discard', 'none' ] },
+ { label => N("protocol = "), val => \$section->{protocol}, list => [ 'esp', 'ah', 'ipcomp' ] },
+ { label => N("mode = "), val => \$section->{mode}, list => [ 'tunnel', 'transport', 'any' ] },
+ { label => N("src_dest = "), val => \$section->{src_dest}, type => 'entry' },
+ { label => N("level = "), val => \$section->{level}, list => [ 'required', 'default', 'use', 'unique' ] },
+ ]
+) 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;
+};
+
+ network::ipsec::add_section_ipsec_conf($section, $ipsec);
+
+ 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't edit !"),
+N("You cannot edit this section.\n
+This section is mandatory for Freswan 2.X.
+One has to specify version 2.0 on the top
+of the %s file, and eventually, disable or
+enable the oportunistic ecryption.\n",$ipsec_conf));
+ goto step_edit_ipsec_conf;
+
+} elsif ($choice =~ /^config setup/) {
+ $in->ask_from('',
+N("Your %s file has several sctions.\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 {
+
+ $in->ask_from('',
+N("Your %s file has several sections, or connections.\n
+You can now edit the chosen section.
+Choose continue when you are done to write the data.\n", $ipsec_conf),
+ [ { label => N("secure_policy = "), val => \$ipsec->{$number}{secure_policy}, list => [ 'spdadd', 'spdadd' ] },
+ { label => N("src_range = "), val => \$ipsec->{$number}{src_range}, type => 'entry' },
+ { label => N("dst_range = "), val => \$ipsec->{$number}{dst_range}, type => 'entry' },
+ { label => N("upperspec = "), val => \$ipsec->{$number}{upperspec}, list => [ 'any', 'any' ] },
+ { label => N("flag = "), val => \$ipsec->{$number}{flag}, list => [ '-P', '-P' ] },
+ { label => N("direction = "), val => \$ipsec->{$number}{direction}, list => [ 'in', 'out' ] },
+ { label => N("ipsec = "), val => \$ipsec->{$number}{ipsec}, list => [ 'ipsec', 'discard', 'none' ] },
+ { label => N("protocol = "), val => \$ipsec->{$number}{protocol}, list => [ 'esp', 'ah', 'ipcomp' ] },
+ { label => N("mode = "), val => \$ipsec->{$number}{mode}, list => [ 'tunnel', 'transport', 'any' ] },
+ { label => N("src_dest = "), val => \$ipsec->{$number}{src_dest}, type => 'entry' },
+ { label => N("level = "), val => \$ipsec->{$number}{level}, list => [ 'required', 'default', 'use', 'unique' ] },
+ ]
+) 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 or 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_conf,$ipsec,$kernel_version) if -e $ipsec_conf;
+
+ 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 "configure $racoon_conf") {
+
+step_configure_racoon_conf:
+
+@section_names = network::ipsec::get_section_names_racoon_conf($racoon_conf,$racoon) if -e $racoon_conf;
+
+#print Dumper($racoon)."\n";
+
+my $choice = $section_names[0] if $section_names[0];
+my $d = $in->ask_from_list_(N("%s entries", $racoon_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\n
+
+What would you like to do ?\n", $racoon_conf),
+ [ N_("display"), N_("add"), N_("edit"), N_("remove"), N_("commit") ]) or goto step_configuration;
+
+#my $existing_section = "";
+
+#- display $racoon_conf -------------------------
+
+step_display_racoon_conf:
+
+if ($d eq "display") {
+ if (-e $racoon_conf) {
+ $in->ask_okcancel(N("Display configuration"),
+ network::ipsec::display_racoon_conf($racoon));
+#print Dumper($racoon)."\n";
+ goto step_configure_racoon_conf;
+ } else {
+$in->ask_okcancel(N("Display 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 %s file contains different sections.\n
+Here is its skeleton : 'path'
+ 'remote'
+ 'sainfo' \n
+You can now add one of these sections.\n
+Choose the section you would like to add.\n", $racoon_conf),
+ [ 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("This section has to be on top of your
+%s file.\n
+Make sure all other section follow these path
+sections.\n
+Choose continue or previous when you are done.\n", $racoon_conf),
+ [ { label => N("path_type ="), val => \$path_section->{1}[1], list => [ 'certificate', 'pre_shared_key', 'include' ] },
+ { 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' ]
+ };
+ $in->ask_from('',
+N("Make sure you already have the path sections
+on the top of your %s file.\n
+
+You can now choose the remote settings.
+Choose continue or previous when you are done.\n", $racoon_conf),
+ [ { label => N("remote ="), val => \$main_remote_section->{1}[1], type => 'entry' },
+ { label => N("exchange_mode ="), val => \$main_remote_section->{2}[1], type => 'entry' },
+ { label => N("generate_policy ="), val => \$main_remote_section->{3}[1], type => 'entry' },
+ { label => N("passive ="), val => \$main_remote_section->{4}[1], type => 'entry' },
+ { label => N("certificate_type ="), val => \$main_remote_section->{5}[1], type => 'entry' },
+ { label => N("my_certfile ="), val => \$main_remote_section->{5}[2], type => 'entry' },
+ { label => N("my_private_key ="), val => \$main_remote_section->{5}[3], type => 'entry' },
+ { label => N("peers_certfile ="), val => \$main_remote_section->{6}[1], type => 'entry' },
+ { label => N("verify_cert ="), val => \$main_remote_section->{7}[1], type => 'entry' },
+ { label => N("my_identifier ="), val => \$main_remote_section->{8}[1], type => 'entry' },
+ { label => N("peers_identifier ="), val => \$main_remote_section->{9}[1], type => 'entry' },
+ { label => N("proposal ="), val => \$proposal_remote_section->{1}[0], type => 'entry' },
+ { label => N("encryption_algorithm ="), val => \$proposal_remote_section->{2}[1], type => 'entry' },
+ { 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], type => 'entry' },
+ ]
+) 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' ],
+ };
+ $in->ask_from('',
+N("Make sure you already have the path sections
+on the top of your %s file.\n
+
+You can now choose the sainfo settings.
+Choose continue or previous when you are done.\n", $racoon_conf),
+ [ { label => N("sainfo_source_address ="), val => \$sainfo_section->{1}[2], type => 'entry' },
+ { label => N("sainfo_source_proto ="), val => \$sainfo_section->{1}[3], type => 'entry' },
+ { label => N("sainfo_dest_address ="), val => \$sainfo_section->{1}[5], type => 'entry' },
+ { label => N("sainfo_dest_proto ="), val => \$sainfo_section->{1}[6], type => 'entry' },
+ { label => N("pfs_group ="), val => \$sainfo_section->{2}[1], type => 'entry' },
+ { label => N("lifetime_number ="), val => \$sainfo_section->{3}[2], type => 'entry' },
+ { label => N("lifetime_unit ="), val => \$sainfo_section->{3}[3], type => 'entry' },
+ { label => N("encryption_algorithm ="), val => \$sainfo_section->{4}[1], type => 'entry' },
+ { label => N("authentication_algorithm ="), val => \$sainfo_section->{5}[1], type => 'entry' },
+ { label => N("compression_algorithm ="), val => \$sainfo_section->{6}[1], type => 'entry' },
+ ]
+) or goto step_configure_racoon_conf;
+
+network::ipsec::add_section_racoon_conf($sainfo_section, $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.\n
+You can choose here 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);
+
+print Dumper($racoon)."\n";
+
+if ($choice =~ /^remote/) {
+ $in->ask_from('',
+N("Your %s file has several sctions.\n
+You can now edit the remote section entries.
+Choose continue when you are done to write the data.\n", $racoon_conf),
+ [ { label => N("remote ="), val => \$racoon->{$number}{1}[1], type => 'entry' },
+ { label => N("exchange_mode ="), val => \$racoon->{$number}{2}[1], type => 'entry' },
+ { label => N("generate_policy ="), val => \$racoon->{$number}{3}[1], type => 'entry' },
+ { label => N("passive ="), val => \$racoon->{$number}{4}[1], type => 'entry' },
+ { label => N("certificate_type ="), val => \$racoon->{$number}{5}[1], type => 'entry' },
+ { label => N("my_certfile ="), val => \$racoon->{$number}{5}[2], type => 'entry' },
+ { label => N("my_private_key ="), val => \$racoon->{$number}{5}[3], type => 'entry' },
+ { label => N("peers_certfile ="), val => \$racoon->{$number}{6}[1], type => 'entry' },
+ { label => N("verify_cert ="), val => \$racoon->{$number}{7}[1], type => 'entry' },
+ { label => N("my_identifier ="), val => \$racoon->{$number}{8}[1], type => 'entry' },
+ { label => N("peers_identifier ="), val => \$racoon->{$number}{9}[1], type => 'entry' },
+ { label => N("proposal ="), val => \$racoon->{$number+1}{1}[0], type => 'entry' },
+ { label => N("encryption_algorithm ="), val => \$racoon->{$number+1}{2}[1], type => 'entry' },
+ { label => N("hash_algorithm ="), val => \$racoon->{$number+1}{3}[1], type => 'entry' },
+ { label => N("authentication_method ="), val => \$racoon->{$number+1}{4}[1], type => 'entry' },
+ { label => N("dh_group ="), val => \$racoon->{$number+1}{5}[1], type => 'entry' },
+ ]
+) or goto step_configure_racoon_conf;
+
+} elsif ($choice =~ /^sainfo/) {
+ $in->ask_from('',
+N("Your %s file has several sctions.\n
+You can now edit the sainfo section entries.
+Choose continue when you are done to write the data.\n", $racoon_conf),
+ [ { label => N("sainfo_source_address ="), val => \$racoon->{$number}{1}[2], type => 'entry' },
+ { label => N("sainfo_source_proto ="), val => \$racoon->{$number}{1}[3], type => 'entry' },
+ { label => N("sainfo_dest_address ="), val => \$racoon->{$number}{1}[5], type => 'entry' },
+ { label => N("sainfo_dest_proto ="), val => \$racoon->{$number}{1}[6], type => 'entry' },
+ { label => N("pfs_group ="), val => \$racoon->{$number}{2}[1], type => 'entry' },
+ { label => N("lifetime_number ="), val => \$racoon->{$number}{3}[2], type => 'entry' },
+ { label => N("lifetime_unit ="), val => \$racoon->{$number}{3}[3], type => 'entry' },
+ { label => N("encryption_algorithm ="), val => \$racoon->{$number}{4}[1], type => 'entry' },
+ { label => N("authentication_algorithm ="), val => \$racoon->{$number}{5}[1], type => 'entry' },
+ { label => N("compression_algorithm ="), val => \$racoon->{$number}{6}[1], 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 or 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 } ]);
+
+#print Dumper($racoon)."\n";
+my $number = network::ipsec::matched_section_key_number_racoon_conf($choice,$racoon);
+network::ipsec::remove_section_racoon_conf($choice,$racoon,$number);
+#print Dumper($racoon)."\n";
+ @section_names = network::ipsec::get_section_names_racoon_conf($racoon_conf,$racoon) if -e $racoon_conf;
+
+ 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 ressources through the Internet,
+in a secure way, using a VPN connection.\n
+
+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
+}