#!/usr/bin/perl ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2007-2011 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### ### # Based on IPFireCore 55 ### use CGI; use CGI qw/:standard/; use Net::DNS; use Net::Ping; use Net::Telnet; use File::Copy; use File::Temp qw/ tempfile tempdir /; use strict; use Archive::Zip qw(:ERROR_CODES :CONSTANTS); require '/var/ipfire/general-functions.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); my %color = (); my %mainsettings = (); &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); ### ### Initialize variables ### my %netsettings=(); my %cgiparams=(); my %vpnsettings=(); my %checked=(); my %confighash=(); my %cahash=(); my %selected=(); my $warnmessage = ''; my $errormessage = ''; my %settings=(); my $routes_push_file = ''; &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{'ROUTES_PUSH'} = ''; $cgiparams{'DCOMPLZO'} = 'off'; $cgiparams{'MSSFIX'} = ''; $cgiparams{'PMTU_DISCOVERY'} = ''; $routes_push_file = "${General::swroot}/ovpn/routes_push"; unless (-e $routes_push_file) { system("touch $routes_push_file"); } &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'}); # prepare openvpn config file ### ### Useful functions ### sub haveOrangeNet { if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;} if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;} return 0; } sub haveBlueNet { if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;} if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;} return 0; } sub sizeformat{ my $bytesize = shift; 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; } 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; } } } } return; } sub writeserverconf { my %sovpnsettings = (); my @temp = (); &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings); &read_routepushfile; 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 OpenVPN for listening on blue and orange\n"; print CONF ";local $sovpnsettings{'VPN_IP'}\n"; print CONF "dev $sovpnsettings{'DDEVICE'}\n"; print CONF "proto $sovpnsettings{'DPROTOCOL'}\n"; print CONF "port $sovpnsettings{'DDEST_PORT'}\n"; print CONF "script-security 3 system\n"; print CONF "ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600\n"; print CONF "client-config-dir /var/ipfire/ovpn/ccd\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"; # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500. # If we doesn't use one of them, we can use the configured mtu value. if ($sovpnsettings{'MSSFIX'} eq 'on') { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } elsif ($sovpnsettings{'PMTU_DISCOVERY'} ne 'off') { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } else { print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; } if ($vpnsettings{'ROUTES_PUSH'} ne '') { @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'}); foreach (@temp) { @tempovpnsubnet = split("\/",&General::ipcidr2msk($_)); print CONF "push \"route " . $tempovpnsubnet[0]. " " . $tempovpnsubnet[1] . "\"\n"; } } if ($sovpnsettings{CLIENT2CLIENT} eq 'on') { print CONF "client-to-client\n"; } if ($sovpnsettings{MSSFIX} eq 'on') { print CONF "mssfix\n"; } if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') { print CONF "fragment $sovpnsettings{'FRAGMENT'}\n"; } if ($sovpnsettings{PMTU_DISCOVERY} ne 'off') { print CONF "mtu-disc $sovpnsettings{'PMTU_DISCOVERY'}\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"; } 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 emptyserverlog{ if (open(FILE, ">/var/log/ovpnserver.log")) { flock FILE, 2; print FILE ""; close FILE; } } ### # m.a.d net2net ### sub validdotmask { my $ipdotmask = $_[0]; if (&General::validip($ipdotmask)) { return 0; } if (!($ipdotmask =~ /^(.*?)\/(.*?)$/)) { } my $mask = $2; if (($mask =~ /\./ )) { return 0; } return 1; } # ------------------------------------------------------------------- sub write_routepushfile { open(FILE, ">$routes_push_file"); flock(FILE, 2); if ($vpnsettings{'ROUTES_PUSH'} ne '') { print FILE $vpnsettings{'ROUTES_PUSH'}; } close(FILE); } sub read_routepushfile { if (-e "$routes_push_file") { open(FILE,"$routes_push_file"); delete $vpnsettings{'ROUTES_PUSH'}; while () { $vpnsettings{'ROUTES_PUSH'} .= $_ }; close(FILE); $cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'}; } } #hier die refresh page if ( -e "${General::swroot}/ovpn/gencanow") { my $refresh = ''; $refresh = ""; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'OVPN'}, 1, $refresh); &Header::openbigbox('100%', 'center'); &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:"); print "\n\n"; print "Please be patient this realy can take some time on older hardware...\n"; &Header::closebox(); &Header::closebigbox(); &Header::closepage(); exit (0); } ##hier die refresh page ### ### 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'}) { #start openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){ &emptyserverlog(); system('/usr/local/bin/openvpnctrl', '-s'); } #stop openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){ system('/usr/local/bin/openvpnctrl', '-k'); &emptyserverlog(); } # #restart openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){ #workarund, till SIGHUP also works when running as nobody system('/usr/local/bin/openvpnctrl', '-r'); &emptyserverlog(); } } ### ### 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'}; $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'}; $vpnsettings{'PMTU_DISCOVERY'} = $cgiparams{'PMTU_DISCOVERY'}; my @temp=(); if ($cgiparams{'FRAGMENT'} eq '') { delete $vpnsettings{'FRAGMENT'}; } else { if ($cgiparams{'FRAGMENT'} !~ /^[0-9]+$/) { $errormessage = "Incorrect value, please insert only numbers."; goto ADV_ERROR; } else { $vpnsettings{'FRAGMENT'} = $cgiparams{'FRAGMENT'}; } } if ($cgiparams{'MSSFIX'} ne 'on') { delete $vpnsettings{'MSSFIX'}; } else { $vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'}; } if ($cgiparams{'PMTU_DISCOVERY'} ne 'off') { if (($cgiparams{'MSSFIX'} eq 'on') || ($cgiparams{'FRAGMENT'} ne '')) { $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'}; goto ADV_ERROR; } } 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{'ROUTES_PUSH'} ne ''){ @temp = split(/\n/,$cgiparams{'ROUTES_PUSH'}); undef $vpnsettings{'ROUTES_PUSH'}; foreach (@temp) { s/^\s+//g; s/\s+$//g; if ($_) { unless (&General::validipandmask($_)) { $errormessage = $Lang::tr{'ovpn errmsg invalid ip or mask'}; goto ADV_ERROR; } my ($ip, $cidr) = split("\/",&General::ipcidr2msk($_)); if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) { $errormessage = $Lang::tr{'ovpn errmsg green already pushed'}; goto ADV_ERROR; } $vpnsettings{'ROUTES_PUSH'} .= $_."\n"; } } &write_routepushfile; undef $vpnsettings{'ROUTES_PUSH'}; } else { undef $vpnsettings{'ROUTES_PUSH'}; &write_routepushfile; } 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); &writeserverconf();#hier ok } ### # m.a.d net2net ### if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'server') { my @remsubnet = split(/\//,$cgiparams{'REMOTE_SUBNET'}); my @ovsubnettemp = split(/\./,$cgiparams{'OVPN_SUBNET'}); my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]"; my $tunmtu = ''; unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";} unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";} open(SERVERCONF, ">${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf: $!"; flock SERVERCONF, 2; print SERVERCONF "# IPFire n2n Open VPN Server Config by ummeegge und m.a.d\n"; print SERVERCONF "\n"; print SERVERCONF "# User Security\n"; print SERVERCONF "user nobody\n"; print SERVERCONF "group nobody\n"; print SERVERCONF "persist-tun\n"; print SERVERCONF "persist-key\n"; print SERVERCONF "script-security 2\n"; print SERVERCONF "# IP/DNS for remote Server Gateway\n"; print SERVERCONF "remote $cgiparams{'REMOTE'}\n"; print SERVERCONF "float\n"; print SERVERCONF "# IP adresses of the VPN Subnet\n"; print SERVERCONF "ifconfig $ovsubnet.1 $ovsubnet.2\n"; print SERVERCONF "# Client Gateway Network\n"; print SERVERCONF "route $remsubnet[0] $remsubnet[1]\n"; print SERVERCONF "# tun Device\n"; print SERVERCONF "dev tun\n"; print SERVERCONF "# Port and Protokol\n"; print SERVERCONF "port $cgiparams{'DEST_PORT'}\n"; if ($cgiparams{'PROTOCOL'} eq 'tcp') { print SERVERCONF "proto tcp-server\n"; print SERVERCONF "# Packet size\n"; if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}}; print SERVERCONF "tun-mtu $tunmtu\n"; } if ($cgiparams{'PROTOCOL'} eq 'udp') { print SERVERCONF "proto udp\n"; print SERVERCONF "# Paketsize\n"; if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print SERVERCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; } if ($cgiparams{'PMTU_DISCOVERY'} ne 'off') { if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) { if($cgiparams{'MTU'} eq '1500') { print SERVERCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n"; } } } print SERVERCONF "# Auth. Server\n"; print SERVERCONF "tls-server\n"; print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n"; print SERVERCONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n"; print SERVERCONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n"; print SERVERCONF "dh ${General::swroot}/ovpn/ca/dh1024.pem\n"; print SERVERCONF "# Cipher\n"; print SERVERCONF "cipher AES-256-CBC\n"; if ($cgiparams{'COMPLZO'} eq 'on') { print SERVERCONF "# Enable Compression\n"; print SERVERCONF "comp-lzo\r\n"; } print SERVERCONF "# Debug Level\n"; print SERVERCONF "verb 3\n"; print SERVERCONF "# Tunnel check\n"; print SERVERCONF "keepalive 10 60\n"; print SERVERCONF "# Start as daemon\n"; print SERVERCONF "daemon $cgiparams{'NAME'}n2n\n"; print SERVERCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n"; print SERVERCONF "# Activate Management Interface and Port\n"; if ($cgiparams{'OVPN_MGMT'} eq '') {print SERVERCONF "management localhost $cgiparams{'DEST_PORT'}\n"} else {print SERVERCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"}; close(SERVERCONF); } ### # m.a.d net2net ### if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'client') { my @ovsubnettemp = split(/\./,$cgiparams{'OVPN_SUBNET'}); my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]"; my @remsubnet = split(/\//,$cgiparams{'REMOTE_SUBNET'}); my $tunmtu = ''; unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";} unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";} open(CLIENTCONF, ">${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf: $!"; flock CLIENTCONF, 2; print CLIENTCONF "# IPFire rewritten n2n Open VPN Client Config by ummeegge und m.a.d\n"; print CLIENTCONF "#\n"; print CLIENTCONF "# User Security\n"; print CLIENTCONF "user nobody\n"; print CLIENTCONF "group nobody\n"; print CLIENTCONF "persist-tun\n"; print CLIENTCONF "persist-key\n"; print CLIENTCONF "script-security 2\n"; print CLIENTCONF "# IP/DNS for remote Server Gateway\n"; print CLIENTCONF "remote $cgiparams{'REMOTE'}\n"; print CLIENTCONF "float\n"; print CLIENTCONF "# IP adresses of the VPN Subnet\n"; print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n"; print CLIENTCONF "# Server Gateway Network\n"; print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n"; print CLIENTCONF "# tun Device\n"; print CLIENTCONF "dev tun\n"; print CLIENTCONF "# Port and Protokol\n"; print CLIENTCONF "port $cgiparams{'DEST_PORT'}\n"; if ($cgiparams{'PROTOCOL'} eq 'tcp') { print CLIENTCONF "proto tcp-client\n"; print CLIENTCONF "# Packet size\n"; if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}}; print CLIENTCONF "tun-mtu $tunmtu\n"; } if ($cgiparams{'PROTOCOL'} eq 'udp') { print CLIENTCONF "proto udp\n"; print CLIENTCONF "# Paketsize\n"; if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print CLIENTCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";} if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; } if ($cgiparams{'PMTU_DISCOVERY'} ne 'off') { if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) { if ($cgiparams{'MTU'} eq '1500') { print CLIENTCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n"; } } } print CLIENTCONF "ns-cert-type server\n"; print CLIENTCONF "# Auth. Client\n"; print CLIENTCONF "tls-client\n"; print CLIENTCONF "# Cipher\n"; print CLIENTCONF "cipher AES-256-CBC\n"; print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n"; if ($cgiparams{'COMPLZO'} eq 'on') { print CLIENTCONF "# Enable Compression\n"; print CLIENTCONF "comp-lzo\r\n"; } print CLIENTCONF "# Debug Level\n"; print CLIENTCONF "verb 3\n"; print CLIENTCONF "# Tunnel check\n"; print CLIENTCONF "keepalive 10 60\n"; print CLIENTCONF "# Start as daemon\n"; print CLIENTCONF "daemon $cgiparams{'NAME'}n2n\n"; print CLIENTCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n"; print CLIENTCONF "# Activate Management Interface and Port\n"; if ($cgiparams{'OVPN_MGMT'} eq '') {print CLIENTCONF "management localhost $cgiparams{'DEST_PORT'}\n"} else {print CLIENTCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"}; close(CLIENTCONF); } ### ### Save main settings ### if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') { &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. 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'){ &disallowreserved($cgiparams{'DDEST_PORT'},0,$cgiparams{'DPROTOCOL'},"dest"); } if ($errormessage) { goto SETTINGS_ERROR; } if ($cgiparams{'ENABLED'} eq 'on'){ &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'}); if (&General::IpInSubnet ( $netsettings{'RED_ADDRESS'}, $tmpovpnsubnet[0], $tmpovpnsubnet[1])) { $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $netsettings{'RED_ADDRESS'}"; goto SETTINGS_ERROR; } if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'}, $tmpovpnsubnet[0], $tmpovpnsubnet[1])) { $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}"; goto SETTINGS_ERROR; } if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'}, $tmpovpnsubnet[0], $tmpovpnsubnet[1])) { $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}"; goto SETTINGS_ERROR; } if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'}, $tmpovpnsubnet[0], $tmpovpnsubnet[1])) { $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}"; goto SETTINGS_ERROR; } 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] , $tmpovpnsubnet[0], $tmpovpnsubnet[1])) { $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]"; } } } close(ALIASES); 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; } $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'}; #wrtie enable if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_blue 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_blue 2>/dev/null");} if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_orange 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_orange 2>/dev/null");} if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");} #new settings for daemon &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); &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 } &cleanssldatabase(); if (open(FILE, ">${General::swroot}/ovpn/caconfig")) { print FILE ""; close FILE; } &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); #&writeserverconf(); ### ### 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); # system('/usr/local/bin/ipsecctrl', 'R'); UPLOADCA_ERROR: ### ### Display ca certificate ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) { &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'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{$cgiparams{'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'}; } ### ### 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/) { # Delete connection # if ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'D', $key); # } 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); # &writeipsecfiles(); } } 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'}; } ### ### 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'}) { my $output; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); &Header::openbigbox('100%', 'LEFT', '', ''); if ($cgiparams{'ACTION'} 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); ### ### 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"); &newcleanssldatabase(); goto ROOTCERT_ERROR; } else { unlink ("${General::swroot}/ovpn/certs/serverreq.pem"); &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"); &cleanssldatabase(); goto ROOTCERT_ERROR; # } else { # &cleanssldatabase(); } # 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"); &cleanssldatabase(); goto ROOTCERT_ERROR; # } else { # &cleanssldatabase(); } 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"); # if ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLE_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'S'); # } ### ### Enable/Disable connection ### ### # m.a.d net2net ### }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); # my $n2nactive = ''; my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`; if ($confighash{$cgiparams{'KEY'}}) { if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { $confighash{$cgiparams{'KEY'}}[0] = 'on'; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); } } else { $confighash{$cgiparams{'KEY'}}[0] = 'off'; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ if ($n2nactive ne ''){ system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]); } } 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/"; ### # m.a.d net2net ### if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-Client.zip"; my $zippathname = "$zippath$zipname"; $clientovpn = "$confighash{$cgiparams{'KEY'}}[1].conf"; my @ovsubnettemp = split(/\./,$confighash{$cgiparams{'KEY'}}[27]); my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]"; my $tunmtu = ''; my @remsubnet = split(/\//,$confighash{$cgiparams{'KEY'}}[8]); my $n2nfragment = ''; open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!"; flock CLIENTCONF, 2; my $zip = Archive::Zip->new(); print CLIENTCONF "# IPFire n2n Open VPN Client Config by ummeegge und m.a.d\n"; print CLIENTCONF "# \n"; print CLIENTCONF "# User Security\n"; print CLIENTCONF "user nobody\n"; print CLIENTCONF "group nobody\n"; print CLIENTCONF "persist-tun\n"; print CLIENTCONF "persist-key\n"; print CLIENTCONF "script-security 2\n"; print CLIENTCONF "# IP/DNS for remote Server Gateway\n"; print CLIENTCONF "remote $vpnsettings{'VPN_IP'}\n"; print CLIENTCONF "float\n"; print CLIENTCONF "# IP adresses of the VPN Subnet\n"; print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n"; print CLIENTCONF "# Server Gateway Network\n"; print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n"; print CLIENTCONF "# tun Device\n"; print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\n"; print CLIENTCONF "# Port and Protokoll\n"; print CLIENTCONF "port $confighash{$cgiparams{'KEY'}}[29]\n"; if ($confighash{$cgiparams{'KEY'}}[28] eq 'tcp') { print CLIENTCONF "proto tcp-client\n"; print CLIENTCONF "# Packet size\n"; if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1400'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]}; print CLIENTCONF "tun-mtu $tunmtu\n"; } if ($confighash{$cgiparams{'KEY'}}[28] eq 'udp') { print CLIENTCONF "proto udp\n"; print CLIENTCONF "# Paketsize\n"; if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]}; print CLIENTCONF "tun-mtu $tunmtu\n"; if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";} if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";} } if ($confighash{$cgiparams{'KEY'}}[32] ne 'off') { if (($confighash{$cgiparams{'KEY'}}[23] ne 'on') || ($confighash{$cgiparams{'KEY'}}[24] eq '')) { if ($tunmtu eq '1500' ) { print CLIENTCONF "mtu-disc $confighash{$cgiparams{'KEY'}}[32]\n"; } } } print CLIENTCONF "ns-cert-type server\n"; print CLIENTCONF "# Auth. Client\n"; print CLIENTCONF "tls-client\n"; print CLIENTCONF "# Cipher\n"; print CLIENTCONF "cipher AES-256-CBC\n"; if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") { print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$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"; } if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') { print CLIENTCONF "# Enable Compression\n"; print CLIENTCONF "comp-lzo\r\n"; } print CLIENTCONF "# Debug Level\n"; print CLIENTCONF "verb 3\n"; print CLIENTCONF "# Tunnel check\n"; print CLIENTCONF "keepalive 10 60\n"; print CLIENTCONF "# Start as daemon\n"; print CLIENTCONF "daemon $confighash{$cgiparams{'KEY'}}[1]n2n\n"; print CLIENTCONF "writepid /var/run/$confighash{$cgiparams{'KEY'}}[1]n2n.pid\n"; print CLIENTCONF "# Activate Management Interface and Port\n"; if ($confighash{$cgiparams{'KEY'}}[22] eq '') {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"} else {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"}; print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\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); } else { my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip"; my $zippathname = "$zippath$zipname"; $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn"; ### # m.a.d net2net ### 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"; # Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500 # or use configured value. if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; } elsif ($vpnsettings{MSSFIX} eq 'on') { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; } elsif ($vpnsettings{PMTU_DISCOVERY} ne 'off') { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\n"; } else { 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' && (&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' && (&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' && (&haveBlueNet())){ print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n"; if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&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' && (&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"; print CLIENTCONF "tls-remote $vpnsettings{ROOTCERT_HOSTNAME}\r\n"; if ($vpnsettings{MSSFIX} eq 'on') { print CLIENTCONF "mssfix\r\n"; } if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) { print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n"; } if ($vpnsettings{PMTU_DISCOVERY} ne 'off') { if(($vpnsettings{MSSFIX} ne 'on') || ($vpnsettings{FRAGMENT} eq '')) { print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\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 ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}); # } # my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`; ### # m.a.d net2net ### if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') { my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf"); my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); unlink ($certfile) or die "Removing $certfile fail: $!"; unlink ($conffile) or die "Removing $conffile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!"; } unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); 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); #&writeserverconf(); } 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'}) { # &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); 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); read_routepushfile; # if ($cgiparams{'CLIENT2CLIENT'} eq '') { # $cgiparams{'CLIENT2CLIENT'} = 'on'; # } 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'; } $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{'ENGINES'}{$cgiparams{'ENGINES'}} = 'SELECTED'; $checked{'MSSFIX'}{'off'} = ''; $checked{'MSSFIX'}{'on'} = ''; $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED'; $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'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'; &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{'ovpn routes push options'}
$Lang::tr{'ovpn routes push'}

$Lang::tr{'misc-options'}
Client-To-Client
Redirect-Gateway def1
Max-Clients
Keppalive
(ping/ping-restart)
fragment
Default: 1300
mssfix Default: on
$Lang::tr{'ovpn mtu-disc'} $Lang::tr{'ovpn mtu-disc yes'} $Lang::tr{'ovpn mtu-disc maybe'} $Lang::tr{'ovpn mtu-disc no'} $Lang::tr{'ovpn mtu-disc off'}

$Lang::tr{'log-options'}
VERB

   
END ; &Header::closebox(); # print ""; &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]; } #gian 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'} = &sizeformat($match[3]); $users[$uid]{'BytesSent'} = &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); } ### ### Enable/Disable connection ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings); &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); if ($confighash{$cgiparams{'KEY'}}) { if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { $confighash{$cgiparams{'KEY'}}[0] = 'on'; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); #&writeserverconf(); # if ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); # } } else { $confighash{$cgiparams{'KEY'}}[0] = 'off'; # if ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}); # } &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); #&writeserverconf(); } } else { $errormessage = $Lang::tr{'invalid key'}; } ### ### 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'}}) { # if ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); # } } else { $errormessage = $Lang::tr{'invalid key'}; } ### ### 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 ($vpnsettings{'ENABLED'} eq 'on' || # $vpnsettings{'ENABLED_BLUE'} eq 'on') { # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}); # } unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); delete $confighash{$cgiparams{'KEY'}}; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); #&writeserverconf(); } else { $errormessage = $Lang::tr{'invalid key'}; } #test33 ### ### Choose between adding a host-net or net-net connection ### ### # m.a.d net2net ### } 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'}); if ( -s "${General::swroot}/ovpn/settings") { print <$Lang::tr{'connection type'}:
$Lang::tr{'host to net vpn'}
$Lang::tr{'net to net vpn'}
$Lang::tr{'net to net vpn'} (Upload Client Package)
 
 Import Connection Name
 Default : Client Packagename

 
* $Lang::tr{'this field may be blank'}
END ; } else { print <$Lang::tr{'connection type'}:
$Lang::tr{'host to net vpn'}
END ; } &Header::closebox(); &Header::closebigbox(); &Header::closepage(); exit (0); ### # m.a.d net2net ### } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2net')){ my @firen2nconf; my @confdetails; my $uplconffilename =''; my $uplconffilename2 =''; my $uplp12name = ''; my $uplp12name2 = ''; my @rem_subnet; my @rem_subnet2; my @tmposupnet3; my $key; my @n2nname; &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); # Check if a file is uploaded if (ref ($cgiparams{'FH'}) ne 'Fh') { $errormessage = $Lang::tr{'there was no file upload'}; goto N2N_ERROR; } # Move uploaded IPfire n2n package to temporary file (my $fh, my $filename) = tempfile( ); if (copy ($cgiparams{'FH'}, $fh) != 1) { $errormessage = $!; goto N2N_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 N2N_ERROR; } my $tempdir = tempdir( CLEANUP => 1 ); my @files = $zip->memberNames(); for(@files) { $zip->extractMemberWithoutPaths($_,"$tempdir/$_"); } my $countfiles = @files; # Check if we have not more then 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 N2N_ERROR; } open(FILE, "$tempdir/$uplconffilename") or die 'Unable to open*.conf file'; @firen2nconf = ; close (FILE); chomp(@firen2nconf); } else { $errormessage = "Filecount does not match only 2 files are allowed\n"; goto N2N_ERROR; } ### # m.a.d net2net ### if ($cgiparams{'n2nname'} ne ''){ $uplconffilename2 = "$cgiparams{'n2nname'}.conf"; $uplp12name2 = "$cgiparams{'n2nname'}.p12"; $n2nname[0] = $cgiparams{'n2nname'}; my @n2nname2 = split(/\./,$uplconffilename); $n2nname2[0] =~ s/\n|\r//g; my $input1 = "${General::swroot}/ovpn/certs/$uplp12name"; my $output1 = "${General::swroot}/ovpn/certs/$uplp12name2"; my $input2 = "$n2nname2[0]n2n"; my $output2 = "$n2nname[0]n2n"; my $filename = "$tempdir/$uplconffilename"; open(FILE, "< $filename") or die 'Unable to open config file.'; my @current = ; close(FILE); foreach (@current) {s/$input1/$output1/g;} foreach (@current) {s/$input2/$output2/g;} open (OUT, "> $filename") || die 'Unable to open config file.'; print OUT @current; close OUT; }else{ $uplconffilename2 = $uplconffilename; $uplp12name2 = $uplp12name; @n2nname = split(/\./,$uplconffilename); $n2nname[0] =~ s/\n|\r//g; } unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";} unless(-d "${General::swroot}/ovpn/n2nconf/$n2nname[0]"){mkdir "${General::swroot}/ovpn/n2nconf/$n2nname[0]", 0770 or die "Unable to create dir $!";} move("$tempdir/$uplconffilename", "${General::swroot}/ovpn/n2nconf/$n2nname[0]/$uplconffilename2"); if ($? ne 0) { $errormessage = "*.conf move failed: $!"; unlink ($filename); goto N2N_ERROR; } move("$tempdir/$uplp12name", "${General::swroot}/ovpn/certs/$uplp12name2"); chmod 0600, "${General::swroot}/ovpn/certs/$uplp12name"; if ($? ne 0) { $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; unlink ($filename); goto N2N_ERROR; } my $complzoactive; my $mssfixactive; my $n2nfragment; my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]);; my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]); my @n2nproto = split(/-/, $n2nproto2[1]); my @n2nport = split(/ /, (grep { /^port/ } @firen2nconf)[0]); my @n2ntunmtu = split(/ /, (grep { /^tun-mtu/ } @firen2nconf)[0]); my @n2ncomplzo = grep { /^comp-lzo/ } @firen2nconf; if ($n2ncomplzo[0] =~ /comp-lzo/){$complzoactive = "on";} else {$complzoactive = "off";} my @n2nmssfix = grep { /^mssfix/ } @firen2nconf; if ($n2nmssfix[0] =~ /mssfix/){$mssfixactive = "on";} else {$mssfixactive = "off";} #my @n2nmssfix = split(/ /, (grep { /^mssfix/ } @firen2nconf)[0]); my @n2nfragment = split(/ /, (grep { /^fragment/ } @firen2nconf)[0]); my @n2nremote = split(/ /, (grep { /^remote/ } @firen2nconf)[0]); my @n2novpnsuball = split(/ /, (grep { /^ifconfig/ } @firen2nconf)[0]); my @n2novpnsub = split(/\./,$n2novpnsuball[1]); my @n2nremsub = split(/ /, (grep { /^route/ } @firen2nconf)[0]); my @n2nmgmt = split(/ /, (grep { /^management/ } @firen2nconf)[0]); my @n2nlocalsub = split(/ /, (grep { /^# remsub/ } @firen2nconf)[0]); ### # m.a.d delete CR and LF from arrays for this chomp doesnt work ### $n2nremote[1] =~ s/\n|\r//g; $n2novpnsub[0] =~ s/\n|\r//g; $n2novpnsub[1] =~ s/\n|\r//g; $n2novpnsub[2] =~ s/\n|\r//g; $n2nproto[0] =~ s/\n|\r//g; $n2nport[1] =~ s/\n|\r//g; $n2ntunmtu[1] =~ s/\n|\r//g; $n2nremsub[1] =~ s/\n|\r//g; $n2nremsub[2] =~ s/\n|\r//g; $n2nlocalsub[2] =~ s/\n|\r//g; $n2nfragment[1] =~ s/\n|\r//g; $n2nmgmt[2] =~ s/\n|\r//g; $n2nmtudisc[1] =~ s/\n|\r//g; chomp ($complzoactive); chomp ($mssfixactive); ### # m.a.d net2net ### ### # Check if there is no other entry with this name ### foreach my $dkey (keys %confighash) { if ($confighash{$dkey}[1] eq $n2nname[0]) { $errormessage = $Lang::tr{'a connection with this name already exists'}; unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!"; unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!"; goto N2N_ERROR; } } ### # Check if OpenVPN Subnet is valid ### foreach my $dkey (keys %confighash) { if ($confighash{$dkey}[27] eq "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0") { $errormessage = 'The OpenVPN Subnet is already in use'; unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!"; unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!"; goto N2N_ERROR; } } ### # Check im Dest Port is vaild ### foreach my $dkey (keys %confighash) { if ($confighash{$dkey}[29] eq $n2nport[1] ) { $errormessage = 'The OpenVPN Port is already in use'; unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!"; unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!"; goto N2N_ERROR; } } $key = &General::findhasharraykey (\%confighash); foreach my $i (0 .. 32) { $confighash{$key}[$i] = "";} $confighash{$key}[0] = 'off'; $confighash{$key}[1] = $n2nname[0]; $confighash{$key}[2] = $n2nname[0]; $confighash{$key}[3] = 'net'; $confighash{$key}[4] = 'cert'; $confighash{$key}[6] = 'client'; $confighash{$key}[8] = $n2nlocalsub[2]; $confighash{$key}[10] = $n2nremote[1]; $confighash{$key}[11] = "$n2nremsub[1]/$n2nremsub[2]"; $confighash{$key}[22] = $n2nmgmt[2]; $confighash{$key}[23] = $mssfixactive; $confighash{$key}[24] = $n2nfragment[1]; $confighash{$key}[25] = 'IPFire n2n Client'; $confighash{$key}[26] = 'red'; $confighash{$key}[27] = "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0"; $confighash{$key}[28] = $n2nproto[0]; $confighash{$key}[29] = $n2nport[1]; $confighash{$key}[30] = $complzoactive; $confighash{$key}[31] = $n2ntunmtu[1]; $confighash{$key}[32] = $n2nmtudisc[1]; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); N2N_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', 'import ipfire net2net config'); } if ($errormessage eq ''){ print <
  
$Lang::tr{'name'}:$n2nname[0]
  
$Lang::tr{'Act as'}$confighash{$key}[6]
Remote Host $confighash{$key}[10]
$Lang::tr{'local subnet'}$confighash{$key}[8]
$Lang::tr{'remote subnet'}$confighash{$key}[11]
$Lang::tr{'ovpn subnet'}$confighash{$key}[27]
$Lang::tr{'protocol'}$confighash{$key}[28]
$Lang::tr{'destination port'}:$confighash{$key}[29]
$Lang::tr{'comp-lzo'}$confighash{$key}[30]
MSSFIX $confighash{$key}[23]
Fragment $confighash{$key}[24]
$Lang::tr{'MTU'}$confighash{$key}[31]
$Lang::tr{'ovpn mtu-disc'}$confighash{$key}[32]
Management Port $confighash{$key}[22]
  
END ; &Header::closebox(); } if ($errormessage) { print ""; } else { print "
"; print ""; print ""; print "
"; } &Header::closebigbox(); &Header::closepage(); exit(0); ## ### Accept IPFire n2n Package Settings ### } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2netakn')){ ### ### Discard and Rollback IPFire n2n Package Settings ### } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'cancel'}) && ($cgiparams{'TYPE'} eq 'net2netakn')){ &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); if ($confighash{$cgiparams{'KEY'}}) { my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf"); my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); unlink ($certfile) or die "Removing $certfile fail: $!"; unlink ($conffile) or die "Removing $conffile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!"; delete $confighash{$cgiparams{'KEY'}}; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); } else { $errormessage = $Lang::tr{'invalid key'}; } ### # m.a.d net2net ### ### ### 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]; # n2n m.a.d new fields $cgiparams{'OVPN_MGMT'} = $confighash{$cgiparams{'KEY'}}[22]; $cgiparams{'MSSFIX'} = $confighash{$cgiparams{'KEY'}}[23]; $cgiparams{'FRAGMENT'} = $confighash{$cgiparams{'KEY'}}[24]; $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25]; $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26]; #new fields $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[27]; $cgiparams{'PROTOCOL'} = $confighash{$cgiparams{'KEY'}}[28]; $cgiparams{'DEST_PORT'} = $confighash{$cgiparams{'KEY'}}[29]; $cgiparams{'COMPLZO'} = $confighash{$cgiparams{'KEY'}}[30]; $cgiparams{'MTU'} = $confighash{$cgiparams{'KEY'}}[31]; $cgiparams{'PMTU_DISCOVERY'} = $confighash{$cgiparams{'KEY'}}[32]; #new fields #ab hiere error uebernehmen } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { $errormessage = $Lang::tr{'connection type is invalid'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) { $errormessage = $Lang::tr{'name must only contain characters'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) { $errormessage = $Lang::tr{'name is invalid'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } if (length($cgiparams{'NAME'}) >60) { $errormessage = $Lang::tr{'name too long'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } ### # m.a.d net2net ### if ($cgiparams{'TYPE'} eq 'net') { if ($cgiparams{'DEST_PORT'} eq $vpnsettings{'DDEST_PORT'}) { $errormessage = $Lang::tr{'openvpn destination port used'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ($cgiparams{'DEST_PORT'} eq '') { $errormessage = $Lang::tr{'openvpn destination port used'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ($cgiparams{'OVPN_SUBNET'} eq $vpnsettings{'DOVPN_SUBNET'}) { $errormessage = $Lang::tr{'openvpn subnet is used'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if (($cgiparams{'PROTOCOL'} eq 'tcp') && ($cgiparams{'MSSFIX'} eq 'on')) { $errormessage = $Lang::tr{'openvpn mssfix allowed with udp'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if (($cgiparams{'PROTOCOL'} eq 'tcp') && ($cgiparams{'FRAGMENT'} ne '')) { $errormessage = $Lang::tr{'openvpn fragment allowed with udp'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if (($cgiparams{'PMTU_DISCOVERY'} ne 'off') && ($cgiparams{'MTU'} ne '1500')) { $errormessage = $Lang::tr{'ovpn mtu-disc and mtu not 1500'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ($cgiparams{'PMTU_DISCOVERY'} ne 'off') { if (($cgiparams{'FRAGMENT'} ne '') || ($cgiparams{'MSSFIX'} eq 'on')) { $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } } if ( &validdotmask ($cgiparams{'LOCAL_SUBNET'})) { $errormessage = $Lang::tr{'openvpn prefix local subnet'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ( &validdotmask ($cgiparams{'OVPN_SUBNET'})) { $errormessage = $Lang::tr{'openvpn prefix openvpn subnet'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ( &validdotmask ($cgiparams{'REMOTE_SUBNET'})) { $errormessage = $Lang::tr{'openvpn prefix remote subnet'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ($cgiparams{'OVPN_MGMT'} eq '') { $cgiparams{'OVPN_MGMT'} = $cgiparams{'DEST_PORT'}; } } # if (($cgiparams{'TYPE'} eq 'net') && ($cgiparams{'SIDE'} !~ /^(left|right)$/)) { # $errormessage = $Lang::tr{'ipfire side is invalid'}; # goto VPNCONF_ERROR; # } # Check if there is no other entry with this name if (! $cgiparams{'KEY'}) { foreach my $key (keys %confighash) { if ($confighash{$key}[1] eq $cgiparams{'NAME'}) { $errormessage = $Lang::tr{'a connection with this name already exists'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } } } if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) { $errormessage = $Lang::tr{'invalid input for remote host/ip'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } if ($cgiparams{'REMOTE'}) { if (! &General::validip($cgiparams{'REMOTE'})) { if (! &General::validfqdn ($cgiparams{'REMOTE'})) { $errormessage = $Lang::tr{'invalid input for remote host/ip'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR; } else { if (&valid_dns_host($cgiparams{'REMOTE'})) { $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}"; if ($cgiparams{'TYPE'} eq 'net') { } } } } } if ($cgiparams{'TYPE'} ne 'host') { unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) { $errormessage = $Lang::tr{'local subnet is invalid'}; if ($cgiparams{'TYPE'} eq 'net') { unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; } goto VPNCONF_ERROR;} } # Check if there is no other entry without IP-address and PSK if ($cgiparams{'REMOTE'} eq '') { 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'}; unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; goto VPNCONF_ERROR; } if ($cgiparams{'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; } #fixplausi if ($cgiparams{'AUTH'} eq 'psk') { # if (! length($cgiparams{'PSK'}) ) { # $errormessage = $Lang::tr{'pre-shared key is too short'}; # goto VPNCONF_ERROR; # } # if ($cgiparams{'PSK'} =~ /['",&]/) { # $errormessage = $Lang::tr{'invalid characters found in pre-shared key'}; # goto VPNCONF_ERROR; # } } 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; } # Move uploaded certificate request to a temporary file (my $fh, my $filename) = tempfile( ); 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', "$cgiparams{'DAYS_VALID'}", '-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"); &newcleanssldatabase(); goto VPNCONF_ERROR; } else { unlink ($filename); &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; } # Move uploaded certificate to a temporary file (my $fh, my $filename) = tempfile( ); if (copy ($cgiparams{'FH'}, $fh) != 1) { $errormessage = $!; goto VPNCONF_ERROR; } # Verify the certificate has a valid CA and move it my $validca = 0; 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; } # Validate input since the form was submitted if (length($cgiparams{'CERT_NAME'}) >60) { $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; } # Replace empty strings with a . (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./; (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./; (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./; # Create the Host certificate request client my $pid = open(OPENSSL, "|-"); $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', "$cgiparams{'DAYS_VALID'}", '-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"); &newcleanssldatabase(); goto VPNCONF_ERROR; } else { unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem"); &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; } # Check if there is no other entry with this common name if ((! $cgiparams{'KEY'}) && ($cgiparams{'AUTH'} ne 'psk')) { 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; } } } # Save the config my $key = $cgiparams{'KEY'}; if (! $key) { $key = &General::findhasharraykey (\%confighash); foreach my $i (0 .. 31) { $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'}; } $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'}; $confighash{$key}[10] = $cgiparams{'REMOTE'}; if ($cgiparams{'OVPN_MGMT'} eq '') { $confighash{$key}[22] = $confighash{$key}[29]; } else { $confighash{$key}[22] = $cgiparams{'OVPN_MGMT'}; } $confighash{$key}[23] = $cgiparams{'MSSFIX'}; $confighash{$key}[24] = $cgiparams{'FRAGMENT'}; $confighash{$key}[25] = $cgiparams{'REMARK'}; $confighash{$key}[26] = $cgiparams{'INTERFACE'}; # new fields $confighash{$key}[27] = $cgiparams{'OVPN_SUBNET'}; $confighash{$key}[28] = $cgiparams{'PROTOCOL'}; $confighash{$key}[29] = $cgiparams{'DEST_PORT'}; $confighash{$key}[30] = $cgiparams{'COMPLZO'}; $confighash{$key}[31] = $cgiparams{'MTU'}; $confighash{$key}[32] = $cgiparams{'PMTU_DISCOVERY'}; # new fileds &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); ### # m.a.d n2n begin ### if ($cgiparams{'TYPE'} eq 'net') { if (-e "/var/run/$confighash{$key}[1]n2n.pid") { system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]); &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); my $key = $cgiparams{'KEY'}; if (! $key) { $key = &General::findhasharraykey (\%confighash); foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";} } $confighash{$key}[0] = 'on'; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); } } ### # m.a.d n2n end ### if ($cgiparams{'EDIT_ADVANCED'} eq 'on') { $cgiparams{'KEY'} = $key; $cgiparams{'ACTION'} = $Lang::tr{'advanced'}; } goto VPNCONF_END; } else { $cgiparams{'ENABLED'} = 'on'; ### # m.a.d n2n begin ### $cgiparams{'MSSFIX'} = 'on'; $cgiparams{'FRAGMENT'} = '1300'; ### # m.a.d n2n end ### $cgiparams{'SIDE'} = 'left'; 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: $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{'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'; $checked{'MSSFIX'}{'off'} = ''; $checked{'MSSFIX'}{'on'} = ''; $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED'; $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\''; 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 ""; if ($cgiparams{'KEY'}) { print ""; print ""; } &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:"); print "\n"; print ""; if ($cgiparams{'TYPE'} eq 'host') { if ($cgiparams{'KEY'}) { print "\n"; } else { print ""; } # print ""; # print ""; # print <"; if ($cgiparams{'KEY'}) { print ""; } else { print ""; } print <  END ; } #jumper print ""; print ""; if ($cgiparams{'TYPE'} eq 'host') { print "\n"; } # if ($cgiparams{'KEY'}) { # print "
$Lang::tr{'name'}:$cgiparams{'NAME'}
$Lang::tr{'interface'}
$cgiparams{'NAME'} 
$Lang::tr{'Act as'} $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'}  
mssfix   $Lang::tr{'openvpn default'}: on
fragment   $Lang::tr{'openvpn default'}: 1300
$Lang::tr{'MTU'}  $Lang::tr{'openvpn default'}: udp/tcp 1500/1400
Management Port  $Lang::tr{'openvpn default'}: $Lang::tr{'destination port'}
$Lang::tr{'ovpn mtu-disc'} $Lang::tr{'ovpn mtu-disc yes'} $Lang::tr{'ovpn mtu-disc maybe'} $Lang::tr{'ovpn mtu-disc no'} $Lang::tr{'ovpn mtu-disc off'}
$Lang::tr{'remark title'} 
$Lang::tr{'enabled'}  
"; # } else { # print " $Lang::tr{'edit advanced settings when done'}"; # } # }else{ print " "; # } &Header::closebox(); if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') { # &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'}); # print < # $Lang::tr{'use a pre-shared key'} # # END # ; # &Header::closebox(); } 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'}); if ($cgiparams{'TYPE'} eq 'host') { 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{'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{'pkcs12 file password'}:
($Lang::tr{'confirmation'})  
* $Lang::tr{'this field may be blank'} END }else{ print <        
* $Lang::tr{'this field may be blank'} END } ### # m.a.d net2net ### ; &Header::closebox(); } print "
"; if ($cgiparams{'KEY'}) { # print ""; } print "
"; &Header::closebigbox(); &Header::closepage(); exit (0); } VPNCONF_END: } # SETTINGS_ERROR: ### ### 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'; $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'; # m.a.d $checked{'MSSFIX'}{'off'} = ''; $checked{'MSSFIX'}{'on'} = ''; $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = '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 <
      $Lang::tr{'ovpn server status'} $sactive $Lang::tr{'ovpn on red'} END ; if (&haveBlueNet()) { print "$Lang::tr{'ovpn on blue'}"; print ""; } if (&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{'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 the file contains entries, print Key to action icons if ( -f "${General::swroot}/ovpn/ca/cacert.pem") { 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" ) { ### # m.a.d net2net #$Lang::tr{'remark'}
L2089 ### &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'} $Lang::tr{'status'} $Lang::tr{'action'} END ; my $id = 0; my $gif; foreach my $key (sort { uc($confighash{$a}[1]) cmp uc($confighash{$b}[1]) } keys %confighash) { if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; } if ($id % 2) { print "\n"; } else { print "\n"; } print "$confighash{$key}[1]"; print "" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")"; if ($confighash{$key}[4] eq 'cert') { print "$confighash{$key}[2]"; } else { print " "; } 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"; print "$confighash{$key}[25]"; my $active = "
$Lang::tr{'capsclosed'}
"; if ($confighash{$key}[0] eq 'off') { $active = "
$Lang::tr{'capsclosed'}
"; } else { ### # m.a.d net2net ### if ($confighash{$key}[3] eq 'net') { if (-e "/var/run/$confighash{$key}[1]n2n.pid") { my @output = ""; my @tustate = ""; my $tport = $confighash{$key}[22]; my $tnet = new Net::Telnet ( Timeout=>5, Errmode=>'return', Port=>$tport); if ($tport ne '') { $tnet->open('127.0.0.1'); @output = $tnet->cmd(String => 'state', Prompt => '/(END.*\n|ERROR:.*\n)/'); @tustate = split(/\,/, $output[1]); ### #CONNECTING -- OpenVPN's initial state. #WAIT -- (Client only) Waiting for initial response from server. #AUTH -- (Client only) Authenticating with server. #GET_CONFIG -- (Client only) Downloading configuration options from server. #ASSIGN_IP -- Assigning IP address to virtual network interface. #ADD_ROUTES -- Adding routes to system. #CONNECTED -- Initialization Sequence Completed. #RECONNECTING -- A restart has occurred. #EXITING -- A graceful exit is in progress. #### if ( $tustate[1] eq 'CONNECTED') { $active = "
$Lang::tr{'capsopen'}
"; } else { $active = "
$tustate[1]
"; } } } } else { 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'}
"; } } } } } my $disable_clientdl = "disabled='disabled'"; if (( $cgiparams{'ENABLED'} eq 'on') || ( $cgiparams{'ENABLED_BLUE'} eq 'on') || ( $cgiparams{'ENABLED_ORANGE'} eq 'on')){ $disable_clientdl = ""; } print <$active
END ; if ($confighash{$key}[4] eq 'cert') { 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') { 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();