Handle hostnames with upper-case letters
[webmin.git] / ipfilter / save_rule.cgi
1 #!/usr/local/bin/perl
2 # Update one firewall rule
3
4 require './ipfilter-lib.pl';
5 &ReadParse();
6 $rules = &get_config();
7 if (!$in{'new'}) {
8         # Get the rule
9         $rule = $rules->[$in{'idx'}];
10         }
11 else {
12         $rule = { 'file' => $config{'ipf_conf'},
13                   'type' => 'ipf' };
14         }
15
16 if ($in{'delete'}) {
17         # Just deleting
18         &lock_file($rule->{'file'});
19         &delete_rule($rule);
20         &flush_file_lines();
21         &unlock_file($rule->{'file'});
22         &webmin_log("delete", "rule", undef, $rule);
23         &redirect("");
24         exit;
25         }
26
27 # Validate and store inputs, starting with action
28 $rule->{'cmt'} = $in{'cmt'};
29 $rule->{'active'} = $in{'active'};
30 $rule->{'action'} = $in{'action'};
31 if ($rule->{'action'} eq "block") {
32         # Parse ICMP block options
33         if ($in{'block_return'}) {
34                 $rule->{'block-return'} = $in{'block_return'};
35                 $rule->{'block-return-dest'} = $in{'block_return_dest'};
36                 }
37         else {
38                 $rule->{'block-return'} = undef;
39                 }
40         }
41 elsif ($rule->{'action'} eq "log") {
42         # Parse logging options
43         &parse_logging_options("log");
44         }
45 elsif ($rule->{'action'} eq "skip") {
46         # Save rule to skip to
47         $in{'skip'} =~ /^\d+$/ || &error($text{'save_eskip'});
48         $rule->{'skip'} = $in{'skip'};
49         }
50 elsif ($rule->{'action'} eq "call") {
51         # Save function to call
52         $in{'call'} =~ /^\S+$/ || &error($text{'save_ecall'});
53         $rule->{'call'} = $in{'call'};
54         $rule->{'call-now'} = $in{'call_now'};
55         }
56
57 # Parse source and destination
58 $rule->{'all'} = $in{'all'};
59 if (!$in{'all'}) {
60         &parse_object_input($rule, "from");
61         &parse_object_input($rule, "to");
62         }
63
64 # Parse other conditions
65 $rule->{'dir'} = $in{'dir'};
66 $rule->{'proto'} = $in{'proto'};
67 if ($in{'tos_def'}) {
68         delete($rule->{'tos'});
69         }
70 else {
71         &valid_hexdec($in{'tos'}) || &error($text{'save_etos'});
72         $rule->{'tos'} = $in{'tos'};
73         }
74 if ($in{'ttl_def'}) {
75         delete($rule->{'ttl'});
76         }
77 else {
78         &valid_hexdec($in{'ttl'}) || &error($text{'save_ettl'});
79         $rule->{'ttl'} = $in{'ttl'};
80         }
81 if ($in{'on'} eq "") {
82         delete($rule->{'on'});
83         }
84 else {
85         $rule->{'on'} = &parse_interface_choice("on", $text{'save_eon'});
86         }
87 if ($in{'flags1_def'}) {
88         delete($rule->{'flags1'});
89         delete($rule->{'flags2'});
90         }
91 else {
92         $in{'flags1'} =~ /^[FSRPAU]+$/ || &error($text{'save_eflags1'});
93         $in{'flags2'} =~ /^[FSRPAU]*$/ || &error($text{'save_eflags2'});
94         $rule->{'flags1'} = $in{'flags1'};
95         $rule->{'flags2'} = $in{'flags2'};
96         }
97 if (!$in{'icmptype'}) {
98         delete($rule->{'icmp-type'});
99         }
100 else {
101         lc($rule->{'proto'}) eq "icmp" || &error($text{'save_eicmp'});
102         $rule->{'icmp-type'} = $in{'icmptype'};
103         $rule->{'icmp-type-code'} = $in{'icmpcode'};
104         }
105
106 # Parse action options
107 $rule->{'quick'} = $in{'quick'};
108 $rule->{'olog'} = $in{'olog'};
109 if ($in{'olog'}) {
110         &parse_logging_options("olog");
111         }
112 if ($in{'tag'}) {
113         &valid_hexdec($in{'tagid'}) || &error($text{'save_etag'});
114         $rule->{'tag'} = $in{'tagid'};
115         }
116 else {
117         delete($rule->{'tag'});
118         }
119 if ($in{'dup_to'}) {
120         $rule->{'dup-to'} = &parse_interface_choice("dup_toiface",
121                                                     $text{'save_edupto'});
122         if ($in{'dup_toip'}) {
123                 &check_ipaddress($in{'dup_toip'}) ||
124                         &error($text{'save_eduptoip'});
125                 $rule->{'dup-to'} .= ":".$in{'dup_toip'};
126                 }
127         }
128 else {
129         delete($rule->{'dup-to'});
130         }
131 if ($in{'fastroute'}) {
132         $rule->{'fastroute'} = &parse_interface_choice("fastrouteiface",
133                                                        $text{'save_eto'});
134         if ($in{'fastrouteip'}) {
135                 &check_ipaddress($in{'fastrouteip'}) ||
136                         &error($text{'save_etoip'});
137                 }
138         $rule->{'fastroute-ip'} = $in{'fastrouteip'};
139         }
140 else {
141         delete($rule->{'fastroute'});
142         }
143 if ($in{'reply_to'}) {
144         $rule->{'reply-to'} = &parse_interface_choice("reply_toiface",
145                                            $text{'save_ereplyto'});
146         $rule->{'reply-to'} =~ /^[a-z]+\d*/ || &error($text{'save_ereply_to'});
147         if ($in{'reply_toip'}) {
148                 &check_ipaddress($in{'reply_toip'}) ||
149                         &error($text{'save_ereplytoip'});
150                 }
151         $rule->{'reply-to-ip'} = $in{'reply_toip'};
152         }
153 else {
154         delete($rule->{'reply-to'});
155         }
156 if ($in{'keep'}) {
157         $rule->{'keep'} = $in{'keepmode'};
158         }
159 else {
160         delete($rule->{'keep'});
161         }
162
163 &lock_file($rule->{'file'});
164 if ($in{'new'}) {
165         if ($in{'before'} ne '') {
166                 # Insert before some rule
167                 $before = $rules->[$in{'before'}];
168                 &insert_rule($rule, $before);
169                 }
170         elsif ($in{'after'} ne '') {
171                 if ($in{'after'} == @$rules - 1) {
172                         &create_rule($rule);    # at end anyway
173                         }
174                 else {
175                         # Insert after some rule
176                         $before = $rules->[$in{'after'}+1];
177                         &insert_rule($rule, $before);
178                         }
179                 }
180         else {
181                 # Append to end
182                 &create_rule($rule);
183                 }
184         }
185 else {
186         &modify_rule($rule);
187         }
188 &flush_file_lines();
189 &unlock_file($rule->{'file'});
190 &copy_to_cluster();
191 &webmin_log($in{'new'} ? "create" : "modify", "rule", undef, $rule);
192
193 &redirect("");
194
195 # parse_logging_options(prefix)
196 sub parse_logging_options
197 {
198 local $pfx = $_[0];
199 if ($in{$pfx."_pri"}) {
200         if ($in{$pfx."_fac"}) {
201                 $rule->{$pfx."-level"} = $in{$pfx."_fac"}.".".$in{$pfx."_pri"};
202                 }
203         else {
204                 $rule->{$pfx."-level"} = $in{$pfx."_pri"};
205                 }
206         }
207 else {
208         delete($rule->{$pfx."-level"});
209         }
210 $rule->{$pfx."-body"} = $in{$pfx."_body"};
211 $rule->{$pfx."-first"} = $in{$pfx."_first"};
212 $rule->{$pfx."-or-block"} = $in{$pfx."_orblock"};
213 }
214
215