]>
Commit | Line | Data |
---|---|---|
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 | |
27 | use 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 | |
33 | require 'CONFIG_ROOT/general-functions.pl';\r | |
34 | require "${General::swroot}/lang.pl";\r | |
35 | require "${General::swroot}/header.pl";\r | |
36 | \r | |
37 | #workaround to suppress a warning when a variable is used only once\r | |
38 | my @dummy = ( ${Header::colouryellow} );\r | |
39 | undef (@dummy);\r | |
40 | \r | |
41 | my %cgiparams=();\r | |
42 | my %selected=();\r | |
43 | my %checked=();\r | |
44 | my $prtrange1=0;\r | |
45 | my $prtrange2=0;\r | |
46 | my $errormessage = '';\r | |
47 | my $filename = "${General::swroot}/portfw/config";\r | |
48 | my $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 | |
67 | my $disable_all = "0";\r | |
68 | my $enable_all = "0";\r | |
69 | \r | |
70 | if ($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 | |
116 | ERROR:\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 | |
163 | if ($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 | |
275 | UPD_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 | |
323 | if ($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 | |
412 | TOGGLEEXIT:\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 | |
418 | if ($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 | |
446 | if ($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 | |
503 | if ($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 | |
531 | if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})\r | |
532 | {\r | |
533 | undef %cgiparams;\r | |
534 | }\r | |
535 | \r | |
536 | if ($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 | |
558 | if ($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 " </class>\n";\r | |
562 | &Header::closebox();\r | |
563 | }\r | |
564 | \r | |
565 | print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>\n";\r | |
566 | \r | |
567 | if ($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 | |
573 | if ($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 | |
581 | print <<END\r | |
582 | <table>\r | |
583 | <tr>\r | |
584 | <td class='base'>$Lang::tr{'protocol'}: <b>$PROT</b></td>\r | |
585 | <td width='20'> </td>\r | |
586 | <td class='base' align='right'>$Lang::tr{'destination ip'}: </td>\r | |
587 | <td><b>$cgiparams{'DEST_IP'}</b></td>\r | |
588 | <td width='20'> </td>\r | |
589 | <td class='base' align='right'>$Lang::tr{'destination port'}: </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 | |
599 | END\r | |
600 | ;\r | |
601 | } else {\r | |
602 | print <<END\r | |
603 | <table width='100%'>\r | |
604 | <tr>\r | |
605 | <td width='10%'>$Lang::tr{'protocol'}: </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 | |
617 | END\r | |
618 | ;\r | |
619 | open(ALIASES, "$aliasfile") or die 'Unable to open aliases file.';\r | |
620 | while (<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 | |
630 | close(ALIASES);\r | |
631 | print <<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'> </td>\r | |
639 | <td> </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 | |
646 | END\r | |
647 | ;\r | |
648 | }\r | |
649 | \r | |
650 | print <<END\r | |
651 | <table>\r | |
652 | <tr>\r | |
653 | <td class='base'>$Lang::tr{'remark title'} <img src='/blob.gif' alt='*' /> </td>\r | |
654 | <td><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td>\r | |
655 | END\r | |
656 | ;\r | |
657 | unless ($cgiparams{'ACTION'} eq $Lang::tr{'add xtaccess'} && $cgiparams{'ENABLED'} eq "off") {\r | |
658 | print "<td width='20'> </td>";\r | |
659 | print "<td>$Lang::tr{'enabled'} </td><td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\n";\r | |
660 | }\r | |
661 | print <<END\r | |
662 | </tr>\r | |
663 | </table>\r | |
664 | END\r | |
665 | ;\r | |
666 | \r | |
667 | 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")){ \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 | |
672 | print <<END\r | |
673 | <table>\r | |
674 | <tr>\r | |
675 | <td class='base'><font class='boldbase' color='${Header::colourred}'>$Lang::tr{'source network'}</font> <img src='/blob.gif' alt='*' /> </td>\r | |
676 | <td><input type='text' name='ORIG_IP' value='$cgiparams{'ORIG_IP'}' size='15' /></td>\r | |
677 | </tr>\r | |
678 | </table>\r | |
679 | END\r | |
680 | ;\r | |
681 | }\r | |
682 | \r | |
683 | print <<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' /> <font class='base'>$Lang::tr{'this field may be blank'}</font></td>\r | |
688 | END\r | |
689 | ;\r | |
690 | \r | |
691 | \r | |
692 | if ($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'}: </td><td width='5%'><input type='checkbox' name='OVERRIDE' $checked{'OVERRIDE'}{'on'} /></td>\n";\r | |
695 | } else {\r | |
696 | print "<td width='40%'> </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%'> </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 | |
716 | print <<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 | |
722 | END\r | |
723 | ;\r | |
724 | &Header::closebox();\r | |
725 | \r | |
726 | print "</form>\n";\r | |
727 | \r | |
728 | &Header::openbox('100%', 'left', $Lang::tr{'current rules'});\r | |
729 | print <<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'> </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 | |
739 | END\r | |
740 | ;\r | |
741 | \r | |
742 | my $id = 0;\r | |
743 | my $xtaccesscolor = '#F6F4F4';\r | |
744 | open(RULES, "$filename") or die 'Unable to open config file.';\r | |
745 | while (<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 | |
817 | print <<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='=>' /></td>\r | |
821 | <td align='center'>$dstaddr</td>\r | |
822 | <td align='left'> $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 | |
861 | END\r | |
862 | ;\r | |
863 | } else { # external access entry\r | |
864 | print <<END\r | |
865 | <td align='center'> </td>\r | |
866 | \r | |
867 | <td align='left' colspan='4'> <font color='${Header::colourred}'>$Lang::tr{'access allowed'}</font> $temp[8] ($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'> </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 | |
900 | END\r | |
901 | ;\r | |
902 | }\r | |
903 | }\r | |
904 | \r | |
905 | close(RULES);\r | |
906 | \r | |
907 | print "</table>";\r | |
908 | \r | |
909 | # If the fixed lease file contains entries, print Key to action icons\r | |
910 | if ( ! -z "$filename") {\r | |
911 | print <<END\r | |
912 | <table>\r | |
913 | <tr>\r | |
914 | <td class='boldbase'> <b>$Lang::tr{'legend'}: </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> </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> </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> </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> </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 | |
931 | END\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 | |
942 | sub 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 | |
1005 | sub 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 | |
1022 | sub 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 | |
1039 | sub 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 | |
1081 | sub 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 | |
1135 | EXITSUB:\r | |
1136 | return;\r | |
1137 | }\r | |
1138 | \r | |
1139 | # Darren Critchley - Duplicate or overlapping Port range check\r | |
1140 | sub 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 |