) {
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)."
"));
}
}
# get_ipsec_version(&out)
sub get_ipsec_version
{
local $out = `$config{'ipsec'} --version 2>&1`;
${$_[0]} = $out;
return $out =~ /(FreeS\/WAN|Openswan|StrongSWAN|Libreswan)\s+([^ \n\(]+)/i ? ($2,$1) : (undef);
}
# got_secret()
# Returns 1 if a valid secret key file exists, 0 if not
sub got_secret
{
local $gotkey;
open(SEC, "<".$config{'secrets'}) || return 0;
while() {
s/\r|\n//g;
s/#.*$//;
if (/Modulus:\s*(\S+)/) {
$gotkey = 1;
}
}
close(SEC);
return $gotkey;
}
# expand_conf(&config)
sub expand_conf
{
my $conf = shift;
for my $n (0..scalar(@$conf)-1) {
$conn = @$conf[$n];
foreach my $key (keys(%{$conn->{'values'}})) {
$expanded{$conn->{'value'}}->{$key} = $conn->{'values'}->{$key};
}
}
# now go through and expand alsos
foreach my $k (keys(%expanded)) {
$conn = \%{$expanded{$k}};
# XXX - only supporing a single level of redirection
# - this should be moved into a function that could be called
# recursively
if ($$conn{'also'}) {
foreach my $also (split(/\000/, $$conn{'also'})) {
foreach my $i (keys(%{$expanded{$also}})) {
$$conn{$i} = $expanded{$also}{$i};
}
}
# there is only one also key
next;
}
}
return %expanded;
}
# restart_ipsec()
# Apply the current configuration, and return an error message on failure or
# undef on success
sub restart_ipsec
{
local $cmd = $config{'restart_cmd'} ||
"($config{'stop_cmd'} && $config{'start_cmd'})";
&before_start();
local $out = &backquote_logged("$cmd 2>&1");
if ($?) {
return "$out
";
}
&after_start();
return undef;
}
# list_secrets()
# Returns a list of IPsec secret keys
sub list_secrets
{
if (!scalar(@list_secrets_cache)) {
local (@lines);
local $lnum = 0;
open(SEC, "<".$config{'secrets'});
while() {
s/\r|\n//g;
s/^\s*#.*$//;
if (/^(\S.*)$/) {
push(@lines, { 'value' => $1,
'line' => $lnum,
'eline' => $lnum });
}
elsif (/^\s+(.*)/ && @lines) {
$lines[$#rv]->{'value'} .= "\n".$1;
$lines[$#rv]->{'eline'} = $lnum;
}
$lnum++;
}
close(SEC);
# Turn joined lines into secrets
local $l;
foreach $l (@lines) {
$l->{'value'} =~ /^([^:]*)\s*:\s+(\S+)\s+((.|\n)*)$/ || next;
local $sec = { 'type' => $2,
'name' => $1,
'value' => $3,
'line' => $l->{'line'},
'eline' => $l->{'eline'},
'idx' => scalar(@list_secrets_cache),
};
$sec->{'name'} =~ s/\n/ /g;
$sec->{'name'} =~ s/\s+$//;
push(@list_secrets_cache, $sec);
}
}
return @list_secrets_cache;
}
# delete_secret(&sec)
# Removes one secret from the file
sub delete_secret
{
local $lref = &read_file_lines($config{'secrets'});
local $lines = $_[0]->{'eline'} - $_[0]->{'line'} + 1;
splice(@$lref, $_[0]->{'line'}, $lines);
&flush_file_lines();
local $s;
splice(@list_secrets_cache, $_[0]->{'idx'}, 1);
foreach $s (@list_secrets_cache) {
if ($s->{'line'} > $_[0]->{'line'}) {
$s->{'line'} -= $lines;
$s->{'eline'} -= $lines;
}
if ($s->{'idx'} > $_[0]->{'idx'}) {
$s->{'idx'}--;
}
}
}
# create_secret(&sec)
# Add one secret to the file
sub create_secret
{
&list_secrets(); # force cache init
local $lref = &read_file_lines($config{'secrets'});
$_[0]->{'line'} = scalar(@$lref);
local @lines = &secret_lines($_[0]);
push(@$lref, @lines);
&flush_file_lines();
$_[0]->{'eline'} = scalar(@$lref)-1;
$_[0]->{'idx'} = scalar(@list_secrets_cache);
push(@list_secrets_cache, $_[0]);
}
# modify_secret(&sec)
# Update one secret in the file
sub modify_secret
{
local $lref = &read_file_lines($config{'secrets'});
local @newlines = &secret_lines($_[0]);
local $oldlines = $_[0]->{'eline'} - $_[0]->{'line'} + 1;
splice(@$lref, $_[0]->{'line'}, $oldlines, @newlines);
&flush_file_lines();
local $s;
foreach $s (@list_secrets_cache) {
if ($s ne $_[0] && $s->{'line'} > $_[0]->{'line'}) {
$s->{'line'} += @newlines - $oldlines;
$s->{'eline'} += @newlines - $oldlines;
}
}
$_[0]->{'eline'} += @newlines - $oldlines;
}
sub secret_lines
{
local $str = $_[0]->{'name'} ? $_[0]->{'name'}." : " : ": ";
$str .= uc($_[0]->{'type'});
$str .= " ".$_[0]->{'value'};
return split(/\n/, $str);
}
@rsa_attribs = ( "Modulus", "PublicExponent", "PrivateExponent",
"Prime1", "Prime2", "Exponent1", "Exponent2", "Coefficient" );
1;