]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - html/cgi-bin/portfw.cgi
makegraphs umgebaut, sodass nurnoch rrd daten geschrieben werden die graphen
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / portfw.cgi
1 #!/usr/bin/perl
2 #
3 # SmoothWall CGIs
4 #
5 # This code is distributed under the terms of the GPL
6 #
7 # (c) The SmoothWall Team
8 # Copyright (c) 2002/04/13 Steve Bootes - Add source IP support
9 #
10 # $Id: portfw.cgi,v 1.5.2.18 2005/05/02 16:19:49 eoberlander Exp $
11 #
12 #
13 # Darren Critchley February 2003 - I added the multiple external access rules for each port forward
14 # A couple of things to remember when reading the code
15 # There are two kinds of records in the config file, those with a number in the first field, and then 0,
16 # these are port forward rules, these records will have a 0 or 0.0.0.0 in position 9 (ORIG_IP)
17 # If there is a 0, it means that there are external access rules, otherwise the port is open to ALL.
18 # The second type of record is a number followed by a number which indicates that it is an external access
19 # rule. The first number indicates which Portfw rule it belongs to, and the second is just a unique key.
20 #
21 # Darren Critchley - March 5, 2003 - if you come along after me and work on this page, please comment your
22 # work. Put your name, and date and then your comment - it helps the person that comes along after you
23 # to figure out why and how things have changed, and it is considered good coding practice
24 # Thanks . . .
25 #
26
27 use strict;
28
29 # enable only the following on debugging purpose
30 #use warnings;
31 #use CGI::Carp 'fatalsToBrowser';
32
33 require '/var/ipfire/general-functions.pl';
34 require "${General::swroot}/lang.pl";
35 require "${General::swroot}/header.pl";
36
37 #workaround to suppress a warning when a variable is used only once
38 my @dummy = ( ${Header::colouryellow} );
39 undef (@dummy);
40
41 my %color = ();
42 my %mainsettings = ();
43 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
44 &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
45
46 my %cgiparams=();
47 my %selected=();
48 my %checked=();
49 my $prtrange1=0;
50 my $prtrange2=0;
51 my $errormessage = '';
52 my $filename = "${General::swroot}/portfw/config";
53 my $aliasfile = "${General::swroot}/ethernet/aliases";
54
55 &Header::showhttpheaders();
56
57 $cgiparams{'ENABLED'} = 'off';
58 $cgiparams{'KEY1'} = '0';
59 $cgiparams{'KEY2'} = '0';
60 $cgiparams{'PROTOCOL'} = '';
61 $cgiparams{'SRC_PORT'} = '';
62 $cgiparams{'DEST_IP'} = '';
63 $cgiparams{'DEST_PORT'} = '';
64 $cgiparams{'SRC_IP'} = '';
65 $cgiparams{'ORIG_IP'} = '';
66 $cgiparams{'REMARK'} = '';
67 $cgiparams{'OVERRIDE'} = 'off';
68 $cgiparams{'ACTION'} = '';
69
70 &Header::getcgihash(\%cgiparams);
71
72 my $disable_all = "0";
73 my $enable_all = "0";
74
75 if ($cgiparams{'ACTION'} eq $Lang::tr{'add'})
76 {
77 &valaddupdate();
78
79 # Darren Critchley - if there is an error, don't waste any more time processing
80 if ($errormessage) { goto ERROR; }
81
82 open(FILE, $filename) or die 'Unable to open config file.';
83 my @current = <FILE>;
84 close(FILE);
85 my $key1 = 0; # used for finding last sequence number used
86 foreach my $line (@current)
87 {
88 my @temp = split(/\,/,$line);
89
90 chomp ($temp[8]);
91 if ($cgiparams{'KEY2'} eq "0"){ # if key2 is 0 then it is a portfw addition
92 if ( $cgiparams{'SRC_PORT'} eq $temp[3] &&
93 $cgiparams{'PROTOCOL'} eq $temp[2] &&
94 $cgiparams{'SRC_IP'} eq $temp[7])
95 {
96 $errormessage =
97 "$Lang::tr{'source port in use'} $cgiparams{'SRC_PORT'}";
98 }
99 # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
100 if ( $temp[1] eq "0") {
101 $key1=$temp[0];
102 }
103 # Darren Critchley - Duplicate or overlapping Port range check
104 if ($temp[1] eq "0" &&
105 $cgiparams{'PROTOCOL'} eq $temp[2] &&
106 $cgiparams{'SRC_IP'} eq $temp[7] &&
107 $errormessage eq '')
108 {
109 &portchecks($temp[3], $temp[5]);
110 }
111 } else {
112 if ( $cgiparams{'KEY1'} eq $temp[0] &&
113 $cgiparams{'ORIG_IP'} eq $temp[8])
114 {
115 $errormessage =
116 "$Lang::tr{'source ip in use'} $cgiparams{'ORIG_IP'}";
117 }
118 }
119 }
120
121 ERROR:
122 unless ($errormessage)
123 {
124 # Darren Critchley - we only want to store ranges with Colons
125 $cgiparams{'SRC_PORT'} =~ tr/-/:/;
126 $cgiparams{'DEST_PORT'} =~ tr/-/:/;
127
128 if ($cgiparams{'KEY1'} eq "0") { # 0 in KEY1 indicates it is a portfw add
129 $key1++; # Add one to last sequence number
130 open(FILE,">>$filename") or die 'Unable to open config file.';
131 flock FILE, 2;
132 if ($cgiparams{'ORIG_IP'} eq '0.0.0.0/0') {
133 # if the default/all is taken, then write it to the rule
134 print FILE "$key1,0,$cgiparams{'PROTOCOL'},$cgiparams{'SRC_PORT'},$cgiparams{'DEST_IP'},$cgiparams{'DEST_PORT'},$cgiparams{'ENABLED'},$cgiparams{'SRC_IP'},$cgiparams{'ORIG_IP'},$cgiparams{'REMARK'}\n";
135 } else { # else create an extra record so it shows up
136 print FILE "$key1,0,$cgiparams{'PROTOCOL'},$cgiparams{'SRC_PORT'},$cgiparams{'DEST_IP'},$cgiparams{'DEST_PORT'},$cgiparams{'ENABLED'},$cgiparams{'SRC_IP'},0,$cgiparams{'REMARK'}\n";
137 print FILE "$key1,1,$cgiparams{'PROTOCOL'},0,$cgiparams{'DEST_IP'},$cgiparams{'DEST_PORT'},$cgiparams{'ENABLED'},0,$cgiparams{'ORIG_IP'},$cgiparams{'REMARK'}\n";
138 }
139 close(FILE);
140 undef %cgiparams;
141 &General::log($Lang::tr{'forwarding rule added'});
142 system('/usr/local/bin/setportfw');
143 } else { # else key1 eq 0
144 my $insertpoint = ($cgiparams{'KEY2'} - 1);
145 open(FILE, ">$filename") or die 'Unable to open config file.';
146 flock FILE, 2;
147 foreach my $line (@current) {
148 chomp($line);
149 my @temp = split(/\,/,$line);
150 if ($cgiparams{'KEY1'} eq $temp[0] && $insertpoint eq $temp[1]) {
151 if ($temp[1] eq "0") { # this is the first xtaccess rule, therefore modify the portfw rule
152 $temp[8] = '0';
153 }
154 print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$temp[7],$temp[8],$temp[9]\n";
155 print FILE "$cgiparams{'KEY1'},$cgiparams{'KEY2'},$cgiparams{'PROTOCOL'},0,$cgiparams{'DEST_IP'},$cgiparams{'DEST_PORT'},$cgiparams{'ENABLED'},0,$cgiparams{'ORIG_IP'},$cgiparams{'REMARK'}\n";
156 } else {
157 print FILE "$line\n";
158 }
159 }
160 close(FILE);
161 undef %cgiparams;
162 &General::log($Lang::tr{'external access rule added'});
163 system('/usr/local/bin/setportfw');
164 } # end if if KEY1 eq 0
165 } # end unless($errormessage)
166 }
167
168 if ($cgiparams{'ACTION'} eq $Lang::tr{'update'})
169 {
170 &valaddupdate();
171
172 # Darren Critchley - If there is an error don't waste any more processing time
173 if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr{'edit'}; goto UPD_ERROR; }
174
175 open(FILE, $filename) or die 'Unable to open config file.';
176 my @current = <FILE>;
177 close(FILE);
178 my $disabledpfw = '0';
179 my $lastpfw = '';
180 my $xtaccessdel = '0';
181
182 foreach my $line (@current)
183 {
184 my @temp = split(/\,/,$line);
185 if ( $temp[1] eq "0" ) { # keep track of the last portfw and if it is enabled
186 $disabledpfw = $temp[6];
187 $lastpfw = $temp[0];
188 }
189 chomp ($temp[8]);
190 if ( $cgiparams{'SRC_PORT'} eq $temp[3] &&
191 $cgiparams{'PROTOCOL'} eq $temp[2] &&
192 $cgiparams{'SRC_IP'} eq $temp[7])
193 {
194 if ($cgiparams{'KEY1'} ne $temp[0] && $cgiparams{'KEY2'} eq "0")
195 {
196 $errormessage =
197 "$Lang::tr{'source port in use'} $cgiparams{'SRC_PORT'}";
198 }
199 }
200 if ($cgiparams{'ORIG_IP'} eq $temp[8])
201 {
202 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} ne $temp[1])
203 # If we have the same source ip within a portfw group, then we have a problem!
204 {
205 $errormessage = "$Lang::tr{'source ip in use'} $cgiparams{'ORIG_IP'}";
206 $cgiparams{'ACTION'} = $Lang::tr{'edit'};
207 }
208 }
209
210 # Darren Critchley - Flag when a user disables an xtaccess
211 if ($cgiparams{'KEY1'} eq $temp[0] &&
212 $cgiparams{'KEY2'} eq $temp[1] &&
213 $cgiparams{'KEY2'} ne "0" && # if KEY2 is 0 then it is a portfw
214 $cgiparams{'ENABLED'} eq "off" &&
215 $temp[6] eq "on") { # we have determined that someone has turned an xtaccess off
216 $xtaccessdel = "1";
217 }
218
219 # Darren Critchley - Portfw enabled, then enable xtaccess for all associated xtaccess records
220 if ($cgiparams{'ENABLED'} eq "on" && $cgiparams{'KEY2'} eq "0" && $cgiparams{'ENABLED'} ne $temp[6])
221 {
222 $enable_all = "1";
223 } else {
224 $enable_all = "0";
225 }
226 # Darren Critchley - Portfw disabled, then disable xtaccess for all associated xtaccess records
227 if ($cgiparams{'ENABLED'} eq "off" && $cgiparams{'KEY2'} eq "0")
228 {
229 $disable_all = "1";
230 } else {
231 $disable_all = "0";
232 }
233
234 # Darren Critchley - if we are enabling an xtaccess, only allow if the associated Portfw is enabled
235 if ($cgiparams{'KEY1'} eq $lastpfw && $cgiparams{'KEY2'} ne "0") { # identifies an xtaccess record in the group
236 if ($cgiparams{'ENABLED'} eq "on" && $cgiparams{'ENABLED'} ne $temp[6] ){ # a change has been made
237 if ($disabledpfw eq "off")
238 {
239 $errormessage = "$Lang::tr{'cant enable xtaccess'}";
240 $cgiparams{'ACTION'} = $Lang::tr{'edit'};
241 }
242 }
243 }
244
245 # Darren Critchley - rule to stop someone from entering ALL into a external access rule,
246 # the portfw is the only place that ALL can be specified
247 if ($cgiparams{'KEY2'} ne "0" && $cgiparams{'ORIG_IP'} eq "0.0.0.0/0") {
248 $errormessage = "$Lang::tr{'xtaccess all error'}";
249 $cgiparams{'ACTION'} = $Lang::tr{'edit'};
250 }
251
252 # Darren Critchley - Duplicate or overlapping Port range check
253 if ($temp[1] eq "0" &&
254 $cgiparams{'KEY1'} ne $temp[0] &&
255 $cgiparams{'PROTOCOL'} eq $temp[2] &&
256 $cgiparams{'SRC_IP'} eq $temp[7] &&
257 $errormessage eq '')
258 {
259 &portchecks($temp[3], $temp[5]);
260 } # end port testing
261
262 }
263
264 # Darren Critchley - if an xtaccess was disabled, now we need to check to see if it was the only xtaccess
265 if($xtaccessdel eq "1") {
266 my $xctr = 0;
267 foreach my $line (@current)
268 {
269 my @temp = split(/\,/,$line);
270 if($temp[0] eq $cgiparams{'KEY1'} &&
271 $temp[6] eq "on") { # we only want to count the enabled xtaccess's
272 $xctr++;
273 }
274 }
275 if ($xctr == 2){
276 $disable_all = "1";
277 }
278 }
279
280 UPD_ERROR:
281 unless ($errormessage)
282 {
283 # Darren Critchley - we only want to store ranges with Colons
284 $cgiparams{'SRC_PORT'} =~ tr/-/:/;
285 $cgiparams{'DEST_PORT'} =~ tr/-/:/;
286
287 open(FILE, ">$filename") or die 'Unable to open config file.';
288 flock FILE, 2;
289 foreach my $line (@current) {
290 chomp($line);
291 my @temp = split(/\,/,$line);
292 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1]) {
293 print FILE "$cgiparams{'KEY1'},$cgiparams{'KEY2'},$cgiparams{'PROTOCOL'},$cgiparams{'SRC_PORT'},$cgiparams{'DEST_IP'},$cgiparams{'DEST_PORT'},$cgiparams{'ENABLED'},$cgiparams{'SRC_IP'},$cgiparams{'ORIG_IP'},$cgiparams{'REMARK'}\n";
294 } else {
295 # Darren Critchley - If it is a port forward record, then chances are good that a change was made to
296 # Destination Ip or Port, and we need to update all the associated external access records
297 if ($cgiparams{'KEY2'} eq "0" && $cgiparams{'KEY1'} eq $temp[0]) {
298 $temp[4] = $cgiparams{'DEST_IP'};
299 $temp[5] = $cgiparams{'DEST_PORT'};
300 $temp[2] = $cgiparams{'PROTOCOL'};
301 }
302
303 # Darren Critchley - If a Portfw has been disabled, then set all associated xtaccess as disabled
304 if ( $disable_all eq "1" && $cgiparams{'KEY1'} eq $temp[0] ) {
305 $temp[6] = 'off';
306 }
307 if ( $enable_all eq "1" && $cgiparams{'KEY1'} eq $temp[0] ) {
308 $temp[6] = 'on';
309 }
310 # Darren Critchley - Deal with the override to allow ALL
311 if ( $cgiparams{'OVERRIDE'} eq "on" && $temp[1] ne "0" && $cgiparams{'KEY1'} eq $temp[0] ) {
312 $temp[6] = 'off';
313 }
314 print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$temp[7],$temp[8],$temp[9]\n";
315 }
316 }
317 close(FILE);
318 undef %cgiparams;
319 &General::log($Lang::tr{'forwarding rule updated'});
320 system('/usr/local/bin/setportfw');
321 }
322 if ($errormessage) {
323 $cgiparams{'ACTION'} = $Lang::tr{'edit'};
324 }
325 }
326
327 # Darren Critchley - Allows rules to be enabled and disabled
328 if ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'})
329 {
330 open(FILE, $filename) or die 'Unable to open config file.';
331 my @current = <FILE>;
332 close(FILE);
333 my $disabledpfw = '0';
334 my $lastpfw = '';
335 my $xtaccessdel = '0';
336
337 foreach my $line (@current)
338 {
339 my @temp = split(/\,/,$line);
340 if ( $temp[1] eq "0" ) { # keep track of the last portfw and if it is enabled
341 $disabledpfw = $temp[6];
342 $lastpfw = $temp[0];
343 }
344 # Darren Critchley - Flag when a user disables an xtaccess
345 if ($cgiparams{'KEY1'} eq $temp[0] &&
346 $cgiparams{'KEY2'} eq $temp[1] &&
347 $cgiparams{'KEY2'} ne "0" && # if KEY2 is 0 then it is a portfw
348 $cgiparams{'ENABLED'} eq "off" &&
349 $temp[6] eq "on") { # we have determined that someone has turned an xtaccess off
350 $xtaccessdel = "1";
351 }
352
353 # Darren Critchley - Portfw enabled, then enable xtaccess for all associated xtaccess records
354 if ($cgiparams{'ENABLED'} eq "on" && $cgiparams{'KEY2'} eq "0" && $cgiparams{'ENABLED'} ne $temp[6])
355 {
356 $enable_all = "1";
357 } else {
358 $enable_all = "0";
359 }
360 # Darren Critchley - Portfw disabled, then disable xtaccess for all associated xtaccess records
361 if ($cgiparams{'ENABLED'} eq "off" && $cgiparams{'KEY2'} eq "0")
362 {
363 $disable_all = "1";
364 } else {
365 $disable_all = "0";
366 }
367
368 # Darren Critchley - if we are enabling an xtaccess, only allow if the associated Portfw is enabled
369 if ($cgiparams{'KEY1'} eq $lastpfw && $cgiparams{'KEY2'} ne "0") { # identifies an xtaccess record in the group
370 if ($cgiparams{'ENABLED'} eq "on" && $cgiparams{'ENABLED'} ne $temp[6] ){ # a change has been made
371 if ($disabledpfw eq "off")
372 {
373 $errormessage = "$Lang::tr{'cant enable xtaccess'}";
374 goto TOGGLEEXIT;
375 }
376 }
377 }
378 }
379
380 # Darren Critchley - if an xtaccess was disabled, now we need to check to see if it was the only xtaccess
381 if($xtaccessdel eq "1") {
382 my $xctr = 0;
383 foreach my $line (@current)
384 {
385 my @temp = split(/\,/,$line);
386 if($temp[0] eq $cgiparams{'KEY1'} &&
387 $temp[6] eq "on") { # we only want to count the enabled xtaccess's
388 $xctr++;
389 }
390 }
391 if ($xctr == 2){
392 $disable_all = "1";
393 }
394 }
395
396 open(FILE, ">$filename") or die 'Unable to open config file.';
397 flock FILE, 2;
398 foreach my $line (@current) {
399 chomp($line);
400 my @temp = split(/\,/,$line);
401 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1]) {
402 print FILE "$cgiparams{'KEY1'},$cgiparams{'KEY2'},$temp[2],$temp[3],$temp[4],$temp[5],$cgiparams{'ENABLED'},$temp[7],$temp[8],$temp[9]\n";
403 } else {
404 # Darren Critchley - If a Portfw has been disabled, then set all associated xtaccess as disabled
405 if ( $disable_all eq "1" && $cgiparams{'KEY1'} eq $temp[0] ) {
406 $temp[6] = 'off';
407 }
408 if ( $enable_all eq "1" && $cgiparams{'KEY1'} eq $temp[0] ) {
409 $temp[6] = 'on';
410 }
411 print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$temp[7],$temp[8],$temp[9]\n";
412 }
413 }
414 close(FILE);
415 &General::log($Lang::tr{'forwarding rule updated'});
416 system('/usr/local/bin/setportfw');
417 TOGGLEEXIT:
418 undef %cgiparams;
419 }
420
421
422 # Darren Critchley - broke out Edit routine from the delete routine - Edit routine now just puts values in fields
423 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'})
424 {
425 open(FILE, "$filename") or die 'Unable to open config file.';
426 my @current = <FILE>;
427 close(FILE);
428
429 unless ($errormessage)
430 {
431 foreach my $line (@current)
432 {
433 chomp($line);
434 my @temp = split(/\,/,$line);
435 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1] ) {
436 $cgiparams{'PROTOCOL'} = $temp[2];
437 $cgiparams{'SRC_PORT'} = $temp[3];
438 $cgiparams{'DEST_IP'} = $temp[4];
439 $cgiparams{'DEST_PORT'} = $temp[5];
440 $cgiparams{'ENABLED'} = $temp[6];
441 $cgiparams{'SRC_IP'} = $temp[7];
442 $cgiparams{'ORIG_IP'} = $temp[8];
443 $cgiparams{'REMARK'} = $temp[9];
444 }
445
446 }
447 }
448 }
449
450 # Darren Critchley - broke out Remove routine as the logic is getting too complex to be combined with the Edit
451 if ($cgiparams{'ACTION'} eq $Lang::tr{'remove'})
452 {
453 open(FILE, "$filename") or die 'Unable to open config file.';
454 my @current = <FILE>;
455 close(FILE);
456
457 # If the record being deleted is an xtaccess record, and it is the only one for a portfw record
458 # then we need to adjust the portfw record to be open to ALL ip addressess or an error will occur
459 # in setportfw.c
460 my $fixportfw = '0';
461 if ($cgiparams{'KEY2'} ne "0") {
462 my $counter = 0;
463 foreach my $line (@current)
464 {
465 chomp($line);
466 my @temp = split(/\,/,$line);
467 if ($temp[0] eq $cgiparams{'KEY1'}) {
468 $counter++;
469 }
470 }
471 if ($counter eq 2) {
472 $fixportfw = '1';
473 }
474 }
475
476 unless ($errormessage)
477 {
478 open(FILE, ">$filename") or die 'Unable to open config file.';
479 flock FILE, 2;
480 my $linedeleted = 0;
481 foreach my $line (@current)
482 {
483 chomp($line);
484 my @temp = split(/\,/,$line);
485
486 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1] ||
487 $cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq "0" )
488 {
489 $linedeleted = 1;
490 } else {
491 if ($temp[0] eq $cgiparams{'KEY1'} && $temp[1] eq "0" && $fixportfw eq "1") {
492 $temp[8] = '0.0.0.0/0';
493 }
494 print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$temp[7],$temp[8],$temp[9]\n";
495 # print FILE "$line\n";
496 }
497 }
498 close(FILE);
499 if ($linedeleted == 1) {
500 &General::log($Lang::tr{'forwarding rule removed'});
501 undef %cgiparams;
502 }
503 system('/usr/local/bin/setportfw');
504 }
505 }
506
507 # Darren Critchley - Added routine to allow external access rules to be added
508 if ($cgiparams{'ACTION'} eq $Lang::tr{'add xtaccess'})
509 {
510 open(FILE, $filename) or die 'Unable to open config file.';
511 my @current = <FILE>;
512 close(FILE);
513 my $key = 0; # used for finding last sequence number used
514 foreach my $line (@current)
515 {
516 my @temp = split(/\,/,$line);
517 if ($temp[0] eq $cgiparams{'KEY1'}) {
518 $key = $temp[1]
519 }
520 if ($cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1] ) {
521 $cgiparams{'PROTOCOL'} = $temp[2];
522 $cgiparams{'SRC_PORT'} = $temp[3];
523 $cgiparams{'DEST_IP'} = $temp[4];
524 $cgiparams{'DEST_PORT'} = $temp[5];
525 $cgiparams{'ENABLED'} = $temp[6];
526 $cgiparams{'SRC_IP'} = $temp[7];
527 $cgiparams{'ORIG_IP'} = '';
528 $cgiparams{'REMARK'} = $temp[9];
529 }
530 }
531 $key++;
532 $cgiparams{'KEY2'} = $key;
533 # Until the ADD button is hit, there needs to be no change to portfw rules
534 }
535
536 if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})
537 {
538 undef %cgiparams;
539 }
540
541 if ($cgiparams{'ACTION'} eq '')
542 {
543 $cgiparams{'PROTOCOL'} = 'tcp';
544 $cgiparams{'ENABLED'} = 'on';
545 $cgiparams{'SRC_IP'} = '0.0.0.0';
546 }
547
548 $selected{'PROTOCOL'}{'udp'} = '';
549 $selected{'PROTOCOL'}{'tcp'} = '';
550 $selected{'PROTOCOL'}{'gre'} = '';
551 $selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = "selected='selected'";
552
553 $selected{'SRC_IP'}{$cgiparams{'SRC_IP'}} = "selected='selected'";
554
555 $checked{'ENABLED'}{'off'} = '';
556 $checked{'ENABLED'}{'on'} = '';
557 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = "checked='checked'";
558
559 &Header::openpage($Lang::tr{'port forwarding configuration'}, 1, '');
560
561 &Header::openbigbox('100%', 'left', '', $errormessage);
562
563 if ($errormessage) {
564 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
565 print "<class name='base'><font color='${Header::colourred}'>$errormessage\n</font>";
566 print "&nbsp;</class>\n";
567 &Header::closebox();
568 }
569
570 print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>\n";
571
572 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
573 &Header::openbox('100%', 'left', $Lang::tr{'edit a rule'});
574 } else {
575 &Header::openbox('100%', 'left', $Lang::tr{'add a new rule'});
576 }
577
578 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY2'} ne "0" || $cgiparams{'ACTION'} eq $Lang::tr{'add xtaccess'}){
579 # if it is not a port forward record, don't validate as the fields are disabled
580 my $PROT = "\U$cgiparams{'PROTOCOL'}\E";
581 # Darren Critchley - Format the source and destination ports
582 my $dstprt = $cgiparams{'DEST_PORT'};
583 $dstprt =~ s/-/ - /;
584 $dstprt =~ s/:/ - /;
585
586 print <<END
587 <table>
588 <tr>
589 <td class='base'>$Lang::tr{'protocol'}: <b>$PROT</b></td>
590 <td width='20'>&nbsp;</td>
591 <td class='base' align='right'>$Lang::tr{'destination ip'}:&nbsp;</td>
592 <td><b>$cgiparams{'DEST_IP'}</b></td>
593 <td width='20'>&nbsp;</td>
594 <td class='base' align='right'>$Lang::tr{'destination port'}:&nbsp;</td>
595 <td><b>$dstprt</b></td>
596 </tr>
597 </table>
598
599 <input type='hidden' name='PROTOCOL' value='$cgiparams{'PROTOCOL'}' />
600 <input type='hidden' name='SRC_IP' value='$cgiparams{'SRC_IP'}' />
601 <input type='hidden' name='SRC_PORT' value='$cgiparams{'SRC_PORT'}' />
602 <input type='hidden' name='DEST_IP' value='$cgiparams{'DEST_IP'}' />
603 <input type='hidden' name='DEST_PORT' value='$cgiparams{'DEST_PORT'}' />
604 END
605 ;
606 } else {
607 print <<END
608 <table width='100%'>
609 <tr>
610 <td width='10%'>$Lang::tr{'protocol'}:&nbsp;</td>
611 <td width='15%'>
612 <select name='PROTOCOL'>
613 <option value='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</option>
614 <option value='udp' $selected{'PROTOCOL'}{'udp'}>UDP</option>
615 <option value='gre' $selected{'PROTOCOL'}{'gre'}>GRE</option>
616 </select>
617 </td>
618 <td class='base' width='20%'><font color='${Header::colourred}'>$Lang::tr{'alias ip'}:</font></td>
619 <td>
620 <select name='SRC_IP'>
621 <option value='0.0.0.0' $selected{'SRC_IP'}{'0.0.0.0'}>DEFAULT IP</option>
622 END
623 ;
624 open(ALIASES, "$aliasfile") or die 'Unable to open aliases file.';
625 while (<ALIASES>)
626 {
627 chomp($_);
628 my @temp = split(/\,/,$_);
629 if ($temp[1] eq 'on') {
630 print "<option value='$temp[0]' $selected{'SRC_IP'}{$temp[0]}>$temp[0]";
631 if (defined $temp[2] and ($temp[2] ne '')) { print " ($temp[2])"; }
632 print "</option>\n";
633 }
634 }
635 close(ALIASES);
636 print <<END
637 </select>
638 </td>
639 <td class='base' width='20%'><font color='${Header::colourred}'>$Lang::tr{'source port'}:</font></td>
640 <td width='10%'><input type='text' name='SRC_PORT' value='$cgiparams{'SRC_PORT'}' size='8' /></td>
641 </tr>
642 <tr>
643 <td class='base'>&nbsp;</td>
644 <td>&nbsp;</td>
645 <td class='base'>$Lang::tr{'destination ip'}:</td>
646 <td><input type='text' name='DEST_IP' value='$cgiparams{'DEST_IP'}' size='15' /></td>
647 <td class='base'>$Lang::tr{'destination port'}:</td>
648 <td><input type='text' name='DEST_PORT' value='$cgiparams{'DEST_PORT'}' size='8' /></td>
649 </tr>
650 </table>
651 END
652 ;
653 }
654
655 print <<END
656 <table>
657 <tr>
658 <td class='base'>$Lang::tr{'remark title'}&nbsp;<img src='/blob.gif' alt='*' />&nbsp;</td>
659 <td><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td>
660 END
661 ;
662 unless ($cgiparams{'ACTION'} eq $Lang::tr{'add xtaccess'} && $cgiparams{'ENABLED'} eq "off") {
663 print "<td width='20'>&nbsp;</td>";
664 print "<td>$Lang::tr{'enabled'}&nbsp;</td><td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\n";
665 }
666 print <<END
667 </tr>
668 </table>
669 END
670 ;
671
672 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY2'} eq "0" && ($cgiparams{'ORIG_IP'} eq "0" || $cgiparams{'ORIG_IP'} eq "0.0.0.0/0")){
673 # if it is a port forward rule with a 0 in the orig_port field, this means there are xtaccess records, and we
674 # don't want to allow a person to change the orig_ip field as it will mess other logic up
675 print "<input type='hidden' name='ORIG_IP' value='$cgiparams{'ORIG_IP'}' />\n";
676 } else {
677 print <<END
678 <table>
679 <tr>
680 <td class='base'><font class='boldbase' color='${Header::colourred}'>$Lang::tr{'source network'}</font>&nbsp;<img src='/blob.gif' alt='*' />&nbsp;</td>
681 <td><input type='text' name='ORIG_IP' value='$cgiparams{'ORIG_IP'}' size='15' /></td>
682 </tr>
683 </table>
684 END
685 ;
686 }
687
688 print <<END
689 <table width='100%'>
690 <hr />
691 <tr>
692 <td class='base' width='25%'><img src='/blob.gif' alt ='*' align='top' />&nbsp;<font class='base'>$Lang::tr{'this field may be blank'}</font></td>
693 END
694 ;
695
696
697 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
698 if($cgiparams{'KEY2'} eq "0"){
699 print "<td width='35%' align='right'>$Lang::tr{'open to all'}:&nbsp;</td><td width='5%'><input type='checkbox' name='OVERRIDE' $checked{'OVERRIDE'}{'on'} /></td>\n";
700 } else {
701 print "<td width='40%'>&nbsp;</td>\n";
702 }
703 print "<td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' />";
704 print "<input type='hidden' name='KEY1' value='$cgiparams{'KEY1'}' />";
705 print "<input type='hidden' name='KEY2' value='$cgiparams{'KEY2'}' /></TD>";
706 print "<td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></td>";
707 # on an edit and an xtaccess add, for some reason the "Reset" button stops working, so I make it a submit button
708 } else {
709 print "<td width='30%'>&nbsp;</td>\n";
710 print "<td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td>";
711 if ($cgiparams{'ACTION'} eq $Lang::tr{'add xtaccess'}) {
712 print "<td align='center' width='15%'><input type='hidden' name='KEY1' value='$cgiparams{'KEY1'}' />";
713 print "<input type='hidden' name='KEY2' value='$cgiparams{'KEY2'}' />";
714 print "<input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></td>";
715 } elsif ($errormessage ne '') {
716 print "<td align='center' width='15%'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></td>";
717 } else {
718 print "<td align='center' width='15%'><input type='reset' name='ACTION' value='$Lang::tr{'reset'}' /></td>";
719 }
720 }
721 print <<END
722 <td width='5%' align='right'>&nbsp;</td>
723 </tr>
724 </table>
725 END
726 ;
727 &Header::closebox();
728
729 print "</form>\n";
730
731 &Header::openbox('100%', 'left', $Lang::tr{'current rules'});
732 print <<END
733 <table width='100%'>
734 <tr>
735 <td width='7%' class='boldbase' align='center'><b>$Lang::tr{'proto'}</b></td>
736 <td width='31%' class='boldbase' align='center'><b>$Lang::tr{'source'}</b></td>
737 <td width='2%' class='boldbase' align='center'>&nbsp;</td>
738 <td width='31%' class='boldbase' align='center'><b>$Lang::tr{'destination'}</b></td>
739 <td width='24%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></td>
740 <td width='4%' class='boldbase' colspan='4' align='center'><b>$Lang::tr{'action'}</b></td>
741 </tr>
742 END
743 ;
744
745 my $id = 0;
746 my $xtaccesscolor = '#F6F4F4';
747 open(RULES, "$filename") or die 'Unable to open config file.';
748 while (<RULES>)
749 {
750 my $protocol = '';
751 my $gif = '';
752 my $gdesc = '';
753 my $toggle = '';
754 chomp($_);
755 my @temp = split(/\,/,$_);
756 $temp[9] ='' unless defined $temp[9];# Glles ESpinasse : suppress warning on page init
757 if ($temp[2] eq 'udp') {
758 $protocol = 'UDP'; }
759 elsif ($temp[2] eq 'gre') {
760 $protocol = 'GRE' }
761 else {
762 $protocol = 'TCP' }
763 # Change bgcolor when a new portfw rule is added
764 if ($temp[1] eq "0"){
765 $id++;
766 }
767 # Darren Critchley highlight the row we are editing
768 if ( $cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY1'} eq $temp[0] && $cgiparams{'KEY2'} eq $temp[1] ) {
769 print "<tr bgcolor='${Header::colouryellow}'>\n";
770 } else {
771 if ($id % 2) {
772 print "<tr bgcolor='$color{'color22'}'>\n";
773 }
774 else {
775 print "<tr bgcolor='$color{'color20'}'>\n";
776 }
777 }
778
779 if ($temp[6] eq 'on') { $gif = 'on.gif'; $toggle='off'; $gdesc=$Lang::tr{'click to disable'};}
780 else { $gif = 'off.gif'; $toggle='on'; $gdesc=$Lang::tr{'click to enable'}; }
781
782 # Darren Critchley - this code no longer works - should we remove?
783 # catch for 'old-style' rules file - assume default ip if
784 # none exists
785 if (!&General::validip($temp[7]) || $temp[7] eq '0.0.0.0') {
786 $temp[7] = 'DEFAULT IP'; }
787 if ($temp[1] eq '0') { # Port forwarding entry
788
789 # Darren Critchley - Format the source and destintation ports
790 my $srcprt = $temp[3];
791 $srcprt =~ s/-/ - /;
792 $srcprt =~ s/:/ - /;
793 my $dstprt = $temp[5];
794 $dstprt =~ s/-/ - /;
795 $dstprt =~ s/:/ - /;
796
797 # Darren Critchley - Get Port Service Name if we can - code borrowed from firewalllog.dat
798 $_=$temp[3];
799 if (/^\d+$/) {
800 my $servi = uc(getservbyport($temp[3], lc($temp[2])));
801 if ($servi ne '' && $temp[3] < 1024) {
802 $srcprt = "$srcprt($servi)"; }
803 }
804 $_=$temp[5];
805 if (/^\d+$/) {
806 my $servi = uc(getservbyport($temp[5], lc($temp[2])));
807 if ($servi ne '' && $temp[5] < 1024) {
808 $dstprt = "$dstprt($servi)"; }
809 }
810
811 # Darren Critchley - If the line is too long, wrap the port numbers
812 my $srcaddr = "$temp[7] : $srcprt";
813 if (length($srcaddr) > 22) {
814 $srcaddr = "$temp[7] :<br /> $srcprt";
815 }
816 my $dstaddr = "$temp[4] : $dstprt";
817 if (length($dstaddr) > 26) {
818 $dstaddr = "$temp[4] :<br /> $dstprt";
819 }
820 print <<END
821 <td align='center'>$protocol</td>
822 <td align='center'>$srcaddr</td>
823 <td align='center'><img src='/images/forward.gif' alt='=&gt;' /></td>
824 <td align='center'>$dstaddr</td>
825 <td align='left'>&nbsp;$temp[9]</td>
826 <td align='center'>
827 <form method='post' name='frm$temp[0]c' action='$ENV{'SCRIPT_NAME'}'>
828 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />
829 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
830 <input type='hidden' name='KEY1' value='$temp[0]' />
831 <input type='hidden' name='KEY2' value='$temp[1]' />
832 <input type='hidden' name='ENABLED' value='$toggle' />
833 </form>
834 </td>
835
836 <td align='center'>
837 <form method='post' name='frm$temp[0]' action='$ENV{'SCRIPT_NAME'}'>
838 <input type='hidden' name='ACTION' value='$Lang::tr{'add xtaccess'}' />
839 <input type='image' name='$Lang::tr{'add xtaccess'}' src='/images/add.gif' alt='$Lang::tr{'add xtaccess'}' title='$Lang::tr{'add xtaccess'}' />
840 <input type='hidden' name='KEY1' value='$temp[0]' />
841 <input type='hidden' name='KEY2' value='$temp[1]' />
842 </form>
843 </td>
844
845 <td align='center'>
846 <form method='post' name='frm$temp[0]' action='$ENV{'SCRIPT_NAME'}'>
847 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
848 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
849 <input type='hidden' name='KEY1' value='$temp[0]' />
850 <input type='hidden' name='KEY2' value='$temp[1]' />
851 </form>
852 </td>
853
854 <td align='center'>
855 <form method='post' name='frm$temp[0]b' action='$ENV{'SCRIPT_NAME'}'>
856 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
857 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
858 <input type='hidden' name='KEY1' value='$temp[0]' />
859 <input type='hidden' name='KEY2' value='$temp[1]' />
860 </form>
861 </td>
862
863 </tr>
864 END
865 ;
866 } else { # external access entry
867 print <<END
868 <td align='center'>&nbsp;</td>
869
870 <td align='left' colspan='4'>&nbsp;<font color='${Header::colourred}'>$Lang::tr{'access allowed'}</font> $temp[8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($temp[9])</td>
871
872 <td align='center'>
873 <form method='post' name='frm$temp[0]$temp[1]t' action='$ENV{'SCRIPT_NAME'}'>
874 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' />
875 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
876 <input type='hidden' name='KEY1' value='$temp[0]' />
877 <input type='hidden' name='KEY2' value='$temp[1]' />
878 <input type='hidden' name='ENABLED' value='$toggle' />
879 </form>
880 </td>
881
882 <td align='center'>&nbsp;</td>
883
884 <td align='center'>
885 <form method='post' name='frm$temp[0]$temp[1]' action='$ENV{'SCRIPT_NAME'}'>
886 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
887 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
888 <input type='hidden' name='KEY1' value='$temp[0]' />
889 <input type='hidden' name='KEY2' value='$temp[1]' />
890 </form>
891 </td>
892
893 <td align='center'>
894 <form method='post' name='frm$temp[0]b$temp[1]b' action='$ENV{'SCRIPT_NAME'}'>
895 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
896 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
897 <input type='hidden' name='KEY1' value='$temp[0]' />
898 <input type='hidden' name='KEY2' value='$temp[1]' />
899 </form>
900 </td>
901
902 </tr>
903 END
904 ;
905 }
906 }
907
908 close(RULES);
909
910 print "</table>";
911
912 # If the fixed lease file contains entries, print Key to action icons
913 if ( ! -z "$filename") {
914 print <<END
915 <table>
916 <tr>
917 <td class='boldbase'>&nbsp;<b>$Lang::tr{'legend'}:&nbsp;</b></td>
918 <td><img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
919 <td class='base'>$Lang::tr{'click to disable'}</td>
920 <td>&nbsp;&nbsp;</td>
921 <td><img src='/images/off.gif' alt='$Lang::tr{'click to enable'}' /></td>
922 <td class='base'>$Lang::tr{'click to enable'}</td>
923 <td>&nbsp;&nbsp;</td>
924 <td><img src='/images/add.gif' alt='$Lang::tr{'add xtaccess'}' /></td>
925 <td class='base'>$Lang::tr{'add xtaccess'}</td>
926 <td>&nbsp;&nbsp;</td>
927 <td><img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
928 <td class='base'>$Lang::tr{'edit'}</td>
929 <td>&nbsp;&nbsp;</td>
930 <td><img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
931 <td class='base'>$Lang::tr{'remove'}</td>
932 </tr>
933 </table>
934 END
935 ;
936 }
937
938 &Header::closebox();
939
940 &Header::closebigbox();
941
942 &Header::closepage();
943
944 # Validate Field Entries
945 sub validateparams
946 {
947 # Darren Critchley - Get rid of dashes in port ranges
948 $cgiparams{'DEST_PORT'}=~ tr/-/:/;
949 $cgiparams{'SRC_PORT'}=~ tr/-/:/;
950
951 # Darren Critchley - code to substitue wildcards
952 if ($cgiparams{'SRC_PORT'} eq "*") {
953 $cgiparams{'SRC_PORT'} = "1:65535";
954 }
955 if ($cgiparams{'SRC_PORT'} =~ /^(\D)\:(\d+)$/) {
956 $cgiparams{'SRC_PORT'} = "1:$2";
957 }
958 if ($cgiparams{'SRC_PORT'} =~ /^(\d+)\:(\D)$/) {
959 $cgiparams{'SRC_PORT'} = "$1:65535";
960 }
961 if ($cgiparams{'DEST_PORT'} eq "*") {
962 $cgiparams{'DEST_PORT'} = "1:65535";
963 }
964 if ($cgiparams{'DEST_PORT'} =~ /^(\D)\:(\d+)$/) {
965 $cgiparams{'DEST_PORT'} = "1:$2";
966 }
967 if ($cgiparams{'DEST_PORT'} =~ /^(\d+)\:(\D)$/) {
968 $cgiparams{'DEST_PORT'} = "$1:65535";
969 }
970
971 # Darren Critchley - Add code for GRE protocol - we want to ignore ports, but we need a place holder
972 if ($cgiparams{'PROTOCOL'} eq 'gre') {
973 $cgiparams{'SRC_PORT'} = "GRE";
974 $cgiparams{'DEST_PORT'} = "GRE";
975 }
976
977 unless($cgiparams{'PROTOCOL'} =~ /^(tcp|udp|gre)$/) { $errormessage = $Lang::tr{'invalid input'}; }
978 # Darren Critchley - Changed how the error routine works a bit - for the validportrange check, we need to
979 # pass in src or dest to determine which side we are working with.
980 # the routine returns the complete error or ''
981 if ($cgiparams{'PROTOCOL'} ne 'gre') {
982 $errormessage = &General::validportrange($cgiparams{'SRC_PORT'}, 'src');
983 }
984 if( ($cgiparams{'ORIG_IP'} ne "0" && $cgiparams{'KEY2'} ne "0") || $cgiparams{'ACTION'} eq $Lang::tr{'add'}) {
985 # if it is a port forward record with 0 in orig_ip then ignore checking this field
986 unless(&General::validipormask($cgiparams{'ORIG_IP'}))
987 {
988 if ($cgiparams{'ORIG_IP'} ne '') {
989 $errormessage = $Lang::tr{'source ip bad'}; }
990 else {
991 $cgiparams{'ORIG_IP'} = '0.0.0.0/0'; }
992 }
993 }
994 # Darren Critchey - New rule that sets destination same as source if dest_port is blank.
995 if ($cgiparams{'DEST_PORT'} eq ''){
996 $cgiparams{'DEST_PORT'} = $cgiparams{'SRC_PORT'};
997 }
998 # Darren Critchey - Just in case error message is already set, this routine would wipe it out if
999 # we don't do a test here
1000 if ($cgiparams{'PROTOCOL'} ne 'gre') {
1001 unless($errormessage) {$errormessage = &General::validportrange($cgiparams{'DEST_PORT'}, 'dest');}
1002 }
1003 unless(&General::validip($cgiparams{'DEST_IP'})) { $errormessage = $Lang::tr{'destination ip bad'}; }
1004 return;
1005 }
1006
1007 # Darren Critchley - we want to make sure that a port range does not overlap another port range
1008 sub checkportoverlap
1009 {
1010 my $portrange1 = $_[0]; # New port range
1011 my $portrange2 = $_[1]; # existing port range
1012 my @tempr1 = split(/\:/,$portrange1);
1013 my @tempr2 = split(/\:/,$portrange2);
1014
1015 unless (&checkportinc($tempr1[0], $portrange2)){ return 0;}
1016 unless (&checkportinc($tempr1[1], $portrange2)){ return 0;}
1017
1018 unless (&checkportinc($tempr2[0], $portrange1)){ return 0;}
1019 unless (&checkportinc($tempr2[1], $portrange1)){ return 0;}
1020
1021 return 1; # Everything checks out!
1022 }
1023
1024 # Darren Critchley - we want to make sure that a port entry is not within an already existing range
1025 sub checkportinc
1026 {
1027 my $port1 = $_[0]; # Port
1028 my $portrange2 = $_[1]; # Port range
1029 my @tempr1 = split(/\:/,$portrange2);
1030
1031 if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
1032 return 1;
1033 } else {
1034 return 0;
1035 }
1036 }
1037
1038 # Darren Critchley - certain ports are reserved for Ipcop
1039 # TCP 67,68,81,222,445
1040 # UDP 67,68
1041 # Params passed in -> port, rangeyn, protocol
1042 sub disallowreserved
1043 {
1044 # port 67 and 68 same for tcp and udp, don't bother putting in an array
1045 my $msg = "";
1046 my @tcp_reserved = (81,222,444);
1047 my $prt = $_[0]; # the port or range
1048 my $ryn = $_[1]; # tells us whether or not it is a port range
1049 my $prot = $_[2]; # protocol
1050 my $srcdst = $_[3]; # source or destination
1051
1052 if ($ryn) { # disect port range
1053 if ($srcdst eq "src") {
1054 $msg = "$Lang::tr{'rsvd src port overlap'}";
1055 } else {
1056 $msg = "$Lang::tr{'rsvd dst port overlap'}";
1057 }
1058 my @tmprng = split(/\:/,$prt);
1059 unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
1060 unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
1061 if ($prot eq "tcp") {
1062 foreach my $prange (@tcp_reserved) {
1063 unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
1064 }
1065 }
1066 } else {
1067 if ($srcdst eq "src") {
1068 $msg = "$Lang::tr{'reserved src port'}";
1069 } else {
1070 $msg = "$Lang::tr{'reserved dst port'}";
1071 }
1072 if ($prt == 67) { $errormessage="$msg 67"; return; }
1073 if ($prt == 68) { $errormessage="$msg 68"; return; }
1074 if ($prot eq "tcp") {
1075 foreach my $prange (@tcp_reserved) {
1076 if ($prange == $prt) { $errormessage="$msg $prange"; return; }
1077 }
1078 }
1079 }
1080 return;
1081 }
1082
1083 # Darren Critchley - Attempt to combine Add/Update validation as they are almost the same
1084 sub valaddupdate
1085 {
1086 if ($cgiparams{'KEY2'} eq "0"){ # if it is a port forward rule, then validate properly
1087 &validateparams();
1088 } else { # it is an xtaccess rule, just check for a valid ip
1089 unless(&General::validipormask($cgiparams{'ORIG_IP'}))
1090 {
1091 if ($cgiparams{'ORIG_IP'} ne '') {
1092 $errormessage = $Lang::tr{'source ip bad'}; }
1093 else { # this rule stops someone from adding an ALL xtaccess record
1094 $errormessage = $Lang::tr{'xtaccess all error'};
1095 $cgiparams{'ACTION'} = $Lang::tr{'add xtaccess'};
1096 }
1097 }
1098 # Darren Critchley - check for 0.0.0.0/0 - not allowed for xtaccess
1099 if ($cgiparams{'ORIG_IP'} eq "0.0.0.0/0" || $cgiparams{'ORIG_IP'} eq "0.0.0.0") {
1100 $errormessage = $Lang::tr{'xtaccess all error'};
1101 $cgiparams{'ACTION'} = $Lang::tr{'add xtaccess'};
1102 }
1103 }
1104 # Darren Critchley - Remove commas from remarks
1105 $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
1106
1107 # Darren Critchley - Check to see if we are working with port ranges
1108 our ($prtrange1, $prtrange2);
1109 $_ = $cgiparams{'SRC_PORT'};
1110 if ($cgiparams{'KEY2'} eq "0" && m/:/){
1111 $prtrange1 = 1;
1112 }
1113 if ($cgiparams{'SRC_IP'} eq '0.0.0.0') { # Dave Roberts - only check if using DEFAULT IP
1114 if ($prtrange1 == 1){ # check for source ports reserved for Ipcop
1115 &disallowreserved($cgiparams{'SRC_PORT'},1,$cgiparams{'PROTOCOL'},"src");
1116 if ($errormessage) { goto EXITSUB; }
1117 } else { # check for source port reserved for Ipcop
1118 &disallowreserved($cgiparams{'SRC_PORT'},0,$cgiparams{'PROTOCOL'},"src");
1119 if ($errormessage) { goto EXITSUB; }
1120 }
1121 }
1122
1123 $_ = $cgiparams{'DEST_PORT'};
1124 if ($cgiparams{'KEY2'} eq "0" && m/:/){
1125 $prtrange2 = 1;
1126 }
1127 if ($cgiparams{'SRC_IP'} eq '0.0.0.0') { # Dave Roberts - only check if using DEFAULT IP
1128 if ($prtrange2 == 1){ # check for destination ports reserved for IPFire
1129 &disallowreserved($cgiparams{'DEST_PORT'},1,$cgiparams{'PROTOCOL'},"dst");
1130 if ($errormessage) { goto EXITSUB; }
1131 } else { # check for destination port reserved for IPFire
1132 &disallowreserved($cgiparams{'DEST_PORT'},0,$cgiparams{'PROTOCOL'},"dst");
1133 if ($errormessage) { goto EXITSUB; }
1134 }
1135 }
1136
1137
1138 EXITSUB:
1139 return;
1140 }
1141
1142 # Darren Critchley - Duplicate or overlapping Port range check
1143 sub portchecks
1144 {
1145 $_ = $_[0];
1146 our ($prtrange1, $prtrange2);
1147 if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
1148 unless (&checkportoverlap($cgiparams{'SRC_PORT'},$_[0])) {
1149 $errormessage = "$Lang::tr{'source port overlaps'} $_[0]";
1150 }
1151 }
1152 if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
1153 unless (&checkportinc($cgiparams{'SRC_PORT'}, $_[0])) {
1154 $errormessage = "$Lang::tr{'srcprt within existing'} $_[0]";
1155 }
1156 }
1157 if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
1158 unless (&checkportinc($_[0], $cgiparams{'SRC_PORT'})) {
1159 $errormessage = "$Lang::tr{'srcprt range overlaps'} $_[0]";
1160 }
1161 }
1162
1163 if ($errormessage eq ''){
1164 $_ = $_[1];
1165 if (m/:/ && $prtrange2 == 1) { # if true then there is a port range
1166 unless (&checkportoverlap($cgiparams{'DEST_PORT'},$_[1])) {
1167 $errormessage = "$Lang::tr{'destination port overlaps'} $_[1]";
1168 }
1169 }
1170 if (m/:/ && $prtrange2 == 0 && $errormessage eq '') { # compare one port to a range
1171 unless (&checkportinc($cgiparams{'DEST_PORT'}, $_[1])) {
1172 $errormessage = "$Lang::tr{'dstprt within existing'} $_[1]";
1173 }
1174 }
1175 if (! m/:/ && $prtrange2 == 1 && $errormessage eq '') { # compare one port to a range
1176 unless (&checkportinc($_[1], $cgiparams{'DEST_PORT'})) {
1177 $errormessage = "$Lang::tr{'dstprt range overlaps'} $_[1]";
1178 }
1179 }
1180 }
1181 return;
1182 }