###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2007-2011 IPFire Team <info@ipfire.org> #
+# Copyright (C) 2007-2013 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
use File::Temp qw/ tempfile tempdir /;
use strict;
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
+use Sort::Naturally;
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
return("$newsize $units[$i]");
}
-sub valid_dns_host {
- my $hostname = $_[0];
- unless ($hostname) { return "No hostname"};
- my $res = new Net::DNS::Resolver;
- my $query = $res->search("$hostname");
- if ($query) {
- foreach my $rr ($query->answer) {
- ## Potential bug - we are only looking at A records:
- return 0 if $rr->type eq "A";
- }
- } else {
- return $res->errorstring;
- }
-}
-
sub cleanssldatabase
{
if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
}
}
-
sub checkportfw {
- my $KEY2 = $_[0]; # key2
- my $SRC_PORT = $_[1]; # src_port
- my $PROTOCOL = $_[2]; # protocol
- my $SRC_IP = $_[3]; # sourceip
-
- my $pfwfilename = "${General::swroot}/portfw/config";
- open(FILE, $pfwfilename) or die 'Unable to open config file.';
- my @pfwcurrent = <FILE>;
- close(FILE);
- my $pfwkey1 = 0; # used for finding last sequence number used
- foreach my $pfwline (@pfwcurrent)
- {
- my @pfwtemp = split(/\,/,$pfwline);
-
- chomp ($pfwtemp[8]);
- if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition
- if ( $SRC_PORT eq $pfwtemp[3] &&
- $PROTOCOL eq $pfwtemp[2] &&
- $SRC_IP eq $pfwtemp[7])
- {
- $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT";
- }
- # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
- if ( $pfwtemp[1] eq "0") {
- $pfwkey1=$pfwtemp[0];
- }
- # Darren Critchley - Duplicate or overlapping Port range check
- if ($pfwtemp[1] eq "0" &&
- $PROTOCOL eq $pfwtemp[2] &&
- $SRC_IP eq $pfwtemp[7] &&
- $errormessage eq '')
- {
- &portchecks($SRC_PORT, $pfwtemp[5]);
-# &portchecks($pfwtemp[3], $pfwtemp[5]);
-# &portchecks($pfwtemp[3], $SRC_IP);
+ my $DPORT = shift;
+ my $DPROT = shift;
+ my %natconfig =();
+ my $confignat = "${General::swroot}/forward/config";
+ $DPROT= uc ($DPROT);
+ &General::readhasharray($confignat, \%natconfig);
+ foreach my $key (sort keys %natconfig){
+ my @portarray = split (/\|/,$natconfig{$key}[30]);
+ foreach my $value (@portarray){
+ if ($value =~ /:/i){
+ my ($a,$b) = split (":",$value);
+ if ($DPROT eq $natconfig{$key}[12] && $DPORT gt $a && $DPORT lt $b){
+ $errormessage= "$Lang::tr{'source port in use'} $DPORT";
+ }
+ }else{
+ if ($DPROT eq $natconfig{$key}[12] && $DPORT eq $value){
+ $errormessage= "$Lang::tr{'source port in use'} $DPORT";
+ }
+ }
}
}
- }
-# $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP";
-
- return;
+ return;
}
sub checkportoverlap
return 0;
}
}
-# Darren Critchley - Duplicate or overlapping Port range check
-sub portchecks
-{
- my $p1 = $_[0]; # New port range
- my $p2 = $_[1]; # existing port range
-# $_ = $_[0];
- our ($prtrange1, $prtrange2);
- $prtrange1 = 0;
-# if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
-# unless (&checkportoverlap($p1,$p2)) {
-# $errormessage = "$Lang::tr{'source port overlaps'} $p1";
-# }
-# }
- if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
- unless (&checkportinc($p2,$p1)) {
- $errormessage = "$Lang::tr{'srcprt within existing'} $p1";
- }
- }
- $prtrange1 = 1;
- if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
- unless (&checkportinc($p1,$p2)) {
- $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2";
- }
- }
- return;
-}
# Darren Critchley - certain ports are reserved for IPFire
# TCP 67,68,81,222,445
}
if ($cgiparams{'DHCP_DOMAIN'} ne ''){
- unless (&General::validfqdn($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) {
+ unless (&General::validdomainname($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) {
$errormessage = $Lang::tr{'invalid input for dhcp domain'};
goto ADV_ERROR;
}
print SERVERCONF "persist-key\n";
print SERVERCONF "script-security 2\n";
print SERVERCONF "# IP/DNS for remote Server Gateway\n";
+
+ if ($cgiparams{'REMOTE'} ne '') {
print SERVERCONF "remote $cgiparams{'REMOTE'}\n";
+ }
+
print SERVERCONF "float\n";
print SERVERCONF "# IP adresses of the VPN Subnet\n";
print SERVERCONF "ifconfig $ovsubnet.1 $ovsubnet.2\n";
if ($cgiparams{'ENABLED'} eq 'on'){
- &checkportfw(0,$cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'},'0.0.0.0');
+ &checkportfw($cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'});
}
if ($errormessage) { goto SETTINGS_ERROR; }
print CLIENTCONF "#OpenVPN Client conf\r\n";
print CLIENTCONF "tls-client\r\n";
print CLIENTCONF "client\r\n";
- print CLIENTCONF "nobind\n";
+ print CLIENTCONF "nobind\r\n";
print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n";
print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
# Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500
# or use configured value.
if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' )
- { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; }
+ { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
elsif ($vpnsettings{MSSFIX} eq 'on')
- { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; }
+ { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
elsif (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
($vpnsettings{'PMTU_DISCOVERY'} eq 'no' ))
- { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; }
+ { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
else
{ print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; }
($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) {
if(($vpnsettings{MSSFIX} ne 'on') || ($vpnsettings{FRAGMENT} eq '')) {
- print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\n";
+ print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\r\n";
}
}
close(CLIENTCONF);
# m.a.d net2net
###
- if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
-
+if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
- my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
- unlink ($certfile) or die "Removing $certfile fail: $!";
- unlink ($conffile) or die "Removing $conffile fail: $!";
- rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!";
-
+ my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
+ unlink ($certfile);
+ unlink ($conffile);
+
+ if (-e "${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") {
+ rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!";
+ }
}
unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
if ($cgiparams{'LOG_VERB'} eq '') {
$cgiparams{'LOG_VERB'} = '3';
}
+ if ($cgiparams{'PMTU_DISCOVERY'} eq '') {
+ $cgiparams{'PMTU_DISCOVERY'} = 'off';
+ }
$checked{'CLIENT2CLIENT'}{'off'} = '';
$checked{'CLIENT2CLIENT'}{'on'} = '';
$checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
}
&Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'});
print <<END
- <form method='post' enctype='multipart/form-data' disabled>
+ <form method='post' enctype='multipart/form-data'>
<table width='100%' border=0>
<tr>
<td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
<td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
</tr>
<tr>
- <td class='base'>Keppalive <br />
+ <td class='base'>Keepalive <br />
(ping/ping-restart)</td>
<td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
<td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
###
if ($cgiparams{'TYPE'} eq 'net') {
-
- if ($cgiparams{'DEST_PORT'} eq $vpnsettings{'DDEST_PORT'}) {
+ if ($cgiparams{'DEST_PORT'} eq $vpnsettings{'DDEST_PORT'}) {
$errormessage = $Lang::tr{'openvpn destination port used'};
unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
goto VPNCONF_ERROR;
}
-
- if ($cgiparams{'DEST_PORT'} eq '') {
+ #Bugfix 10357
+ foreach my $key (sort keys %confighash){
+ if ( ($confighash{$key}[22] eq $cgiparams{'DEST_PORT'} && $cgiparams{'NAME'} ne $confighash{$key}[1]) || ($confighash{$key}[29] eq $cgiparams{'DEST_PORT'} && $cgiparams{'NAME'} ne $confighash{$key}[1])){
$errormessage = $Lang::tr{'openvpn destination port used'};
unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
+ goto VPNCONF_ERROR;
+ }
+ }
+ if ($cgiparams{'DEST_PORT'} eq '') {
+ $errormessage = $Lang::tr{'invalid port'};
+ unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
+ rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
goto VPNCONF_ERROR;
}
+ # Check if the input for the transfer net is valid.
+ if (!&General::validipandmask($cgiparams{'OVPN_SUBNET'})){
+ $errormessage = $Lang::tr{'ccd err invalidnet'};
+ unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
+ rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
+ goto VPNCONF_ERROR;
+ }
+
if ($cgiparams{'OVPN_SUBNET'} eq $vpnsettings{'DOVPN_SUBNET'}) {
$errormessage = $Lang::tr{'openvpn subnet is used'};
unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
}
}
- if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) {
- $errormessage = $Lang::tr{'invalid input for remote host/ip'};
- if ($cgiparams{'TYPE'} eq 'net') {
- unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
- rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
- }
- goto VPNCONF_ERROR;
- }
+ # Check if a remote host/IP has been set for the client.
+ if ($cgiparams{'TYPE'} eq 'net') {
+ if ($cgiparams{'SIDE'} ne 'server' && $cgiparams{'REMOTE'} eq '') {
+ $errormessage = $Lang::tr{'invalid input for remote host/ip'};
- if ($cgiparams{'REMOTE'}) {
- if (! &General::validip($cgiparams{'REMOTE'})) {
- if (! &General::validfqdn ($cgiparams{'REMOTE'})) {
- $errormessage = $Lang::tr{'invalid input for remote host/ip'};
- if ($cgiparams{'TYPE'} eq 'net') {
- unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
- rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
- }
- goto VPNCONF_ERROR;
- } else {
- if (&valid_dns_host($cgiparams{'REMOTE'})) {
- $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}";
- if ($cgiparams{'TYPE'} eq 'net') {
+ # Check if this is a N2N connection and drop temporary config.
+ unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
+ rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
- }
- }
+ goto VPNCONF_ERROR;
+ }
+
+ # Check if a remote host/IP has been configured - the field can be empty on the server side.
+ if ($cgiparams{'REMOTE'} ne '') {
+ # Check if the given IP is valid - otherwise check if it is a valid domain.
+ if (! &General::validip($cgiparams{'REMOTE'})) {
+ # Check for a valid domain.
+ if (! &General::validfqdn ($cgiparams{'REMOTE'})) {
+ $errormessage = $Lang::tr{'invalid input for remote host/ip'};
+
+ # Check if this is a N2N connection and drop temporary config.
+ unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
+ rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
+
+ goto VPNCONF_ERROR;
+ }
+ }
}
- }
}
+
if ($cgiparams{'TYPE'} ne 'host') {
unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) {
$errormessage = $Lang::tr{'local subnet is invalid'};
}
}
- # Save the config
+ # Save the config
my $key = $cgiparams{'KEY'};
if (! $key) {
if ( -e "${General::swroot}/ovpn/ccd/$confighash{$key}[2]"){
unlink "${General::swroot}/ovpn/ccd/$cgiparams{'CERT_NAME'}";
}
+ $confighash{$key}[2] =~ s/ /_/gi;
open ( CCDRWCONF,'>',"${General::swroot}/ovpn/ccd/$confighash{$key}[2]") or die "Unable to create clientconfigfile $!";
print CCDRWCONF "# OpenVPN clientconfig from ccd extension by Copymaster#\n\n";
if($cgiparams{'CHECK1'} eq 'dynamic'){
$checked{'MSSFIX'}{'on'} = '';
$checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
+ if ($cgiparams{'PMTU_DISCOVERY'} eq '') {
+ $cgiparams{'PMTU_DISCOVERY'} = 'off';
+ }
$checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
</tr>
END
;
- my $id = 0;
- my $gif;
- foreach my $key (sort { uc($confighash{$a}[1]) cmp uc($confighash{$b}[1]) } keys %confighash) {
- if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
-
+ my $id = 0;
+ my $gif;
+ foreach my $key (sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) {
+ if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
if ($id % 2) {
print "<tr bgcolor='$color{'color20'}'>\n";
} else {
}
- my $disable_clientdl = "disabled='disabled'";
- if (( $cgiparams{'ENABLED'} eq 'on') ||
- ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
- ( $cgiparams{'ENABLED_ORANGE'} eq 'on')){
- $disable_clientdl = "";
- }
print <<END
<td align='center'>$active</td>
<form method='post' name='frm${key}a'><td align='center'>
- <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.png' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
- <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl />
- <input type='hidden' name='KEY' value='$key' $disable_clientdl />
+ <input type='image' name='$Lang::tr{'dl client arch'}' src='/images/openvpn.png' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
+ <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' />
+ <input type='hidden' name='KEY' value='$key' />
</td></form>
END
;