ipsec/0040755000567100000120000000000007701233276011654 5ustar jcameronwheelipsec/images/0040775000567100000120000000000007701233300013107 5ustar jcameronwheelipsec/images/icon.gif0100644000567100000120000000267107701233275014542 0ustar jcameronwheelGIF89a00̙ZZZfffFFFݘCCC+++AAA,,,ޮ444{{{ ___RRR222zzz|||GGGiii 000mmmaaaWWW ddduuu$$$999///666=== 𠠠>>>ĝ:::;;;ƽ~~~<<<׌???bbb```^^^ooo%%%\\\[[[VVVYYYյ凇˻cccͅ,00H C#@E b CZd C-d Y"C 0he̅0Y R:uF0OM4)  T [ bP v!DA%5q)T`ѢmX.xQ0bH:ð́4kެmp q^]DGYf@٤e&{u:zQ=j8Gm AHNBBbY "d@$J0I—>>VVVvvv..."""fffJJJ222 򚚚&&&666BBBjjj^^^RRR***:::nnnzzzFFFNNNbbbrrr~~~ZZZFFNRRV,009@ E(@=)3A:2<8B<8>6'=+)>61A+<) 4*B%2. 4%2>"E0CUañN 8-i!?IyGq)'ىM$ * !$1 tCH |`AA /0-2&k£$hPYea`1!zB&*-(P`Ѡcph al`CApud {XW,882TdFbkɜ (*luz t@.1lwMw&agS{rtvxMu-o~{n#jf o} K Ƞ )mIaM@L=KB0]F.[@EM,al0fk ƪ;ipsec/images/config.gif0100644000567100000120000000104307701233276015050 0ustar jcameronwheelGIF89a00UUU999rrr㎎ fff߽@\!,00'dihl@ # `8Xp),Qs,(u bER؈5a}UwDP%4IKx&JL ~& S kS% KB$ SS S AS aKTT'њ̈Ǐ\ Aï[BťȊwK SzS>1VeM"Ɩ(jP }LHE$#]Lp#sC|)b4 E$D1YUa TLT$Ѓp.WIxr!у Z ǧ9IdR5ӡP`SUKp̳ݽh0ķ߿Iˆ+!xob2"GV\/hyʗ#?--N^zu Ȓ#M;ipsec/images/smallicon.gif0100664000567100000120000000127607701233276015576 0ustar jcameronwheelGIF87a}}}{{{wwwoooWWWQQQEEE777---+++%%% rrrpppnnnlllXXX@@@<<<444,,, ,;;8'220RR8. ;8C/RJ*N8C8D0%(@8=3 ʧCʢ%"tH"TOD"Dk*J$ZIb!# ^20)1 $InvrXʐ@;ipsec/lang/0040775000567100000120000000000007701233276012577 5ustar jcameronwheelipsec/lang/en0100664000567100000120000002013407701233276013121 0ustar jcameronwheelindex_title=IPsec VPN Configuration index_eipsec=The FreeSWAN command $1 was not found on your system or is not the right program. Maybe it is not installed, or your module configuration is incorrect. index_out=The output from $1 was : index_version=FreeSWAN version $1 index_econfig=The FreeSWAN configuration file $1 was not found on your system. Maybe it is not installed, or your module configuration is incorrect. index_nokey=No host key appears to listed in the file $1. One must be generated for your system before you can define any VPN connections. index_newkey=Generate key for host: index_none=No IPsec VPN connections have been defined yet. index_add=Add a new IPsec VPN connection. index_adddef=Add defaults for all connections index_start=Start IPsec Server index_startdesc=Click this button to start the FreeSWAN IPsec server process. Until it is started your system will be unable to accept or establish connections. index_stop=Stop IPsec Server index_stopdesc=Click this button to shut down the FreeSWAN IPsec server process and terminate all established connections. index_restart=Apply Configuration index_restartdesc=Click this button to activate the current configuration by re-starting the running FreeSWAN IPsec server process. Any established connections will be terminated. index_conn=Connection $1 index_defconn=Defaults for all connections index_boot=Start at boot time index_bootdesc=Change this option to control whether the IPsec server is started at boot time or not. index_return=connections list index_header1=Existing VPN connections index_header2=Global options and policies index_up=Start Connection: index_updesc=Select a connection from the list next to this button, and click it to attempt its immediate establishment. index_nopol=No network policies were found - maybe your network configuration is incorrect. index_import=Import connection from file stop_err=Failed to stop IPsec server start_err=Failed to start IPsec server restart_err=Failed to re-start IPsec server start_elog=The following errors were logged : $1 newkey_err=Failed to generate key newkey_ehost=Missing or invalid hostname edit_title1=Create Connection edit_title2=Edit Connection edit_header=IPsec VPN connection details edit_name=Connection name edit_auto=At IPsec startup edit_amode=Default (usually $edit_amodeignore) edit_amodeadd=Add connection edit_amodestart=Start connection edit_amodeignore=Ignore edit_comp=Compress data? edit_cmodeyes=$yes edit_cmodeno=$no edit_cmode=Default (usually $no) edit_type=Connection type edit_tmodetunnel=Tunnel (host or network) edit_tmodetransport=Transport (host to host only) edit_tmodepassthrough=Passthrough (no encryption) edit_tmode=Default (usually Tunnel) edit_left=Local or left system's settings edit_right=Remote or right system's settings edit_addr=Public IP address edit_addr-1=None edit_addr0=From default route edit_addr1=Automatic edit_addr2=Automatic from DNS edit_addr3=Address or hostname .. edit_id=System identifier edit_id1=IP address .. edit_id2=Hostname .. edit_subnet=Private subnet behind system edit_hop=Next hop to other system edit_hopdir=Automatic edit_hopip=IP address .. edit_hoproute=Default route edit_key=System's public key edit_key0=None edit_key1=Lookup in DNS edit_key2=Entered below .. edit_none=None edit_default=Defaults for all connections edit_export=Export Configuration .. edit_return=connection details config_title=Server Configuration config_header=Global VPN server settings config_ifaces=Network interfaces for IPsec config_ifaces0=Default config_ifaces1=None config_ifaces2=Default route interface config_ifaces3=Listed below .. config_riface=Real interface config_iiface=IPsec interface config_syslog=Syslog logging level config_fac=Log to facility config_pri=with priority config_fwd=Enable IP forwarding? config_err=Failed to save server configuration config_eri=The real interface '$1' is listed more than once config_enone=No network interfaces were specified showkey_title=Show Public Key showkey_desc1=The public RSA key shown below should be copied into the configuration of other systems connecting to this one, in the section related to this host. showkey_desc2=The values shown below can be used to create a DNS KEY record for this host, so that other systems connecting to it can look up its public key. showkey_flags=Flags showkey_proto=Protocol showkey_alg=Algorithm showkey_key=Key data policy_desc_block=Blocked Networks policy_desc_clear=Clear Traffic Networks policy_desc_clear-or-private=Opportunistic Networks policy_desc_private=Encrypted Networks policy_desc_private-or-clear=Encrypted or Clear Networks policy_desc=$1 Networks policy_longdesc_block=Communication to the networks selected below will never be allowed. policy_longdesc_clear=Communication to the networks selected below will always be in the clear. policy_longdesc_clear-or-private=Communication to the networks selected below will be in the clear unless the other end initiates IPsec encryption. policy_longdesc_private=Communication to the networks selected below will always be encrypted with IPsec. policy_longdesc_private-or-clear=Communication to the networks selected below will be encrypted if possible but in the clear otherwise. If the target host has a DNS KEY record, data must be sent encrypted. policy_longdesc=The networks selected below are used for the $1 policy. policy_mode0=No networks policy_mode1=All networks policy_mode2=Listed networks .. policy_net=Network address policy_mask=Prefix policy_err=Failed to save networks policy_enet=Invalid network IP address on row $1 policy_emask=Invalid prefix length on row $2 save_err=Failed to save connection save_ename=Missing or invalid connection name save_eleft=Missing or invalid local server address or hostname save_eright=Missing or invalid remote server address or hostname save_eleftid1=Missing or invalid local server identifying IP address save_erightid1=Missing or invalid remote server identifying IP address save_eleftid2=Missing or invalid local server identifying hostname save_erightid2=Missing or invalid remote server identifying hostname save_eleftsubnet=Missing or invalid local server subnet save_erightsubnet=Missing or invalid remote server subnet save_eleftkey=Missing local server public key save_erightkey=Missing remote server public key save_elefthop=Missing or invalid local server next hop gateway save_erighthop=Missing or invalid remote server next hop gateway log_create_conn=Created connection $1 log_delete_conn=Deleted connection $1 log_modify_conn=Modified connection $1 log_import_conn=Imported connection $1 log_up=Started connection $1 log_policy=Saved $1 log_start=Started IPsec server log_stop=Stopped IPsec server log_restart=Re-started IPsec server log_boot=Enabled IPsec at boot time log_unboot=Disabled IPsec at boot time log_config=Saved server configuration up_title=Start Connection up_cmd=Starting connection with command $1 .. export_title=Export Configuration export_desc=This form can be used to export the configuration file section for connection $1, so that it can be easily imported on the server at the other end. export_print=Display configuration in browser export_save=Write configuration to file .. export_ok=Export Now export_err=Failed to export configuration export_efile=Missing filename export_esave=Failed to write to file : $1 export_done=Exported configuration for connection $1 to $2 ($3 bytes). import_title=Import Configuration import_desc=This form can be used to import a configuration file section for a connection, such as one created by the module's export feature on another system. import_upload=Import from upload file .. import_file=Import from server-side file .. import_ok=Import Now import_err=Failed to import configuration import_eupload=No file selected to upload import_efile=No server-side file entered import_eopen=Server-side file does not exist import_eformat=No IPsec connection found in file - maybe it is not a valid export file import_eclash=A connection called $1 already exists. import_done1=Successfully added the new IPsec connection $1. import_done2=Successfully updated the IPsec connection $1. import_over=Overwrite existing connection with the same name? ipsec/ipsec-lib.pl0100664000567100000120000001227007701233276014061 0ustar jcameronwheel# ipsec-lib.pl # Common functions for managing the freeswan config file # XXX check for new errors in log after applying # XXX option to download connection as .conf file, and upload an existing # .conf file for addition do '../web-lib.pl'; &init_config(); # get_config([file]) # Returns an array of configured connections sub get_config { local $file = $_[0] || $config{'file'}; local (@rv, $sect); local $lnum = 0; local $fh = "CONF".$get_config_fh++; open($fh, $file); while(<$fh>) { s/\r|\n//g; s/#.*$//; if (/^\s*([^= ]+)\s*=\s*"([^"]*)"/ || /^\s*([^= ]+)\s*=\s*'([^"]*)'/ || /^\s*([^= ]+)\s*=\s*(\S+)/) { # Directive within a section if ($sect) { $sect->{'values'}->{lc($1)} = $2; $sect->{'eline'} = $lnum; } } elsif (/^\s*include\s+(\S+)/) { # Including possibly multiple files local $inc = $1; if ($inc !~ /^\//) { $file =~ /^(.*)\//; $inc = "$1/$inc"; } local $g; foreach $g (glob($inc)) { local @inc = &get_config($g); map { $_->{'index'} += scalar(@rv) } @inc; push(@rv, @inc); } } elsif (/^\s*(\S+)\s+(\S+)/) { # Start of a section $sect = { 'name' => $1, 'value' => $2, 'line' => $lnum, 'eline' => $lnum, 'file' => $file, 'index' => scalar(@rv), 'values' => { } }; push(@rv, $sect); } $lnum++; } close($fh); return @rv; } # create_conn(&conn) # Add a new connection to the config file sub create_conn { local $lref = &read_file_lines($config{'file'}); push(@$lref, "", &conn_lines($_[0])); &flush_file_lines(); } # modify_conn(&conn) sub modify_conn { local $lref = &read_file_lines($_[0]->{'file'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1, &conn_lines($_[0])); &flush_file_lines(); } # delete_conn(&conn) sub delete_conn { local $lref = &read_file_lines($_[0]->{'file'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1); &flush_file_lines(); } # conn_lines(&conn) sub conn_lines { local @rv; push(@rv, $_[0]->{'name'}." ".$_[0]->{'value'}); foreach $o (sort { $a cmp $b } keys %{$_[0]->{'values'}}) { local $v = $_[0]->{'values'}->{$o}; if ($v =~ /\s|=/) { push(@rv, "\t".$o."=\"".$v."\""); } else { push(@rv, "\t".$o."=".$v); } } return @rv; } # is_ipsec_running() sub is_ipsec_running { local $out = `$config{'ipsec'} auto --status 2>&1`; return $? || $out =~ /not running/i ? 0 : 1; } # get_public_key() # Returns this system's public key sub get_public_key { local $out = `$config{'ipsec'} showhostkey --file '$config{'secrets'}' --left 2>&1`; if ($out =~ /leftrsasigkey=(\S+)/) { return $1; } return undef; } # get_public_key_dns() # Returns the flags, protocol, algorithm and key data for the public key, # suitable for creating a DNS KEY record sub get_public_key_dns { local $out = `$config{'ipsec'} showhostkey --file '$config{'secrets'}' 2>&1`; if ($out =~ /KEY\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) { return ($1, $2, $3, $4); } return (); } # list_policies() # Returns a list of all policy files sub list_policies { local ($f, @rv); opendir(DIR, $config{'policies_dir'}); while($f = readdir(DIR)) { push(@rv, $f) if ($f !~ /^\./ && $f !~ /\.rpmsave$/); } closedir(DIR); return @rv; } # read_policy(name) sub read_policy { local @rv; open(FILE, "$config{'policies_dir'}/$_[0]"); while() { push(@rv, "$1/$2") if (/^\s*([0-9\.]+)\/(\d+)/); } close(FILE); return @rv; } # write_policy(name, &nets) sub write_policy { local $lref = &read_file_lines("$config{'policies_dir'}/$_[0]"); local $l = 0; foreach $p (@{$_[1]}) { while($l < @$lref && $lref->[$l] !~ /^\s*([0-9\.]+)\/(\d+)/) { $l++; } if ($l < @$lref) { # Found line to replace $lref->[$l] = $p; } else { # Add at end push(@$lref, $p); } $l++; } while($l < @$lref) { if ($lref->[$l] =~ /^\s*([0-9\.]+)\/(\d+)/) { splice(@$lref, $l, 1); } else { $l++; } } &flush_file_lines(); } # wrap_lines(text, width) # Given a multi-line string, return an array of lines wrapped to # the given width sub wrap_lines { local $rest = $_[0]; local @rv; while(length($rest) > $_[1]) { push(@rv, substr($rest, 0, $_[1])); $rest = substr($rest, $_[1]); } push(@rv, $rest) if ($rest ne ''); return @rv; } # before_start() # Work out which log file IPsec messages go to, and record the size sub before_start { @ipsec_logfiles = ( $config{'logfile'} ); if (&foreign_check("syslog")) { # Find all syslog logfiles &foreign_require("syslog", "syslog-lib.pl"); local $conf = &syslog::get_config(); foreach $c (@$conf) { push(@ipsec_logfiles, $c->{'file'}) if ($c->{'file'} && -f $c->{'file'}); } } @ipsec_logfiles = &unique(@ipsec_logfiles); @ipsec_logfile_sizes = map { local @st = stat($_); $st[7] } @ipsec_logfiles; } # after_start() # Check any new IPsec-related messages in the log for errors sub after_start { # Give the server a chance to start sleep(5); # Look for new error messages local $i; for($i=0; $i<@ipsec_logfiles; $i++) { open(LOG, $ipsec_logfiles[$i]) || next; seek(LOG, $ipsec_logfile_sizes[$i], 0); while() { s/\r|\n//g; if (/ipsec/i && /error/i) { s/^(\S+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\S+)\s+//; push(@errs, $_); } } close(LOG); } # Fail if there were any if (@errs) { &error(&text('start_elog', "

".join("
", @errs)."

")); } } 1; ipsec/module.info0100664000567100000120000000027007701233277014015 0ustar jcameronwheelcategory=net longdesc=Set up a client or server for an IPsec VPN using FreeSWAN. depends=net syslog proc 1.100 os_support=*-linux desc=IPsec VPN Configuration version=1.100 name=IPsec ipsec/start.cgi0100775000567100000120000000043707701233276013503 0ustar jcameronwheel#!/usr/local/bin/perl # start.cgi # Start the IPsec server require './ipsec-lib.pl'; &error_setup($text{'start_err'}); &before_start(); $out = &backquote_logged("$config{'start_cmd'} 2>&1"); if ($?) { &error("

$out
"); } &after_start(); &webmin_log("start"); &redirect(""); ipsec/config.info0100664000567100000120000000052607701233276014000 0ustar jcameronwheelfile=FreeSWAN IPsec configuration file,0 secrets=IPsec secrets file,0 ipsec=Full path to ipsec command,0 policies_dir=Policy files directory,0 start_cmd=Command to start IPsec server,0 stop_cmd=Command to stop IPsec server,0 restart_cmd=Command to re-start IPsec server,3,Just stop and start logfile=File to which IPsec messages are logged,0 ipsec/index.cgi0100775000567100000120000001260107701233276013451 0ustar jcameronwheel#!/usr/local/bin/perl # index.cgi # Display existing IPsec tunnels require './ipsec-lib.pl'; # Make sure the ipsec command exists if (!&has_command($config{'ipsec'}) || ($out = `$config{'ipsec'} --version 2>&1`) !~ /FreeS\/WAN\s+([^ \n\(]+)/i) { &header($text{'index_title'}, "", "intro", 1, 1, 0, &help_search_link("freeswan", "doc", "google")); print "
\n"; print "

",&text('index_eipsec', "$config{'ipsec'}", "$gconfig{'webprefix'}/config.cgi?$module_name"),"

\n"; if ($out) { print &text('index_out', "$config{'ipsec'} --version"),"\n"; print "

$out
\n"; } } else { $ipsec_version = $1; &header($text{'index_title'}, "", "intro", 1, 1, 0, &help_search_link("freeswan", "doc", "google"), undef, undef, &text('index_version', $ipsec_version)); print "
\n"; # Make sure the config file exists if (!-r $config{'file'}) { print "

",&text('index_econfig', "$config{'file'}", "$gconfig{'webprefix'}/config.cgi?$module_name"),"

\n"; } else { # Check for the host secret open(SEC, $config{'secrets'}); while() { s/\r|\n//g; s/#.*$//; if (/Modulus:\s*(\S+)/) { $gotkey = 1; } } close(SEC); if (!$gotkey) { # No key setup yet .. offer to create one print "

",&text('index_nokey', "$config{'secrets'}"),"
\n"; print "

\n"; print "\n"; printf "\n", &get_system_hostname(); print "
\n"; } else { # Show icons for connections print "

$text{'index_header1'}

\n"; @conf = &get_config(); @conns = grep { $_->{'name'} eq 'conn' } @conf; if (@conns) { foreach $c (@conns) { push(@links, "edit.cgi?idx=". $c->{'index'}); if ($c->{'value'} eq '%default') { push(@titles, "$text{'index_defconn'}"); $has_default++; } else { push(@titles, &text('index_conn', "$c->{'value'}")); push(@start, $c->{'value'}); } push(@icons, "images/conn.gif"); } &icons_table(\@links, \@titles, \@icons); } else { print "$text{'index_none'}

\n"; } print "$text{'index_add'}"; if (!$has_default) { print " " x 3; print "$text{'index_adddef'}"; } print " " x 3; print "$text{'index_import'}"; print "

\n"; # Show icons for various options print "


\n"; print "

$text{'index_header2'}

\n"; @links = ( "edit_config.cgi", "showkey.cgi" ); @titles = ( $text{'config_title'}, $text{'showkey_title'} ); @icons = ( "images/config.gif", "images/showkey.gif" ); if ($ipsec_version =~ /(\d+)/ && $1 >= 2) { @policies = &list_policies(); foreach $p (@policies) { push(@links, "edit_policy.cgi?policy=$p"); push(@titles, $text{'policy_desc_'.$p} || &text('policy_desc', $p)); push(@icons, "images/policy.gif"); } $got_policies = 1; } &icons_table(\@links, \@titles, \@icons, 7); if (!@policies && $got_policies) { print "",&text('index_nopol', "$gconfig{'webprefix'}/config.cgi?$module_name"),"

\n"; } print "


\n"; print "\n"; # Start connection button if (@start && &is_ipsec_running()) { print "\n"; print "\n"; print "\n"; print "\n"; } # Start/stop/restart ipsec buttons if (&is_ipsec_running()) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } else { print "\n"; print "\n"; print "\n"; print "\n"; } # Show boot-time start button if (&foreign_check("init") && &foreign_require("init", "init-lib.pl") && (%iconfig = &foreign_config("init")) && $iconfig{'init_dir'} && (($starting = &init::action_status("ipsec")) > 0)) { print "\n"; print "\n"; print "\n", $starting == 2 ? "" : "checked", $text{'no'}; print "\n"; print "\n"; } print "
\n"; print "$text{'index_updesc'}
$text{'index_restartdesc'}
$text{'index_stopdesc'}
$text{'index_startdesc'}
\n"; printf " %s\n", $starting == 2 ? "checked" : "", $text{'yes'}; printf " %s$text{'index_bootdesc'}
\n"; } } } print "
\n"; &footer("/", $text{'index'}); ipsec/config0100664000567100000120000000036107701233276013043 0ustar jcameronwheelfile=/etc/ipsec.conf secrets=/etc/ipsec.secrets ipsec=/usr/local/sbin/ipsec policies_dir=/etc/ipsec.d/policies start_cmd=/etc/init.d/ipsec start stop_cmd=/etc/init.d/ipsec stop restart_cmd=/etc/init.d/ipsec restart logfile=/var/log/messages ipsec/stop.cgi0100775000567100000120000000037107701233276013330 0ustar jcameronwheel#!/usr/local/bin/perl # stop.cgi # Stop the IPsec server require './ipsec-lib.pl'; &error_setup($text{'stop_err'}); $out = &backquote_logged("$config{'stop_cmd'} 2>&1"); if ($?) { &error("
$out
"); } &webmin_log("stop"); &redirect(""); ipsec/restart.cgi0100775000567100000120000000056107701233276014030 0ustar jcameronwheel#!/usr/local/bin/perl # restart.cgi # Re-start the IPsec server require './ipsec-lib.pl'; &error_setup($text{'restart_err'}); $cmd = $config{'restart_cmd'} || "($config{'stop_cmd'} && $config{'start_cmd'})"; &before_start(); $out = &backquote_logged("$cmd 2>&1"); if ($?) { &error("
$out
"); } &after_start(); &webmin_log("restart"); &redirect(""); ipsec/edit_policy.cgi0100775000567100000120000000247707701233276014660 0ustar jcameronwheel#!/usr/local/bin/perl # edit_policy.cgi # Display entries from a policy file for editing require './ipsec-lib.pl'; &ReadParse(); &header($text{'policy_desc_'.$in{'policy'}} || &text('policy_desc', $in{'policy'}), ""); print "
\n"; # Show explanation of this policy print $text{'policy_longdesc_'.$in{'policy'}} || &text('policy_longdesc', $in{'policy'}),"

\n"; print "

\n"; print "\n"; @policies = &read_policy($in{'policy'}); $mode = !@policies ? 0 : @policies == 1 && $policies[0] eq "0.0.0.0/0" ? 1 : 2; foreach $m (0 .. 2) { printf " %s\n", $m, $mode == $m ? "checked" : "", $text{'policy_mode'.$m}; } print "
\n"; # Show a table of networks print "\n"; print " ", "\n"; $i = 0; foreach $p ($mode == 2 ? @policies : ( ), "", "") { local ($n, $m) = split(/\//, $p); print "\n"; print "\n"; print "\n"; print "\n"; $i++; } print "
$text{'policy_net'}$text{'policy_mask'}
\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); ipsec/newkey.cgi0100775000567100000120000000061207701233276013643 0ustar jcameronwheel#!/usr/local/bin/perl # newkey.cgi # Generate a new host key require './ipsec-lib.pl'; &ReadParse(); &error_setup($text{'newkey_err'}); $in{'host'} =~ /^[a-z0-9\.\-]+$/i || &error($text{'newkey_ehost'}); $out = &backquote_logged("$config{'ipsec'} newhostkey --output '$config{'secrets'}' --hostname '$in{'host'}' 2>&1"); $? && &error("
$out
"); &webmin_log("newkey"); &redirect(""); ipsec/bootup.cgi0100775000567100000120000000060307701233276013651 0ustar jcameronwheel#!/usr/local/bin/perl # bootup.cgi # Enable or disable the ipsec bootup action require './ipsec-lib.pl'; &foreign_require("init", "init-lib.pl"); &ReadParse(); if ($in{'boot'} && $in{'starting'} != 2) { &init::enable_at_boot("ipsec"); &webmin_log("boot"); } elsif (!$in{'boot'} && $in{'starting'} == 2) { &init::disable_at_boot("ipsec"); &webmin_log("unboot"); } &redirect(""); ipsec/edit.cgi0100775000567100000120000001263407701233276013275 0ustar jcameronwheel#!/usr/local/bin/perl # edit.cgi # Show a form for editing or creating a connection require './ipsec-lib.pl'; &ReadParse(); if ($in{'new'}) { &header($text{'edit_title1'}, "", "edit"); } else { &header($text{'edit_title2'}, "", "edit"); @conf = &get_config(); $conn = $conf[$in{'idx'}]; } print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'edit_header'}
\n"; # Connection name print "\n"; if ($conn->{'value'} eq '%default' || $in{'new'} == 2) { print "\n"; } else { printf "\n", $conn->{'value'}; } # ipsec startup option $a = $conn->{'values'}->{'auto'}; print "\n"; print "\n"; # compression option $c = $conn->{'values'}->{'compress'}; print "\n"; # connection type option $t = $conn->{'values'}->{'type'}; print "\n"; print "\n"; foreach $d ('left', 'right') { print "
$text{'edit_name'}$text{'edit_default'}$text{'edit_auto'}
$text{'edit_comp'} \n"; foreach $o ('yes', 'no', '') { printf " %s\n", $o, $c eq $o ? "checked" : "", $text{'edit_cmode'.$o}; } print "$text{'edit_type'}

\n"; print "\n"; print "\n"; print "
",$text{'edit_'.$d},"
\n"; # left/right $a = $conn->{'values'}->{$d}; $amode = $a eq '%defaultroute' ? 0 : $a eq '%any' ? 1 : $a eq '%opportunistic' ? 2 : 3; if ($a eq '' && $conn->{'value'} eq '%default' || $in{'new'} == 2) { $amode = -1; } print "\n", $amode == 3 ? $a : undef; # leftid/rightid $i = $conn->{'values'}->{$d."id"}; $imode = $i =~ /^\@/ ? 2 : $i eq '' ? 0 : 1; print "\n"; # leftrsasigkey/rightrsasigkey $k = $conn->{'values'}->{$d.'rsasigkey'}; if ($in{'new'} == 1 && $d eq 'left') { $k = &get_public_key(); } $kmode = $k eq '%dns' ? 1 : $k ? 2 : 0; print " ", "\n"; # leftnexthop/rightnexthop $h = $conn->{'values'}->{$d.'nexthop'}; $hmode = $h eq '%direct' ? 1 : $h eq '%defaultroute' ? 3 : $h ? 2 : 0; print "\n", $hmode == 2 ? $h : undef; } print "
$text{'edit_addr'} \n"; foreach $m ($amode == -1 ? (-1 .. 3) : (0 .. 3)) { printf "%s\n", $m, $m == $amode ? "checked" : "", $text{'edit_addr'.$m}; } printf "
$text{'edit_id'} \n"; printf " %s\n", $imode == 0 ? "checked" : "", $text{'default'}; printf " %s\n", $imode == 1 ? "checked" : "", $text{'edit_id1'}; printf " %s\n", $imode == 2 ? "checked" : "", $text{'edit_id2'}; printf "\n", $imode == 2 ? substr($i, 1) : $i; # leftsubnet/rightsubnet $s = $conn->{'values'}->{$d.'subnet'}; print "
$text{'edit_subnet'} \n"; printf " %s\n", $s ? "" : "checked", $text{'edit_none'}; printf " %s\n", $s ? "checked" : ""; print "
$text{'edit_key'}\n"; foreach $m (0 .. 2) { printf " %s\n", $m, $kmode == $m ? "checked" : "", $text{'edit_key'.$m}; } print "
$text{'edit_hop'} \n"; printf " %s\n", $hmode == 0 ? "checked" : "", $text{'default'}; printf " %s\n", $hmode == 1 ? "checked" : "", $text{'edit_hopdir'}; printf " %s\n", $hmode == 3 ? "checked" : "", $text{'edit_hoproute'}; printf " %s\n", $hmode == 2 ? "checked" : "", $text{'edit_hopip'}; printf "
\n"; print "\n"; if ($in{'new'}) { print "\n"; } else { print "\n"; if ($conn->{'value'} ne '%default') { print "\n"; } print "\n"; } print "
\n"; print "
\n"; &footer("", $text{'index_return'}); ipsec/save.cgi0100775000567100000120000000663207701233276013307 0ustar jcameronwheel#!/usr/local/bin/perl # save.cgi # Save, create or delete an ipsec connection require './ipsec-lib.pl'; &ReadParse(); if ($in{'export'}) { # Just redirect to export form &redirect("export_form.cgi?idx=$in{'idx'}"); exit; } @conf = &get_config(); if ($in{'new'}) { $conn = { 'name' => 'conn', 'values' => { } }; $conn->{'value'} = '%default' if ($in{'new'} == 2); } else { $conn = $conf[$in{'idx'}]; } &error_setup($text{'save_err'}); $file = $conn->{'file'} || $config{'file'}; &lock_file($file); if ($in{'delete'}) { # Just remove this connection &delete_conn($conn); } else { # Validate and store general inputs if ($conn->{'value'} ne '%default') { $in{'name'} =~ /^\S+$/ || &error($text{'save_ename'}); $conn->{'value'} = $in{'name'}; } if ($in{'auto'}) { $conn->{'values'}->{'auto'} = $in{'auto'}; } else { delete($conn->{'values'}->{'auto'}); } if ($in{'comp'}) { $conn->{'values'}->{'compress'} = $in{'comp'}; } else { delete($conn->{'values'}->{'compress'}); } if ($in{'type'}) { $conn->{'values'}->{'type'} = $in{'type'}; } else { delete($conn->{'values'}->{'type'}); } # Validate and store left/right inputs foreach $d ('left', 'right') { # left/right if ($in{"${d}_mode"} == -1) { delete($conn->{'values'}->{$d}); } elsif ($in{"${d}_mode"} == 0) { $conn->{'values'}->{$d} = '%defaultroute'; } elsif ($in{"${d}_mode"} == 1) { $conn->{'values'}->{$d} = '%any'; } elsif ($in{"${d}_mode"} == 2) { $conn->{'values'}->{$d} = '%opportunistic'; } else { gethostbyname($in{$d}) || &error($text{"save_e${d}"}); $conn->{'values'}->{$d} = $in{$d}; } # leftid/rightid if ($in{"${d}_id_mode"} == 0) { delete($conn->{'values'}->{"${d}id"}); } elsif ($in{"${d}_id_mode"} == 1) { &check_ipaddress($in{"${d}_id"}) || &error($text{"save_e${d}id1"}); $conn->{'values'}->{"${d}id"} = $in{"${d}_id"}; } else { $in{"${d}_id"} =~ /^[a-z0-9\.\-]+$/i || &error($text{"save_e${d}id2"}); $conn->{'values'}->{"${d}id"} = "@".$in{"${d}_id"}; } # leftsubnet/rightsubnet if ($in{"${d}_subnet_def"}) { delete($conn->{'values'}->{"${d}subnet"}); } else { $in{"${d}_subnet"} =~ /^(\S+)\/(\d+)$/ && &check_ipaddress("$1") && $2 <= 32 || &error($text{"save_e${d}subnet"}); $conn->{'values'}->{"${d}subnet"} = $in{"${d}_subnet"}; } # leftrsasigkey/rightrsasigkey if ($in{"${d}_key_mode"} == 0) { delete($conn->{'values'}->{"${d}rsasigkey"}); } elsif ($in{"${d}_key_mode"} == 1) { $conn->{'values'}->{"${d}rsasigkey"} = '%dns'; } else { $in{"${d}_key"} =~ s/\s//g; $in{"${d}_key"} || &error($text{"save_e${d}key"}); $conn->{'values'}->{"${d}rsasigkey"} = $in{"${d}_key"}; } # leftnexthop/rightnexthop if ($in{"${d}_hop_mode"} == 0) { delete($conn->{'values'}->{"${d}nexthop"}); } elsif ($in{"${d}_hop_mode"} == 1) { $conn->{'values'}->{"${d}nexthop"} = '%direct'; } elsif ($in{"${d}_hop_mode"} == 3) { $conn->{'values'}->{"${d}nexthop"} = '%defaultroute'; } else { &check_ipaddress($in{"${d}_hop"}) || &error($text{"save_e${d}hop"}); $conn->{'values'}->{"${d}nexthop"} = $in{"${d}_hop"}; } } # Update or add if ($in{'new'}) { &create_conn($conn); } else { &modify_conn($conn); } } &unlock_file($file); &webmin_log($in{'new'} ? "create" : $in{'delete'} ? "delete" : "modify", "conn", $conn->{'value'}, $conn->{'values'}); &redirect(""); ipsec/showkey.cgi0100775000567100000120000000155207701233276014036 0ustar jcameronwheel#!/usr/local/bin/perl # showkey.cgi # Show this host's public key in a format suitable for inclusion in the config # file of another host require './ipsec-lib.pl'; &header($text{'showkey_title'}, ""); print "
\n"; print "$text{'showkey_desc1'}

\n"; print "",join("
", &wrap_lines(&get_public_key(), 80)),"

\n"; print "$text{'showkey_desc2'}

\n"; ($flags, $proto, $alg, $key) = &get_public_key_dns(); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'showkey_flags'} $flags
$text{'showkey_proto'} $proto
$text{'showkey_alg'} $alg
$text{'showkey_key'} ", join("
", &wrap_lines($key, 80)),"
\n"; print "


\n"; &footer("", $text{'index_return'}); ipsec/edit_config.cgi0100775000567100000120000000665307701233276014626 0ustar jcameronwheel#!/usr/local/bin/perl # edit_config.cgi # Show global configuration options require './ipsec-lib.pl'; &header($text{'config_title'}, ""); print "
\n"; @conf = &get_config(); ($config) = grep { $_->{'name'} eq 'config' } @conf; print "
\n"; print "\n"; print "\n"; print "
$text{'config_header'}
\n"; # Get list of interfaces &foreign_require("net", "net-lib.pl"); @allifaces = &unique(sort { $a cmp $b } (map { $_->{'fullname'} } &net::active_interfaces()), (map { $_->{'fullname'} } &net::boot_interfaces()) ); # Show interfaces to listen on $i = $config->{'values'}->{'interfaces'}; $imode = $i eq '%none' ? 1 : $i eq '%defaultroute' ? 2 : $i ? 3 : 0; print "\n"; # syslog facility/level &foreign_require("syslog", "syslog-lib.pl"); $s = $config->{'values'}->{'syslog'}; print "\n"; # automatic forwarding enable $f = $config->{'values'}->{'forwardcontrol'}; print "\n"; printf "\n", $f eq 'yes' ? "" : "checked", $text{'no'}; print "\n"; print "\n"; print "
$text{'config_ifaces'} \n"; foreach $m (0 .. 3) { printf " %s\n", $m, $m == $imode ? "checked" : "", $text{'config_ifaces'.$m}; } @iflist = $imode == 3 ? split(/\s+/, $i) : (); print "
\n"; print " ", "\n"; $n = 0; foreach $ifc (@iflist, "") { local ($ii, $ri) = split(/=/, $ifc); print "\n"; $found = 0; print "\n"; $found = 0; print "\n"; print "\n"; $n++; } print "
$text{'config_riface'}$text{'config_iiface'}
$text{'config_syslog'} \n"; printf " %s (%s)\n", $s ? "" : "checked", $text{'default'}, "daemon.error"; printf " %s\n", $s ? "checked" : "", $text{'config_fac'}; ($fac, $pri) = split(/\./, $s); $pri =~ s/warn$/warning/; $pri =~ s/panic$/emerg/; $pri =~ s/error$/err/; print " $text{'config_pri'}\n"; print "
$text{'config_fwd'} %s\n", $f eq 'yes' ? "checked" : "", $text{'yes'}; printf " %s
\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); ipsec/log_parser.pl0100644000567100000120000000120007701233276014334 0ustar jcameronwheel# log_parser.pl # Functions for parsing this module's logs do 'ipsec-lib.pl'; # parse_webmin_log(user, script, action, type, object, ¶ms) # Converts logged information from this module into human-readable form sub parse_webmin_log { local ($user, $script, $action, $type, $object, $p, $long) = @_; if ($type eq "conn") { return &text('log_'.$action.'_conn', "$object"); } elsif ($action eq "up") { return &text('log_up', "$object"); } elsif ($action eq "policy") { return &text('log_policy', $text{'policy_desc_'.$object} || &text('policy_desc', $object)); } else { return $text{'log_'.$action}; } } ipsec/save_policy.cgi0100775000567100000120000000132307701233276014656 0ustar jcameronwheel#!/usr/local/bin/perl # save_policy.cgi # Update some policy file require './ipsec-lib.pl'; &ReadParse(); &error_setup($text{'policy_err'}); if ($in{'mode'} == 0) { @policies = ( ); } elsif ($in{'mode'} == 1) { @policies = ( "0.0.0.0/0" ); } else { for($i=0; defined($n = $in{"net_$i"}); $i++) { next if ($n eq ''); $m = $in{"mask_$i"}; &check_ipaddress($n) || &error(&text('policy_enet', $i+1)); $m =~ /^\d+/ && $m <= 32 || &error(&text('policy_emask', $i+1)); push(@policies, "$n/$m"); } } &lock_file("$config{'policies_dir'}/$in{'policy'}"); &write_policy($in{'policy'}, \@policies); &unlock_file("$config{'policies_dir'}/$in{'policy'}"); &webmin_log("policy", undef, $in{'policy'}); &redirect(""); ipsec/save_config.cgi0100775000567100000120000000270707701233276014633 0ustar jcameronwheel#!/usr/local/bin/perl # save_config.cgi # Update or create the config section require './ipsec-lib.pl'; &ReadParse(); &error_setup($text{'config_err'}); @conf = &get_config(); ($config) = grep { $_->{'name'} eq 'config' } @conf; if (!$config) { $config = { 'name' => 'config', 'value' => 'setup', 'values' => { } }; } # Validate and store inputs if ($in{'ifaces_mode'} == 0) { delete($config->{'values'}->{'interfaces'}); } elsif ($in{'ifaces_mode'} == 1) { $config->{'values'}->{'interfaces'} = '%none'; } elsif ($in{'ifaces_mode'} == 2) { $config->{'values'}->{'interfaces'} = '%defaultroute'; } else { for($n=0; defined($ri = $in{"ri_$n"}); $n++) { next if (!$ri); $ii = $in{"ii_$n"}; $done{$ri}++ && &error(&text('config_eri', $ri)); push(@ifaces, "$ii=$ri"); } @ifaces || &error($text{'config_enone'}); $config->{'values'}->{'interfaces'} = join(" ", @ifaces); } if ($in{'syslog_def'}) { delete($config->{'values'}->{'syslog'}); } else { $config->{'values'}->{'syslog'} = $in{'fac'}.".".$in{'pri'}; } if ($in{'fwd'} eq 'yes' || $config->{'values'}->{'forwardcontrol'}) { $config->{'values'}->{'forwardcontrol'} = $in{'fwd'}; } else { delete($config->{'values'}->{'forwardcontrol'}); } # Create or update the section $file = $config->{'file'} || $config{'file'}; &lock_file($file); if ($config->{'file'}) { &modify_conn($config); } else { &create_conn($config); } &unlock_file($file); &webmin_log("config"); &redirect(""); ipsec/up.cgi0100775000567100000120000000143407701233276012770 0ustar jcameronwheel#!/usr/local/bin/perl # up.cgi # Attempt to open a connection that was not started automatically require './ipsec-lib.pl'; &ReadParse(); $| = 1; $theme_no_table++; &header($text{'up_title'}, ""); print "
\n"; # Try to connect $cmd = "$config{'ipsec'} auto --up '$in{'conn'}'"; print "",&text('up_cmd', "$cmd"),"\n"; print "
";
&foreign_require("proc", "proc-lib.pl");
&proc::safe_process_exec_logged($cmd, 0, 0, STDOUT, undef, 1);
print "
\n"; # Save connection in config &lock_file("$module_config_directory/config"); $config{'conn'} = $in{'conn'}; &write_file("$module_config_directory/config", \%config); &unlock_file("$module_config_directory/config"); if (!$?) { &webmin_log("up", undef, $in{'conn'}); } print "
\n"; &footer("", $text{'index_return'}); ipsec/help/0040775000567100000120000000000007701233276012606 5ustar jcameronwheelipsec/help/intro.html0100664000567100000120000000521607701233276014630 0ustar jcameronwheel
IPsec VPN Configuration
This module allows you to configure FreeSWAN, a free implementation of the IPsec VPN protocols for Linux. IPsec transparently encrypts all data travelling between two networks, and unlike other VPN protocols makes use of existing IP addresses for the VPN rather than creating new ones. It is typically used to allow remote clients access to a private internal LAN over the Internet.

For two systems to communicate using IPsec, each must have a connection defined containing the IP address, identifying hostname, RSA key and private network (if any) of both systems. Each configured connection will show up as an icon on the module's main page. Often the configuration details that you enter when creating a connection will be identical on both systems, only with the local and remote section swapped. Every host that wants to communicate using IPsec must have a public/private key pair, used for both encryption and authentication. Each end of a connection must know the other end's public key, which can be either stored in the connection settings or looked up from a DNS server. The Show Public Key feature of this module can be used to display this host's key.

IPsec is more complex to set up that other VPN protocols, but is more secure and capable, and considered the industry standard. Unfortunately, there are many configuration errors that you can make which may cause your connection to fail to start, or to simply silently fail to route traffic. Even though this module protects you from simple mistakes, it cannot save you from more serious conceptual problems.


On this module's main page are icons for any existing IPsec connections and a link for creating a new one, both of which will taken you to a similar connection details form if clicked on. Below them are icons for editing global settings (such as the network interfaces to use), and displaying the system's public key.

If you are using FreeSWAN version 2, you will also see icons for editing the various policy files that determine what kind of communication (encrypted or clear) will be used for various networks. Typically these can be left unchanged, as the default is to encrypt whenever possible.

Near the bottom of the page are buttons for starting or stopping the FreeSWAN server process, and applying the current settings when it is running. Your system will be unable to establish or receive IPsec connections unless the server is active. The Start Connection button in this section can be used to force the establishment of an IPsec tunnel that is not automatically brought up when the server is started.


ipsec/help/edit.html0100664000567100000120000000520507701233276014420 0ustar jcameronwheel
Edit or Create Connection
This page allowes you to create a new IPsec connection, or edit the details of an existing one. A connection with the same settings must be created on the systems at both ends of the VPN tunnel that you want to create.

Fields in the IPsec VPN connection details section that must be provided for each connection and their recommended settings are listed below :

Connection name
A short name for this connection with no spaces.
At IPsec startup
If Add connection is chosen, this connection will only be established when explicity started. If Start connection is chosen then it will be launched as soon as the IPsec server is started. The former option is best for tunnels to remote systems that are only periodically active, while the latter is suitable for permanent VPN links.
Compress data?
Should be left set to Default.
Connection type
Should also be left set to Default.
Addtional information must be supplied for the systems on either end of the connection. This must be the same on both systems, although generally the Local and Remote details are swapped so that the settings for this host are always in the Local or left system's settings section. The fields in each section and their suggested settings are :
Public IP address
This field should be set to the fixed IP address of the system, or Automatic for a host whose IP is dynamically assigned. Both the local and remote sections cannot have this field set to Automatic at the same time though.
System identifier
The Hostname option should be selected and the system's hostname entered into the text field. FreeSWAN uses this setting to determine which section of the connection applied to which host.
Private subnet behind system
If this system has an internal network connected to it that the other host should be granted access to, enter a network address and prefix length (like 192.168.1.0/24) into this field.
System's public key
You should generally select Entered below and enter the system's RSA public key into the text box. This can be seen on the Show Public Key page on that system.
Next hop to other system
Unless you have an unusual network setup, this field should be set to Default route.
After creating or editing a connection, the Apply Configuration button on the module's main page must be used to activate the changes.


ipsec/config-redhat-linux0100664000567100000120000000040007701233276015437 0ustar jcameronwheelfile=/etc/ipsec.conf secrets=/etc/ipsec.secrets ipsec=/usr/local/sbin/ipsec policies_dir=/etc/ipsec.d/policies start_cmd=/etc/rc.d/init.d/ipsec start stop_cmd=/etc/rc.d/init.d/ipsec stop restart_cmd=/etc/rc.d/init.d/ipsec restart logfile=/var/log/messages ipsec/config-mandrake-linux0100664000567100000120000000042507701233276015761 0ustar jcameronwheelfile=/etc/freeswan/ipsec.conf secrets=/etc/freeswan/ipsec.secrets ipsec=/usr/sbin/ipsec policies_dir=/etc/freeswan/ipsec.d/policies start_cmd=/etc/rc.d/init.d/ipsec start stop_cmd=/etc/rc.d/init.d/ipsec stop restart_cmd=/etc/rc.d/init.d/ipsec restart logfile=/var/log/messages ipsec/export_form.cgi0100775000567100000120000000142507701233276014710 0ustar jcameronwheel#!/usr/local/bin/perl # export_form.cgi # Show a form for exporting an IPsec config section to a file require './ipsec-lib.pl'; &ReadParse(); &header($text{'export_title'}, ""); print "
\n"; print "
\n"; print "\n"; @conf = &get_config(); $conn = $conf[$in{'idx'}]; print &text('export_desc', "$conn->{'value'}"),"

\n"; printf " %s
\n", $text{'export_print'}; printf " %s\n", $text{'export_save'}; print " ",&file_chooser_button("file", 0),"

\n"; print "

\n"; print "
\n"; &footer("edit.cgi?idx=$in{'idx'}", $text{'edit_return'}); ipsec/import_form.cgi0100775000567100000120000000142507701233276014701 0ustar jcameronwheel#!/usr/local/bin/perl # import_form.cgi # Show a form for importing an IPsec config section from a file require './ipsec-lib.pl'; &ReadParse(); &header($text{'import_title'}, ""); print "
\n"; print "
\n"; print "$text{'import_desc'}

\n"; printf " %s\n", $text{'import_upload'}; print "
\n"; printf " %s\n", $text{'import_file'}; print " ",&file_chooser_button("file", 0),"

\n"; print " $text{'import_over'}

\n"; print "

\n"; print "
\n"; &footer("", $text{'index_return'}); ipsec/export.cgi0100775000567100000120000000162007701233276013662 0ustar jcameronwheel#!/usr/local/bin/perl # export.cgi # Actually do the export of a connection require './ipsec-lib.pl'; &error_setup($text{'export_err'}); &ReadParse(); # Get the config lines @conf = &get_config(); $conn = $conf[$in{'idx'}]; $lref = &read_file_lines($conn->{'file'}); @lines = map { "$_\n" } @$lref[$conn->{'line'} .. $conn->{'eline'}]; if ($in{'mode'} == 0) { # Just show on screen print "Content-type: text/plain\n\n"; print @lines; } else { # Save to file $in{'file'} || &error($text{'export_efile'}); open(EXPORT, ">$in{'file'}") || &error(&text('export_esave', $!)); print EXPORT @lines; close(EXPORT); # Tell the user &header($text{'export_title'}, ""); print "
\n"; @st = stat($in{'file'}); print "

",&text('export_done', "$conn->{'value'}", "$in{'file'}", $st[7]),"

\n"; print "


\n"; &footer("edit.cgi?idx=$in{'idx'}", $text{'edit_return'}); } ipsec/import.cgi0100775000567100000120000000317107701233276013656 0ustar jcameronwheel#!/usr/local/bin/perl # import.cgi # Add an imported connection to the config file require './ipsec-lib.pl'; &ReadParseMime(); &error_setup($text{'import_err'}); # Get the file if ($in{'mode'} == 0) { $in{'upload'} || &error($text{'import_eupload'}); $in{'upload'} =~ s/\r//g; @data = split(/\n/, $in{'upload'}); } else { $in{'file'} || &error($text{'import_efile'}); open(FILE, $in{'file'}) || &error($text{'import_eopen'}); while() { s/\r|\n//g; push(@data, $_); } close(FILE); } # Read and validate it $temp = &tempname(); open(TEMP, ">$temp"); print TEMP map { "$_\n" } @data; close(TEMP); @iconf = &get_config($temp); unlink($temp); if (@iconf != 1 || $iconf[0]->{'name'} ne 'conn') { &error($text{'import_eformat'}); } @conf = &get_config(); foreach $c (@conf) { if (lc($c->{'value'}) eq lc($iconf[0]->{'value'})) { $clash = $c; if (!$in{'over'}) { &error(&text('import_eclash', "$iconf[0]->{'value'}")); } } } # Add to the real config file if ($clash) { &lock_file($clash->{'file'}); $lref = &read_file_lines($clash->{'file'}); splice(@$lref, $clash->{'line'}, $clash->{'eline'} - $clash->{'line'} + 1, @data); } else { &lock_file($config{'file'}); $lref = &read_file_lines($config{'file'}); push(@$lref, @data); } &flush_file_lines(); &unlock_all_files(); # Tell the user &header($text{'import_title'}, ""); print "
\n"; print "

",&text($clash ? 'import_done2' : 'import_done1', "$iconf[0]->{'value'}"),"

\n"; print "


\n"; &footer("", $text{'index_return'}); # All done &webmin_log("import", "conn", $iconf[0]->{'value'}, $iconf[0]->{'values'});