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