File Coverage

blib/lib/Net/SecurityCenter/API/Analysis.pm
Criterion Covered Total %
statement 15 144 10.4
branch 0 40 0.0
condition n/a
subroutine 5 16 31.2
pod 6 6 100.0
total 26 206 12.6


line stmt bran cond sub pod time code
1             package Net::SecurityCenter::API::Analysis;
2              
3 2     2   2385 use warnings;
  2         5  
  2         78  
4 2     2   22 use strict;
  2         4  
  2         43  
5              
6 2     2   11 use Carp;
  2         4  
  2         127  
7              
8 2     2   17 use parent 'Net::SecurityCenter::Base';
  2         16  
  2         17  
9              
10 2     2   160 use Net::SecurityCenter::Utils qw(:all);
  2         4  
  2         4531  
11              
12             our $VERSION = '0.311';
13              
14             my $common_template = {
15             tool => {
16             allow => [
17             'cceipdetail', 'cveipdetail', 'iavmipdetail', 'iplist',
18             'listmailclients', 'listservices', 'listos', 'listsoftware',
19             'listsshservers', 'listvuln', 'listwebclients', 'listwebservers',
20             'sumasset', 'sumcce', 'sumclassa', 'sumclassb',
21             'sumclassc', 'sumcve', 'sumdnsname', 'sumfamily',
22             'sumiavm', 'sumid', 'sumip', 'summsbulletin',
23             'sumport', 'sumprotocol', 'sumremediation', 'sumseverity',
24             'sumuserresponsibility', 'trend', 'vulndetails', 'vulnipdetail',
25             'vulnipsummary'
26             ],
27             },
28             view => {
29             allow => [ 'all', 'new', 'patched' ]
30             },
31             limit => {
32             allow => qr/^\d+$/,
33             default => 1000,
34             },
35             page => {
36             allow => qr/^(\d+|all)$/,
37             default => 'all',
38             },
39             sort_dir => {
40             allow => [ 'ASC', 'DESC' ],
41             filter => sub { uc $_[0] },
42             },
43             scan_id => {
44             allow => qr/^\d+$/,
45             },
46             lce_id => {
47             allow => qr/^\d+$/,
48             },
49             query_id => {
50             allow => qr/^\d+$/,
51             },
52             date => {
53             allow => qr/^(\d+|all)$/,
54             }
55             };
56              
57             #-------------------------------------------------------------------------------
58             # METHODS
59             #-------------------------------------------------------------------------------
60              
61             sub get {
62              
63 0     0 1   my ( $self, %args ) = @_;
64              
65             my $tmpl = {
66             type => {
67             allow => [ 'scLog', 'vuln', 'event', 'mobile', 'user' ],
68             required => 1,
69             },
70             tool => $common_template->{'tool'},
71             source => {
72             allow => [ 'cumulative', 'individual', 'archive', 'patched', 'lce' ],
73             },
74             sort_dir => $common_template->{'sort_dir'},
75             sort_field => {},
76             view => $common_template->{'view'},
77             scan_id => $common_template->{'scan_id'},
78             lce_id => $common_template->{'lce_id'},
79             query_id => $common_template->{'query_id'},
80             query => {},
81             filters => {},
82             date => $common_template->{'date'},
83             limit => $common_template->{'limit'},
84 0           page => $common_template->{'page'},
85             download => {},
86             columns => {},
87             };
88              
89 0           my $params = sc_check_params( $tmpl, \%args );
90              
91 0           my $scan_id = delete( $params->{'scan_id'} );
92 0           my $query_id = delete( $params->{'query_id'} );
93 0           my $lce_id = delete( $params->{'lce_id'} );
94 0           my $tool = delete( $params->{'tool'} );
95 0           my $type = delete( $params->{'type'} );
96 0           my $filters = delete( $params->{'filters'} );
97 0           my $date = delete( $params->{'date'} );
98 0           my $source = delete( $params->{'source'} );
99 0           my $sort_dir = delete( $params->{'sort_dir'} );
100 0           my $sort_field = delete( $params->{'sort_field'} );
101 0           my $view = delete( $params->{'view'} );
102              
103             # Fallback sourceType param
104 0 0         if ( defined( $params->{'source_type'} ) ) {
105 0           $type = $params->{'source_type'};
106             }
107              
108             # Pagination
109 0           my $count = 0;
110 0           my $page = delete( $params->{'page'} );
111 0           my $limit = delete( $params->{'limit'} );
112 0           my $total = $limit;
113              
114             # For download API
115 0           my $download = delete( $params->{'download'} );
116 0           my $columns = delete( $params->{'columns'} );
117              
118 0           my $analysis_params = {
119             type => $type,
120             query => {
121             filters => [],
122             type => $type,
123             }
124             };
125              
126 0           my @results = ();
127              
128             # If not defined the query build the query using "filters" argument
129 0 0         if ($filters) {
130              
131 0 0         if ( ref $filters->[0] eq 'ARRAY' ) {
132              
133 0           foreach my $filter ( @{$filters} ) {
  0            
134              
135             push(
136 0           @{ $analysis_params->{'query'}->{'filters'} },
  0            
137             {
138             'filterName' => $filter->[0],
139             'operator' => $filter->[1],
140             'value' => $filter->[2],
141             'type' => $type,
142             }
143             );
144             }
145              
146             } else {
147 0           $analysis_params->{'query'}->{'filters'} = $filters;
148             }
149              
150             }
151              
152 0 0         if ($query_id) {
153 0           $analysis_params->{'query'}->{'id'} = $query_id;
154             }
155              
156 0 0         if ($source) {
157 0           $analysis_params->{'sourceType'} = $source;
158             }
159              
160 0 0         if ($tool) {
161 0           $analysis_params->{'query'}->{'tool'} = $tool;
162             }
163              
164 0 0         if ($sort_dir) {
165 0           $analysis_params->{'sortDir'} = $sort_dir;
166             }
167              
168 0 0         if ($sort_field) {
169 0           $analysis_params->{'sortField'} = $sort_field;
170             }
171              
172 0 0         if ($view) {
173 0           $analysis_params->{'view'} = $view;
174             }
175              
176 0 0         if ($scan_id) {
177 0           $analysis_params->{'scanID'} = $scan_id;
178             }
179              
180             # Add pagination
181 0 0         if ( $page eq 'all' ) {
182 0           $analysis_params->{'query'}->{'startOffset'} = 0;
183 0           $analysis_params->{'query'}->{'endOffset'} = $limit;
184             } else {
185 0           $analysis_params->{'query'}->{'startOffset'} = $page * $limit;
186 0           $analysis_params->{'query'}->{'endOffset'} = ( $page + 1 ) * $limit;
187             }
188              
189             # Add date params for "scLog" analysis type
190 0 0         if ( $type eq 'scLog' ) {
191 0           $analysis_params->{'date'} = $date;
192             }
193              
194             # Download API
195 0 0         if ($download) {
196              
197 0           my @columns_params = ();
198              
199 0           foreach my $column ( split( /,/, $columns ) ) {
200 0           push( @columns_params, { 'name' => $column } );
201             }
202              
203 0           $analysis_params->{'columns'} = \@columns_params;
204              
205             # TODO check offset
206 0           my $result = $self->client->post( '/analysis/download', $analysis_params );
207 0           return $result;
208             }
209              
210 0           while ( $total > $count ) {
211 0           my $result = $self->client->post( '/analysis', $analysis_params );
212              
213 0 0         return if ( !$result );
214              
215 0           push( @results, @{ $result->{'results'} } );
  0            
216              
217 0           $total = $result->{'totalRecords'};
218              
219 0 0         if ( $page eq 'all' ) {
220 0           $count = $result->{'endOffset'};
221 0           $analysis_params->{'query'}->{'startOffset'} = $count;
222 0           $analysis_params->{'query'}->{'endOffset'} = $count + $limit;
223             } else {
224 0           $count = $total;
225             }
226              
227             }
228              
229 0           return \@results;
230              
231             }
232              
233             #-------------------------------------------------------------------------------
234              
235             sub download {
236              
237 0     0 1   my ( $self, %args ) = @_;
238              
239 0           $args{'download'} = 1;
240              
241 0           return $self->get(%args);
242              
243             }
244              
245             #-------------------------------------------------------------------------------
246              
247             sub get_vulnerabilities {
248              
249 0     0 1   my ( $self, %args ) = @_;
250              
251             my $tmpl = {
252             query_id => $common_template->{'query_id'},
253             sort_dir => $common_template->{'sort_dir'},
254             sort_field => {},
255             source => {
256             allow => [ 'individual', 'cumulative', 'patched' ],
257             },
258             view => $common_template->{'view'},
259             scan_id => $common_template->{'scan_id'},
260             tool => {
261             allow => $common_template->{'tool'}->{'allow'},
262             default => 'vulndetails',
263             },
264             page => $common_template->{'page'},
265 0           limit => $common_template->{'limit'},
266             filters => {}
267             };
268              
269 0           my $params = sc_check_params( $tmpl, \%args );
270              
271 0           $params->{'type'} = 'vuln';
272              
273 0           return $self->get( %{$params} );
  0            
274              
275             }
276              
277             #-------------------------------------------------------------------------------
278              
279             sub get_events {
280              
281 0     0 1   my ( $self, %args ) = @_;
282              
283             my $tmpl = {
284             query_id => $common_template->{'query_id'},
285             sort_dir => $common_template->{'sort_dir'},
286             sort_field => {},
287             source => {
288             allow => [ 'lce', 'archive' ],
289             },
290             lce_id => $common_template->{'lce_id'},
291             view => {},
292             limit => $common_template->{'limit'},
293 0           page => $common_template->{'page'},
294             tool => {
295             allow => [
296             'listdata', 'sumasset', 'sumclassa', 'sumclassb', 'sumclassc', 'sumconns',
297             'sumdate', 'sumdstip', 'sumevent', 'sumevent2', 'sumip', 'sumport',
298             'sumprotocol', 'sumsrcip', 'sumtime', 'sumtype', 'sumuser', 'syslog',
299             'timedist'
300             ],
301             default => 'syslog'
302             }
303             };
304              
305 0           my $params = sc_check_params( $tmpl, \%args );
306              
307 0           $params->{'type'} = 'event';
308              
309 0           return $self->get( %{$params} );
  0            
310              
311             }
312              
313             #-------------------------------------------------------------------------------
314              
315             sub get_mobile {
316              
317 0     0 1   my ( $self, %args ) = @_;
318              
319             my $tmpl = {
320             query_id => $common_template->{'query_id'},
321             sort_dir => $common_template->{'sort_dir'},
322             sort_field => {},
323             tool => {
324             allow => [
325             'listvuln', 'sumdeviceid', 'summdmuser', 'summodel',
326             'sumoscpe', 'sumpluginid', 'sumseverity', 'vulndetails'
327             ],
328             default => 'vulndetails'
329             },
330             limit => $common_template->{'limit'},
331 0           page => $common_template->{'page'},
332             };
333              
334 0           my $params = sc_check_params( $tmpl, \%args );
335              
336 0           $params->{'type'} = 'mobile';
337              
338 0           return $self->get( %{$params} );
  0            
339              
340             }
341              
342             #-------------------------------------------------------------------------------
343              
344             sub get_log {
345              
346 0     0 1   my ( $self, %args ) = @_;
347              
348             my $severity_filter = sub {
349              
350 0     0     my $severity = { 'INFO' => 0, 'WARNING' => 1, 'CRITICAL' => 2 };
351              
352             return {
353             filterName => 'severity',
354             value => {
355 0           id => $severity->{ uc( $_[0] ) },
356             operator => '=',
357             name => uc( $_[0] ),
358             }
359             };
360              
361 0           };
362              
363             my $keyword_filter = sub {
364 0     0     return { filterName => 'keyword', operator => '=', value => $_[0] };
365 0           };
366              
367             my $module_filter = sub {
368 0     0     return { filterName => 'module', operator => '=', value => $_[0] };
369 0           };
370              
371             my $organization_filter = sub {
372 0     0     return { filterName => 'module', operator => '=', value => { id => $_[0] } };
373 0           };
374              
375             my $initiator_filter = sub {
376 0     0     return { filterName => 'initiator', operator => '=', value => { id => $_[0] } };
377 0           };
378              
379             my $tmpl = {
380             severity => {
381             allow => [ 'info', 'warning', 'critical' ],
382             post_filter => \&$severity_filter,
383             },
384             keywords => {
385             filter => \&$keyword_filter,
386             },
387             module => {
388             filter => \&$module_filter,
389             },
390             organization => {
391             filter => \&$organization_filter,
392             },
393             initiator => {
394             filter => \&$initiator_filter,
395             },
396             date => $common_template->{'date'},
397             limit => $common_template->{'limit'},
398 0           page => $common_template->{'page'},
399             };
400              
401 0           my $params = sc_check_params( $tmpl, \%args );
402              
403             my $analysis_params = {
404             type => 'scLog',
405 0           date => $params->{'date'},
406             filters => [],
407             };
408              
409 0           my $severity = delete( $params->{'severity'} );
410 0           my $keyword = delete( $params->{'keyword'} );
411 0           my $module = delete( $params->{'module'} );
412 0           my $organization = delete( $params->{'orgwnization'} );
413 0           my $initiator = delete( $params->{'initiator'} );
414              
415 0 0         if ($severity) {
416 0           push( @{ $analysis_params->{'filters'} }, $severity );
  0            
417             }
418              
419 0 0         if ($keyword) {
420 0           push( @{ $analysis_params->{'filters'} }, $keyword );
  0            
421             }
422              
423 0 0         if ($module) {
424 0           push( @{ $analysis_params->{'filters'} }, $module );
  0            
425             }
426              
427 0 0         if ($organization) {
428 0           push( @{ $analysis_params->{'filters'} }, $organization );
  0            
429             }
430              
431 0 0         if ($initiator) {
432 0           push( @{ $analysis_params->{'filters'} }, $initiator );
  0            
433             }
434              
435 0           return $self->get( %{$analysis_params} );
  0            
436              
437             }
438              
439             #-------------------------------------------------------------------------------
440              
441             1;
442              
443             __END__