diff options
Diffstat (limited to 'perl-install')
-rw-r--r-- | perl-install/network/ipsec.pm | 781 | ||||
-rw-r--r-- | perl-install/standalone/drakvpn | 943 |
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 +} |