From: ms Date: Fri, 2 Jun 2006 15:59:39 +0000 (+0000) Subject: Hinzugefügt: X-Git-Tag: v2.3-beta1~1102 X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=commitdiff_plain;h=6e13d0a5c5355055343b1f0ab9b7058a64bca89e Hinzugefügt: * OpenVPN GUI Alpha7 Geändert: * XAMPP von 1.5.3 --> 1.5.3a git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@152 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8 --- diff --git a/config/ovpn/caconfig b/config/ovpn/caconfig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/ovpn/certs/index.txt b/config/ovpn/certs/index.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/ovpn/certs/serial b/config/ovpn/certs/serial new file mode 100644 index 0000000000..a616ad491b --- /dev/null +++ b/config/ovpn/certs/serial @@ -0,0 +1 @@ +01 \ No newline at end of file diff --git a/config/ovpn/openssl/ovpn.cnf b/config/ovpn/openssl/ovpn.cnf new file mode 100644 index 0000000000..8643ea7415 --- /dev/null +++ b/config/ovpn/openssl/ovpn.cnf @@ -0,0 +1,103 @@ +HOME = . +RANDFILE = /var/ipcop/ovpn/ca/.rnd +oid_section = new_oids + +[ new_oids ] + +[ ca ] +default_ca = openvpn + +[ openvpn ] +dir = /var/ipcop/ovpn +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/certs/index.txt +new_certs_dir = $dir/certs +certificate = $dir/ca/cacert.pem +serial = $dir/certs/serial +crl = $dir/crl.pem +private_key = $dir/ca/cakey.pem +RANDFILE = $dir/ca/.rand +x509_extensions = usr_cert +default_days = 999999 +default_crl_days= 30 +default_md = md5 +preserve = no +policy = policy_match +email_in_dn = no + +[ policy_match ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca +string_mask = nombstr + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = GB +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = + +localityName = Locality Name (eg, city) +#localityName_default = + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = My Company Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, your name or your server\'s hostname) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 40 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 +unstructuredName = An optional company name + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always + +[ server ] + +# JY ADDED -- Make a cert with nsCertType set to "server" +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = CA:true + +[ crl_ext ] +authorityKeyIdentifier=keyid:always,issuer:always + +[ engine ] +default = openssl diff --git a/config/ovpn/ovpnconfig b/config/ovpn/ovpnconfig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/ovpn/settings b/config/ovpn/settings new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/ovpn/verify b/config/ovpn/verify new file mode 100644 index 0000000000..f56b330b09 --- /dev/null +++ b/config/ovpn/verify @@ -0,0 +1,16 @@ +#!/bin/sh +if [ $1 -eq 0 ]; then + name2=`echo $2` + name3=${name2##*/} + name4=${name3##*CN=} + clientdisabled=`/bin/grep -iwc off,.*,$name4 /var/ipcop/ovpn/ovpnconfig` + if [ "$clientdisabled" = "1" ]; then + exit 1 + fi + exit 0 +fi + +exit 0 + + + diff --git a/doc/packages-list.txt b/doc/packages-list.txt index c188ef160d..5cc9b04cbc 100644 --- a/doc/packages-list.txt +++ b/doc/packages-list.txt @@ -215,6 +215,6 @@ * vim-6.3 * vlan.1.9 * wget-1.10.2 - * xampp-linux-1.5.3 + * xampp-linux-1.5.3a * xinetd-2.3.14 * zlib-1.2.3 diff --git a/html/cgi-bin/connections.cgi b/html/cgi-bin/connections.cgi index 673a025e5f..ed1d117aea 100644 --- a/html/cgi-bin/connections.cgi +++ b/html/cgi-bin/connections.cgi @@ -74,6 +74,48 @@ push(@network, '127.0.0.1'); push(@masklen, '255.255.255.255' ); push(@colour, ${Header::colourfw} ); +# Add OpenVPN net and RED/BLUE/ORANGE entry (when appropriate) +if (-e "${General::swroot}/ovpn/settings") { + my %ovpnsettings = (); + &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings); + my @tempovpnsubnet = split("\/",$ovpnsettings{'DOVPN_SUBNET'}); + + # add OpenVPN net + push(@network, $tempovpnsubnet[0]); + push(@masklen, $tempovpnsubnet[1]); + push(@colour, ${Header::colourovpn} ); + push(@ports, '0' ); + push(@protocols, '' ); + + if ( ($ovpnsettings{'ENABLED'} eq 'on') && open(IP, "${General::swroot}/red/local-ipaddress") ) { + # add RED:port / proto + my $redip = ; + close(IP); + chomp $redip; + push(@network, $redip ); + push(@masklen, '255.255.255.255' ); + push(@colour, ${Header::colourovpn} ); + push(@ports, $ovpnsettings{'DDEST_PORT'} ); + push(@protocols, $ovpnsettings{'DPROTOCOL'} ); + } + if ( ($ovpnsettings{'ENABLED_BLUE'} eq 'on') && $netsettings{'BLUE_DEV'} ) { + # add BLUE:port / proto + push(@network, $netsettings{'BLUE_ADDRESS'} ); + push(@masklen, '255.255.255.255' ); + push(@colour, ${Header::colourovpn} ); + push(@ports, $ovpnsettings{'DDEST_PORT'} ); + push(@protocols, $ovpnsettings{'DPROTOCOL'} ); + } + if ( ($ovpnsettings{'ENABLED_ORANGE'} eq 'on') && $netsettings{'ORANGE_DEV'} ) { + # add ORANGE:port / proto + push(@network, $netsettings{'ORANGE_ADDRESS'} ); + push(@masklen, '255.255.255.255' ); + push(@colour, ${Header::colourovpn} ); + push(@ports, $ovpnsettings{'DDEST_PORT'} ); + push(@protocols, $ovpnsettings{'DPROTOCOL'} ); + } +} + # Add Orange Network if ($netsettings{'ORANGE_DEV'}) { push(@network, $netsettings{'ORANGE_NETADDRESS'}); @@ -370,6 +412,7 @@ print <$Lang::tr{'wireless'} IPFire $Lang::tr{'vpn'} + $Lang::tr{'OpenVPN'}
diff --git a/html/cgi-bin/logs.cgi/log.dat b/html/cgi-bin/logs.cgi/log.dat index 76d5d29596..854bad4688 100644 --- a/html/cgi-bin/logs.cgi/log.dat +++ b/html/cgi-bin/logs.cgi/log.dat @@ -59,6 +59,7 @@ my %sections = ( 'kernel' => '(kernel)', 'ipsec' => '(ipsec_[\w_]+|pluto\[.*\])', 'snort' => '(snort)', + 'openvpn' => '(openvpnserver)\[.*\]', 'installpackage' => '(installpackage\[.*\])' ); @@ -74,6 +75,7 @@ my %trsections = ( 'auth' => "$Lang::tr{'loginlogout'}", 'kernel' => "$Lang::tr{'kernel'}", 'ipsec' => 'IPSec', + 'openvpn' => 'OpenVPN', 'snort' => 'Snort', 'installpackage' => "$Lang::tr{'update transcript'}" ); @@ -350,8 +352,8 @@ print < $Lang::tr{'time'} - $Lang::tr{'section'} -   + $Lang::tr{'section'} +   END ; diff --git a/html/cgi-bin/ovpnfunc.pl b/html/cgi-bin/ovpnfunc.pl new file mode 100644 index 0000000000..8471ab349d --- /dev/null +++ b/html/cgi-bin/ovpnfunc.pl @@ -0,0 +1,778 @@ +#!/usr/bin/perl -w +package Ovpnfunc; +use Archive::Zip qw(:ERROR_CODES :CONSTANTS); +use Net::DNS; +use File::Copy; +use File::Temp qw/ tempfile tempdir /; +use strict; +require '/var/ipfire/general-functions.pl'; +my %netsettings=(); +my $errormessage = ''; +my $errormessage2 = ''; +my @subnets; # array of anonymous hashes {cn, from, to} +my @subnets2; # array of anonymous hashes {cn, from, to} +my %overlaps; # hash {cn} of anonymous arrays of subnets +my ($subnet, $from, $to, $i, $j); +&General::readhash("${General::swroot}/ethernet/settings", \%netsettings); +sub haveOrangeNet +{ + if ($netsettings{'CONFIG_TYPE'} == 1) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;} + return 0; +} + +sub haveBlueNet +{ + if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 6) {return 1;} + if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;} + return 0; +} + +sub sizeformat{ + my $bytesize = $_[0]; + my $i = 0; + + while(abs($bytesize) >= 1024){ + $bytesize=$bytesize/1024; + $i++; + last if($i==6); + } + + my @units = ("Bytes","KB","MB","GB","TB","PB","EB"); + my $newsize=(int($bytesize*100 +0.5))/100; + 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")) { + print FILE "01"; + close FILE; + } + if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) { + print FILE ""; + close FILE; + } + unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/serial.old"); + unlink ("${General::swroot}/ovpn/certs/01.pem"); +} + +sub newcleanssldatabase +{ + if (! -s "${General::swroot}/ovpn/certs/serial" ) { + open(FILE, ">${General::swroot}(ovpn/certs/serial"); + print FILE "01"; + close FILE; + } + if (! -s ">${General::swroot}/ovpn/certs/index.txt") { + system ("touch ${General::swroot}/ovpn/certs/index.txt"); + } + unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/serial.old"); +} + +sub deletebackupcert +{ + if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) { + my $hexvalue = ; + chomp $hexvalue; + close FILE; + 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 = ; + 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); + } + } + } +# $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP"; + + return $errormessage; +} + +sub checkportoverlap +{ + my $portrange1 = $_[0]; # New port range + my $portrange2 = $_[1]; # existing port range + my @tempr1 = split(/\:/,$portrange1); + my @tempr2 = split(/\:/,$portrange2); + + unless (&checkportinc($tempr1[0], $portrange2)){ return 0;} + unless (&checkportinc($tempr1[1], $portrange2)){ return 0;} + + unless (&checkportinc($tempr2[0], $portrange1)){ return 0;} + unless (&checkportinc($tempr2[1], $portrange1)){ return 0;} + + return 1; # Everything checks out! +} + +# Darren Critchley - we want to make sure that a port entry is not within an already existing range +sub checkportinc +{ + my $port1 = $_[0]; # Port + my $portrange2 = $_[1]; # Port range + my @tempr1 = split(/\:/,$portrange2); + + if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) { + return 1; + } else { + 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 +# UDP 67,68 +# Params passed in -> port, rangeyn, protocol +sub disallowreserved +{ + # port 67 and 68 same for tcp and udp, don't bother putting in an array + my $msg = ""; + my @tcp_reserved = (81,222,445); + my $prt = $_[0]; # the port or range + my $ryn = $_[1]; # tells us whether or not it is a port range + my $prot = $_[2]; # protocol + my $srcdst = $_[3]; # source or destination + if ($ryn) { # disect port range + if ($srcdst eq "src") { + $msg = "$Lang::tr{'rsvd src port overlap'}"; + } else { + $msg = "$Lang::tr{'rsvd dst port overlap'}"; + } + my @tmprng = split(/\:/,$prt); + unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; } + unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; } + if ($prot eq "tcp") { + foreach my $prange (@tcp_reserved) { + unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; } + } + } + } else { + if ($srcdst eq "src") { + $msg = "$Lang::tr{'reserved src port'}"; + } else { + $msg = "$Lang::tr{'reserved dst port'}"; + } + if ($prt == 67) { $errormessage="$msg 67"; return; } + if ($prt == 68) { $errormessage="$msg 68"; return; } + if ($prot eq "tcp") { + foreach my $prange (@tcp_reserved) { + if ($prange == $prt) { + $errormessage = "$msg $prange"; + return $errormessage; } + } + } + } + return $errormessage; +} + +sub writeserverconf { + my %sovpnsettings = (); + &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings); + + open(CONF, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!"; + flock CONF, 2; + print CONF "#OpenVPN Server conf\n"; + print CONF "\n"; + print CONF "daemon openvpnserver\n"; + print CONF "writepid /var/run/openvpn.pid\n"; + print CONF "#DAN prepare ZERINA for listening on blue and orange\n"; + print CONF ";local $sovpnsettings{'VPN_IP'}\n"; + print CONF "dev $sovpnsettings{'DDEVICE'}\n"; + print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; + print CONF "proto $sovpnsettings{'DPROTOCOL'}\n"; + print CONF "port $sovpnsettings{'DDEST_PORT'}\n"; + print CONF "tls-server\n"; + print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n"; + print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n"; + print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n"; + print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n"; + my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'}); + print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n"; + print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n"; + if ($sovpnsettings{AD_ROUTE1} ne '') { + my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE1'}); + print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; + } + if ($sovpnsettings{AD_ROUTE2} ne '') { + my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE2'}); + print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; + } + if ($sovpnsettings{AD_ROUTE3} ne '') { + my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE3'}); + print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; + } + if ($sovpnsettings{CLIENT2CLIENT} eq 'on') { + print CONF "client-to-client\n"; + } + if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) { + print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n"; + } + print CONF "status-version 1\n"; + print CONF "status /var/log/ovpnserver.log 30\n"; + print CONF "cipher $sovpnsettings{DCIPHER}\n"; + if ($sovpnsettings{DCOMPLZO} eq 'on') { + print CONF "comp-lzo\n"; + } + if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') { + print CONF "push \"redirect-gateway def1\"\n"; + } + if ($sovpnsettings{DHCP_DOMAIN} ne '') { + print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n"; + } + + if ($sovpnsettings{DHCP_DNS} ne '') { + print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n"; + } + + if ($sovpnsettings{DHCP_WINS} ne '') { + print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n"; + } + + if ($sovpnsettings{DHCP_WINS} eq '') { + print CONF "max-clients 100\n"; + } + + if ($sovpnsettings{DHCP_WINS} ne '') { + print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n"; + } + + ################################################################################# + # Added by Philipp Jenni # + # # + # Contact: philipp.jenni-at-gmx.ch # + # Date: 2006-04-22 # + # Description: Add the FAST-IO Parameter from OpenVPN to der Server.Config. # + # Add the NICE Parameter from OpenVPN to der Server.Config. # + # Add the MTU-DISC Parameter from OpenVPN to der Server.Config. # + # Add the MSSFIX Parameter from OpenVPN to der Server.Config. # + # Add the FRAMGMENT Parameter from OpenVPN to der Server.Config. # + ################################################################################# + if ($sovpnsettings{EXTENDED_FASTIO} eq 'on') { + print CONF "fast-io\n"; + } + if ($sovpnsettings{EXTENDED_NICE} != 0) { + print CONF "nice $sovpnsettings{EXTENDED_NICE}\n"; + } + if ($sovpnsettings{EXTENDED_MTUDISC} eq 'on') { + print CONF "mtu-disc yes\n"; + } + if ($sovpnsettings{EXTENDED_MSSFIX} ne '') { + print CONF "mssfix $sovpnsettings{EXTENDED_MSSFIX}\n"; + } + if ($sovpnsettings{EXTENDED_FRAGMENT} ne '') { + print CONF "fragment $sovpnsettings{EXTENDED_FRAGMENT}\n"; + } + ################################################################################# + # End of Inserted Data # + ################################################################################# + + print CONF "tls-verify /var/ipfire/ovpn/verify\n"; + print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n"; + print CONF "user nobody\n"; + print CONF "group nobody\n"; + print CONF "persist-key\n"; + print CONF "persist-tun\n"; + if ($sovpnsettings{LOG_VERB} ne '') { + print CONF "verb $sovpnsettings{LOG_VERB}\n"; + } else { + print CONF "verb 3\n"; + } + print CONF "\n"; + + close(CONF); +} + +sub writenet2netconf { + my $n2nkey = $_[0]; + my $zerinaclient = $_[1]; + my %n2nconfighash = (); + my $file = ''; +# my $file = ''; + my $clientovpn = ''; + my @fileholder; + my $tempdir = tempdir( CLEANUP => 1 ); + my $zippath = "$tempdir/"; + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); + if (! $n2nkey) { + $n2nkey = &General::findhasharraykey (\%n2nconfighash); + foreach my $i (0 .. 25) { $n2nconfighash{$n2nkey}[$i] = "";} + } + my $zipname = "$n2nconfighash{$n2nkey}[1].zip"; + my $zippathname = "$zippath$zipname"; + if ($n2nconfighash{$n2nkey}[3] eq 'net') { + if ($zerinaclient eq '') { + if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]"){ + while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/*.conf")) { + unlink $file + } + } else { + mkdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]", 0770); + } + open(CONF, ">${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf: $!"; + } else { + $clientovpn = "$n2nconfighash{$n2nkey}[1].conf"; + open(CONF, ">$tempdir/$clientovpn") or die "Unable to open $tempdir/$clientovpn: $!"; + } + flock CONF, 2; + print CONF "dev tun\n"; + print CONF "tun-mtu $n2nconfighash{$n2nkey}[17]\n"; + print CONF "proto $n2nconfighash{$n2nkey}[14]\n"; + print CONF "port $n2nconfighash{$n2nkey}[15]\n"; + my @tempovpnsubnet = split("\/",$n2nconfighash{$n2nkey}[13]); + my @ovpnip = split /\./,$tempovpnsubnet[0]; +# if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[19] eq 'no'))) { + if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) { + print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].1 $ovpnip[0].$ovpnip[1].$ovpnip[2].2\n"; + print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; + print CONF "tls-server\n"; + print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n"; + print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n"; + print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n"; + print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n"; + my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]); + print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; + } else { + print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].2 $ovpnip[0].$ovpnip[1].$ovpnip[2].1\n"; + #print CONF "$zerinaclient ufuk 10=$n2nconfighash{$n2nkey}[10] 18=$n2nconfighash{$n2nkey}[18] 19=$n2nconfighash{$n2nkey}[19] \n"; + if ($zerinaclient ne 'true'){ + if ($n2nconfighash{$n2nkey}[19] eq 'no'){ + print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; + } else { + print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; + } + } else { + print CONF "remote $n2nconfighash{$n2nkey}[18]\n"; + } + print CONF "tls-client\n"; + if ($zerinaclient ne 'true'){ + print CONF "pkcs12 ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].p12\n"; + } else { + print CONF "pkcs12 $n2nconfighash{$n2nkey}[1].p12\n"; + } + if ($n2nconfighash{$n2nkey}[19] eq 'no'){ + my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[8]); + print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; + } else { + my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]); + print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; + } + } + if ($n2nconfighash{$n2nkey}[26] > 0 && $n2nconfighash{$n2nkey}[27] > 0) { + print CONF "keepalive $n2nconfighash{$n2nkey}[26] $n2nconfighash{$n2nkey}[27]\n"; + } else { + print CONF "keepalive 10 60\n"; + } + print CONF "cipher $n2nconfighash{$n2nkey}[20]\n"; + if ($n2nconfighash{$n2nkey}[16] eq 'on') { + print CONF "comp-lzo\n"; + } + if ($n2nconfighash{$n2nkey}[42] ne '') { + print CONF "verb $n2nconfighash{$n2nkey}[42]\n"; + } else { + print CONF "verb 3\n"; + } + if ($n2nconfighash{$n2nkey}[19] eq 'no'){ + print CONF "#$n2nconfighash{$n2nkey}[11]\n"; + } else { + print CONF "#$n2nconfighash{$n2nkey}[8]\n"; + } + if ($zerinaclient ne 'true') { + print CONF "daemon OVPN_$n2nconfighash{$n2nkey}[1]\n"; + print CONF "#status ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].log 2\n"; + } + close(CONF); + if ($zerinaclient eq 'true') { + my $zip = Archive::Zip->new(); + $zip->addFile( "${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12", "$n2nconfighash{$n2nkey}[1].p12") or die "Can't add file ${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12\n"; + $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n"; + my $status = $zip->writeToFileNamed($zippathname); + open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!"; + @fileholder = ; + print "Content-Type:application/x-download\n"; + print "Content-Disposition:attachment;filename=$zipname\n\n"; + print @fileholder; + exit (0); + } + } +} + +sub removenet2netconf { + my %n2nconfighash = (); + my $key = $_[0]; + my $file = ''; + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); + if ($n2nconfighash{$key}[3] eq 'net') { + if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"){ + while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]/*")) { + unlink $file + } + rmdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"); + } + } +} + +sub emptyserverlog{ + if (open(FILE, ">/var/log/ovpnserver.log")) { + flock FILE, 2; + print FILE ""; + close FILE; + } +} + +sub displayca { + my $key = $_[0]; + my %cahash = (); + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + if ( -f "${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem") { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:"); + my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem`; + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } +} +sub displayroothost { + my $roothost = $_[0]; + my $output; + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + if ($roothost eq $Lang::tr{'show root certificate'}) { + &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:"); + $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`; + } else { + &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:"); + $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; + } + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); +} + +sub killconnection { + my $key = $_[0]; + my %n2nconfighash = (); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); + my $n2nactive = `/bin/ps ax|grep $n2nconfighash{$key}[1].conf|grep -v grep|awk \'{print \$1}\'`; + if ($n2nactive ne ''){ + system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive); + } +} + +sub cidrormask { + my $cidrmask = $_[0]; + my $cidrmask2 = $cidrmask; + if ("/$cidrmask" =~ /^\/(\d+)/){#cidr + if ($cidrmask2 = &cidr2mask("/$cidrmask")) { + return $cidrmask2; + } else { + if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask + return $cidrmask; + } + } + } else { + if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask + return $cidrmask; + } + } +} +sub cidr2mask { + my( $cidr ) = @_; + my( $one32 ) = 0xffffffff; + my( @d, $n, $bits ); + + if ( $cidr eq "/0" ) { + return "0.0.0.0"; + } + + if ( $cidr !~ /\/(\d+)/ ) { + return undef; + } + $bits = $1; + + if ( $bits > 32 ) { + return undef; + } + + #-- convert to subnet-style mask + $n = $one32 << (32 - $bits); + $d[3] = $n % 256; $n = int( $n / 256); + $d[2] = $n % 256; $n = int( $n / 256); + $d[1] = $n % 256; $n = int( $n / 256); + $d[0] = $n; + return join '.', @d; +} + + +# ---------------------------------------------------------------------------- +# $cidr = &mask2cidr( $mask ) +# ---------------------------------------------------------------------------- + +sub mask2cidr { + my( $mask ) = @_; + my( @d, $n, $bits ); + + if ( $mask eq "0.0.0.0" ) { + return "/0"; + } + + if ( ! &validMask( $mask ) ) { + return undef; + } + + @d = split /\./, $mask; + $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3]; + $bits = 32; + while ( ($n % 2) == 0 ) { + $n >>= 1; + $bits -= 1; + } + return "/$bits"; +} + + +# ---------------------------------------------------------------------------- +# $yesno = &validMask( $mask ) +# ---------------------------------------------------------------------------- + +sub validMask { + my( $mask ) = @_; + my( @d, $n, $str ); + + @d = split /\./, $mask; + $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3]; + $str = sprintf "%b", $n; + return ( $str =~ /^1+0*$/ ); +} + +sub overlapping { + # read all subnets from AD, convert to integer range, and sort. + foreach $subnet (@subnets2) { + ($from, $to) = &subnet2range ($subnet); + push @subnets, { cn => $subnet, from => $from, to => $to }; + } + @subnets = sort { $a->{from} <=> $b->{from} } @subnets; + + # compare all possible subnets for overlap; depend on sort order. + for ($i=0; $i<=$#subnets; $i++) { + for ($j=$i+1; $j<=$#subnets; $j++) { + last if $subnets[$i]->{to} < $subnets[$j]->{from}; # no possible overlap anymore; + push @{$overlaps{$subnets[$i]->{cn}}}, $subnets[$j]->{cn} if $subnets[$i]->{to} >= $subnets[$j]->{from}; + } + } + + if (scalar (keys %overlaps)) { + foreach $subnet (sort keys %overlaps) { + #$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC : %s\n", $subnet, join (", ", sort @{$overlaps{$subnet}}); + $errormessage = "$subnet : $overlaps{$subnet}[0]"; + last; + } + } + return $errormessage; +} + +# &subnet2range ($subnet) +# convert subnets to integers in order to compare them later. +# A subnet looks like this: 10.1.2.0/24 +# returns beginning and end of subnet as integer +# +sub subnet2range { + my $subnet = shift (@_); + my ($from, $to); + + $subnet =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/ || die "bad subnet $subnet\n"; + $from = $1*2**24 + $2*2**16 + $3*2**8 + $4; + $to = $from + 2**(32-$5) - 1; + return ($from, $to); +} + +sub ovelapplausi { + my $tmpovpnsubnet0 = $_[0]; + my $tmpovpnsubnet1 = $_[1]; + my %vpnconfighash = (); + my $tmpcidr = ''; + my @tmpremotevpnsubnet; + &General::readhasharray("${General::swroot}/vpn/config", \%vpnconfighash); + + if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'}, + $tmpovpnsubnet0, $tmpovpnsubnet1)) { + $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}"; + return $errormessage; + } + + if (&haveBlueNet()) { + if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'}, + $tmpovpnsubnet0, $tmpovpnsubnet1)) { + $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}"; + return $errormessage; + } + } + if (&haveOrangeNet()) { + if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'}, + $tmpovpnsubnet0, $tmpovpnsubnet1)) { + $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}"; + return $errormessage; + } + } + open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.'; + while () + { + chomp($_); + my @tempalias = split(/\,/,$_); + if ($tempalias[1] eq 'on') { + if (&General::IpInSubnet ($tempalias[0] , + $tmpovpnsubnet0, $tmpovpnsubnet1)) { + $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]"; + exit $errormessage; + } + } + } + close(ALIASES); + + #check against ipsec connections + foreach my $key (keys %vpnconfighash) { + #$confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'}; + #$confighash{$key}[3]#host or net + #$confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'}; + #$confighash{$key}[10] = $cgiparams{'REMOTE'}; + &emptyarray(); + $tmpcidr = &mask2cidr($tmpovpnsubnet1); + push @subnets2, "$tmpovpnsubnet0$tmpcidr"; + @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]); + $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); + push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; + $errormessage2 = &overlapping(); + if ($errormessage2 ne '') { + $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 "; + last; + } + &emptyarray(); + if ($vpnconfighash{$key}[3] eq 'net'){ + if (&General::IpInSubnet ($vpnconfighash{$key}[10],$tmpovpnsubnet0, $tmpovpnsubnet1)) { + $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC Connection/IP: $vpnconfighash{$key}[1]/$vpnconfighash{$key}[10]"; + last; + } + #check agains ipsec local subent + push @subnets2, "$tmpovpnsubnet0$tmpcidr"; + @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[11]); + $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); + push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; + $errormessage2 = &overlapping(); + if ($errormessage2 ne '') { + $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'remote subnet'} $errormessage2 "; + last; + } + &emptyarray(); + push @subnets2, "$tmpovpnsubnet0$tmpcidr"; + @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]); + $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); + push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; + $errormessage2 = &overlapping(); + if ($errormessage2 ne '') { + $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 "; + last; + } + &emptyarray(); + } + } + #check against OpenVPN Connections (aware check against itself) + return $errormessage; +} +sub emptyarray { + @subnets2 = (); + @subnets = (); +} \ No newline at end of file diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi new file mode 100644 index 0000000000..33e6140b97 --- /dev/null +++ b/html/cgi-bin/ovpnmain.cgi @@ -0,0 +1,3247 @@ +#!/usr/bin/perl +# based on SmoothWall and IPCop CGIs +# +# This code is distributed under the terms of the GPL +# Main idea from zeroconcept +# ZERNINA-VERSION:0.9.7a7 +# (c) 2005 Ufuk Altinkaynak +# +# Ipcop and OpenVPN eas as one two three.. +# + +use CGI; +use CGI qw/:standard/; +use Net::DNS; +use File::Copy; +use File::Temp qw/ tempfile tempdir /; +use strict; +use Archive::Zip qw(:ERROR_CODES :CONSTANTS); +use Net::Ping; +require '/var/ipfire/general-functions.pl'; +require '/home/httpd/cgi-bin/ovpnfunc.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; +require "${General::swroot}/countries.pl"; + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; +#workaround to suppress a warning when a variable is used only once +my @dummy = ( ${Header::colourgreen} ); +undef (@dummy); + + + +### +### Initialize variables +### +my %netsettings=(); +my %cgiparams=(); +my %vpnsettings=(); +my %checked=(); +my %confighash=(); +my %cahash=(); +my %selected=(); +my $warnmessage = ''; +my $errormessage = ''; +my %settings=(); +my $zerinaclient = ''; +&General::readhash("${General::swroot}/ethernet/settings", \%netsettings); +$cgiparams{'ENABLED'} = 'off'; +$cgiparams{'ENABLED_BLUE'} = 'off'; +$cgiparams{'ENABLED_ORANGE'} = 'off'; +$cgiparams{'EDIT_ADVANCED'} = 'off'; +$cgiparams{'NAT'} = 'off'; +$cgiparams{'COMPRESSION'} = 'off'; +$cgiparams{'ONLY_PROPOSED'} = 'off'; +$cgiparams{'ACTION'} = ''; +$cgiparams{'CA_NAME'} = ''; +$cgiparams{'DHCP_DOMAIN'} = ''; +$cgiparams{'DHCP_DNS'} = ''; +$cgiparams{'DHCP_WINS'} = ''; +$cgiparams{'DCOMPLZO'} = 'off'; +&Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'}); + +# prepare openvpn config file +### +### Useful functions +### + +### +### OpenVPN Server Control +### +if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} || + $cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'} || + $cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}) { + my $serveractive = `/bin/ps ax|grep server.conf|grep -v grep|awk \'{print \$1}\'`; + #start openvpn server + if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){ + &Ovpnfunc::emptyserverlog(); + system('/usr/local/bin/openvpnctrl', '-s'); + } + #stop openvpn server + if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){ + if ($serveractive ne ''){ + system('/usr/local/bin/openvpnctrl', '-kn2n', $serveractive); + } + system('/usr/local/bin/openvpnctrl', '-k'); + &Ovpnfunc::emptyserverlog(); + } +# #restart openvpn server + if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){ +#workarund, till SIGHUP also works when running as nobody + if ($serveractive ne ''){ + system('/usr/local/bin/openvpnctrl', '-kn2n', $serveractive); + } + system('/usr/local/bin/openvpnctrl', '-k'); + &Ovpnfunc::emptyserverlog(); + system('/usr/local/bin/openvpnctrl', '-s'); + } +} + +### +### Save Advanced options +### + +if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too, + #DAN this value has to leave. +#new settings for daemon + $vpnsettings{'LOG_VERB'} = $cgiparams{'LOG_VERB'}; + $vpnsettings{'KEEPALIVE_1'} = $cgiparams{'KEEPALIVE_1'}; + $vpnsettings{'KEEPALIVE_2'} = $cgiparams{'KEEPALIVE_2'}; + $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'}; + $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'}; + $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'}; + $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'}; + $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'}; + $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'}; + #additional push route + $vpnsettings{'AD_ROUTE1'} = $cgiparams{'AD_ROUTE1'}; + $vpnsettings{'AD_ROUTE2'} = $cgiparams{'AD_ROUTE2'}; + $vpnsettings{'AD_ROUTE3'} = $cgiparams{'AD_ROUTE3'}; + #additional push route + + ################################################################################# + # Added by Philipp Jenni # + # # + # Contact: philipp.jenni-at-gmx.ch # + # Date: 2006-04-22 # + # Description: Add the FAST-IO Parameter from OpenVPN to the Zerina Config # + # Add the NICE Parameter from OpenVPN to the Zerina Config # + # Add the MTU-DISC Parameter from OpenVPN to the Zerina Config # + # Add the MSSFIX Parameter from OpenVPN to the Zerina Config # + # Add the FRAMGMENT Parameter from OpenVPN to the Zerina Config # + ################################################################################# + $vpnsettings{'EXTENDED_FASTIO'} = $cgiparams{'EXTENDED_FASTIO'}; + $vpnsettings{'EXTENDED_NICE'} = $cgiparams{'EXTENDED_NICE'}; + $vpnsettings{'EXTENDED_MTUDISC'} = $cgiparams{'EXTENDED_MTUDISC'}; + $vpnsettings{'EXTENDED_MSSFIX'} = $cgiparams{'EXTENDED_MSSFIX'}; + $vpnsettings{'EXTENDED_FRAGMENT'} = $cgiparams{'EXTENDED_FRAGMENT'}; + ################################################################################# + # End of Inserted Data # + ################################################################################# + + + if ($cgiparams{'DHCP_DOMAIN'} ne ''){ + unless (&General::validfqdn($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) { + $errormessage = $Lang::tr{'invalid input for dhcp domain'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'DHCP_DNS'} ne ''){ + unless (&General::validfqdn($cgiparams{'DHCP_DNS'}) || &General::validip($cgiparams{'DHCP_DNS'})) { + $errormessage = $Lang::tr{'invalid input for dhcp dns'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'DHCP_WINS'} ne ''){ + unless (&General::validfqdn($cgiparams{'DHCP_WINS'}) || &General::validip($cgiparams{'DHCP_WINS'})) { + $errormessage = $Lang::tr{'invalid input for dhcp wins'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'AD_ROUTE1'} ne ''){ + if (! &General::validipandmask($cgiparams{'AD_ROUTE1'})) { + $errormessage = $Lang::tr{'route subnet is invalid'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'AD_ROUTE2'} ne ''){ + if (! &General::validipandmask($cgiparams{'AD_ROUTE2'})) { + $errormessage = $Lang::tr{'route subnet is invalid'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'AD_ROUTE3'} ne ''){ + if (! &General::validipandmask($cgiparams{'AD_ROUTE3'})) { + $errormessage = $Lang::tr{'route subnet is invalid'}; + goto ADV_ERROR; + } + } + + if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) { + $errormessage = $Lang::tr{'invalid input for max clients'}; + goto ADV_ERROR; + } + if ($cgiparams{'KEEPALIVE_1'} ne '') { + if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) { + $errormessage = $Lang::tr{'invalid input for keepalive 1'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'KEEPALIVE_2'} ne ''){ + if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) { + $errormessage = $Lang::tr{'invalid input for keepalive 2'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){ + $errormessage = $Lang::tr{'invalid input for keepalive 1:2'}; + goto ADV_ERROR; + } + + &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); + &Ovpnfunc::writeserverconf();#hier ok +} + +### +### Save main settings +### +if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too, + #DAN this value has to leave. + if ($cgiparams{'ENABLED'} eq 'on'){ + unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'})) { + $errormessage = $Lang::tr{'invalid input for hostname'}; + goto SETTINGS_ERROR; + } + } + if ($cgiparams{'ENABLED'} eq 'on'){ + $errormessage = &Ovpnfunc::disallowreserved($cgiparams{'DDEST_PORT'},0,$cgiparams{'DPROTOCOL'},"dest"); + } + if ($errormessage) { goto SETTINGS_ERROR; } + + + if ($cgiparams{'ENABLED'} eq 'on'){ + $errormessage = &Ovpnfunc::checkportfw(0,$cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'},'0.0.0.0'); + } + + if ($errormessage) { goto SETTINGS_ERROR; } + + if (! &General::validipandmask($cgiparams{'DOVPN_SUBNET'})) { + $errormessage = $Lang::tr{'ovpn subnet is invalid'}; + goto SETTINGS_ERROR; + } + my @tmpovpnsubnet = split("\/",$cgiparams{'DOVPN_SUBNET'}); + $tmpovpnsubnet[1] = &Ovpnfunc::cidrormask($tmpovpnsubnet[1]); + $cgiparams{'DOVPN_SUBNET'} = "$tmpovpnsubnet[0]/$tmpovpnsubnet[1]";#convert from cidr + #plausi1 + $errormessage = &Ovpnfunc::ovelapplausi($tmpovpnsubnet[0],$tmpovpnsubnet[1]); + #plausi1 + if ($errormessage ne ''){ + goto SETTINGS_ERROR; + } + if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto SETTINGS_ERROR; + } + if ((length($cgiparams{'DMTU'})==0) || (($cgiparams{'DMTU'}) < 1000 )) { + $errormessage = $Lang::tr{'invalid mtu input'}; + goto SETTINGS_ERROR; + } + + unless (&General::validport($cgiparams{'DDEST_PORT'})) { + $errormessage = $Lang::tr{'invalid port'}; + goto SETTINGS_ERROR; + } + #hhh + foreach my $dkey (keys %confighash) {#Check if there is no other entry with this name + if ($confighash{$dkey}[14] eq $cgiparams{'DPROTOCOL'} && $confighash{$dkey}[15] eq $cgiparams{'DDEST_PORT'}){ + $errormessage = "Choosed Protocol/Port combination is already used by connection: $confighash{$dkey}[1]"; + goto SETTINGS_ERROR; + } + } + #hhh + $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'}; + $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'}; + $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'}; + $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'}; +#new settings for daemon + $vpnsettings{'DOVPN_SUBNET'} = $cgiparams{'DOVPN_SUBNET'}; + $vpnsettings{'DDEVICE'} = $cgiparams{'DDEVICE'}; + $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'}; + $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'}; + $vpnsettings{'DMTU'} = $cgiparams{'DMTU'}; + $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; + $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'}; +#new settings for daemon + &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); + &Ovpnfunc::writeserverconf();#hier ok +SETTINGS_ERROR: +### +### Reset all step 2 +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'} && $cgiparams{'AREUSURE'} eq 'yes') { + my $file = ''; + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + foreach my $key (keys %confighash) { + if ($confighash{$key}[4] eq 'cert') { + delete $confighash{$cgiparams{'$key'}}; + } + } + while ($file = glob("${General::swroot}/ovpn/ca/*")) { + unlink $file + } + while ($file = glob("${General::swroot}/ovpn/certs/*")) { + unlink $file + } + while ($file = glob("${General::swroot}/ovpn/crls/*")) { + unlink $file + } + &Ovpnfunc::cleanssldatabase(); + if (open(FILE, ">${General::swroot}/ovpn/caconfig")) { + print FILE ""; + close FILE; + } + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); +### +### Reset all step 1 +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'}) { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'}); + print <
+ + $Lang::tr{'capswarning'}: + $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'} + + +
+END + ; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit (0); + +### +### Upload CA Certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) { + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + + if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) { + $errormessage = $Lang::tr{'name must only contain characters'}; + goto UPLOADCA_ERROR; + } + + if (length($cgiparams{'CA_NAME'}) >60) { + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; + } + + if ($cgiparams{'CA_NAME'} eq 'ca') { + $errormessage = $Lang::tr{'name is invalid'}; + goto UPLOAD_CA_ERROR; + } + + # Check if there is no other entry with this name + foreach my $key (keys %cahash) { + if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) { + $errormessage = $Lang::tr{'a ca certificate with this name already exists'}; + goto UPLOADCA_ERROR; + } + } + + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto UPLOADCA_ERROR; + } + # Move uploaded ca to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto UPLOADCA_ERROR; + } + my $temp = `/usr/bin/openssl x509 -text -in $filename`; + if ($temp !~ /CA:TRUE/i) { + $errormessage = $Lang::tr{'not a valid ca certificate'}; + unlink ($filename); + goto UPLOADCA_ERROR; + } else { + move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + goto UPLOADCA_ERROR; + } + } + + my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem`; + $casubject =~ /Subject: (.*)[\n]/; + $casubject = $1; + $casubject =~ s+/Email+, E+; + $casubject =~ s/ ST=/ S=/; + $casubject = &Header::cleanhtml($casubject); + + my $key = &General::findhasharraykey (\%cahash); + $cahash{$key}[0] = $cgiparams{'CA_NAME'}; + $cahash{$key}[1] = $casubject; + &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash); + UPLOADCA_ERROR: + +### +### Display ca certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) { + &Ovpnfunc::displayca($cgiparams{'KEY'}); +### +### Download ca certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) { + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + + if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + print "Content-Type: application/octet-stream\r\n"; + print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`; + exit(0); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } + +### +### Remove ca certificate (step 2) +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'} && $cgiparams{'AREUSURE'} eq 'yes') { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + + if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + foreach my $key (keys %confighash) { + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; + if ($test =~ /: OK/) { + unlink ("${General::swroot}/ovpn//certs/$confighash{$key}[1]cert.pem"); + unlink ("${General::swroot}/ovpn/certs/$confighash{$key}[1].p12"); + delete $confighash{$key}; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + } + } + unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); + delete $cahash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } +### +### Remove ca certificate (step 1) +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'}) { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + + my $assignedcerts = 0; + if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + foreach my $key (keys %confighash) { + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; + if ($test =~ /: OK/) { + $assignedcerts++; + } + } + if ($assignedcerts) { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'}); + print <
+ + + $Lang::tr{'capswarning'}: $assignedcerts + $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'} + + +
+END + ; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit (0); + } else { + unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); + delete $cahash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash); +# system('/usr/local/bin/ipsecctrl', 'R'); + } + } else { + $errormessage = $Lang::tr{'invalid key'}; + } + +### +### Display root certificate +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} || $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) { + &Ovpnfunc::displayroothost($cgiparams{'ACTION'}); +### +### Download root certificate +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) { + if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) { + print "Content-Type: application/octet-stream\r\n"; + print "Content-Disposition: filename=cacert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/cacert.pem`; + exit(0); + } + +### +### Download host certificate +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) { + if ( -f "${General::swroot}/ovpn/certs/servercert.pem" ) { + print "Content-Type: application/octet-stream\r\n"; + print "Content-Disposition: filename=servercert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`; + exit(0); + } +### +### Form for generating a root certificate +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} || + $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { + + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + if (-f "${General::swroot}/ovpn/ca/cacert.pem") { + $errormessage = $Lang::tr{'valid root certificate already exists'}; + $cgiparams{'ACTION'} = ''; + goto ROOTCERT_ERROR; + } + + if (($cgiparams{'ROOTCERT_HOSTNAME'} eq '') && -e "${General::swroot}/red/active") { + if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { + my $ipaddr = ; + close IPADDR; + chomp ($ipaddr); + $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; + if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') { + $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr; + } + } + } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { + + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto ROOTCERT_ERROR; + } + + # Move uploaded certificate request to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto ROOTCERT_ERROR; + } + + # Create a temporary dirctory + my $tempdir = tempdir( CLEANUP => 1 ); + + # Extract the CA certificate from the file + my $pid = open(OPENSSL, "|-"); + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; + if ($pid) { # parent + if ($cgiparams{'P12_PASS'} ne '') { + print OPENSSL "$cgiparams{'P12_PASS'}\n"; + } + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'pkcs12', '-cacerts', '-nokeys', + '-in', $filename, + '-out', "$tempdir/cacert.pem")) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } + + # Extract the Host certificate from the file + $pid = open(OPENSSL, "|-"); + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; + if ($pid) { # parent + if ($cgiparams{'P12_PASS'} ne '') { + print OPENSSL "$cgiparams{'P12_PASS'}\n"; + } + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'pkcs12', '-clcerts', '-nokeys', + '-in', $filename, + '-out', "$tempdir/hostcert.pem")) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } + + # Extract the Host key from the file + $pid = open(OPENSSL, "|-"); + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; + if ($pid) { # parent + if ($cgiparams{'P12_PASS'} ne '') { + print OPENSSL "$cgiparams{'P12_PASS'}\n"; + } + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'pkcs12', '-nocerts', + '-nodes', + '-in', $filename, + '-out', "$tempdir/serverkey.pem")) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + unlink ($filename); + goto ROOTCERT_ERROR; + } + } + + move("$tempdir/cacert.pem", "${General::swroot}/ovpn/ca/cacert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + goto ROOTCERT_ERROR; + } + + move("$tempdir/hostcert.pem", "${General::swroot}/ovpn/certs/servercert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + goto ROOTCERT_ERROR; + } + + move("$tempdir/serverkey.pem", "${General::swroot}/ovpn/certs/serverkey.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + goto ROOTCERT_ERROR; + } + + goto ROOTCERT_SUCCESS; + + } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') { + + # Validate input since the form was submitted + if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){ + $errormessage = $Lang::tr{'organization cant be empty'}; + goto ROOTCERT_ERROR; + } + if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) { + $errormessage = $Lang::tr{'organization too long'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for organization'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){ + $errormessage = $Lang::tr{'hostname cant be empty'}; + goto ROOTCERT_ERROR; + } + unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) { + $errormessage = $Lang::tr{'invalid input for hostname'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) { + $errormessage = $Lang::tr{'invalid input for e-mail address'}; + goto ROOTCERT_ERROR; + } + if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) { + $errormessage = $Lang::tr{'e-mail address too long'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for department'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for city'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for state or province'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) { + $errormessage = $Lang::tr{'invalid input for country'}; + goto ROOTCERT_ERROR; + } + + # Copy the cgisettings to vpnsettings and save the configfile + $vpnsettings{'ROOTCERT_ORGANIZATION'} = $cgiparams{'ROOTCERT_ORGANIZATION'}; + $vpnsettings{'ROOTCERT_HOSTNAME'} = $cgiparams{'ROOTCERT_HOSTNAME'}; + $vpnsettings{'ROOTCERT_EMAIL'} = $cgiparams{'ROOTCERT_EMAIL'}; + $vpnsettings{'ROOTCERT_OU'} = $cgiparams{'ROOTCERT_OU'}; + $vpnsettings{'ROOTCERT_CITY'} = $cgiparams{'ROOTCERT_CITY'}; + $vpnsettings{'ROOTCERT_STATE'} = $cgiparams{'ROOTCERT_STATE'}; + $vpnsettings{'ROOTCERT_COUNTRY'} = $cgiparams{'ROOTCERT_COUNTRY'}; + &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); + + # Replace empty strings with a . + (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./; + (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./; + (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./; + + # refresh + #system ('/bin/touch', "${General::swroot}/ovpn/gencanow"); + + # Create the CA certificate + my $pid = open(OPENSSL, "|-"); + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; + if ($pid) { # parent + print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n"; + print OPENSSL "$state\n"; + print OPENSSL "$city\n"; + print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; + print OPENSSL "$ou\n"; + print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n"; + print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n"; + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/ca/cakey.pem"); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + goto ROOTCERT_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', + '-days', '999999', '-newkey', 'rsa:2048', + '-keyout', "${General::swroot}/ovpn/ca/cakey.pem", + '-out', "${General::swroot}/ovpn/ca/cacert.pem", + '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + goto ROOTCERT_ERROR; + } + } + + # Create the Host certificate request + $pid = open(OPENSSL, "|-"); + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; + if ($pid) { # parent + print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n"; + print OPENSSL "$state\n"; + print OPENSSL "$city\n"; + print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; + print OPENSSL "$ou\n"; + print OPENSSL "$cgiparams{'ROOTCERT_HOSTNAME'}\n"; + print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n"; + print OPENSSL ".\n"; + print OPENSSL ".\n"; + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + unlink ("${General::swroot}/ovpn/certs/serverreq.pem"); + goto ROOTCERT_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', + '-newkey', 'rsa:1024', + '-keyout', "${General::swroot}/ovpn/certs/serverkey.pem", + '-out', "${General::swroot}/ovpn/certs/serverreq.pem", + '-extensions', 'server', + '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" )) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + unlink ("${General::swroot}/ovpn/certs/serverreq.pem"); + unlink ("${General::swroot}/ovpn/ca/cakey.pem"); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + goto ROOTCERT_ERROR; + } + } + + # Sign the host certificate request + system('/usr/bin/openssl', 'ca', '-days', '999999', + '-batch', '-notext', + '-in', "${General::swroot}/ovpn/certs/serverreq.pem", + '-out', "${General::swroot}/ovpn/certs/servercert.pem", + '-extensions', 'server', + '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/ca/cakey.pem"); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/serverkey.pem"); + unlink ("${General::swroot}/ovpn/certs/serverreq.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + &Ovpnfunc::newcleanssldatabase(); + goto ROOTCERT_ERROR; + } else { + unlink ("${General::swroot}/ovpn/certs/serverreq.pem"); + &Ovpnfunc::deletebackupcert(); + } + + # Create an empty CRL + system('/usr/bin/openssl', 'ca', '-gencrl', + '-out', "${General::swroot}/ovpn/crls/cacrl.pem", + '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" ); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/crls/cacrl.pem"); + &Ovpnfunc::cleanssldatabase(); + goto ROOTCERT_ERROR; + } + # Create Diffie Hellmann Parameter + system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache', + '-out', "${General::swroot}/ovpn/ca/dh1024.pem", + '1024' ); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/certs/serverkey.pem"); + unlink ("${General::swroot}/ovpn/certs/servercert.pem"); + unlink ("${General::swroot}/ovpn/ca/cacert.pem"); + unlink ("${General::swroot}/ovpn/crls/cacrl.pem"); + unlink ("${General::swroot}/ovpn/ca/dh1024.pem"); + &Ovpnfunc::cleanssldatabase(); + goto ROOTCERT_ERROR; + } + goto ROOTCERT_SUCCESS; + } + ROOTCERT_ERROR: + if ($cgiparams{'ACTION'} ne '') { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } + &Header::openbox('100%', 'LEFT', "$Lang::tr{'generate root/host certificates'}:"); + print < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'organization name'}: 
$Lang::tr{'ipfires hostname'}: 
$Lang::tr{'your e-mail'}:  
$Lang::tr{'your department'}:  
$Lang::tr{'city'}:  
$Lang::tr{'state or province'}:  
$Lang::tr{'country'}: 
   
+ * $Lang::tr{'this field may be blank'}
+ $Lang::tr{'capswarning'}: + $Lang::tr{'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient'} +
$Lang::tr{'upload p12 file'}: 
$Lang::tr{'pkcs12 file password'}: * 
  
+  $Lang::tr{'this field may be blank'}
+END + ; + &Header::closebox(); + + &Header::closebigbox(); + &Header::closepage(); + exit(0) + } + + ROOTCERT_SUCCESS: + system ("chmod 600 ${General::swroot}/ovpn/certs/serverkey.pem"); + +### +### Enable/Disable connection +### +}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + if ($confighash{$cgiparams{'KEY'}}) { + my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1].conf|grep -v grep|awk \'{print \$1}\'`; + if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { + $confighash{$cgiparams{'KEY'}}[0] = 'on'; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + if ($n2nactive eq ''){ + system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); + } else { + system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive); + system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); + } + } else { + $confighash{$cgiparams{'KEY'}}[0] = 'off'; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + if ($n2nactive ne ''){ + system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive); + } + } + } else { + $errormessage = $Lang::tr{'invalid key'}; + } + +### +### Download OpenVPN client package +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'dl client arch'}) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + my $file = ''; + my $clientovpn = ''; + my @fileholder; + my $tempdir = tempdir( CLEANUP => 1 ); + my $zippath = "$tempdir/"; + my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip"; + my $zippathname = "$zippath$zipname"; + #anna + if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ + $zerinaclient = 'true'; + &Ovpnfunc::writenet2netconf($cgiparams{'KEY'},$zerinaclient); + exit(0); + } + $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn"; + open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!"; + flock CLIENTCONF, 2; + + my $zip = Archive::Zip->new(); + + print CLIENTCONF "#OpenVPN Server conf\r\n"; + print CLIENTCONF "tls-client\r\n"; + print CLIENTCONF "client\r\n"; + print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n"; + print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n"; + print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; + if ( $vpnsettings{'ENABLED'} eq 'on'){ + print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n"; + if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&Ovpnfunc::haveBlueNet())){ + print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Blue interface\r\n"; + print CLIENTCONF ";remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; + } + if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&Ovpnfunc::haveOrangeNet())){ + print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n"; + print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; + } + } elsif ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&Ovpnfunc::haveBlueNet())){ + print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; + if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&Ovpnfunc::haveOrangeNet())){ + print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n"; + print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; + } + } elsif ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&Ovpnfunc::haveOrangeNet())){ + print CLIENTCONF "remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; + } + + if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") { + print CLIENTCONF "pkcs12 $confighash{$cgiparams{'KEY'}}[1].p12\r\n"; + $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n"; + } else { + print CLIENTCONF "ca cacert.pem\r\n"; + print CLIENTCONF "cert $confighash{$cgiparams{'KEY'}}[1]cert.pem\r\n"; + print CLIENTCONF "key $confighash{$cgiparams{'KEY'}}[1].key\r\n"; + $zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem") or die "Can't add file cacert.pem\n"; + $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "$confighash{$cgiparams{'KEY'}}[1]cert.pem") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1]cert.pem\n"; + } + print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n"; + if ($vpnsettings{DCOMPLZO} eq 'on') { + print CLIENTCONF "comp-lzo\r\n"; + } + print CLIENTCONF "verb 3\r\n"; + print CLIENTCONF "ns-cert-type server\r\n"; + close(CLIENTCONF); + $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n"; + my $status = $zip->writeToFileNamed($zippathname); + + open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!"; + @fileholder = ; + print "Content-Type:application/x-download\n"; + print "Content-Disposition:attachment;filename=$zipname\n\n"; + print @fileholder; + exit (0); + +### +### Remove connection +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + if ($confighash{$cgiparams{'KEY'}}) { + if ($confighash{$cgiparams{'KEY'}}[19] eq 'yes') { + &Ovpnfunc::killconnection($cgiparams{'KEY'}); + &Ovpnfunc::removenet2netconf($cgiparams{'KEY'}); + delete $confighash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + } else { + my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`; + unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); + unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); + &Ovpnfunc::killconnection($cgiparams{'KEY'}); + &Ovpnfunc::removenet2netconf($cgiparams{'KEY'}); + delete $confighash{$cgiparams{'KEY'}}; + my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + } + } else { + $errormessage = $Lang::tr{'invalid key'}; + } +### +### Download PKCS12 file +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n"; + print "Content-Type: application/octet-stream\r\n\r\n"; + print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12`; + exit (0); + +### +### Display certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:"); + my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + } +### +### Display Certificate Revoke List +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show crl'}) { + if ( -f "${General::swroot}/ovpn/crls/cacrl.pem") { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbox('100%', 'LEFT', "$Lang::tr{'crl'}:"); + my $output = `/usr/bin/openssl crl -text -noout -in ${General::swroot}/ovpn/crls/cacrl.pem`; + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + } + +### +### Advanced Server Settings +### + +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'advanced server'}) { + %cgiparams = (); + %cahash = (); + %confighash = (); + &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams); + +ADV_ERROR: + if ($cgiparams{'MAX_CLIENTS'} eq '') { + $cgiparams{'MAX_CLIENTS'} = '100'; + } + + if ($cgiparams{'KEEPALIVE_1'} eq '') { + $cgiparams{'KEEPALIVE_1'} = '10'; + } + if ($cgiparams{'KEEPALIVE_2'} eq '') { + $cgiparams{'KEEPALIVE_2'} = '60'; + } + if ($cgiparams{'LOG_VERB'} eq '') { + $cgiparams{'LOG_VERB'} = '3'; + } + if ($cgiparams{'EXTENDED_NICE'} eq '') { + $cgiparams{'EXTENDED_NICE'} = '0'; + } + $checked{'CLIENT2CLIENT'}{'off'} = ''; + $checked{'CLIENT2CLIENT'}{'on'} = ''; + $checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED'; + $checked{'REDIRECT_GW_DEF1'}{'off'} = ''; + $checked{'REDIRECT_GW_DEF1'}{'on'} = ''; + $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED'; + $selected{'LOG_VERB'}{'1'} = ''; + $selected{'LOG_VERB'}{'2'} = ''; + $selected{'LOG_VERB'}{'3'} = ''; + $selected{'LOG_VERB'}{'4'} = ''; + $selected{'LOG_VERB'}{'5'} = ''; + $selected{'LOG_VERB'}{'6'} = ''; + $selected{'LOG_VERB'}{'7'} = ''; + $selected{'LOG_VERB'}{'8'} = ''; + $selected{'LOG_VERB'}{'9'} = ''; + $selected{'LOG_VERB'}{'10'} = ''; + $selected{'LOG_VERB'}{'11'} = ''; + $selected{'LOG_VERB'}{'0'} = ''; + $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED'; + + ################################################################################# + # Added by Philipp Jenni # + # # + # Contact: philipp.jenni-at-gmx.ch # + # Date: 2006-04-22 # + # Description: Definitions to set the FASTIO Checkbox # + # Definitions to set the MTUDISC Checkbox # + # Definitions to set the NICE Selectionbox # + ################################################################################# + $checked{'EXTENDED_FASTIO'}{'off'} = ''; + $checked{'EXTENDED_FASTIO'}{'on'} = ''; + $checked{'EXTENDED_FASTIO'}{$cgiparams{'EXTENDED_FASTIO'}} = 'CHECKED'; + $checked{'EXTENDED_MTUDISC'}{'off'} = ''; + $checked{'EXTENDED_MTUDISC'}{'on'} = ''; + $checked{'EXTENDED_MTUDISC'}{$cgiparams{'EXTENDED_MTUDISC'}} = 'CHECKED'; + $selected{'EXTENDED_NICE'}{'-13'} = ''; + $selected{'EXTENDED_NICE'}{'-10'} = ''; + $selected{'EXTENDED_NICE'}{'-7'} = ''; + $selected{'EXTENDED_NICE'}{'-3'} = ''; + $selected{'EXTENDED_NICE'}{'0'} = ''; + $selected{'EXTENDED_NICE'}{'3'} = ''; + $selected{'EXTENDED_NICE'}{'7'} = ''; + $selected{'EXTENDED_NICE'}{'10'} = ''; + $selected{'EXTENDED_NICE'}{'13'} = ''; + $selected{'EXTENDED_NICE'}{$cgiparams{'EXTENDED_NICE'}} = 'SELECTED'; + ################################################################################# + # End of inserted Data # + ################################################################################# + + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'status ovpn'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + &Header::closebox(); + } + &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'}); + print < + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'dhcp-options'}
Domain
DNS
WINS
+
+ + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'add-route'}
$Lang::tr{'subnet'} 1
$Lang::tr{'subnet'} 2
$Lang::tr{'subnet'} 3
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'misc-options'}
Client-To-Client
Redirect-Gateway def1
Max-Clients
Keppalive (ping/ping-restart)
$Lang::tr{'ovpn_processprio'} + +
$Lang::tr{'ovpn_fastio'} + +
$Lang::tr{'ovpn_mtudisc'} + +
$Lang::tr{'ovpn_mssfix'} + +
$Lang::tr{'ovpn_fragment'} + +
+
+ + + + + + + + + + + + + + +
$Lang::tr{'log-options'}
VERB
+
+ + + + + + + +
  
+ +END +; + + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit(0); + +### +### Openvpn Connections Statistics +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ovpn con stat'}) { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ovpn con stat'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn con stat'}); + +# +# $Lang::tr{'protocol'} +# protocol temp removed + print < + + $Lang::tr{'common name'} + $Lang::tr{'real address'} + $Lang::tr{'virtual address'} + $Lang::tr{'loged in at'} + $Lang::tr{'bytes sent'} + $Lang::tr{'bytes received'} + $Lang::tr{'last activity'} + +END +; + my $filename = "/var/log/ovpnserver.log"; + open(FILE, $filename) or die 'Unable to open config file.'; + my @current = ; + close(FILE); + my @users =(); + my $status; + my $uid = 0; + my $cn; + my @match = (); + my $proto = "udp"; + my $address; + my %userlookup = (); + foreach my $line (@current) + { + chomp($line); + if ( $line =~ /^Updated,(.+)/){ + @match = split( /^Updated,(.+)/, $line); + $status = $match[1]; + } + if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) { + @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line); + if ($match[1] ne "Common Name") { + $cn = $match[1]; + $userlookup{$match[2]} = $uid; + $users[$uid]{'CommonName'} = $match[1]; + $users[$uid]{'RealAddress'} = $match[2]; + $users[$uid]{'BytesReceived'} = &Ovpnfunc::sizeformat($match[3]); + $users[$uid]{'BytesSent'} = &Ovpnfunc::sizeformat($match[4]); + $users[$uid]{'Since'} = $match[5]; + $users[$uid]{'Proto'} = $proto; + $uid++; + } + } + if ( $line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) { + @match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line); + if ($match[1] ne "Virtual Address") { + $address = $match[3]; + #find the uid in the lookup table + $uid = $userlookup{$address}; + $users[$uid]{'VirtualAddress'} = $match[1]; + $users[$uid]{'LastRef'} = $match[4]; + } + } + } + my $user2 = @users; + if ($user2 >= 1){ + for (my $idx = 1; $idx <= $user2; $idx++){ + if ($idx % 2) { + print "\n"; + } else { + print "\n"; + } + print "$users[$idx-1]{'CommonName'}"; + print "$users[$idx-1]{'RealAddress'}"; + print "$users[$idx-1]{'VirtualAddress'}"; + print "$users[$idx-1]{'Since'}"; + print "$users[$idx-1]{'BytesSent'}"; + print "$users[$idx-1]{'BytesReceived'}"; + print "$users[$idx-1]{'LastRef'}"; +# print "$users[$idx-1]{'Proto'}"; + } + } + + print ""; + print < + + + + + $Lang::tr{'the statistics were last updated at'} $status + +END +; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + +### +### Download Certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) { + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { + print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n"; + print "Content-Type: application/octet-stream\r\n\r\n"; + print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + exit (0); + } + +### +### Restart connection +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + if ($confighash{$cgiparams{'KEY'}}) { + } else { + $errormessage = $Lang::tr{'invalid key'}; + } + +### +### Choose between adding a host-net or net-net connection +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbox('100%', 'LEFT', $Lang::tr{'connection type'}); + print <$Lang::tr{'connection type'}:
+ + + + + + + + + +
$Lang::tr{'host to net vpn'}
$Lang::tr{'net to net vpn'}
upload a ZERINA Net-to-Net package
+END + ; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit (0); + +### +### uploading a ZERINA n2n connection package +### +} elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'zerinan2n')){ + my @zerinaconf; + my @confdetails; + my $uplconffilename =''; + my $uplp12name = ''; + my $complzoactive =''; + my @rem_subnet; + my @rem_subnet2; + my @tmposupnet3; + my $key; + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); +# Move uploaded ZERINA n2n package to a temporary file + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto ZERINA_ERROR; + } + # Move uploaded ca to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto ZERINA_ERROR; + } + + my $zip = Archive::Zip->new(); + my $zipName = $filename; + my $status = $zip->read( $zipName ); + if ($status != AZ_OK) { + $errormessage = "Read of $zipName failed\n"; + goto ZERINA_ERROR; + } + #my $tempdir = tempdir( CLEANUP => 1 ); + my $tempdir = tempdir(); + my @files = $zip->memberNames(); + for(@files) { + $zip->extractMemberWithoutPaths($_,"$tempdir/$_"); + } + my $countfiles = @files; + # see if we have 2 files + if ( $countfiles == 2){ + foreach (@files){ + if ( $_ =~ /.conf$/){ + $uplconffilename = $_; + } + if ( $_ =~ /.p12$/){ + $uplp12name = $_; + } + } + if (($uplconffilename eq '') || ($uplp12name eq '')){ + $errormessage = "Either no *.conf or no *.p12 file found\n"; + goto ZERINA_ERROR; + } + open(FILE, "$tempdir/$uplconffilename") or die 'Unable to open*.conf file'; + @zerinaconf = ; + close (FILE); + chomp(@zerinaconf); + } else { + # only 2 files are allowed + $errormessage = "Filecount does not match only 2 files are allowed\n"; + goto ZERINA_ERROR; + } + #prepare imported data not elegant, will be changed later + my $ufuk = (@zerinaconf); + push(@confdetails, substr($zerinaconf[0],4));#dev tun 0 + push(@confdetails, substr($zerinaconf[1],8));#mtu value 1 + push(@confdetails, substr($zerinaconf[2],6));#protocol 2 + push(@confdetails, substr($zerinaconf[3],5));#port 3 + push(@confdetails, substr($zerinaconf[4],9));#ovpn subnet 4 + push(@confdetails, substr($zerinaconf[5],7));#remote ip 5 + push(@confdetails, $zerinaconf[6]); #tls-server/tls-client 6 + push(@confdetails, substr($zerinaconf[7],7));#pkcs12 name 7 + push(@confdetails, substr($zerinaconf[$ufuk-1],1));#remote subnet 8 + push(@confdetails, substr($zerinaconf[9],10));#keepalive 9 + push(@confdetails, substr($zerinaconf[10],7));#cipher 10 + if ($ufuk == 14) { + push(@confdetails, $zerinaconf[$ufuk-3]);#complzo 11 + $complzoactive = "on"; + } else { + $complzoactive = "off"; + } + push(@confdetails, substr($zerinaconf[$ufuk-2],5));#verb 12 + push(@confdetails, substr($zerinaconf[8],6));#localsubnet 13 + #push(@confdetails, substr($uplconffilename,0,-5));#connection Name 14 + push(@confdetails, substr($uplp12name,0,-4));#connection Name 14 + #chomp(@confdetails); + foreach my $dkey (keys %confighash) {#Check if there is no other entry with this name + if ($confighash{$dkey}[1] eq $confdetails[$ufuk]) { + $errormessage = $Lang::tr{'a connection with this name already exists'}; + goto ZERINA_ERROR; + } + } + if ($confdetails[$ufuk] eq 'server') { + $errormessage = $Lang::tr{'server reserved'}; + goto ZERINA_ERROR; + } + @rem_subnet2 = split(/ /,$confdetails[4]); + @tmposupnet3 = split /\./,$rem_subnet2[0]; + $errormessage = &Ovpnfunc::ovelapplausi("$tmposupnet3[0].$tmposupnet3[1].$tmposupnet3[2].0","255.255.255.0"); + if ($errormessage ne ''){ + goto ZERINA_ERROR; + } + + $key = &General::findhasharraykey (\%confighash); + foreach my $i (0 .. 42) { $confighash{$key}[$i] = "";} + $confighash{$key}[0] = 'off'; + $confighash{$key}[1] = $confdetails[$ufuk]; + #$confighash{$key}[2] = $confdetails[7]; + $confighash{$key}[2] = $confdetails[$ufuk]; + $confighash{$key}[3] = 'net'; + $confighash{$key}[4] = 'cert'; + $confighash{$key}[6] = 'client'; + $confighash{$key}[8] = $confdetails[8]; + @rem_subnet = split(/ /,$confdetails[$ufuk-1]); + $confighash{$key}[11] = "$rem_subnet[0]/$rem_subnet[1]"; + $confighash{$key}[10] = $confdetails[5]; + $confighash{$key}[25] = 'imported'; + $confighash{$key}[12] = 'red'; + my @tmposupnet = split(/ /,$confdetails[4]); + my @tmposupnet2 = split /\./,$tmposupnet[0]; + $confighash{$key}[13] = "$tmposupnet2[0].$tmposupnet2[1].$tmposupnet2[2].0/255.255.255.0"; + $confighash{$key}[14] = $confdetails[2]; + $confighash{$key}[15] = $confdetails[3]; + $confighash{$key}[16] = $complzoactive; + $confighash{$key}[17] = $confdetails[1]; + $confighash{$key}[18] = '';# nn2nvpn_ip + $confighash{$key}[19] = 'yes';# nn2nvpn_ip + $cgiparams{'KEY'} = $key; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + mkdir("${General::swroot}/ovpn/n2nconf/$confdetails[14]", 0770); + move("$tempdir/$uplconffilename", "${General::swroot}/ovpn/n2nconf/$confdetails[14]/$uplconffilename"); + if ($? ne 0) { + $errormessage = "*.conf move failed: $!"; + unlink ($filename); + goto ZERINA_ERROR; + } + move("$tempdir/$uplp12name", "${General::swroot}/ovpn/n2nconf/$confdetails[14]/$uplp12name"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + goto ZERINA_ERROR; + } + ZERINA_ERROR: + + &Header::showhttpheaders(); + &Header::openpage('Validate imported configuration', 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } else { + &Header::openbox('100%', 'LEFT', 'Validate imported configuration'); + } + if ($errormessage eq ''){ + print < +   +   + $Lang::tr{'name'}: + $confdetails[$ufuk] + $Lang::tr{'Act as'} + $confdetails[6] + $Lang::tr{'remote host/ip'}: + $confdetails[5] + $Lang::tr{'local subnet'} + $confighash{$key}[8] + $Lang::tr{'remote subnet'} + $confighash{$key}[11] + $Lang::tr{'ovpn subnet'} + $confighash{$key}[$ufuk-1] + $Lang::tr{'protocol'} + $confdetails[2] + $Lang::tr{'destination port'}: + $confdetails[3] + $Lang::tr{'comp-lzo'} + $complzoactive + $Lang::tr{'cipher'} + $confdetails[10] + $Lang::tr{'MTU'}  + $confdetails[1] +END +; + + &Header::closebox(); + } + if ($errormessage) { + print ""; + } else { + print "
"; + print ""; + print ""; + print "
"; + } + &Header::closebigbox(); + &Header::closepage(); + exit(0); + +### +### Approve Zerina n2n +### +} elsif (($cgiparams{'ACTION'} eq 'Approved') && ($cgiparams{'TYPE'} eq 'zerinan2n')){ + &Ovpnfunc::writenet2netconf($cgiparams{'KEY'},$zerinaclient); +### +### Discard Zerina n2n +### +} elsif (($cgiparams{'ACTION'} eq 'Discard') && ($cgiparams{'TYPE'} eq 'zerinan2n')){ + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + if ($confighash{$cgiparams{'KEY'}}) { + &Ovpnfunc::removenet2netconf(); + delete $confighash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } +### +### Adding a new connection +### +} elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) || + ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) || + ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) { + + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) { + if (! $confighash{$cgiparams{'KEY'}}[0]) { + $errormessage = $Lang::tr{'invalid key'}; + goto VPNCONF_END; + } + $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0]; + $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1]; + $cgiparams{'TYPE'} = $confighash{$cgiparams{'KEY'}}[3]; + $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4]; + $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5]; + $cgiparams{'SIDE'} = $confighash{$cgiparams{'KEY'}}[6]; + $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8]; + $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10]; + $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11]; + $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25]; + $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[12]; + $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[13];#new fields + $cgiparams{'PROTOCOL'} = $confighash{$cgiparams{'KEY'}}[14]; + $cgiparams{'DEST_PORT'} = $confighash{$cgiparams{'KEY'}}[15]; + $cgiparams{'COMPLZO'} = $confighash{$cgiparams{'KEY'}}[16]; + $cgiparams{'MTU'} = $confighash{$cgiparams{'KEY'}}[17]; + $cgiparams{'N2NVPN_IP'} = $confighash{$cgiparams{'KEY'}}[18];#new fields + $cgiparams{'ZERINA_CLIENT'} = $confighash{$cgiparams{'KEY'}}[19];#new fields + $cgiparams{'CIPHER'} = $confighash{$cgiparams{'KEY'}}[20];#new fields + if ($cgiparams{'ZERINA_CLIENT'} eq ''){ + $cgiparams{'ZERINA_CLIENT'} = 'no'; + } + } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {#ab hiere error uebernehmen + $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); + # n2n error + if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { + $errormessage = $Lang::tr{'connection type is invalid'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) { + $errormessage = $Lang::tr{'name must only contain characters'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault|server)$/) { + $errormessage = $Lang::tr{'name is invalid'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'NAME'}) >60) { + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; + } + if (! $cgiparams{'KEY'}) {# Check if there is no other entry with this name + foreach my $key (keys %confighash) { + if ($confighash{$key}[1] eq $cgiparams{'NAME'}) { + $errormessage = $Lang::tr{'a connection with this name already exists'}; + goto VPNCONF_ERROR; + } + } + } + if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) { + $errormessage = $Lang::tr{'invalid input for remote host/ip'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'REMOTE'}) { + if (! &General::validip($cgiparams{'REMOTE'})) { + if (! &General::validfqdn ($cgiparams{'REMOTE'})) { + $errormessage = $Lang::tr{'invalid input for remote host/ip'}; + goto VPNCONF_ERROR; + } else { + if (&Ovpnfunc::valid_dns_host($cgiparams{'REMOTE'})) { + $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}"; + } + } + } + } + if ($cgiparams{'TYPE'} ne 'host') { + unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) { + $errormessage = $Lang::tr{'local subnet is invalid'}; + goto VPNCONF_ERROR; + } + } + #hier1 + my @tmpovpnsubnet = split("\/",$cgiparams{'LOCAL_SUBNET'}); + $tmpovpnsubnet[1] = &Ovpnfunc::cidrormask($tmpovpnsubnet[1]); + $cgiparams{'LOCAL_SUBNET'} = "$tmpovpnsubnet[0]/$tmpovpnsubnet[1]";#convert from cidr + #hier1 + if ($cgiparams{'REMOTE'} eq '') {# Check if there is no other entry without IP-address and PSK + foreach my $key (keys %confighash) { + if(($cgiparams{'KEY'} ne $key) && ($confighash{$key}[4] eq 'psk' || $cgiparams{'AUTH'} eq 'psk') && $confighash{$key}[10] eq '') { + $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'}; + goto VPNCONF_ERROR; + } + } + } + if (($cgiparams{'TYPE'} eq 'net') && (! &General::validipandmask($cgiparams{'REMOTE_SUBNET'}))) { + $errormessage = $Lang::tr{'remote subnet is invalid'}; + goto VPNCONF_ERROR; + } + #hier2 + my @tmpovpnsubnet = split("\/",$cgiparams{'REMOTE_SUBNET'}); + $tmpovpnsubnet[1] = &Ovpnfunc::cidrormask($tmpovpnsubnet[1]); + $cgiparams{'REMOTE_SUBNET'} = "$tmpovpnsubnet[0]/$tmpovpnsubnet[1]";#convert from cidr + #hier2 + if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'ENABLED'} eq 'on'){ + $errormessage = &Ovpnfunc::disallowreserved($cgiparams{'DEST_PORT'},0,$cgiparams{'PROTOCOL'},"dest"); + } + if ($errormessage) { goto VPNCONF_ERROR; } + + if ($cgiparams{'ENABLED'} eq 'on'){ + $errormessage = &Ovpnfunc::checkportfw(0,$cgiparams{'DEST_PORT'},$cgiparams{'PROTOCOL'},'0.0.0.0'); + } + if ($errormessage) { goto VPNCONF_ERROR; } +#raul + if ($cgiparams{'TYPE'} eq 'net') { + if (! &General::validipandmask($cgiparams{'OVPN_SUBNET'})) { + $errormessage = $Lang::tr{'ovpn subnet is invalid'}; + goto VPNCONF_ERROR; + } + #hier3 + my @tmpovpnsubnet = split("\/",$cgiparams{'OVPN_SUBNET'}); + $tmpovpnsubnet[1] = &Ovpnfunc::cidrormask($tmpovpnsubnet[1]); + $cgiparams{'OVPN_SUBNET'} = "$tmpovpnsubnet[0]/$tmpovpnsubnet[1]";#convert from cidr + #hier3 + #plausi2 + $errormessage = &Ovpnfunc::ovelapplausi($tmpovpnsubnet[0],$tmpovpnsubnet[1]); + #plausi2 + if ($errormessage ne ''){ + goto VPNCONF_ERROR; + } + if ((length($cgiparams{'MTU'})==0) || (($cgiparams{'MTU'}) < 1000 )) { + $errormessage = $Lang::tr{'invalid mtu input'}; + goto VPNCONF_ERROR; + } + unless (&General::validport($cgiparams{'DEST_PORT'})) { + $errormessage = $Lang::tr{'invalid port'}; + goto VPNCONF_ERROR; + } + # check protcol/port overlap against existing connections gian + foreach my $dkey (keys %confighash) {#Check if there is no other entry with this name + if ($dkey ne $cgiparams{'KEY'}) { + if ($confighash{$dkey}[14] eq $cgiparams{'PROTOCOL'} && $confighash{$dkey}[15] eq $cgiparams{'DEST_PORT'}){ + #if ($confighash{$dkey}[14] eq 'on') { + $errormessage = "Choosed Protocol/Port combination is already used by connection: $confighash{$dkey}[1]"; + goto VPNCONF_ERROR; + #} else { + # $warnmessage = "Choosed Protcol/Port combination is used by inactive connection: $confighash{$dkey}[1]"; + #} + } + } + } + #check protcol/port overlap against RWserver gian + if ($vpnsettings{'ENABLED'} eq 'on') { + if ($vpnsettings{'DPROTOCOL'} eq $cgiparams{'PROTOCOL'} && $vpnsettings{'DDEST_PORT'} eq $cgiparams{'DEST_PORT'}){ + $errormessage = "Choosed Protocol/Port combination is already used OpenVPN Roadwarrior Server"; + goto VPNCONF_ERROR; + } + } + } + if ($cgiparams{'AUTH'} eq 'psk') { + #removed + } elsif ($cgiparams{'AUTH'} eq 'certreq') { + # { + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; + } + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto VPNCONF_ERROR; + } + (my $fh, my $filename) = tempfile( );# Move uploaded certificate request to a temporary file + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto VPNCONF_ERROR; + } + # Sign the certificate request and move it + # Sign the host certificate request + system('/usr/bin/openssl', 'ca', '-days', '999999', + '-batch', '-notext', + '-in', $filename, + '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem", + '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ($filename); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + &Ovpnfunc::newcleanssldatabase(); + goto VPNCONF_ERROR; + } else { + unlink ($filename); + &Ovpnfunc::deletebackupcert(); + } + my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`; + $temp =~ /Subject:.*CN=(.*)[\n]/; + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + $cgiparams{'CERT_NAME'} = $temp; + $cgiparams{'CERT_NAME'} =~ s/,//g; + $cgiparams{'CERT_NAME'} =~ s/\'//g; + if ($cgiparams{'CERT_NAME'} eq '') { + $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; + goto VPNCONF_ERROR; + } + } elsif ($cgiparams{'AUTH'} eq 'certfile') { + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; + } + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto VPNCONF_ERROR; + } + (my $fh, my $filename) = tempfile( );# Move uploaded certificate to a temporary file + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto VPNCONF_ERROR; + } + my $validca = 0;# Verify the certificate has a valid CA and move it + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`; + if ($test =~ /: OK/) { + $validca = 1; + } else { + foreach my $key (keys %cahash) { + $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`; + if ($test =~ /: OK/) { + $validca = 1; + } + } + } + if (! $validca) { + $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'}; + unlink ($filename); + goto VPNCONF_ERROR; + } else { + move($filename, "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + goto VPNCONF_ERROR; + } + } + my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`; + $temp =~ /Subject:.*CN=(.*)[\n]/; + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + $cgiparams{'CERT_NAME'} = $temp; + $cgiparams{'CERT_NAME'} =~ s/,//g; + $cgiparams{'CERT_NAME'} =~ s/\'//g; + if ($cgiparams{'CERT_NAME'} eq '') { + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; + goto VPNCONF_ERROR; + } + } elsif ($cgiparams{'AUTH'} eq 'certgen'){ + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'CERT_NAME'}) >60) {# Validate input since the form was submitted + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { + $errormessage = $Lang::tr{'invalid input for name'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) { + $errormessage = $Lang::tr{'invalid input for e-mail address'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'CERT_EMAIL'}) > 40) { + $errormessage = $Lang::tr{'e-mail address too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for department'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'CERT_ORGANIZATION'}) >60) { + $errormessage = $Lang::tr{'organization too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { + $errormessage = $Lang::tr{'invalid input for organization'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for city'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for state or province'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) { + $errormessage = $Lang::tr{'invalid input for country'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_PASS1'} ne '' && $cgiparams{'CERT_PASS2'} ne ''){ + if (length($cgiparams{'CERT_PASS1'}) < 5) { + $errormessage = $Lang::tr{'password too short'}; + goto VPNCONF_ERROR; + } + } + if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) { + $errormessage = $Lang::tr{'passwords do not match'}; + goto VPNCONF_ERROR; + } + (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;# Replace empty strings with a . + (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./; + (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./; + my $pid = open(OPENSSL, "|-");# Create the Host certificate request client + $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto VPNCONF_ERROR;}; + if ($pid) { # parent + print OPENSSL "$cgiparams{'CERT_COUNTRY'}\n"; + print OPENSSL "$state\n"; + print OPENSSL "$city\n"; + print OPENSSL "$cgiparams{'CERT_ORGANIZATION'}\n"; + print OPENSSL "$ou\n"; + print OPENSSL "$cgiparams{'CERT_NAME'}\n"; + print OPENSSL "$cgiparams{'CERT_EMAIL'}\n"; + print OPENSSL ".\n"; + print OPENSSL ".\n"; + close (OPENSSL); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}key.pem"); + unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}req.pem"); + goto VPNCONF_ERROR; + } + } else { # child + unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', + '-newkey', 'rsa:1024', + '-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem", + '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem", + '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) { + $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem"); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem"); + goto VPNCONF_ERROR; + } + } + # Sign the host certificate request + system('/usr/bin/openssl', 'ca', '-days', '999999', + '-batch', '-notext', + '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem", + '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem", + '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem"); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem"); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + &Ovpnfunc::newcleanssldatabase(); + goto VPNCONF_ERROR; + } else { + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem"); + &Ovpnfunc::deletebackupcert(); + } + # Create the pkcs12 file + system('/usr/bin/openssl', 'pkcs12', '-export', + '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem", + '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem", + '-name', $cgiparams{'NAME'}, + '-passout', "pass:$cgiparams{'CERT_PASS1'}", + '-certfile', "${General::swroot}/ovpn/ca/cacert.pem", + '-caname', "$vpnsettings{'ROOTCERT_ORGANIZATION'} CA", + '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem"); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12"); + goto VPNCONF_ERROR; + } else { + unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem"); + } + } elsif ($cgiparams{'AUTH'} eq 'cert') { + ;# Nothing, just editing + } else { + $errormessage = $Lang::tr{'invalid input for authentication method'}; + goto VPNCONF_ERROR; + } + if ((! $cgiparams{'KEY'}) && ($cgiparams{'AUTH'} ne 'psk')) {# Check if there is no other entry with this common name + foreach my $key (keys %confighash) { + if ($confighash{$key}[2] eq $cgiparams{'CERT_NAME'}) { + $errormessage = $Lang::tr{'a connection with this common name already exists'}; + goto VPNCONF_ERROR; + } + } + } + + my $key = $cgiparams{'KEY'};# Save the config + if (! $key) { + $key = &General::findhasharraykey (\%confighash); + foreach my $i (0 .. 42) { $confighash{$key}[$i] = "";} + } + $confighash{$key}[0] = $cgiparams{'ENABLED'}; + $confighash{$key}[1] = $cgiparams{'NAME'}; + if ((! $cgiparams{'KEY'}) && $cgiparams{'AUTH'} ne 'psk') { + $confighash{$key}[2] = $cgiparams{'CERT_NAME'}; + } + $confighash{$key}[3] = $cgiparams{'TYPE'}; + if ($cgiparams{'AUTH'} eq 'psk') { + $confighash{$key}[4] = 'psk'; + $confighash{$key}[5] = $cgiparams{'PSK'}; + } else { + $confighash{$key}[4] = 'cert'; + } + if ($cgiparams{'TYPE'} eq 'net') { + $confighash{$key}[6] = $cgiparams{'SIDE'}; + $confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'}; + if ( $cgiparams{'SIDE'} eq 'client') { + $confighash{$key}[19] = 'yes'; + } else{ + $confighash{$key}[19] = 'no'; + } + } + $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'}; + $confighash{$key}[10] = $cgiparams{'REMOTE'}; + $confighash{$key}[25] = $cgiparams{'REMARK'}; + $confighash{$key}[12] = $cgiparams{'INTERFACE'}; + $confighash{$key}[13] = $cgiparams{'OVPN_SUBNET'};# new fields + $confighash{$key}[14] = $cgiparams{'PROTOCOL'}; + $confighash{$key}[15] = $cgiparams{'DEST_PORT'}; + $confighash{$key}[16] = $cgiparams{'COMPLZO'}; + $confighash{$key}[17] = $cgiparams{'MTU'}; + $confighash{$key}[18] = $cgiparams{'N2NVPN_IP'};# new fileds + $confighash{$key}[19] = $cgiparams{'ZERINA_CLIENT'};# new fileds + $confighash{$key}[20] = $cgiparams{'CIPHER'}; + + #default n2n advanced + $confighash{$key}[26] = '10';#keepalive ping + $confighash{$key}[27] = '60';#keepalive restart + $confighash{$key}[28] = '0';#nice + $confighash{$key}[42] = '3';#verb + #default n2n advanced + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + &Ovpnfunc::writenet2netconf($key,$zerinaclient); + #ppp + my $n2nactive = `/bin/ps ax|grep $cgiparams{'NAME'}.conf|grep -v grep|awk \'{print \$1}\'`; + if ($cgiparams{'ENABLED'}) { + if ($n2nactive eq ''){ + system('/usr/local/bin/openvpnctrl', '-sn2n', $cgiparams{'NAME'}); + } else { + system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive); + system('/usr/local/bin/openvpnctrl', '-sn2n', $cgiparams{'NAME'}); + } + } else { + if ($n2nactive ne ''){ + system('/usr/local/bin/openvpnctrl', '-kn2n', $cgiparams{'NAME'}); + } + } + if ($cgiparams{'EDIT_ADVANCED'} eq 'on') { + $cgiparams{'KEY'} = $key; + $cgiparams{'ACTION'} = $Lang::tr{'advanced'}; + } + goto VPNCONF_END; + } else { + $cgiparams{'ENABLED'} = 'on'; + if ($cgiparams{'ZERINA_CLIENT'} eq ''){ + $cgiparams{'ZERINA_CLIENT'} = 'no'; + } + if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { + $cgiparams{'AUTH'} = 'psk'; + } elsif ( ! -f "${General::swroot}/ovpn/ca/cacert.pem") { + $cgiparams{'AUTH'} = 'certfile'; + } else { + $cgiparams{'AUTH'} = 'certgen'; + } + $cgiparams{'LOCAL_SUBNET'} ="$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}"; + $cgiparams{'CERT_ORGANIZATION'} = $vpnsettings{'ROOTCERT_ORGANIZATION'}; + $cgiparams{'CERT_CITY'} = $vpnsettings{'ROOTCERT_CITY'}; + $cgiparams{'CERT_STATE'} = $vpnsettings{'ROOTCERT_STATE'}; + $cgiparams{'CERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'}; + } + VPNCONF_ERROR: + # n2n default settings + if ($cgiparams{'CIPHER'} eq '') { + $cgiparams{'CIPHER'} = 'BF-CBC'; + } + if ($cgiparams{'MTU'} eq '') { + $cgiparams{'MTU'} = '1400'; + } + if ($cgiparams{'OVPN_SUBNET'} eq '') { + $cgiparams{'OVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0'; + } + #n2n default settings + $checked{'ENABLED'}{'off'} = ''; + $checked{'ENABLED'}{'on'} = ''; + $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED'; + $checked{'ENABLED_BLUE'}{'off'} = ''; + $checked{'ENABLED_BLUE'}{'on'} = ''; + $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED'; + $checked{'ENABLED_ORANGE'}{'off'} = ''; + $checked{'ENABLED_ORANGE'}{'on'} = ''; + $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED'; + $checked{'EDIT_ADVANCED'}{'off'} = ''; + $checked{'EDIT_ADVANCED'}{'on'} = ''; + $checked{'EDIT_ADVANCED'}{$cgiparams{'EDIT_ADVANCED'}} = 'CHECKED'; + $selected{'SIDE'}{'server'} = ''; + $selected{'SIDE'}{'client'} = ''; + $selected{'SIDE'}{$cgiparams{'SIDE'}} = 'SELECTED'; + +# $selected{'DDEVICE'}{'tun'} = ''; +# $selected{'DDEVICE'}{'tap'} = ''; +# $selected{'DDEVICE'}{$cgiparams{'DDEVICE'}} = 'SELECTED'; + + $selected{'PROTOCOL'}{'udp'} = ''; + $selected{'PROTOCOL'}{'tcp'} = ''; + $selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED'; + + $checked{'AUTH'}{'psk'} = ''; + $checked{'AUTH'}{'certreq'} = ''; + $checked{'AUTH'}{'certgen'} = ''; + $checked{'AUTH'}{'certfile'} = ''; + $checked{'AUTH'}{$cgiparams{'AUTH'}} = 'CHECKED'; + $selected{'INTERFACE'}{$cgiparams{'INTERFACE'}} = 'SELECTED'; + $checked{'COMPLZO'}{'off'} = ''; + $checked{'COMPLZO'}{'on'} = ''; + $checked{'COMPLZO'}{$cgiparams{'COMPLZO'}} = 'CHECKED'; + $selected{'CIPHER'}{'DES-CBC'} = ''; + $selected{'CIPHER'}{'DES-EDE-CBC'} = ''; + $selected{'CIPHER'}{'DES-EDE3-CBC'} = ''; + $selected{'CIPHER'}{'DESX-CBC'} = ''; + $selected{'CIPHER'}{'RC2-CBC'} = ''; + $selected{'CIPHER'}{'RC2-40-CBC'} = ''; + $selected{'CIPHER'}{'RC2-64-CBC'} = ''; + $selected{'CIPHER'}{'BF-CBC'} = ''; + $selected{'CIPHER'}{'CAST5-CBC'} = ''; + $selected{'CIPHER'}{'AES-128-CBC'} = ''; + $selected{'CIPHER'}{'AES-192-CBC'} = ''; + $selected{'CIPHER'}{'AES-256-CBC'} = ''; + $selected{'CIPHER'}{$cgiparams{'CIPHER'}} = 'SELECTED'; + + if (1) { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } + if ($warnmessage) { + &Header::openbox('100%', 'LEFT', "$Lang::tr{'warning messages'}:"); + print "$warnmessage"; + print " "; + &Header::closebox(); + } + print "
"; + print ""; + print ""; + if ($cgiparams{'KEY'}) { + print ""; + print ""; + print ""; + } + &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:"); + print "\n"; + print ""; + if ($cgiparams{'TYPE'} eq 'host') { + if ($cgiparams{'KEY'}) { + print "\n"; + } else { + print ""; + } + } else { + print ""; + if ($cgiparams{'KEY'}) { + print ""; + } else { + print ""; + } + print ""; + print ""; + print ""; + if ((($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) && ($cgiparams{'ZERINA_CLIENT'} eq 'no')) || + (($cgiparams{'ACTION'} eq $Lang::tr{'save'}) && ($cgiparams{'ZERINA_CLIENT'} eq 'no')) || + (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'ZERINA_CLIENT'} eq 'no'))) { + print ""; + print ""; + print ""; + print ""; + print ""; + } else { + print ""; + print ""; + print ""; + } + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + } + print ""; + print ""; +# if ($cgiparams{'TYPE'} eq 'net') { + print "\n"; + + if ($cgiparams{'TYPE'} eq 'host') { + print "
$Lang::tr{'name'}:$cgiparams{'NAME'}$cgiparams{'NAME'}  
$Lang::tr{'Act as'}
$Lang::tr{'local vpn hostname/ip'}:$Lang::tr{'remote host/ip'}:
$Lang::tr{'Act as'}$cgiparams{'SIDE'}$Lang::tr{'remote host/ip'}:
$Lang::tr{'local subnet'}$Lang::tr{'remote subnet'}
$Lang::tr{'ovpn subnet'}
$Lang::tr{'protocol'}$Lang::tr{'destination port'}:
$Lang::tr{'comp-lzo'}$Lang::tr{'cipher'}
$Lang::tr{'MTU'} 
$Lang::tr{'remark title'} 
$Lang::tr{'enabled'}  
"; + } elsif ($cgiparams{'ACTION'} ne $Lang::tr{'edit'}){ + print " $Lang::tr{'edit advanced settings when done'}"; + } else { + print ""; + } + + + &Header::closebox(); + if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') { + ;#we dont have psk + } elsif (! $cgiparams{'KEY'}) { + my $disabled=''; + my $cakeydisabled=''; + my $cacrtdisabled=''; + if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" }; + if ( ! -f "${General::swroot}/ovpn/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" }; + &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'}); + print < + + + $Lang::tr{'upload a certificate request'} + + + $Lang::tr{'upload a certificate'} + + + $Lang::tr{'generate a certificate'}  +   + $Lang::tr{'users fullname or system hostname'}: + +   + $Lang::tr{'users email'}:  + +   + $Lang::tr{'users department'}:  + +   + $Lang::tr{'organization name'}:  + +   + $Lang::tr{'city'}:  + +   + $Lang::tr{'state or province'}:  + +   + $Lang::tr{'country'}: + +  $Lang::tr{'pkcs12 file password'}:
($Lang::tr{'confirmation'}) + + +END + ; + &Header::closebox(); + } + print "
"; + if ($cgiparams{'KEY'}) { + print ""; + } + print "
"; + &Header::closebigbox(); + &Header::closepage(); + exit (0); + } + VPNCONF_END: +} +### +### Advanced settings +### +if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || + ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq 'yes')) { + &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + + if (! $confighash{$cgiparams{'KEY'}}) { + $errormessage = $Lang::tr{'invalid key'}; + goto ADVANCED_END; + } + #n2n advanced error + if ($cgiparams{'KEEPALIVE_1'} ne '') { + if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) { + $errormessage = $Lang::tr{'invalid input for keepalive 1'}; + goto ADVANCED_ERROR; + } + } + if ($cgiparams{'KEEPALIVE_2'} ne ''){ + if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) { + $errormessage = $Lang::tr{'invalid input for keepalive 2'}; + goto ADVANCED_ERROR; + } + } + if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){ + $errormessage = $Lang::tr{'invalid input for keepalive 1:2'}; + goto ADVANCED_ERROR; + } + if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { +# if ($cgiparams{'NAT'} !~ /^(on|off)$/) { +# $errormessage = $Lang::tr{'invalid input'}; +# goto ADVANCED_ERROR; +# } + #n2n advanced error + #cgi an config + $confighash{$cgiparams{'KEY'}}[26] = $cgiparams{'KEEPALIVE_1'}; + $confighash{$cgiparams{'KEY'}}[27] = $cgiparams{'KEEPALIVE_2'}; + $confighash{$cgiparams{'KEY'}}[28] = $cgiparams{'EXTENDED_NICE'}; + $confighash{$cgiparams{'KEY'}}[29] = $cgiparams{'EXTENDED_FASTIO'}; + $confighash{$cgiparams{'KEY'}}[30] = $cgiparams{'EXTENDED_MTUDISC'}; + $confighash{$cgiparams{'KEY'}}[31] = $cgiparams{'EXTENDED_MSSFIX'}; + $confighash{$cgiparams{'KEY'}}[32] = $cgiparams{'EXTENDED_FRAGMENT'}; + $confighash{$cgiparams{'KEY'}}[33] = $cgiparams{'PROXY_HOST'}; + $confighash{$cgiparams{'KEY'}}[34] = $cgiparams{'PROXY_PORT'}; + $confighash{$cgiparams{'KEY'}}[35] = $cgiparams{'PROXY_USERNAME'}; + $confighash{$cgiparams{'KEY'}}[36] = $cgiparams{'PROXY_PASS'}; + $confighash{$cgiparams{'KEY'}}[37] = $cgiparams{'PROXY_AUTH_METHOD'}; + $confighash{$cgiparams{'KEY'}}[38] = $cgiparams{'http-proxy-retry'}; + $confighash{$cgiparams{'KEY'}}[39] = $cgiparams{'PROXY_TIMEOUT'}; + $confighash{$cgiparams{'KEY'}}[40] = $cgiparams{'PROXY_OPT_VERSION'}; + $confighash{$cgiparams{'KEY'}}[41] = $cgiparams{'PROXY_OPT_AGENT'}; + $confighash{$cgiparams{'KEY'}}[42] = $cgiparams{'LOG_VERB'}; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + &Ovpnfunc::writenet2netconf($cgiparams{'KEY'},$zerinaclient); + # restart n2n after advanced save ? + goto ADVANCED_END; + } else { + $cgiparams{'KEEPALIVE_1'} = $confighash{$cgiparams{'KEY'}}[26]; + $cgiparams{'KEEPALIVE_2'} = $confighash{$cgiparams{'KEY'}}[27]; + $cgiparams{'EXTENDED_NICE'} = $confighash{$cgiparams{'KEY'}}[28]; + $cgiparams{'EXTENDED_FASTIO'} = $confighash{$cgiparams{'KEY'}}[29]; + $cgiparams{'EXTENDED_MTUDISC'} = $confighash{$cgiparams{'KEY'}}[30]; + $cgiparams{'EXTENDED_MSSFIX'} = $confighash{$cgiparams{'KEY'}}[31]; + $cgiparams{'EXTENDED_FRAGMENT'} = $confighash{$cgiparams{'KEY'}}[32]; + $cgiparams{'PROXY_HOST'} = $confighash{$cgiparams{'KEY'}}[33]; + $cgiparams{'PROXY_PORT'} = $confighash{$cgiparams{'KEY'}}[34]; + $cgiparams{'PROXY_USERNAME'} = $confighash{$cgiparams{'KEY'}}[35]; + $cgiparams{'PROXY_PASS'} = $confighash{$cgiparams{'KEY'}}[36]; + $cgiparams{'PROXY_AUTH_METHOD'} = $confighash{$cgiparams{'KEY'}}[37]; + $cgiparams{'http-proxy-retry'} = $confighash{$cgiparams{'KEY'}}[38]; + $cgiparams{'PROXY_TIMEOUT'} = $confighash{$cgiparams{'KEY'}}[39]; + $cgiparams{'PROXY_OPT_VERSION'} = $confighash{$cgiparams{'KEY'}}[40]; + $cgiparams{'PROXY_OPT_AGENT'} = $confighash{$cgiparams{'KEY'}}[41]; + $cgiparams{'LOG_VERB'} = $confighash{$cgiparams{'KEY'}}[42]; + #cgi an config + } + ADVANCED_ERROR: + #Schalter setzen + $selected{'EXTENDED_NICE'}{'-13'} = ''; + $selected{'EXTENDED_NICE'}{'-10'} = ''; + $selected{'EXTENDED_NICE'}{'-7'} = ''; + $selected{'EXTENDED_NICE'}{'-3'} = ''; + $selected{'EXTENDED_NICE'}{'0'} = ''; + $selected{'EXTENDED_NICE'}{'3'} = ''; + $selected{'EXTENDED_NICE'}{'7'} = ''; + $selected{'EXTENDED_NICE'}{'10'} = ''; + $selected{'EXTENDED_NICE'}{'13'} = ''; + $selected{'EXTENDED_NICE'}{$cgiparams{'EXTENDED_NICE'}} = 'SELECTED'; + $checked{'EXTENDED_FASTIO'}{'off'} = ''; + $checked{'EXTENDED_FASTIO'}{'on'} = ''; + $checked{'EXTENDED_FASTIO'}{$cgiparams{'EXTENDED_FASTIO'}} = 'CHECKED'; + $checked{'EXTENDED_MTUDISC'}{'off'} = ''; + $checked{'EXTENDED_MTUDISC'}{'on'} = ''; + $checked{'EXTENDED_MTUDISC'}{$cgiparams{'EXTENDED_MTUDISC'}} = 'CHECKED'; + $selected{'LOG_VERB'}{'1'} = ''; + $selected{'LOG_VERB'}{'2'} = ''; + $selected{'LOG_VERB'}{'3'} = ''; + $selected{'LOG_VERB'}{'4'} = ''; + $selected{'LOG_VERB'}{'5'} = ''; + $selected{'LOG_VERB'}{'6'} = ''; + $selected{'LOG_VERB'}{'7'} = ''; + $selected{'LOG_VERB'}{'8'} = ''; + $selected{'LOG_VERB'}{'9'} = ''; + $selected{'LOG_VERB'}{'10'} = ''; + $selected{'LOG_VERB'}{'11'} = ''; + $selected{'LOG_VERB'}{'0'} = ''; + $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED'; + $selected{'PROXY_AUTH_METHOD'}{'none'} = ''; + $selected{'PROXY_AUTH_METHOD'}{'basic'} = ''; + $selected{'PROXY_AUTH_METHOD'}{'ntlm'} = ''; + $selected{'PROXY_AUTH_METHOD'}{$cgiparams{'PROXY_AUTH_METHOD'}} = 'SELECTED'; + $checked{'PROXY_RETRY'}{'off'} = ''; + $checked{'PROXY_RETRY'}{'on'} = ''; + $checked{'PROXY_RETRY'}{$cgiparams{'PROXY_RETRY'}} = 'CHECKED'; + #Schalter setzen + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'LEFT', '', $errormessage); + + if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } + + if ($warnmessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'warning messages'}); + print "$warnmessage"; + print " "; + &Header::closebox(); + } + + print "
\n"; + print "\n"; + print "\n"; + + &Header::openbox('100%', 'LEFT', "$Lang::tr{'advanced'}:"); + print < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'misc-options'}
Keppalive (ping/ping-restart)
$Lang::tr{'ovpn_processprio'} + +
$Lang::tr{'ovpn_fastio'} + +
$Lang::tr{'ovpn_mtudisc'} + +
$Lang::tr{'ovpn_mssfix'} + +
$Lang::tr{'ovpn_fragment'} + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'proxy'} $Lang::tr{'settings'}
$Lang::tr{'proxy'} $Lang::tr{'host'}:$Lang::tr{'proxy port'}:
$Lang::tr{'username'}$Lang::tr{'password'}
$Lang::tr{'authentication'} $Lang::tr{'method'} + +
http-proxy-retryhttp-proxy-timeout
http-proxy-option VERSIONhttp-proxy-option AGENT
+
+ + + + + + + + + + +
$Lang::tr{'log-options'}
VERB
+ +EOF + ; + &Header::closebox(); + print "
"; + print "
"; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + + ADVANCED_END: +} +### +### Default status page +### +%cgiparams = (); +%cahash = (); +%confighash = (); +&General::readhash("${General::swroot}/ovpn/settings", \%cgiparams); +&General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); +&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); +my @status = `/bin/cat /var/log/ovpnserver.log`; +if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") { + if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { + my $ipaddr = ; + close IPADDR; + chomp ($ipaddr); + $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; + if ($cgiparams{'VPN_IP'} eq '') { + $cgiparams{'VPN_IP'} = $ipaddr; + } + } +} +#default setzen +if ($cgiparams{'DCIPHER'} eq '') { + $cgiparams{'DCIPHER'} = 'BF-CBC'; +} +# if ($cgiparams{'DCOMPLZO'} eq '') { +# $cgiparams{'DCOMPLZO'} = 'on'; +# } +if ($cgiparams{'DDEST_PORT'} eq '') { + $cgiparams{'DDEST_PORT'} = '1194'; +} +if ($cgiparams{'DMTU'} eq '') { + $cgiparams{'DMTU'} = '1400'; +} +if ($cgiparams{'DOVPN_SUBNET'} eq '') { + $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0'; +} +$checked{'ENABLED'}{'off'} = ''; +$checked{'ENABLED'}{'on'} = ''; +$checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED'; +$checked{'ENABLED_BLUE'}{'off'} = ''; +$checked{'ENABLED_BLUE'}{'on'} = ''; +$checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED'; +$checked{'ENABLED_ORANGE'}{'off'} = ''; +$checked{'ENABLED_ORANGE'}{'on'} = ''; +$checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED'; +#new settings +$selected{'DDEVICE'}{'tun'} = ''; +$selected{'DDEVICE'}{'tap'} = ''; +$selected{'DDEVICE'}{$cgiparams{'DDEVICE'}} = 'SELECTED'; +$selected{'DPROTOCOL'}{'udp'} = ''; +$selected{'DPROTOCOL'}{'tcp'} = ''; +$selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED'; +$selected{'DCIPHER'}{'DES-CBC'} = ''; +$selected{'DCIPHER'}{'DES-EDE-CBC'} = ''; +$selected{'DCIPHER'}{'DES-EDE3-CBC'} = ''; +$selected{'DCIPHER'}{'DESX-CBC'} = ''; +$selected{'DCIPHER'}{'RC2-CBC'} = ''; +$selected{'DCIPHER'}{'RC2-40-CBC'} = ''; +$selected{'DCIPHER'}{'RC2-64-CBC'} = ''; +$selected{'DCIPHER'}{'BF-CBC'} = ''; +$selected{'DCIPHER'}{'CAST5-CBC'} = ''; +$selected{'DCIPHER'}{'AES-128-CBC'} = ''; +$selected{'DCIPHER'}{'AES-192-CBC'} = ''; +$selected{'DCIPHER'}{'AES-256-CBC'} = ''; +$selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED'; +$checked{'DCOMPLZO'}{'off'} = ''; +$checked{'DCOMPLZO'}{'on'} = ''; +$checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED'; + +#new settings +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'status ovpn'}, 1, ''); +&Header::openbigbox('100%', 'LEFT', '', $errormessage); + +if ($errormessage) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + &Header::closebox(); +} + +my $sactive = "
$Lang::tr{'stopped'}
"; +my $srunning = "no"; +my $activeonrun = ""; +if ( -e "/var/run/openvpn.pid"){ + $sactive = "
$Lang::tr{'running'}
"; + $srunning ="yes"; + $activeonrun = ""; +} else { + $activeonrun = "disabled='disabled'"; +} +&Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'}); +print "
ZERINA-0.9.7a7
"; +print < +
+  +  +  +$Lang::tr{'ovpn server status'} +$sactive +$Lang::tr{'ovpn on red'} + +END +; +if (&Ovpnfunc::haveBlueNet()) { + print "$Lang::tr{'ovpn on blue'}"; + print ""; +} +if (&Ovpnfunc::haveOrangeNet()) { + print "$Lang::tr{'ovpn on orange'}"; + print ""; +} +print <$Lang::tr{'local vpn hostname/ip'}: + + $Lang::tr{'ovpn subnet'} + +$Lang::tr{'ovpn device'} + +$Lang::tr{'protocol'} + + $Lang::tr{'destination port'}: + +$Lang::tr{'MTU'}  + +$Lang::tr{'comp-lzo'} + + $Lang::tr{'cipher'} + +END +; + +if ( $srunning eq "yes" ) { + print ""; + print ""; + print ""; + print ""; +} else{ + print ""; + print ""; + if (( -e "${General::swroot}/ovpn/ca/cacert.pem" && + -e "${General::swroot}/ovpn/ca/dh1024.pem" && + -e "${General::swroot}/ovpn/certs/servercert.pem" && + -e "${General::swroot}/ovpn/certs/serverkey.pem") && + (( $cgiparams{'ENABLED'} eq 'on') || + ( $cgiparams{'ENABLED_BLUE'} eq 'on') || + ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){ + print ""; + print ""; + } else { + print ""; + print ""; + } +} +print ""; +&Header::closebox(); +&Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}:"); +print < + + $Lang::tr{'name'} + $Lang::tr{'subject'} + $Lang::tr{'action'} + +EOF + ; +if (-f "${General::swroot}/ovpn/ca/cacert.pem") { + my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`; + $casubject =~ /Subject: (.*)[\n]/; + $casubject = $1; + $casubject =~ s+/Email+, E+; + $casubject =~ s/ ST=/ S=/; + print < + $Lang::tr{'root certificate'} + $casubject +
+ + +
+
+ + +
+   +END + ; +} else { + # display rootcert generation buttons + print < + $Lang::tr{'root certificate'}: + $Lang::tr{'not present'} +   +END + ; +} + +if (-f "${General::swroot}/ovpn/certs/servercert.pem") { + my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; + $hostsubject =~ /Subject: (.*)[\n]/; + $hostsubject = $1; + $hostsubject =~ s+/Email+, E+; + $hostsubject =~ s/ ST=/ S=/; + print < + $Lang::tr{'host certificate'} + $hostsubject +
+ + +
+
+ + +
+   +END + ; +} else { + # Nothing + print < + $Lang::tr{'host certificate'}: + $Lang::tr{'not present'} +   +END + ; +} + +if (! -f "${General::swroot}/ovpn/ca/cacert.pem") { + print "
"; + print ""; + print "
\n"; +} + +if (keys %cahash > 0) { + foreach my $key (keys %cahash) { + if (($key + 1) % 2) { + print "\n"; + } else { + print "\n"; + } + print "$cahash{$key}[0]\n"; + print "$cahash{$key}[1]\n"; + print < + + + + +
+ + + +
+
+ + + +
+END + ; + } +} +print ""; +if ( -f "${General::swroot}/ovpn/ca/cacert.pem") {# If the file contains entries, print Key to action icons + print < + +   $Lang::tr{'legend'}: +     $Lang::tr{ + $Lang::tr{'show certificate'} +     $Lang::tr{ + $Lang::tr{'download certificate'} + + +END + ; +} +print < + + + + + +
$Lang::tr{'ca name'}: +
+END + ; +&Header::closebox(); +if ( $srunning eq "yes" ) { + print "
\n"; +}else{ + print "
\n"; +} +if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'Client status and controlc' }); + print < + + $Lang::tr{'name'} + $Lang::tr{'type'} + $Lang::tr{'common name'} + $Lang::tr{'valid till'} + $Lang::tr{'remark'}
L2089 + $Lang::tr{'status'} + $Lang::tr{'action'} + +END + ; + my $id = 0; + my $gif; + foreach my $key (keys %confighash) { + if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; } + if ($id % 2) { + print "\n"; + } else { + print "\n"; + } + print "$confighash{$key}[1]"; + if ($confighash{$key}[3] ne 'host') { + print "" . $confighash{$key}[6] . "-" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")"; + } else { + print "" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")"; + } + if ($confighash{$key}[4] eq 'cert') { + print "$confighash{$key}[2]"; + } else { + print " "; + } + if ($confighash{$key}[19] ne 'yes') { + my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; + $cavalid =~ /Not After : (.*)[\n]/; + $cavalid = $1; + print "$cavalid"; + } else { + print " "; + } + print "$confighash{$key}[25]"; + my $active = "
$Lang::tr{'capsclosed'}
"; + if ($confighash{$key}[0] eq 'off') { + $active = "
$Lang::tr{'capsclosed'}
"; + } else { + if ($confighash{$key}[3] eq 'host') { + my $cn; + my @match = (); + foreach my $line (@status) { + chomp($line); + if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) { + @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line); + if ($match[1] ne "Common Name") { + $cn = $match[1]; + } + $cn =~ s/[_]/ /g; + if ($cn eq "$confighash{$key}[2]") { + $active = "
$Lang::tr{'capsopen'}
"; + } + } + } + } else { + my @tempovpnsubnet = split("\/",$confighash{$key}[13]); + my @ovpnip = split /\./,$tempovpnsubnet[0]; + my $pingip = ""; + if ($confighash{$key}[6] eq 'server') { + $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].2"; + } else { + $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].1"; + } + my $p = Net::Ping->new("udp",1); + if ($p->ping($pingip)) { + $active = "
$Lang::tr{'capsopen'}
"; + } + $p->close(); + } + } + print "$active"; + my $disable_clientdl = ""; + if ($confighash{$key}[6] ne 'client') { + print < + + + + +END + ; } else { + print " "; + } + if ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { + print < + + + + +END + ; } else { + print " "; + } + if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") { + print < + + + + +END + ; } elsif ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { + print < + + + + +END + ; } else { + print " "; + } + print < + + + + +
+ + + +
+
+ + + +
+ +END + ; + $id++; + } + ; + + # If the config file contains entries, print Key to action icons + if ( $id ) { + print < + +   $Lang::tr{'legend'}: +   $Lang::tr{ + $Lang::tr{'click to disable'} +     $Lang::tr{ + $Lang::tr{'show certificate'} +     $Lang::tr{ + $Lang::tr{'edit'} +     $Lang::tr{ + $Lang::tr{'remove'} + + +   +   ?OFF + $Lang::tr{'click to enable'} +     ?FLOPPY + $Lang::tr{'download certificate'} +     ?RELOAD + $Lang::tr{'dl client arch'} + + +END + ; + } + print < +
+ + +
+ +END + ; + &Header::closebox(); +} +&Header::closepage(); \ No newline at end of file diff --git a/html/html/images/openvpn.gif b/html/html/images/openvpn.gif new file mode 100644 index 0000000000..e4c789b6c4 Binary files /dev/null and b/html/html/images/openvpn.gif differ diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index 4fd441ec1d..b06f13c81f 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -958,6 +958,106 @@ 'you can only define one roadwarrior connection when using pre-shared key authentication' => 'Sie können nur eine Roadwarrior Verbindung definieren, wenn die Pre-shared Schlüsselauthentifizierung verwendet wird.
Entweder haben Sie bereits eine Roadwarrior Verbindung mit Pre-shared Schlüsselauthentifizierung, oder Sie versuchen gerade eine hinzuzufügen.', 'your department' => 'Ihre Abteilung', 'your e-mail' => 'Ihre E-mail Adresse', +'connect' => 'OVPN Start / Verbinden', +'disconnect' => 'OVPN Stop / Trennen', +'add new ovpn' => 'OpenVPN Einstellungen:', +'Remote IP' => 'Entfernte IP / Hostname (DynDNS):', +'comment' => 'Kommentar:', +'alt ovpn' => 'OpenVPN', +'ovpn' => 'OpenVPN', +'ovpn log' => 'OVPN-Log', +'ovpn config' => 'OVPN-Konfiguration', +'ovpnstatus log' => 'OVPN-Status-Log', +'ovpnsys log' => 'OVPN-System-Log', +'current ovpn' => 'Aktive OVPN-Verbindung:', +'Local VPN IP' => 'Internes Netzwerk (GREEN):', +'Remote VPN IP' => 'VPN Subnetz (z.B. 10.0.10.0/255.255.255.0):', +'Ping'=> 'Ping :', +'optional data'=> '3. Optionale Einstellungen:', +'requested data' => '1. Verbindungs Einstellungen:', +'Resolv'=> 'Resolv-Retry:', +'Verbose'=> 'Verbose:', +'MTU'=> 'MTU Size:', +'choose config' => 'Konfiguration auswaehlen', +'generate' => 'Root/Host Zertifikate generieren', +'test' => 'test', +'ovpn dl' => 'OVPN-Konfiguration downloaden', +'key stuff' => '2. Keys und Zertifikate', +'status ovpn' => '4. OpenVPN Status / Konfiguration:', +'manage ovpn' => '5. Tunnel Management:', +'genkey' => 'PSK erzeugen', +'exportkey' => 'PSK exportieren', +'importkey' => 'PSK importieren', +'OpenVPN' => 'OpenVPN', +'o-yes' => 'Aktiv', +'o-no' => 'Inaktiv', +'comp-lzo' => 'LZO-Kompression:', +'error external access' => 'Kann /var/ipcop/xtaccess/config nicht öffnen (external acccess could not be granted)!', +'error config' => 'Kann /var/ipcop/ovpn/config/ZERINA.ovpn nicht öffnen!', +'hint' => 'Tipp:', +'empty' => 'Dieses Feld kann leer bleiben', +'cipher' => 'Verschlüsselung:', +'debugme' => 'Noch nicht implementiert', +'Client status and controlc' => 'Client Status und Kontrolle:', +'Act as' => 'Konfiguriert als:', +'openvpn server' => 'OpenVPN Server', +'openvpn client' => 'OpenVPN Client', +'ovpn subnet' => 'OpenVPN Subnetz (z.B. 10.0.10.0/255.255.255.0)', +'gen static key' => 'Statischen Schlüssel erzeugen', +'upload static key' => 'Statischen Schlüssel hochladen', +'ovpn device' => 'OpenVPN Gerät', +'external access rule changed' => 'External access Regel geaendert; Der access controller wird neu gestartet.', +'ovpn subnet is invalid' => 'Das OpenVPN Subnetz ist ungültig.', +'invalid mtu input' => 'Ungültige MTU', +'start ovpn server' => 'Starte OpenVPN Server', +'stop ovpn server' => 'Stoppe OpenVPN Server', +'restart ovpn server' => 'OpenVPN Server neu starten', +'ovpn server status', => 'OpenVPN Server Status:', +'dl client arch', => 'Client Paket herunterladen (zip)', +'ovpn on red' => 'OpenVPN auf ROT', +'ovpn on blue' => 'OpenVPN auf BLAU', +'ovpn on orange' => 'OpenVPN auf ORANGE', +'ovpn con stat' => 'OpenVPN Verbindungs-Statistik', +'real address' => 'Reale Addresse', +'virtual address' => 'Virtuelle Addresse', +'loged in at' => 'Angemeldet seit', +'bytes sent' => 'Bytes Gesendet', +'bytes received' => 'Bytes Empfangen', +'last activity' => 'Letzte Aktivitaet', +'ovpn subnet overlap' => 'OpenVPN Subnetz überschneidet sich mit : ', +'show crl' => 'Certificate Revocation List anzeigen', +'crl' => 'Certificate Revocation List', +'advanced server' => 'Erweiterte Server Optionen', +'dhcp-options' => 'DHCP push Optionen', +'log-options' => 'Logfile options', +'misc-options' => 'Sonstige Optionen', +'save-adv-options' => 'Erweiterte Optionen speichern', +'cancel-adv-options' => 'Abbrechen', +'invalid input for dhcp domain' => 'Ungültige Eingabe für DHCP Domain', +'invalid input for dhcp dns' => 'Ungültige Eingabe für DHCP DNS', +'invalid input for dhcp wins' => 'Ungültige Eingabe für DHCP WINS', +'invalid input for max clients' => 'Ungültige Eingabe für Max Clients', +'invalid input for keepalive 1' => 'Ungültige Eingabe für Keepalive ping', +'invalid input for keepalive 2' => 'Ungültige Eingabe für Keepalive ping-restart', +'valid till' => 'Güig bis', +'ovpn_processprio' => 'Prozesspriorität', +'ovpn_fastio' => 'Fast-IO', +'ovpn_mtudisc' => 'MTU-Discovery', +'ovpn_mssfix' => 'MSSFIX Grösse', +'ovpn_fragment' => 'Fragmentgrösse', +'ovpn_processprioEH' => 'Extrem Hoch', +'ovpn_processprioVH' => 'Sehr Hoch', +'ovpn_processprioH' => 'Hoch', +'ovpn_processprioEN' => 'Höher als Normal', +'ovpn_processprioN' => 'Normal', +'ovpn_processprioLN' => 'Tiefer als Normal', +'ovpn_processprioD' => 'Tief', +'ovpn_processprioVD' => 'Sehr Tief', +'ovpn_processprioED' => 'Extrem Tief', +'server reserved' => 'The connection name server is reserved and not allowed', +'add-route' => 'Additional push route', +'subnet' => 'Subnet', +'route subnet is invalid' => 'Additional push route subnet is invalid', ); diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 68c1fad3e7..64bda8cef8 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -989,5 +989,107 @@ 'traffics' => 'Utilization-overview:', 'trafficsum' => 'Totals', 'trafficto' => 'To', +'connect' => 'OVPN Start / Connect', +'disconnect' => 'OVPN Stop / Disconnect', +'add new ovpn' => 'OpenVPN Settings:', +'Remote IP' => 'Remote IP / Hostname (DynDNS):', +'comment' => 'Description:', +'alt ovpn' => 'OpenVPN', +'ovpn' => 'OpenVPN', +'ovpn log' => 'OVPN-Log', +'ovpn config' => 'OVPN-Config', +'ovpnstatus log' => 'OVPN-Status-Log', +'ovpnsys log' => 'OVPN-System-Log', +'current ovpn' => 'Active OVPN-Connection:', +'Local VPN IP' => 'Internal Network (GREEN):', +'Remote VPN IP' => 'VPN Subnet (e.g. 10.0.10.0/255.255.255.0):', +'Ping'=> 'Ping :', +'optional data'=> '3. Optional Settings:', +'requested data' => '1. Connection Settings:', +'Resolv'=> 'Resolv-Retry:', +'Verbose'=> 'Verbose:', +'MTU'=> 'MTU Size:', +'choose config' => 'Choose Config', +'generate' => 'Generate Root/Host Zertifikate', +'test' => 'test', +'ovpn dl' => 'OVPN-Config Download', +'key stuff' => '2. Keys and Certificates', +'status ovpn' => '4. OpenVPN Status / Configuration:', +'manage ovpn' => '5. Tunnel Management:', +'genkey' => 'Generate PSK', +'exportkey' => 'Export PSK', +'importkey' => 'Import PSK', +'OpenVPN' => 'OpenVPN', +'o-yes' => 'Activ', +'o-no' => 'Inactiv', +'comp-lzo' => 'LZO-Compression:', +'error external access' => 'Could not open /var/ipcop/xtaccess/config (external acccess could not be granted)!', +'error config' => 'Could not open /var/ipcop/ovpn/config/ZERINA.ovpn !', +'hint' => 'Hint:', +'empty' => 'This field may be left blank', +'cipher' => 'Encryption:', +'debugme' => 'Not yet implemented', +'Client status and controlc' => 'Client status and control:', +'Act as' => 'Act as:', +'openvpn server' => 'OpenVPN Server', +'openvpn client' => 'OpenVPN Client', +'ovpn subnet' => 'OpenVPN Subnet(e.g. 10.0.10.0/255.255.255.0)', +'gen static key' => 'Generate a static Key', +'upload static key' => 'Upload a static Key', +'ovpn device' => 'OpenVPN device', +'external access rule changed' => 'External access rule changed; restarting access controller', +'ovpn subnet is invalid' => 'OpenVPN subnet is invalid.', +'invalid mtu input' => 'Invalid MTU', +'start ovpn server' => 'Start OpenVPN Server', +'stop ovpn server' => 'Stop OpenVPN Server', +'restart ovpn server' => 'Restart OpenVPN Server', +'ovpn server status', => 'Current OpenVPN Server Status:', +'dl client arch', => 'Download Client Package (zip)', +'ovpn on red' => 'OpenVPN on RED', +'ovpn on blue' => 'OpenVPN on BLUE', +'ovpn on orange' => 'OpenVPN on ORANGE', +'ovpn con stat' => 'OpenVPN Connection Statistics', +'real address' => 'Real Address', +'virtual address' => 'Virtual Address', +'loged in at' => 'Logged In At', +'bytes sent' => 'Bytes Sent', +'bytes received' => 'Bytes Received', +'last activity' => 'Last Activity', +'ovpn subnet overlap' => 'OpenVPN Subnet overlaps with : ', +'show crl' => 'Show Certificate Revocation List', +'crl' => 'Certificate Revocation List', +'advanced server' => 'Advanced Server options', +'dhcp-options' => 'DHCP push options', +'log-options' => 'Logfile options', +'misc-options' => 'Miscellaneous options', +'save-adv-options' => 'Save Advanced options', +'cancel-adv-options' => 'Cancel', +'invalid input for dhcp domain' => 'Invalid input for DHCP Domain', +'invalid input for dhcp dns' => 'Invalid input for DHCP DNS', +'invalid input for dhcp wins' => 'Invalid input for DHCP WINS', +'invalid input for max clients' => 'Invalid input for Max Clients', +'invalid input for keepalive 1' => 'Invalid input for Keepalive ping', +'invalid input for keepalive 2' => 'Invalid input for Keepalive ping-restart', +'invalid input for keepalive 2' => 'Invalid input for Keepalive ping-restart', +'invalid input for keepalive 1:2' => 'Invalid input for Keepalive use at least a ratio of 1:2', +'valid till' => 'Valid till', +'ovpn_processprio' => 'Process priority', +'ovpn_fastio' => 'Fast-IO', +'ovpn_mtudisc' => 'MTU-Discovery', +'ovpn_mssfix' => 'MSSFIX Size', +'ovpn_fragment' => 'Fragmentsize', +'ovpn_processprioEH' => 'Extremely high', +'ovpn_processprioVH' => 'Very high', +'ovpn_processprioH' => 'High', +'ovpn_processprioEN' => 'More highly than normal', +'ovpn_processprioN' => 'Normal', +'ovpn_processprioLN' => 'More deeply than normal', +'ovpn_processprioD' => 'Deeply', +'ovpn_processprioVD' => 'Very deeply', +'ovpn_processprioED' => 'Extremely deeply', +'server reserved' => 'The connection name server is reserved and not allowed', +'add-route' => 'Additional push route', +'subnet' => 'Subnet', +'route subnet is invalid' => 'Additional push route subnet is invalid', ); diff --git a/lfs/openvpn b/lfs/openvpn index c93fce2a5d..c0a00f70c4 100644 --- a/lfs/openvpn +++ b/lfs/openvpn @@ -58,9 +58,6 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects)) md5 : $(subst %,%_MD5,$(objects)) -#dist: -# make-packages.sh postfix $(THISAPP) - ############################################################################### # Downloading, checking, md5sum ############################################################################### @@ -81,8 +78,15 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && ./configure --enable-pthread --sysconfdir=/var/ipfire/ovpn + cd $(DIR_APP) && ./configure --enable-pthread --sysconfdir=/var/ipfire/ovpn --prefix=/usr cd $(DIR_APP) && make cd $(DIR_APP) && make install + cd $(DIR_APP) && cp -Rvf $(DIR_SRC)/config/ovpn /var/ipfire + chown -R nobody:nobody /var/ipfire/ovpn + chown root.nobody /var/log/ovpnserver.log + chmod 755 /var/ipfire/ovpn/verify + chmod 660 /var/log/ovpnserver.log + chmod 700 /var/ipfire/ovpn/certs + chmod 700 /var/ipfire/ovpn/n2nconf @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/lfs/sysklogd b/lfs/sysklogd index 433e99cf96..badf836380 100644 --- a/lfs/sysklogd +++ b/lfs/sysklogd @@ -85,8 +85,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/sysklogd-1.4.1-owl-syslogd-crunch_list.diff cd $(DIR_APP) && CFLAGS="$(CFLAGS) -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce" make -e cd $(DIR_APP) && CFLAGS="$(CFLAGS) -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce" make -e install - touch /var/log/{boot.log,dhcpcd.log,messages} - chmod 664 /var/log/{boot.log,dhcpcd.log,messages} - chown 0:105 /var/log/{boot.log,dhcpcd.log,messages} + touch /var/log/{boot.log,dhcpcd.log,messages,ovpnserver.log} + chmod 664 /var/log/{boot.log,dhcpcd.log,messages,ovpnserver.log} + chown 0:105 /var/log/{boot.log,dhcpcd.log,messages,ovpnserver.log} @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/lfs/xampp b/lfs/xampp index 8d625867fe..d59e4882f8 100644 --- a/lfs/xampp +++ b/lfs/xampp @@ -26,7 +26,7 @@ include Config -VER = 1.5.3 +VER = 1.5.3a THISAPP = xampp-linux-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -48,8 +48,8 @@ xampp-linux-devel-$(VER).tar.gz = $(URL_IPFIRE)/xampp-linux-devel-$(VER).tar.gz PostGreSQL-AddOn-1.0-pgsql8.1.tar.gz = $(URL_IPFIRE)/PostGreSQL-AddOn-1.0-pgsql8.1.tar.gz Python-AddOn-1.3.tar.gz = $(URL_IPFIRE)/Python-AddOn-1.3.tar.gz -$(DL_FILE)_MD5 = 649c1fdc76435e3d5315e1ad86f9bace -xampp-linux-devel-$(VER).tar.gz_MD5 = fbdc87b3c1d6ee123173d08310baca7a +$(DL_FILE)_MD5 = 422ab1faa4ab7afb3be8918ab8223b6b +xampp-linux-devel-$(VER).tar.gz_MD5 = 30b4bce92ec389adf61cbf67246efd1f PostGreSQL-AddOn-1.0-pgsql8.1.tar.gz_MD5 = 63171afe553fd557032407e1ba6af477 Python-AddOn-1.3.tar.gz_MD5 = 5a962ea63c3e502227c8cca30e0ce786 diff --git a/src/ROOTFILES.i386 b/src/ROOTFILES.i386 index 00b9a66adb..53ebddd375 100644 --- a/src/ROOTFILES.i386 +++ b/src/ROOTFILES.i386 @@ -1355,6 +1355,7 @@ tmp #usr/local/bin usr/local/bin/httpscert usr/local/bin/makegraphs +#usr/local/bin/make-packages.sh usr/local/bin/readhash usr/local/bin/setddns.pl usr/local/bin/setreservedports @@ -16351,6 +16352,7 @@ usr/sbin/syslogd var/log/boot.log var/log/dhcpcd.log var/log/messages +var/log/ovpnserver.log var/empty ## ## sysvinit-2.86 @@ -20995,6 +20997,9 @@ home/httpd/cgi-bin/ids.cgi home/httpd/cgi-bin/index.cgi home/httpd/cgi-bin/ipinfo.cgi home/httpd/cgi-bin/fwhits.cgi +home/httpd/cgi-bin/ovpnfunc.pl +home/httpd/cgi-bin/ovpnmain.cgi +home/httpd/html/images/openvpn.gif #home/httpd/cgi-bin/logs.cgi home/httpd/cgi-bin/logs.cgi/config.dat home/httpd/cgi-bin/logs.cgi/firewalllog.dat @@ -22498,6 +22503,7 @@ usr/local/bin/ipfirereboot usr/local/bin/ipfirerscfg usr/local/bin/ipsecctrl usr/local/bin/logwatch +usr/local/bin/openvpnctrl usr/local/bin/rebuildhosts usr/local/bin/restartdhcp usr/local/bin/restartntpd diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile index ffcd4ddd4a..b896748294 100644 --- a/src/misc-progs/Makefile +++ b/src/misc-progs/Makefile @@ -9,7 +9,7 @@ SUID_PROGS = setdmzholes setportfw setfilters setxtaccess restartdhcp restartsno ipfirebkcfg ipfirerscfg installpackage installfcdsl ipsecctrl \ setaliases ipfirebackup restartntpd \ restartapplejuice setdate rebuildhosts \ - restartsyslogd logwatch + restartsyslogd logwatch openvpnctrl # restartwireless install : all @@ -36,6 +36,9 @@ $(PROGS): setuid.o logwatch: logwatch.c setuid.o ../install+setup/libsmooth/varval.o $(COMPILE) -I../install+setup/libsmooth/ logwatch.c setuid.o ../install+setup/libsmooth/varval.o -o $@ +openvpnctrl: openvpnctrl.c setuid.o ../install+setup/libsmooth/varval.o + $(COMPILE) -I../install+setup/libsmooth/ openvpnctrl.c setuid.o ../install+setup/libsmooth/varval.o -o $@ + setaliases: setaliases.c setuid.o ../install+setup/libsmooth/varval.o $(COMPILE) -I../install+setup/libsmooth/ setaliases.c setuid.o ../install+setup/libsmooth/varval.o -o $@ diff --git a/src/misc-progs/openvpnctrl.c b/src/misc-progs/openvpnctrl.c new file mode 100644 index 0000000000..ab3242c413 --- /dev/null +++ b/src/misc-progs/openvpnctrl.c @@ -0,0 +1,451 @@ +#include +#include +#include +#include +#include +#include +#include "setuid.h" +#include "libsmooth.h" + +/* + Version History + + 1.0.0.0 many things happend before ... + + 2.0.0.1 2005/06/09 tarralan + add. Version History + add. deleteChainReference(char*) + add. createChainReference(char*) + mod. deleteChain(char*) + mod. flushChain(char*) + add. flushAllChains() + del. deletechains() + add. consts for chain names + del. createchains() + add. createAllChains() + add. ovpnInit() + add. global vars for chain and interface status + add. usage of consts for chain names + mod. reworked createAllChains() + + 2.0.0.2 2005/06/09 horizont + change the input + forward chain position index based on active interfaces + + 2.0.0.3 2005/06/09 tarralan + mod. removed const attribute + + 2.0.0.4 2005/06/12 tarralan + add. debug condition für output + mod. changed definition auf consts + + 2.0.0.5-7 2005/06/12 tarralan + debugging + + 2.0.0.8 2005/06/12 tarralan + add. executeCommand() + + 2.0.0.9-16 2005/06/12 tarralan + debugging + + 2.0.0.17 2005/06/12 tarralan + mod. createAllChains + + 2.0.1.1 2005/06/12 tarralan + non-debug build + + 2.0.1.2 2005/06/13 tarralan + mod. some options renamed + + 2.0.1.3 2005/06/13 tarralan + mod. startDaemon() to verify if OpenVPN is enabled + mod. createAllChains() to verify if OpenVPN is enabled + mod. command help + + 2.0.1.4 2005/06/13 tarralan + mod. bug fixed with the -sdo option + 2.0.1.5 2005/11/06 Ufuk Altinkaynak + mod. bug fixed no need to read blue and orange dev, when they are not enabled + 2.0.1.6 2005/01/03 Ufuk Altinkaynak + mod. bug fixed reported by weizen_42 see http://www.vpnforum.de/viewtopic.php?p=7113#7113 + +# ZERNINA-VERSION:0.9.0b +# (c) 2005 tarralan + Ufuk Altinkaynak +# +# Ipcop and OpenVPN eas as one two three.. +# +*/ +#define noovpndebug + +// global vars + struct keyvalue *kv = NULL; + FILE *ifacefile = NULL; + +char redif[STRING_SIZE]; +char blueif[STRING_SIZE]; +char orangeif[STRING_SIZE]; +char enablered[STRING_SIZE] = "off"; +char enableblue[STRING_SIZE] = "off"; +char enableorange[STRING_SIZE] = "off"; + +// consts +char OVPNRED[STRING_SIZE] = "OVPN"; +char OVPNBLUE[STRING_SIZE] = "OVPN_BLUE_"; +char OVPNORANGE[STRING_SIZE] = "OVPN_ORANGE_"; +char WRAPPERVERSION[STRING_SIZE] = "2.0.1.6"; + +void exithandler(void) +{ + if(kv) + freekeyvalues(kv); + if (ifacefile) + fclose(ifacefile); +} + +void usage(void) +{ +#ifdef ovpndebug + printf("Wrapper for OpenVPN v%s-debug\n", WRAPPERVERSION); +#else + printf("Wrapper for OpenVPN v%s\n", WRAPPERVERSION); +#endif + printf("openvpnctrl