]>
Commit | Line | Data |
---|---|---|
6e13d0a5 MT |
1 | #!/usr/bin/perl -w |
2 | package Ovpnfunc; | |
3 | use Archive::Zip qw(:ERROR_CODES :CONSTANTS); | |
4 | use Net::DNS; | |
5 | use File::Copy; | |
6 | use File::Temp qw/ tempfile tempdir /; | |
7 | use strict; | |
8 | require '/var/ipfire/general-functions.pl'; | |
9 | my %netsettings=(); | |
10 | my $errormessage = ''; | |
11 | my $errormessage2 = ''; | |
12 | my @subnets; # array of anonymous hashes {cn, from, to} | |
13 | my @subnets2; # array of anonymous hashes {cn, from, to} | |
14 | my %overlaps; # hash {cn} of anonymous arrays of subnets | |
15 | my ($subnet, $from, $to, $i, $j); | |
16 | &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); | |
17 | sub haveOrangeNet | |
18 | { | |
19 | if ($netsettings{'CONFIG_TYPE'} == 1) {return 1;} | |
20 | if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;} | |
21 | if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;} | |
22 | if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;} | |
23 | return 0; | |
24 | } | |
25 | ||
26 | sub haveBlueNet | |
27 | { | |
28 | if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;} | |
29 | if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;} | |
30 | if ($netsettings{'CONFIG_TYPE'} == 6) {return 1;} | |
31 | if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;} | |
32 | return 0; | |
33 | } | |
34 | ||
35 | sub sizeformat{ | |
36 | my $bytesize = $_[0]; | |
37 | my $i = 0; | |
38 | ||
39 | while(abs($bytesize) >= 1024){ | |
40 | $bytesize=$bytesize/1024; | |
41 | $i++; | |
42 | last if($i==6); | |
43 | } | |
44 | ||
45 | my @units = ("Bytes","KB","MB","GB","TB","PB","EB"); | |
46 | my $newsize=(int($bytesize*100 +0.5))/100; | |
47 | return("$newsize $units[$i]"); | |
48 | } | |
49 | ||
50 | sub valid_dns_host { | |
51 | my $hostname = $_[0]; | |
52 | unless ($hostname) { return "No hostname"}; | |
53 | my $res = new Net::DNS::Resolver; | |
54 | my $query = $res->search("$hostname"); | |
55 | if ($query) { | |
56 | foreach my $rr ($query->answer) { | |
57 | ## Potential bug - we are only looking at A records: | |
58 | return 0 if $rr->type eq "A"; | |
59 | } | |
60 | } else { | |
61 | return $res->errorstring; | |
62 | } | |
63 | } | |
64 | ||
65 | sub cleanssldatabase | |
66 | { | |
67 | if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) { | |
68 | print FILE "01"; | |
69 | close FILE; | |
70 | } | |
71 | if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) { | |
72 | print FILE ""; | |
73 | close FILE; | |
74 | } | |
75 | unlink ("${General::swroot}/ovpn/certs/index.txt.old"); | |
76 | unlink ("${General::swroot}/ovpn/certs/serial.old"); | |
77 | unlink ("${General::swroot}/ovpn/certs/01.pem"); | |
78 | } | |
79 | ||
80 | sub newcleanssldatabase | |
81 | { | |
82 | if (! -s "${General::swroot}/ovpn/certs/serial" ) { | |
83 | open(FILE, ">${General::swroot}(ovpn/certs/serial"); | |
84 | print FILE "01"; | |
85 | close FILE; | |
86 | } | |
87 | if (! -s ">${General::swroot}/ovpn/certs/index.txt") { | |
88 | system ("touch ${General::swroot}/ovpn/certs/index.txt"); | |
89 | } | |
90 | unlink ("${General::swroot}/ovpn/certs/index.txt.old"); | |
91 | unlink ("${General::swroot}/ovpn/certs/serial.old"); | |
92 | } | |
93 | ||
94 | sub deletebackupcert | |
95 | { | |
96 | if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) { | |
97 | my $hexvalue = <FILE>; | |
98 | chomp $hexvalue; | |
99 | close FILE; | |
100 | unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem"); | |
101 | } | |
102 | } | |
103 | ||
104 | sub checkportfw { | |
105 | my $KEY2 = $_[0]; # key2 | |
106 | my $SRC_PORT = $_[1]; # src_port | |
107 | my $PROTOCOL = $_[2]; # protocol | |
108 | my $SRC_IP = $_[3]; # sourceip | |
109 | my $pfwfilename = "${General::swroot}/portfw/config"; | |
110 | open(FILE, $pfwfilename) or die 'Unable to open config file.'; | |
111 | my @pfwcurrent = <FILE>; | |
112 | close(FILE); | |
113 | my $pfwkey1 = 0; # used for finding last sequence number used | |
114 | foreach my $pfwline (@pfwcurrent) | |
115 | { | |
116 | my @pfwtemp = split(/\,/,$pfwline); | |
117 | ||
118 | chomp ($pfwtemp[8]); | |
119 | if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition | |
120 | if ( $SRC_PORT eq $pfwtemp[3] && | |
121 | $PROTOCOL eq $pfwtemp[2] && | |
122 | $SRC_IP eq $pfwtemp[7]) | |
123 | { | |
124 | $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT"; | |
125 | } | |
126 | # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number | |
127 | if ( $pfwtemp[1] eq "0") { | |
128 | $pfwkey1=$pfwtemp[0]; | |
129 | } | |
130 | # Darren Critchley - Duplicate or overlapping Port range check | |
131 | if ($pfwtemp[1] eq "0" && | |
132 | $PROTOCOL eq $pfwtemp[2] && | |
133 | $SRC_IP eq $pfwtemp[7] && | |
134 | $errormessage eq '') | |
135 | { | |
136 | &portchecks($SRC_PORT, $pfwtemp[5]); | |
137 | # &portchecks($pfwtemp[3], $pfwtemp[5]); | |
138 | # &portchecks($pfwtemp[3], $SRC_IP); | |
139 | } | |
140 | } | |
141 | } | |
142 | # $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP"; | |
143 | ||
144 | return $errormessage; | |
145 | } | |
146 | ||
147 | sub checkportoverlap | |
148 | { | |
149 | my $portrange1 = $_[0]; # New port range | |
150 | my $portrange2 = $_[1]; # existing port range | |
151 | my @tempr1 = split(/\:/,$portrange1); | |
152 | my @tempr2 = split(/\:/,$portrange2); | |
153 | ||
154 | unless (&checkportinc($tempr1[0], $portrange2)){ return 0;} | |
155 | unless (&checkportinc($tempr1[1], $portrange2)){ return 0;} | |
156 | ||
157 | unless (&checkportinc($tempr2[0], $portrange1)){ return 0;} | |
158 | unless (&checkportinc($tempr2[1], $portrange1)){ return 0;} | |
159 | ||
160 | return 1; # Everything checks out! | |
161 | } | |
162 | ||
163 | # Darren Critchley - we want to make sure that a port entry is not within an already existing range | |
164 | sub checkportinc | |
165 | { | |
166 | my $port1 = $_[0]; # Port | |
167 | my $portrange2 = $_[1]; # Port range | |
168 | my @tempr1 = split(/\:/,$portrange2); | |
169 | ||
170 | if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) { | |
171 | return 1; | |
172 | } else { | |
173 | return 0; | |
174 | } | |
175 | } | |
176 | # Darren Critchley - Duplicate or overlapping Port range check | |
177 | sub portchecks | |
178 | { | |
179 | my $p1 = $_[0]; # New port range | |
180 | my $p2 = $_[1]; # existing port range | |
181 | # $_ = $_[0]; | |
182 | our ($prtrange1, $prtrange2); | |
183 | $prtrange1 = 0; | |
184 | # if (m/:/ && $prtrange1 == 1) { # comparing two port ranges | |
185 | # unless (&checkportoverlap($p1,$p2)) { | |
186 | # $errormessage = "$Lang::tr{'source port overlaps'} $p1"; | |
187 | # } | |
188 | # } | |
189 | if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range | |
190 | unless (&checkportinc($p2,$p1)) { | |
191 | $errormessage = "$Lang::tr{'srcprt within existing'} $p1"; | |
192 | } | |
193 | } | |
194 | $prtrange1 = 1; | |
195 | if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range | |
196 | unless (&checkportinc($p1,$p2)) { | |
197 | $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2"; | |
198 | } | |
199 | } | |
200 | return; | |
201 | } | |
202 | ||
bb89e92a MT |
203 | # Darren Critchley - certain ports are reserved for IPFire |
204 | # TCP 67,68,81,222,444 | |
6e13d0a5 MT |
205 | # UDP 67,68 |
206 | # Params passed in -> port, rangeyn, protocol | |
207 | sub disallowreserved | |
208 | { | |
209 | # port 67 and 68 same for tcp and udp, don't bother putting in an array | |
210 | my $msg = ""; | |
bb89e92a | 211 | my @tcp_reserved = (81,222,444); |
6e13d0a5 MT |
212 | my $prt = $_[0]; # the port or range |
213 | my $ryn = $_[1]; # tells us whether or not it is a port range | |
214 | my $prot = $_[2]; # protocol | |
215 | my $srcdst = $_[3]; # source or destination | |
216 | if ($ryn) { # disect port range | |
217 | if ($srcdst eq "src") { | |
218 | $msg = "$Lang::tr{'rsvd src port overlap'}"; | |
219 | } else { | |
220 | $msg = "$Lang::tr{'rsvd dst port overlap'}"; | |
221 | } | |
222 | my @tmprng = split(/\:/,$prt); | |
223 | unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; } | |
224 | unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; } | |
225 | if ($prot eq "tcp") { | |
226 | foreach my $prange (@tcp_reserved) { | |
227 | unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; } | |
228 | } | |
229 | } | |
230 | } else { | |
231 | if ($srcdst eq "src") { | |
232 | $msg = "$Lang::tr{'reserved src port'}"; | |
233 | } else { | |
234 | $msg = "$Lang::tr{'reserved dst port'}"; | |
235 | } | |
236 | if ($prt == 67) { $errormessage="$msg 67"; return; } | |
237 | if ($prt == 68) { $errormessage="$msg 68"; return; } | |
238 | if ($prot eq "tcp") { | |
239 | foreach my $prange (@tcp_reserved) { | |
240 | if ($prange == $prt) { | |
241 | $errormessage = "$msg $prange"; | |
242 | return $errormessage; } | |
243 | } | |
244 | } | |
245 | } | |
246 | return $errormessage; | |
247 | } | |
248 | ||
249 | sub writeserverconf { | |
250 | my %sovpnsettings = (); | |
251 | &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings); | |
252 | ||
253 | open(CONF, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!"; | |
254 | flock CONF, 2; | |
255 | print CONF "#OpenVPN Server conf\n"; | |
256 | print CONF "\n"; | |
257 | print CONF "daemon openvpnserver\n"; | |
258 | print CONF "writepid /var/run/openvpn.pid\n"; | |
259 | print CONF "#DAN prepare ZERINA for listening on blue and orange\n"; | |
260 | print CONF ";local $sovpnsettings{'VPN_IP'}\n"; | |
261 | print CONF "dev $sovpnsettings{'DDEVICE'}\n"; | |
262 | print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; | |
bb89e92a MT |
263 | if ($sovpnsettings{'DPROTOCOL'} eq 'tcp') { |
264 | print CONF "proto $sovpnsettings{'DPROTOCOL'}-server\n"; | |
265 | } else { | |
266 | print CONF "proto $sovpnsettings{'DPROTOCOL'}\n"; | |
267 | } | |
6e13d0a5 MT |
268 | print CONF "port $sovpnsettings{'DDEST_PORT'}\n"; |
269 | print CONF "tls-server\n"; | |
270 | print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n"; | |
271 | print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n"; | |
272 | print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n"; | |
273 | print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n"; | |
274 | my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'}); | |
275 | print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n"; | |
276 | print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n"; | |
277 | if ($sovpnsettings{AD_ROUTE1} ne '') { | |
278 | my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE1'}); | |
279 | print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; | |
280 | } | |
281 | if ($sovpnsettings{AD_ROUTE2} ne '') { | |
282 | my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE2'}); | |
283 | print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; | |
284 | } | |
285 | if ($sovpnsettings{AD_ROUTE3} ne '') { | |
286 | my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE3'}); | |
287 | print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n"; | |
288 | } | |
289 | if ($sovpnsettings{CLIENT2CLIENT} eq 'on') { | |
290 | print CONF "client-to-client\n"; | |
291 | } | |
292 | if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) { | |
293 | print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n"; | |
294 | } | |
295 | print CONF "status-version 1\n"; | |
296 | print CONF "status /var/log/ovpnserver.log 30\n"; | |
297 | print CONF "cipher $sovpnsettings{DCIPHER}\n"; | |
298 | if ($sovpnsettings{DCOMPLZO} eq 'on') { | |
299 | print CONF "comp-lzo\n"; | |
300 | } | |
301 | if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') { | |
302 | print CONF "push \"redirect-gateway def1\"\n"; | |
303 | } | |
304 | if ($sovpnsettings{DHCP_DOMAIN} ne '') { | |
305 | print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n"; | |
306 | } | |
307 | ||
308 | if ($sovpnsettings{DHCP_DNS} ne '') { | |
309 | print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n"; | |
310 | } | |
311 | ||
312 | if ($sovpnsettings{DHCP_WINS} ne '') { | |
313 | print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n"; | |
314 | } | |
315 | ||
316 | if ($sovpnsettings{DHCP_WINS} eq '') { | |
317 | print CONF "max-clients 100\n"; | |
318 | } | |
319 | ||
320 | if ($sovpnsettings{DHCP_WINS} ne '') { | |
321 | print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n"; | |
322 | } | |
323 | ||
324 | ################################################################################# | |
325 | # Added by Philipp Jenni # | |
326 | # # | |
327 | # Contact: philipp.jenni-at-gmx.ch # | |
328 | # Date: 2006-04-22 # | |
329 | # Description: Add the FAST-IO Parameter from OpenVPN to der Server.Config. # | |
330 | # Add the NICE Parameter from OpenVPN to der Server.Config. # | |
331 | # Add the MTU-DISC Parameter from OpenVPN to der Server.Config. # | |
332 | # Add the MSSFIX Parameter from OpenVPN to der Server.Config. # | |
333 | # Add the FRAMGMENT Parameter from OpenVPN to der Server.Config. # | |
334 | ################################################################################# | |
335 | if ($sovpnsettings{EXTENDED_FASTIO} eq 'on') { | |
336 | print CONF "fast-io\n"; | |
337 | } | |
338 | if ($sovpnsettings{EXTENDED_NICE} != 0) { | |
339 | print CONF "nice $sovpnsettings{EXTENDED_NICE}\n"; | |
340 | } | |
341 | if ($sovpnsettings{EXTENDED_MTUDISC} eq 'on') { | |
342 | print CONF "mtu-disc yes\n"; | |
343 | } | |
344 | if ($sovpnsettings{EXTENDED_MSSFIX} ne '') { | |
345 | print CONF "mssfix $sovpnsettings{EXTENDED_MSSFIX}\n"; | |
346 | } | |
347 | if ($sovpnsettings{EXTENDED_FRAGMENT} ne '') { | |
348 | print CONF "fragment $sovpnsettings{EXTENDED_FRAGMENT}\n"; | |
349 | } | |
350 | ################################################################################# | |
351 | # End of Inserted Data # | |
352 | ################################################################################# | |
353 | ||
354 | print CONF "tls-verify /var/ipfire/ovpn/verify\n"; | |
355 | print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n"; | |
356 | print CONF "user nobody\n"; | |
357 | print CONF "group nobody\n"; | |
358 | print CONF "persist-key\n"; | |
359 | print CONF "persist-tun\n"; | |
360 | if ($sovpnsettings{LOG_VERB} ne '') { | |
361 | print CONF "verb $sovpnsettings{LOG_VERB}\n"; | |
362 | } else { | |
363 | print CONF "verb 3\n"; | |
364 | } | |
365 | print CONF "\n"; | |
366 | ||
367 | close(CONF); | |
368 | } | |
369 | ||
370 | sub writenet2netconf { | |
371 | my $n2nkey = $_[0]; | |
372 | my $zerinaclient = $_[1]; | |
373 | my %n2nconfighash = (); | |
374 | my $file = ''; | |
375 | # my $file = ''; | |
376 | my $clientovpn = ''; | |
377 | my @fileholder; | |
378 | my $tempdir = tempdir( CLEANUP => 1 ); | |
379 | my $zippath = "$tempdir/"; | |
380 | &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); | |
381 | if (! $n2nkey) { | |
382 | $n2nkey = &General::findhasharraykey (\%n2nconfighash); | |
383 | foreach my $i (0 .. 25) { $n2nconfighash{$n2nkey}[$i] = "";} | |
384 | } | |
385 | my $zipname = "$n2nconfighash{$n2nkey}[1].zip"; | |
386 | my $zippathname = "$zippath$zipname"; | |
387 | if ($n2nconfighash{$n2nkey}[3] eq 'net') { | |
388 | if ($zerinaclient eq '') { | |
389 | if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]"){ | |
390 | while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/*.conf")) { | |
391 | unlink $file | |
392 | } | |
393 | } else { | |
394 | mkdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]", 0770); | |
395 | } | |
396 | open(CONF, ">${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf: $!"; | |
397 | } else { | |
398 | $clientovpn = "$n2nconfighash{$n2nkey}[1].conf"; | |
399 | open(CONF, ">$tempdir/$clientovpn") or die "Unable to open $tempdir/$clientovpn: $!"; | |
400 | } | |
401 | flock CONF, 2; | |
bb89e92a | 402 | print CONF "dev tun\n"; |
6e13d0a5 | 403 | print CONF "tun-mtu $n2nconfighash{$n2nkey}[17]\n"; |
bb89e92a MT |
404 | if ($n2nconfighash{$n2nkey}[14] eq 'udp') { |
405 | print CONF "proto $n2nconfighash{$n2nkey}[14]\n"; | |
406 | } elsif ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) { | |
407 | print CONF "proto $n2nconfighash{$n2nkey}[14]-server\n"; | |
408 | } else { | |
409 | print CONF "proto $n2nconfighash{$n2nkey}[14]-client\n"; | |
410 | } | |
6e13d0a5 MT |
411 | print CONF "port $n2nconfighash{$n2nkey}[15]\n"; |
412 | my @tempovpnsubnet = split("\/",$n2nconfighash{$n2nkey}[13]); | |
413 | my @ovpnip = split /\./,$tempovpnsubnet[0]; | |
414 | # if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[19] eq 'no'))) { | |
415 | if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) { | |
416 | print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].1 $ovpnip[0].$ovpnip[1].$ovpnip[2].2\n"; | |
417 | print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; | |
418 | print CONF "tls-server\n"; | |
419 | print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n"; | |
420 | print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n"; | |
421 | print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n"; | |
422 | print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n"; | |
423 | my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]); | |
424 | print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; | |
425 | } else { | |
426 | print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].2 $ovpnip[0].$ovpnip[1].$ovpnip[2].1\n"; | |
427 | #print CONF "$zerinaclient ufuk 10=$n2nconfighash{$n2nkey}[10] 18=$n2nconfighash{$n2nkey}[18] 19=$n2nconfighash{$n2nkey}[19] \n"; | |
428 | if ($zerinaclient ne 'true'){ | |
429 | if ($n2nconfighash{$n2nkey}[19] eq 'no'){ | |
430 | print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; | |
431 | } else { | |
432 | print CONF "remote $n2nconfighash{$n2nkey}[10]\n"; | |
433 | } | |
434 | } else { | |
435 | print CONF "remote $n2nconfighash{$n2nkey}[18]\n"; | |
436 | } | |
437 | print CONF "tls-client\n"; | |
438 | if ($zerinaclient ne 'true'){ | |
439 | print CONF "pkcs12 ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].p12\n"; | |
440 | } else { | |
441 | print CONF "pkcs12 $n2nconfighash{$n2nkey}[1].p12\n"; | |
442 | } | |
443 | if ($n2nconfighash{$n2nkey}[19] eq 'no'){ | |
444 | my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[8]); | |
445 | print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; | |
446 | } else { | |
447 | my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]); | |
448 | print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n"; | |
449 | } | |
450 | } | |
451 | if ($n2nconfighash{$n2nkey}[26] > 0 && $n2nconfighash{$n2nkey}[27] > 0) { | |
452 | print CONF "keepalive $n2nconfighash{$n2nkey}[26] $n2nconfighash{$n2nkey}[27]\n"; | |
453 | } else { | |
454 | print CONF "keepalive 10 60\n"; | |
455 | } | |
456 | print CONF "cipher $n2nconfighash{$n2nkey}[20]\n"; | |
457 | if ($n2nconfighash{$n2nkey}[16] eq 'on') { | |
458 | print CONF "comp-lzo\n"; | |
459 | } | |
460 | if ($n2nconfighash{$n2nkey}[42] ne '') { | |
461 | print CONF "verb $n2nconfighash{$n2nkey}[42]\n"; | |
462 | } else { | |
463 | print CONF "verb 3\n"; | |
464 | } | |
465 | if ($n2nconfighash{$n2nkey}[19] eq 'no'){ | |
466 | print CONF "#$n2nconfighash{$n2nkey}[11]\n"; | |
467 | } else { | |
468 | print CONF "#$n2nconfighash{$n2nkey}[8]\n"; | |
469 | } | |
470 | if ($zerinaclient ne 'true') { | |
471 | print CONF "daemon OVPN_$n2nconfighash{$n2nkey}[1]\n"; | |
472 | print CONF "#status ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].log 2\n"; | |
473 | } | |
474 | close(CONF); | |
475 | if ($zerinaclient eq 'true') { | |
476 | my $zip = Archive::Zip->new(); | |
477 | $zip->addFile( "${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12", "$n2nconfighash{$n2nkey}[1].p12") or die "Can't add file ${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12\n"; | |
478 | $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n"; | |
479 | my $status = $zip->writeToFileNamed($zippathname); | |
480 | open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!"; | |
481 | @fileholder = <DLFILE>; | |
482 | print "Content-Type:application/x-download\n"; | |
483 | print "Content-Disposition:attachment;filename=$zipname\n\n"; | |
484 | print @fileholder; | |
485 | exit (0); | |
486 | } | |
487 | } | |
488 | } | |
489 | ||
490 | sub removenet2netconf { | |
491 | my %n2nconfighash = (); | |
492 | my $key = $_[0]; | |
493 | my $file = ''; | |
494 | &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); | |
495 | if ($n2nconfighash{$key}[3] eq 'net') { | |
496 | if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"){ | |
497 | while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]/*")) { | |
498 | unlink $file | |
499 | } | |
500 | rmdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"); | |
501 | } | |
502 | } | |
503 | } | |
504 | ||
505 | sub emptyserverlog{ | |
506 | if (open(FILE, ">/var/log/ovpnserver.log")) { | |
507 | flock FILE, 2; | |
508 | print FILE ""; | |
509 | close FILE; | |
510 | } | |
511 | } | |
512 | ||
513 | sub displayca { | |
514 | my $key = $_[0]; | |
515 | my %cahash = (); | |
516 | &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); | |
517 | if ( -f "${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem") { | |
518 | &Header::showhttpheaders(); | |
519 | &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); | |
520 | &Header::openbigbox('100%', 'LEFT', '', $errormessage); | |
521 | &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:"); | |
522 | my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem`; | |
523 | $output = &Header::cleanhtml($output,"y"); | |
524 | print "<pre>$output</pre>\n"; | |
525 | &Header::closebox(); | |
526 | print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>"; | |
527 | &Header::closebigbox(); | |
528 | &Header::closepage(); | |
529 | exit(0); | |
530 | } else { | |
531 | $errormessage = $Lang::tr{'invalid key'}; | |
532 | } | |
533 | } | |
534 | sub displayroothost { | |
535 | my $roothost = $_[0]; | |
536 | my $output; | |
537 | &Header::showhttpheaders(); | |
538 | &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); | |
539 | &Header::openbigbox('100%', 'LEFT', '', ''); | |
540 | if ($roothost eq $Lang::tr{'show root certificate'}) { | |
541 | &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:"); | |
542 | $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`; | |
543 | } else { | |
544 | &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:"); | |
545 | $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; | |
546 | } | |
547 | $output = &Header::cleanhtml($output,"y"); | |
548 | print "<pre>$output</pre>\n"; | |
549 | &Header::closebox(); | |
550 | print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>"; | |
551 | &Header::closebigbox(); | |
552 | &Header::closepage(); | |
553 | exit(0); | |
554 | } | |
555 | ||
556 | sub killconnection { | |
557 | my $key = $_[0]; | |
558 | my %n2nconfighash = (); | |
559 | &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash); | |
560 | my $n2nactive = `/bin/ps ax|grep $n2nconfighash{$key}[1].conf|grep -v grep|awk \'{print \$1}\'`; | |
561 | if ($n2nactive ne ''){ | |
562 | system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive); | |
563 | } | |
564 | } | |
565 | ||
566 | sub cidrormask { | |
567 | my $cidrmask = $_[0]; | |
568 | my $cidrmask2 = $cidrmask; | |
569 | if ("/$cidrmask" =~ /^\/(\d+)/){#cidr | |
570 | if ($cidrmask2 = &cidr2mask("/$cidrmask")) { | |
571 | return $cidrmask2; | |
572 | } else { | |
573 | if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask | |
574 | return $cidrmask; | |
575 | } | |
576 | } | |
577 | } else { | |
578 | if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask | |
579 | return $cidrmask; | |
580 | } | |
581 | } | |
582 | } | |
583 | sub cidr2mask { | |
584 | my( $cidr ) = @_; | |
585 | my( $one32 ) = 0xffffffff; | |
586 | my( @d, $n, $bits ); | |
587 | ||
588 | if ( $cidr eq "/0" ) { | |
589 | return "0.0.0.0"; | |
590 | } | |
591 | ||
592 | if ( $cidr !~ /\/(\d+)/ ) { | |
593 | return undef; | |
594 | } | |
595 | $bits = $1; | |
596 | ||
597 | if ( $bits > 32 ) { | |
598 | return undef; | |
599 | } | |
600 | ||
601 | #-- convert to subnet-style mask | |
602 | $n = $one32 << (32 - $bits); | |
603 | $d[3] = $n % 256; $n = int( $n / 256); | |
604 | $d[2] = $n % 256; $n = int( $n / 256); | |
605 | $d[1] = $n % 256; $n = int( $n / 256); | |
606 | $d[0] = $n; | |
607 | return join '.', @d; | |
608 | } | |
609 | ||
610 | ||
611 | # ---------------------------------------------------------------------------- | |
612 | # $cidr = &mask2cidr( $mask ) | |
613 | # ---------------------------------------------------------------------------- | |
614 | ||
615 | sub mask2cidr { | |
616 | my( $mask ) = @_; | |
617 | my( @d, $n, $bits ); | |
618 | ||
619 | if ( $mask eq "0.0.0.0" ) { | |
620 | return "/0"; | |
621 | } | |
622 | ||
623 | if ( ! &validMask( $mask ) ) { | |
624 | return undef; | |
625 | } | |
626 | ||
627 | @d = split /\./, $mask; | |
628 | $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3]; | |
629 | $bits = 32; | |
630 | while ( ($n % 2) == 0 ) { | |
631 | $n >>= 1; | |
632 | $bits -= 1; | |
633 | } | |
634 | return "/$bits"; | |
635 | } | |
636 | ||
637 | ||
638 | # ---------------------------------------------------------------------------- | |
639 | # $yesno = &validMask( $mask ) | |
640 | # ---------------------------------------------------------------------------- | |
641 | ||
642 | sub validMask { | |
643 | my( $mask ) = @_; | |
644 | my( @d, $n, $str ); | |
645 | ||
646 | @d = split /\./, $mask; | |
647 | $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3]; | |
648 | $str = sprintf "%b", $n; | |
649 | return ( $str =~ /^1+0*$/ ); | |
650 | } | |
651 | ||
652 | sub overlapping { | |
653 | # read all subnets from AD, convert to integer range, and sort. | |
654 | foreach $subnet (@subnets2) { | |
655 | ($from, $to) = &subnet2range ($subnet); | |
656 | push @subnets, { cn => $subnet, from => $from, to => $to }; | |
657 | } | |
658 | @subnets = sort { $a->{from} <=> $b->{from} } @subnets; | |
659 | ||
660 | # compare all possible subnets for overlap; depend on sort order. | |
661 | for ($i=0; $i<=$#subnets; $i++) { | |
662 | for ($j=$i+1; $j<=$#subnets; $j++) { | |
663 | last if $subnets[$i]->{to} < $subnets[$j]->{from}; # no possible overlap anymore; | |
664 | push @{$overlaps{$subnets[$i]->{cn}}}, $subnets[$j]->{cn} if $subnets[$i]->{to} >= $subnets[$j]->{from}; | |
665 | } | |
666 | } | |
667 | ||
668 | if (scalar (keys %overlaps)) { | |
669 | foreach $subnet (sort keys %overlaps) { | |
670 | #$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC : %s\n", $subnet, join (", ", sort @{$overlaps{$subnet}}); | |
671 | $errormessage = "$subnet : $overlaps{$subnet}[0]"; | |
672 | last; | |
673 | } | |
674 | } | |
675 | return $errormessage; | |
676 | } | |
677 | ||
678 | # &subnet2range ($subnet) | |
679 | # convert subnets to integers in order to compare them later. | |
680 | # A subnet looks like this: 10.1.2.0/24 | |
681 | # returns beginning and end of subnet as integer | |
682 | # | |
683 | sub subnet2range { | |
684 | my $subnet = shift (@_); | |
685 | my ($from, $to); | |
686 | ||
687 | $subnet =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/ || die "bad subnet $subnet\n"; | |
688 | $from = $1*2**24 + $2*2**16 + $3*2**8 + $4; | |
689 | $to = $from + 2**(32-$5) - 1; | |
690 | return ($from, $to); | |
691 | } | |
692 | ||
693 | sub ovelapplausi { | |
694 | my $tmpovpnsubnet0 = $_[0]; | |
695 | my $tmpovpnsubnet1 = $_[1]; | |
696 | my %vpnconfighash = (); | |
697 | my $tmpcidr = ''; | |
698 | my @tmpremotevpnsubnet; | |
699 | &General::readhasharray("${General::swroot}/vpn/config", \%vpnconfighash); | |
700 | ||
701 | if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'}, | |
702 | $tmpovpnsubnet0, $tmpovpnsubnet1)) { | |
703 | $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}"; | |
704 | return $errormessage; | |
705 | } | |
706 | ||
707 | if (&haveBlueNet()) { | |
708 | if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'}, | |
709 | $tmpovpnsubnet0, $tmpovpnsubnet1)) { | |
710 | $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}"; | |
711 | return $errormessage; | |
712 | } | |
713 | } | |
714 | if (&haveOrangeNet()) { | |
715 | if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'}, | |
716 | $tmpovpnsubnet0, $tmpovpnsubnet1)) { | |
717 | $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}"; | |
718 | return $errormessage; | |
719 | } | |
720 | } | |
721 | open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.'; | |
722 | while (<ALIASES>) | |
723 | { | |
724 | chomp($_); | |
725 | my @tempalias = split(/\,/,$_); | |
726 | if ($tempalias[1] eq 'on') { | |
727 | if (&General::IpInSubnet ($tempalias[0] , | |
728 | $tmpovpnsubnet0, $tmpovpnsubnet1)) { | |
729 | $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]"; | |
730 | exit $errormessage; | |
731 | } | |
732 | } | |
733 | } | |
734 | close(ALIASES); | |
735 | ||
736 | #check against ipsec connections | |
737 | foreach my $key (keys %vpnconfighash) { | |
738 | #$confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'}; | |
739 | #$confighash{$key}[3]#host or net | |
740 | #$confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'}; | |
741 | #$confighash{$key}[10] = $cgiparams{'REMOTE'}; | |
742 | &emptyarray(); | |
743 | $tmpcidr = &mask2cidr($tmpovpnsubnet1); | |
744 | push @subnets2, "$tmpovpnsubnet0$tmpcidr"; | |
745 | @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]); | |
746 | $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); | |
747 | push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; | |
748 | $errormessage2 = &overlapping(); | |
749 | if ($errormessage2 ne '') { | |
750 | $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 "; | |
751 | last; | |
752 | } | |
753 | &emptyarray(); | |
754 | if ($vpnconfighash{$key}[3] eq 'net'){ | |
755 | if (&General::IpInSubnet ($vpnconfighash{$key}[10],$tmpovpnsubnet0, $tmpovpnsubnet1)) { | |
756 | $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC Connection/IP: $vpnconfighash{$key}[1]/$vpnconfighash{$key}[10]"; | |
757 | last; | |
758 | } | |
759 | #check agains ipsec local subent | |
760 | push @subnets2, "$tmpovpnsubnet0$tmpcidr"; | |
761 | @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[11]); | |
762 | $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); | |
763 | push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; | |
764 | $errormessage2 = &overlapping(); | |
765 | if ($errormessage2 ne '') { | |
766 | $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'remote subnet'} $errormessage2 "; | |
767 | last; | |
768 | } | |
769 | &emptyarray(); | |
770 | push @subnets2, "$tmpovpnsubnet0$tmpcidr"; | |
771 | @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]); | |
772 | $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]); | |
773 | push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr"; | |
774 | $errormessage2 = &overlapping(); | |
775 | if ($errormessage2 ne '') { | |
776 | $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 "; | |
777 | last; | |
778 | } | |
779 | &emptyarray(); | |
780 | } | |
781 | } | |
782 | #check against OpenVPN Connections (aware check against itself) | |
783 | return $errormessage; | |
784 | } | |
785 | sub emptyarray { | |
786 | @subnets2 = (); | |
787 | @subnets = (); | |
bb89e92a MT |
788 | } |
789 | sub rwclientstatus { | |
790 | my $activeonrun = $_[0]; | |
791 | my @status = `/bin/cat /var/log/ovpnserver.log`; | |
792 | my %confighash = (); | |
793 | my $dis = '' | |
794 | &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); | |
795 | if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) { | |
796 | $dis = ''; | |
797 | } else { | |
798 | $dis = "disabled='disabled'"; | |
799 | } | |
800 | ||
801 | &Header::openbox('100%', 'LEFT', "Roadwarrior $Lang::tr{'Client status and controlc'}"); | |
802 | print <<END | |
803 | <table width='100%' border='0' cellspacing='1' cellpadding='0'> | |
804 | <tr> | |
805 | <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td> | |
806 | <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td> | |
807 | <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td> | |
808 | <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td> | |
809 | <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td> | |
810 | <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td> | |
811 | <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td> | |
812 | </tr> | |
813 | END | |
814 | ; | |
815 | my $id = 0; | |
816 | my $gif; | |
817 | foreach my $key (keys %confighash) { | |
818 | if ($confighash{$key}[3] eq 'host') { | |
819 | if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; } | |
820 | if ($id % 2) { | |
821 | print "<tr bgcolor='${Header::table1colour}'>\n"; | |
822 | } else { | |
823 | print "<tr bgcolor='${Header::table2colour}'>\n"; | |
824 | } | |
825 | print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>"; | |
826 | print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>"; | |
827 | if ($confighash{$key}[4] eq 'cert') { | |
828 | print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>"; | |
829 | } else { | |
830 | print "<td align='left'> </td>"; | |
831 | } | |
832 | if ($confighash{$key}[19] ne 'yes') { | |
833 | my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; | |
834 | $cavalid =~ /Not After : (.*)[\n]/; | |
835 | $cavalid = $1; | |
836 | print "<td align='center'>$cavalid</td>"; | |
837 | } else { | |
838 | print "<td> </td>"; | |
839 | } | |
840 | print "<td align='center'>$confighash{$key}[25]</td>"; | |
841 | my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>"; | |
842 | if ($confighash{$key}[0] eq 'off') { | |
843 | $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>"; | |
844 | } else { | |
845 | my $cn; | |
846 | my @match = (); | |
847 | foreach my $line (@status) { | |
848 | chomp($line); | |
849 | if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) { | |
850 | @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line); | |
851 | if ($match[1] ne "Common Name") { | |
852 | $cn = $match[1]; | |
853 | } | |
854 | $cn =~ s/[_]/ /g; | |
855 | if ($cn eq "$confighash{$key}[2]") { | |
856 | $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>"; | |
857 | } | |
858 | } | |
859 | } | |
860 | } | |
861 | print "<td align='center'>$active</td>"; | |
862 | my $disable_clientdl = ""; | |
863 | if ($confighash{$key}[6] ne 'client') { | |
864 | print <<END | |
865 | <form method='post' name='frm${key}a'><td align='center'> | |
866 | <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.gif' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' /> | |
867 | <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl /> | |
868 | <input type='hidden' name='KEY' value='$key' $disable_clientdl /> | |
869 | </td></form> | |
870 | END | |
871 | ; } else { | |
872 | print "<td> </td>"; | |
873 | } | |
874 | if ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { | |
875 | print <<END | |
876 | <form method='post' name='frm${key}b'><td align='center'> | |
877 | <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' /> | |
878 | <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' /> | |
879 | <input type='hidden' name='KEY' value='$key' /> | |
880 | </td></form> | |
881 | END | |
882 | ; } else { | |
883 | print "<td> </td>"; | |
884 | } | |
885 | if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") { | |
886 | print <<END | |
887 | <form method='post' name='frm${key}c'><td align='center'> | |
888 | <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/floppy.gif' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' /> | |
889 | <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' /> | |
890 | <input type='hidden' name='KEY' value='$key' /> | |
891 | </td></form> | |
892 | END | |
893 | ; } elsif ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { | |
894 | print <<END | |
895 | <form method='post' name='frm${key}c'><td align='center'> | |
896 | <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' /> | |
897 | <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' /> | |
898 | <input type='hidden' name='KEY' value='$key' /> | |
899 | </td></form> | |
900 | END | |
901 | ; } else { | |
902 | print "<td> </td>"; | |
903 | } | |
904 | print <<END | |
905 | <form method='post' name='frm${key}d'><td align='center'> | |
906 | <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' /> | |
907 | <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' /> | |
908 | <input type='hidden' name='KEY' value='$key' /> | |
909 | </td></form> | |
910 | <form method='post' name='frm${key}e'><td align='center'> | |
911 | <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' /> | |
912 | <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/> | |
913 | <input type='hidden' name='KEY' value='$key' /> | |
914 | </td></form> | |
915 | <form method='post' name='frm${key}f'><td align='center'> | |
916 | <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' /> | |
917 | <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' /> | |
918 | <input type='hidden' name='KEY' value='$key' /> | |
919 | </td></form> | |
920 | </tr> | |
921 | END | |
922 | ; | |
923 | $id++; | |
924 | } | |
925 | } | |
926 | ; | |
927 | # If the config file contains entries, print Key to action icons | |
928 | if ( $id ) { | |
929 | print <<END | |
930 | <table> | |
931 | <tr> | |
932 | <td class='boldbase'> <b>$Lang::tr{'legend'}:</b></td> | |
933 | <td> <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td> | |
934 | <td class='base'>$Lang::tr{'click to disable'}</td> | |
935 | <td> <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td> | |
936 | <td class='base'>$Lang::tr{'show certificate'}</td> | |
937 | <td> <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td> | |
938 | <td class='base'>$Lang::tr{'edit'}</td> | |
939 | <td> <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td> | |
940 | <td class='base'>$Lang::tr{'remove'}</td> | |
941 | </tr> | |
942 | <tr> | |
943 | <td> </td> | |
944 | <td> <img src='/images/off.gif' alt='?OFF' /></td> | |
945 | <td class='base'>$Lang::tr{'click to enable'}</td> | |
946 | <td> <img src='/images/floppy.gif' alt='?FLOPPY' /></td> | |
947 | <td class='base'>$Lang::tr{'download certificate'}</td> | |
948 | <td> <img src='/images/openvpn.gif' alt='?RELOAD'/></td> | |
949 | <td class='base'>$Lang::tr{'dl client arch'}</td> | |
950 | </tr> | |
951 | </table> | |
952 | END | |
953 | ; | |
954 | } | |
955 | print <<END | |
956 | <table width='100%'> | |
957 | <form method='post'> | |
958 | <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' $dis /> | |
959 | <input type='hidden' name='TYPE' value='host' /></td> | |
960 | <td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr> | |
961 | </form> | |
962 | </table> | |
963 | END | |
964 | ; | |
965 | &Header::closebox(); | |
966 | #} | |
967 | } | |
968 | sub net2netstatus { | |
969 | #net2net connections | |
970 | my $activeonrun = $_[0]; | |
971 | my @status = `/bin/cat /var/log/ovpnserver.log`; | |
972 | my %confighash = (); | |
973 | my $dis = '' | |
974 | &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); | |
975 | if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) { | |
976 | $dis = ''; | |
977 | } else { | |
978 | $dis = "disabled='disabled'"; | |
979 | } | |
980 | &Header::openbox('100%', 'LEFT', "Net to Net Connection status and control:"); | |
981 | print <<END | |
982 | <table width='100%' border='0' cellspacing='1' cellpadding='0'> | |
983 | <tr> | |
984 | <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td> | |
985 | <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td> | |
986 | <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td> | |
987 | <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td> | |
988 | <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td> | |
989 | <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td> | |
990 | <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td> | |
991 | </tr> | |
992 | END | |
993 | ; | |
994 | my $id = 0; | |
995 | my $gif; | |
996 | foreach my $key (keys %confighash) { | |
997 | if ($confighash{$key}[3] eq 'net') { | |
998 | if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; } | |
999 | if ($id % 2) { | |
1000 | print "<tr bgcolor='${Header::table1colour}'>\n"; | |
1001 | } else { | |
1002 | print "<tr bgcolor='${Header::table2colour}'>\n"; | |
1003 | } | |
1004 | print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>"; | |
1005 | print "<td align='center' nowrap='nowrap'>" . $confighash{$key}[6] . "-" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>"; | |
1006 | if ($confighash{$key}[4] eq 'cert') { | |
1007 | print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>"; | |
1008 | } else { | |
1009 | print "<td align='left'> </td>"; | |
1010 | } | |
1011 | if ($confighash{$key}[19] ne 'yes') { | |
1012 | my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; | |
1013 | $cavalid =~ /Not After : (.*)[\n]/; | |
1014 | $cavalid = $1; | |
1015 | print "<td align='center'>$cavalid</td>"; | |
1016 | } else { | |
1017 | print "<td> </td>"; | |
1018 | } | |
1019 | print "<td align='center'>$confighash{$key}[25]</td>"; | |
1020 | my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>"; | |
1021 | if ($confighash{$key}[0] eq 'off') { | |
1022 | $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>"; | |
1023 | } else { | |
1024 | my @tempovpnsubnet = split("\/",$confighash{$key}[13]); | |
1025 | my @ovpnip = split /\./,$tempovpnsubnet[0]; | |
1026 | my $pingip = ""; | |
1027 | if ($confighash{$key}[6] eq 'server') { | |
1028 | $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].2"; | |
1029 | } else { | |
1030 | $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].1"; | |
1031 | } | |
1032 | my $p = Net::Ping->new("udp",1); | |
1033 | if ($p->ping($pingip)) { | |
1034 | $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>"; | |
1035 | } | |
1036 | $p->close(); | |
1037 | } | |
1038 | print "<td align='center'>$active</td>"; | |
1039 | my $disable_clientdl = ""; | |
1040 | if ($confighash{$key}[6] ne 'client') { | |
1041 | print <<END | |
1042 | <form method='post' name='frm${key}a'><td align='center'> | |
1043 | <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.gif' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' /> | |
1044 | <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl /> | |
1045 | <input type='hidden' name='KEY' value='$key' $disable_clientdl /> | |
1046 | </td></form> | |
1047 | END | |
1048 | ; } else { | |
1049 | print "<td> </td>"; | |
1050 | } | |
1051 | if ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { | |
1052 | print <<END | |
1053 | <form method='post' name='frm${key}b'><td align='center'> | |
1054 | <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' /> | |
1055 | <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' /> | |
1056 | <input type='hidden' name='KEY' value='$key' /> | |
1057 | </td></form> | |
1058 | END | |
1059 | ; } else { | |
1060 | print "<td> </td>"; | |
1061 | } | |
1062 | if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") { | |
1063 | print <<END | |
1064 | <form method='post' name='frm${key}c'><td align='center'> | |
1065 | <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/floppy.gif' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' /> | |
1066 | <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' /> | |
1067 | <input type='hidden' name='KEY' value='$key' /> | |
1068 | </td></form> | |
1069 | END | |
1070 | ; } elsif ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') { | |
1071 | print <<END | |
1072 | <form method='post' name='frm${key}c'><td align='center'> | |
1073 | <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' /> | |
1074 | <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' /> | |
1075 | <input type='hidden' name='KEY' value='$key' /> | |
1076 | </td></form> | |
1077 | END | |
1078 | ; } else { | |
1079 | print "<td> </td>"; | |
1080 | } | |
1081 | ||
1082 | print <<END | |
1083 | <form method='post' name='frm${key}d'><td align='center'> | |
1084 | <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' /> | |
1085 | <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' /> | |
1086 | <input type='hidden' name='KEY' value='$key' /> | |
1087 | </td></form> | |
1088 | <form method='post' name='frm${key}e'><td align='center'> | |
1089 | <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' /> | |
1090 | <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/> | |
1091 | <input type='hidden' name='KEY' value='$key' /> | |
1092 | </td></form> | |
1093 | <form method='post' name='frm${key}f'><td align='center'> | |
1094 | <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' /> | |
1095 | <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' /> | |
1096 | <input type='hidden' name='KEY' value='$key' /> | |
1097 | </td></form> | |
1098 | </tr> | |
1099 | END | |
1100 | ; | |
1101 | $id++; | |
1102 | } | |
1103 | } | |
1104 | ; | |
1105 | ||
1106 | # If the config file contains entries, print Key to action icons | |
1107 | if ( $id ) { | |
1108 | print <<END | |
1109 | <table> | |
1110 | <tr> | |
1111 | <td class='boldbase'> <b>$Lang::tr{'legend'}:</b></td> | |
1112 | <td> <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td> | |
1113 | <td class='base'>$Lang::tr{'click to disable'}</td> | |
1114 | <td> <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td> | |
1115 | <td class='base'>$Lang::tr{'show certificate'}</td> | |
1116 | <td> <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td> | |
1117 | <td class='base'>$Lang::tr{'edit'}</td> | |
1118 | <td> <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td> | |
1119 | <td class='base'>$Lang::tr{'remove'}</td> | |
1120 | </tr> | |
1121 | <tr> | |
1122 | <td> </td> | |
1123 | <td> <img src='/images/off.gif' alt='?OFF' /></td> | |
1124 | <td class='base'>$Lang::tr{'click to enable'}</td> | |
1125 | <td> <img src='/images/floppy.gif' alt='?FLOPPY' /></td> | |
1126 | <td class='base'>$Lang::tr{'download certificate'}</td> | |
1127 | <td> <img src='/images/openvpn.gif' alt='?RELOAD'/></td> | |
1128 | <td class='base'>$Lang::tr{'dl client arch'}</td> | |
1129 | </tr> | |
1130 | </table> | |
1131 | END | |
1132 | ; | |
1133 | } | |
1134 | print <<END | |
1135 | <table width='100%'> | |
1136 | <form method='post'> | |
1137 | <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' $ dis /></td></tr> | |
1138 | </form> | |
1139 | </table> | |
1140 | END | |
1141 | ; | |
1142 | &Header::closebox(); | |
1143 | #} | |
1144 | #net2net connections | |
1145 | } |