File Coverage

blib/lib/Net/OpenVAS/OMP.pm
Criterion Covered Total %
statement 33 101 32.6
branch 0 22 0.0
condition 0 16 0.0
subroutine 11 19 57.8
pod 3 3 100.0
total 47 161 29.1


line stmt bran cond sub pod time code
1             package Net::OpenVAS::OMP;
2              
3 1     1   8 use strict;
  1         2  
  1         28  
4 1     1   4 use warnings;
  1         2  
  1         22  
5 1     1   631 use utf8;
  1         15  
  1         4  
6 1     1   36 use feature ':5.10';
  1         2  
  1         94  
7              
8 1     1   4 use Carp;
  1         2  
  1         56  
9 1     1   849 use IO::Socket::SSL;
  1         87233  
  1         8  
10 1     1   1116 use XML::Simple qw( :strict );
  1         9803  
  1         7  
11              
12 1     1   575 use Net::OpenVAS::Error;
  1         3  
  1         38  
13 1     1   478 use Net::OpenVAS::OMP::Response;
  1         3  
  1         31  
14 1     1   462 use Net::OpenVAS::OMP::Request;
  1         3  
  1         263  
15              
16             our $VERSION = '0.100';
17              
18             sub import {
19              
20 0     0     my ( $class, @flags ) = @_;
21              
22 0 0         if ( grep( /^-commands$/, @_ ) ) {
23 0           my @commands = qw(
24             authenticate commands create_agent create_alert create_asset create_config
25             create_credential create_filter create_group create_note create_override
26             create_permission create_port_list create_port_range create_report
27             create_report_format create_role create_scanner create_schedule create_tag
28             create_target create_task create_user delete_agent delete_asset
29             delete_config delete_alert delete_credential delete_filter delete_group
30             delete_note delete_override delete_report delete_permission delete_port_list
31             delete_port_range delete_report_format delete_role delete_scanner
32             delete_schedule delete_tag delete_target delete_task delete_user
33             describe_auth empty_trashcan get_agents get_configs get_aggregates
34             get_alerts get_assets get_credentials get_feeds get_filters get_groups
35             get_info get_notes get_nvts get_nvt_families get_overrides get_permissions
36             get_port_lists get_preferences get_reports get_report_formats get_results
37             get_roles get_scanners get_schedules get_settings get_system_reports
38             get_tags get_targets get_tasks get_users get_version help modify_agent
39             modify_alert modify_asset modify_auth modify_config modify_credential
40             modify_filter modify_group modify_note modify_override modify_permission
41             modify_port_list modify_report modify_report_format modify_role
42             modify_scanner modify_schedule modify_setting modify_target modify_tag
43             modify_task modify_user move_task restore resume_task run_wizard start_task
44             stop_task sync_cert sync_feed sync_config sync_scap test_alert verify_agent
45             verify_report_format verify_scanner
46             );
47              
48 0           foreach my $command (@commands) {
49              
50             my $sub = sub {
51 0     0     my ( $self, %hash ) = @_;
52 0           return $self->command( $command, \%hash );
53 0           };
54              
55 1     1   8 no strict 'refs'; ## no critic
  1         2  
  1         1107  
56 0           *{$command} = $sub;
  0            
57              
58             }
59             }
60              
61             }
62              
63             sub new {
64              
65 0     0 1   my ( $class, %options ) = @_;
66              
67 0   0       my $openvas = delete( $options{'host'} ) || undef;
68 0   0       my $ssl_opts = delete( $options{'ssl_options'} ) || {};
69 0   0       my $logger = delete( $options{'logger'} ) || undef;
70 0   0       my $timeout = delete( $options{'timeout'} ) || 60;
71 0           my $username = delete( $options{'username'} );
72 0           my $password = delete( $options{'password'} );
73              
74 0 0         if ( !$openvas ) {
75 0           $@ = 'Specify valid OpenVAS hostname or IP address and port (eg. 127.0.0.1:9330)'; ## no critic
76 0           return;
77             }
78              
79 0 0 0       if ( !$username || !$password ) {
80 0           $@ = 'Specify OpenVAS username and password'; ## no critic
81 0           return;
82             }
83              
84 0           my ( $host, $port ) = split /:/, $openvas;
85              
86 0   0       $port ||= 9390;
87              
88 0           my $self = {
89             host => $host,
90             port => $port,
91             options => \%options,
92             logger => $logger,
93             timeout => $timeout,
94             username => $username,
95             password => $password,
96             socket => undef,
97             error => undef,
98             };
99              
100 0           bless $self, $class;
101              
102 0 0         if ( !$self->_connect ) {
103 0           $@ = $self->error;
104 0           return;
105             }
106              
107 0           return $self;
108              
109             }
110              
111             sub _connect {
112              
113 0     0     my ($self) = @_;
114              
115             my %ssl = (
116             PeerHost => $self->{'host'},
117             PeerPort => $self->{'port'},
118 0           Timeout => $self->{'timeout'},
119             Proto => 'tcp',
120             SSL_verify_mode => 0,
121             );
122              
123             my $socket = IO::Socket::SSL->new(%ssl)
124             or croak( sprintf 'Unable to connect to OpenVAS via %s:%s (%s - %s)',
125 0 0         $self->{'host'}, $self->{'port'}, $!, $SSL_ERROR );
126              
127 0           $self->{'socket'} = \*$socket;
128              
129             my $request = Net::OpenVAS::OMP::Request->new(
130             command => 'authenticate',
131             arguments => {
132             'credentials' => [
133             {
134             'username' => [ $self->{'username'} ],
135 0           'password' => [ $self->{'password'} ]
136             }
137             ]
138             }
139             );
140              
141 0           $self->{'socket'}->syswrite( $request->raw );
142              
143 0           my $omp_response = $self->_read;
144 0           my $response = Net::OpenVAS::OMP::Response->new(
145             request => $request,
146             response => $omp_response
147             );
148              
149 0 0         if ( !$response->error ) {
150 0           return 1;
151             } else {
152 0           $self->{'error'} = $response->error;
153             }
154              
155 0           return;
156              
157             }
158              
159             sub _read {
160              
161 0     0     my ($self) = @_;
162              
163 0           my $response;
164              
165 0           while ( my $length = $self->{'socket'}->sysread( my $buffer, 1024 ) ) {
166 0           $response .= $buffer;
167 0 0 0       last if ( $length < 1024 || $length == 0 );
168             }
169              
170 0           return $response;
171              
172             }
173              
174             sub _write {
175              
176 0     0     my ( $self, $data ) = @_;
177              
178 0           $self->_connect;
179              
180 0           $self->{'socket'}->syswrite($data);
181 0           my $response = $self->_read;
182              
183 0           return $response;
184              
185             }
186              
187             sub command {
188              
189 0     0 1   my ( $self, $command, $arguments ) = @_;
190              
191 0           my $request = Net::OpenVAS::OMP::Request->new(
192             command => $command,
193             arguments => $arguments
194             );
195              
196 0 0         if ( defined( $self->{'logger'} ) ) {
197 0           $self->{'logger'}->debug( $request->raw );
198             }
199              
200 0           my $omp_response = $self->_write( $request->raw );
201              
202 0 0         if ( defined( $self->{'logger'} ) ) {
203 0           $self->{'logger'}->debug($omp_response);
204             }
205              
206 0           my $response = Net::OpenVAS::OMP::Response->new(
207             request => $request,
208             response => $omp_response
209             );
210              
211 0 0         if ( $response->error ) {
212 0           $self->{'error'} = $response->error;
213             }
214              
215 0           return $response;
216              
217             }
218              
219             sub error {
220              
221 0     0 1   my ( $self, $message, $code ) = @_;
222              
223 0 0         if ( defined $message ) {
224 0           $self->{'error'} = Net::OpenVAS::Error->new( $message, $code );
225             }
226              
227 0           return $self->{'error'};
228              
229             }
230              
231             1;
232             =head1 NAME
233              
234             Net::OpenVAS - Perl extension for OpenVAS Scanner
235              
236             =head1 SYNOPSIS
237              
238             use Net::OpenVAS qw( -commands );
239              
240             my $openvas = Net::OpenVAS->new(
241             host => 'localhost:9390',
242             username => 'admin',
243             password => 's3cr3t'
244             ) or die "ERROR: $@";
245              
246             my $task = $openvas->create_task(
247             name => [ 'Scan created via Net::OpenVAS' ],
248             target => { id => 'a800d5c7-3493-4f73-8401-c42e5f2bfc9c' },
249             config => { id => 'daba56c8-73ec-11df-a475-002264764cea' }
250             );
251              
252             if ( $task->is_created ) {
253              
254             my $task_id = $task->result->{id};
255              
256             say "Created task $task_id";
257              
258             my $task_start = $openvas->start_task( task_id => $task_id );
259              
260             say "Task $task_id started (" . $task_start->status_text . ')' if ( $task_start->is_accepted );
261              
262             }
263              
264             if ( $openvas->error ) {
265             say "ERROR: " . $openvas->error;
266             }
267              
268             =head1 DESCRIPTION
269              
270             This module provides Perl scripts easy way to interface the OMP (OpenVAS Management Protocol) of OpenVAS.
271              
272             For more information about the OPM follow the online documentation:
273              
274             L
275              
276              
277             =head1 CONSTRUCTOR
278              
279             =head2 Net::OpenVAS::OMP->new ( host => $host, username => $username, password => $password [, logger => $logger, timeout => 60, ssl_options => \%ssl_options ] )
280              
281             Create a new instance of L.
282              
283             Params:
284              
285             =over 4
286              
287             =item * C : OpenVAS host (and port)
288              
289             =item * C, C : OpenVAS Credentials
290              
291             =item * C : Request timeout in seconds (default is 60) If a socket open,
292             read or write takes longer than the timeout, an exception is thrown.
293              
294             =item * C : A hashref of C options to pass through to L.
295              
296             =item * C : A logger instance (eg. L or L for log
297             the REST request and response messages.
298              
299             =back
300              
301              
302             =head1 METHODS
303              
304             =head2 $openvas->command ( $command [, \%arguments ] )
305              
306             Execute a command to OpenVAS via OMP and return L class instance.
307              
308             my $task = $openvas->command( 'get_tasks', task_id => '46f15597-b721-403c-96a1-cce439af63a7' );
309              
310             =head2 $openvas->error
311              
312             Return L class instance.
313              
314             =head2 COMMANDS HELPER
315              
316             L provide a flag (C<-commands>) for import all OpenVAS OMP commands.
317              
318             use Net::OpenVAS::OMP;
319             [...]
320             my $version = $openvas->command('get_version');
321              
322             use Net::OpenVAS::OMP qw( -commands );
323             [...]
324             my $version = $openvas->get_version;
325              
326             Available commands:
327              
328             authenticate commands create_agent create_alert create_asset create_config
329             create_credential create_filter create_group create_note create_override
330             create_permission create_port_list create_port_range create_report
331             create_report_format create_role create_scanner create_schedule create_tag
332             create_target create_task create_user delete_agent delete_asset
333             delete_config delete_alert delete_credential delete_filter delete_group
334             delete_note delete_override delete_report delete_permission delete_port_list
335             delete_port_range delete_report_format delete_role delete_scanner
336             delete_schedule delete_tag delete_target delete_task delete_user
337             describe_auth empty_trashcan get_agents get_configs get_aggregates
338             get_alerts get_assets get_credentials get_feeds get_filters get_groups
339             get_info get_notes get_nvts get_nvt_families get_overrides get_permissions
340             get_port_lists get_preferences get_reports get_report_formats get_results
341             get_roles get_scanners get_schedules get_settings get_system_reports
342             get_tags get_targets get_tasks get_users get_version help modify_agent
343             modify_alert modify_asset modify_auth modify_config modify_credential
344             modify_filter modify_group modify_note modify_override modify_permission
345             modify_port_list modify_report modify_report_format modify_role
346             modify_scanner modify_schedule modify_setting modify_target modify_tag
347             modify_task modify_user move_task restore resume_task run_wizard start_task
348             stop_task sync_cert sync_feed sync_config sync_scap test_alert verify_agent
349             verify_report_format verify_scanner
350              
351             =head1 SUPPORT
352              
353             =head2 Bugs / Feature Requests
354              
355             Please report any bugs or feature requests through the issue tracker
356             at L.
357             You will be notified automatically of any progress on your issue.
358              
359             =head2 Source Code
360              
361             This is open source software. The code repository is available for
362             public review and contribution under the terms of the license.
363              
364             L
365              
366             git clone https://github.com/giterlizzi/perl-Net-OpenVAS.git
367              
368              
369             =head1 AUTHOR
370              
371             =over 4
372              
373             =item * Giuseppe Di Terlizzi
374              
375             =back
376              
377              
378             =head1 LICENSE AND COPYRIGHT
379              
380             This software is copyright (c) 2020 by Giuseppe Di Terlizzi.
381              
382             This is free software; you can redistribute it and/or modify it under
383             the same terms as the Perl 5 programming language system itself.
384              
385             =cut