Firewall/Host: add permissions
[pve-firewall.git] / src / PVE / API2 / Firewall / Host.pm
1 package PVE::API2::Firewall::Host;
2
3 use strict;
4 use warnings;
5 use PVE::JSONSchema qw(get_standard_option);
6 use PVE::RPCEnvironment;
7
8 use PVE::Firewall;
9 use PVE::API2::Firewall::Rules;
10
11 use Data::Dumper; # fixme: remove
12
13 use base qw(PVE::RESTHandler);
14
15 __PACKAGE__->register_method ({
16     subclass => "PVE::API2::Firewall::HostRules",  
17     path => 'rules',
18 });
19
20 __PACKAGE__->register_method({
21     name => 'index',
22     path => '',
23     method => 'GET',
24     permissions => { user => 'all' },
25     description => "Directory index.",
26     parameters => {
27         additionalProperties => 0,
28         properties => {
29             node => get_standard_option('pve-node'),
30         },
31     },
32     returns => {
33         type => 'array',
34         items => {
35             type => "object",
36             properties => {},
37         },
38         links => [ { rel => 'child', href => "{name}" } ],
39     },
40     code => sub {
41         my ($param) = @_;
42
43         my $result = [
44             { name => 'rules' },
45             { name => 'options' },
46             { name => 'log' },
47             ];
48
49         return $result;
50     }});
51
52 my $option_properties = {
53     enable => {
54         description => "Enable host firewall rules.",
55         type => 'boolean',
56         optional => 1,
57     },
58     log_level_in =>  get_standard_option('pve-fw-loglevel', {
59         description => "Log level for incoming traffic." }),
60     log_level_out =>  get_standard_option('pve-fw-loglevel', {
61         description => "Log level for outgoing traffic." }),
62     tcp_flags_log_level =>  get_standard_option('pve-fw-loglevel', {
63         description => "Log level for illegal tcp flags filter." }),
64     smurf_log_level =>  get_standard_option('pve-fw-loglevel', {
65         description => "Log level for SMURFS filter." }),
66     nosmurfs => {
67         description => "Enable SMURFS filter.",
68         type => 'boolean',
69         optional => 1,
70     },
71     tcpflags => {
72         description => "Filter illegal combinations of TCP flags.",
73         type => 'boolean',
74         optional => 1,
75     },
76     nf_conntrack_max => {
77         description => "Maximum number of tracked connections.",
78         type => 'integer',
79         optional => 1,
80         minimum => 32768,
81     },
82     nf_conntrack_tcp_timeout_established => {
83         description => "Conntrack established timeout.",
84         type => 'integer',
85         optional => 1,
86         minimum => 7875,
87     }
88 };
89
90 my $add_option_properties = sub {
91     my ($properties) = @_;
92
93     foreach my $k (keys %$option_properties) {
94         $properties->{$k} = $option_properties->{$k};
95     }
96     
97     return $properties;
98 };
99
100
101 __PACKAGE__->register_method({
102     name => 'get_options',
103     path => 'options',
104     method => 'GET',
105     description => "Get host firewall options.",
106     proxyto => 'node',
107     permissions => {
108         check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
109     },
110     parameters => {
111         additionalProperties => 0,
112         properties => {
113             node => get_standard_option('pve-node'),
114         },
115     },
116     returns => {
117         type => "object",
118         #additionalProperties => 1,
119         properties => $option_properties,
120     },
121     code => sub {
122         my ($param) = @_;
123
124         my $hostfw_conf = PVE::Firewall::load_hostfw_conf();
125
126         return PVE::Firewall::copy_opject_with_digest($hostfw_conf->{options});
127     }});
128
129 __PACKAGE__->register_method({
130     name => 'set_options',
131     path => 'options',
132     method => 'PUT',
133     description => "Set Firewall options.",
134     protected => 1,
135     proxyto => 'node',
136     permissions => {
137         check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
138     },
139     parameters => {
140         additionalProperties => 0,
141         properties => &$add_option_properties({
142             node => get_standard_option('pve-node'),
143             delete => {
144                 type => 'string', format => 'pve-configid-list',
145                 description => "A list of settings you want to delete.",
146                 optional => 1,
147             },
148             digest => get_standard_option('pve-config-digest'),
149         }),
150     },
151     returns => { type => "null" },
152     code => sub {
153         my ($param) = @_;
154
155         my $hostfw_conf = PVE::Firewall::load_hostfw_conf();
156
157         my (undef, $digest) = PVE::Firewall::copy_opject_with_digest($hostfw_conf->{options});
158         PVE::Tools::assert_if_modified($digest, $param->{digest});
159
160         if ($param->{delete}) {
161             foreach my $opt (PVE::Tools::split_list($param->{delete})) {
162                 raise_param_exc({ delete => "no such option '$opt'" }) 
163                     if !$option_properties->{$opt};
164                 delete $hostfw_conf->{options}->{$opt};
165             }
166         }
167
168         if (defined($param->{enable})) {
169             $param->{enable} = $param->{enable} ? 1 : 0;
170         }
171
172         foreach my $k (keys %$option_properties) {
173             next if !defined($param->{$k});
174             $hostfw_conf->{options}->{$k} = $param->{$k}; 
175         }
176
177         PVE::Firewall::save_hostfw_conf($hostfw_conf);
178
179         return undef;
180     }});
181
182 __PACKAGE__->register_method({
183     name => 'log', 
184     path => 'log', 
185     method => 'GET',
186     description => "Read firewall log",
187     proxyto => 'node',
188     permissions => {
189         check => ['perm', '/nodes/{node}', [ 'Sys.Syslog' ]],
190     },
191     protected => 1,
192     parameters => {
193         additionalProperties => 0,
194         properties => {
195             node => get_standard_option('pve-node'),
196             start => {
197                 type => 'integer',
198                 minimum => 0,
199                 optional => 1,
200             },
201             limit => {
202                 type => 'integer',
203                 minimum => 0,
204                 optional => 1,
205             },
206         },
207     },
208     returns => {
209         type => 'array',
210         items => { 
211             type => "object",
212             properties => {
213                 n => {
214                   description=>  "Line number",
215                   type=> 'integer',
216                 },
217                 t => {
218                   description=>  "Line text",
219                   type => 'string',
220                 }
221             }
222         }
223     },
224     code => sub {
225         my ($param) = @_;
226
227         my $rpcenv = PVE::RPCEnvironment::get();
228         my $user = $rpcenv->get_user();
229         my $node = $param->{node};
230
231         my ($count, $lines) = PVE::Tools::dump_logfile("/var/log/pve-firewall.log", $param->{start}, $param->{limit});
232
233         $rpcenv->set_result_attrib('total', $count);
234             
235         return $lines; 
236     }});
237
238 1;