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         27  
4 1     1   5 use warnings;
  1         2  
  1         21  
5 1     1   613 use utf8;
  1         15  
  1         5  
6 1     1   33 use feature ':5.10';
  1         1  
  1         95  
7              
8 1     1   6 use Carp;
  1         2  
  1         62  
9 1     1   889 use IO::Socket::SSL;
  1         88266  
  1         8  
10 1     1   1201 use XML::Simple qw( :strict );
  1         9473  
  1         6  
11              
12 1     1   620 use Net::OpenVAS::Error;
  1         2  
  1         46  
13 1     1   503 use Net::OpenVAS::OMP::Response;
  1         4  
  1         30  
14 1     1   471 use Net::OpenVAS::OMP::Request;
  1         8  
  1         301  
15              
16             our $VERSION = '0.101';
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         1192  
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              
233             =head1 NAME
234              
235             Net::OpenVAS - Perl extension for OpenVAS Scanner
236              
237             =head1 SYNOPSIS
238              
239             use Net::OpenVAS qw( -commands );
240              
241             my $openvas = Net::OpenVAS->new(
242             host => 'localhost:9390',
243             username => 'admin',
244             password => 's3cr3t'
245             ) or die "ERROR: $@";
246              
247             my $task = $openvas->create_task(
248             name => [ 'Scan created via Net::OpenVAS' ],
249             target => { id => 'a800d5c7-3493-4f73-8401-c42e5f2bfc9c' },
250             config => { id => 'daba56c8-73ec-11df-a475-002264764cea' }
251             );
252              
253             if ( $task->is_created ) {
254              
255             my $task_id = $task->result->{id};
256              
257             say "Created task $task_id";
258              
259             my $task_start = $openvas->start_task( task_id => $task_id );
260              
261             say "Task $task_id started (" . $task_start->status_text . ')' if ( $task_start->is_accepted );
262              
263             }
264              
265             if ( $openvas->error ) {
266             say "ERROR: " . $openvas->error;
267             }
268              
269             =head1 DESCRIPTION
270              
271             This module provides Perl scripts easy way to interface the OMP (OpenVAS Management Protocol) of OpenVAS.
272              
273             For more information about the OPM follow the online documentation:
274              
275             L
276              
277              
278             =head1 CONSTRUCTOR
279              
280             =head2 Net::OpenVAS::OMP->new ( host => $host, username => $username, password => $password [, logger => $logger, timeout => 60, ssl_options => \%ssl_options ] )
281              
282             Create a new instance of L.
283              
284             Params:
285              
286             =over 4
287              
288             =item * C : OpenVAS host (and port)
289              
290             =item * C, C : OpenVAS Credentials
291              
292             =item * C : Request timeout in seconds (default is 60) If a socket open,
293             read or write takes longer than the timeout, an exception is thrown.
294              
295             =item * C : A hashref of C options to pass through to L.
296              
297             =item * C : A logger instance (eg. L or L for log
298             the REST request and response messages.
299              
300             =back
301              
302              
303             =head1 METHODS
304              
305             =head2 $openvas->command ( $command [, \%arguments ] )
306              
307             Execute a command to OpenVAS via OMP and return L class instance.
308              
309             my $task = $openvas->command( 'get_tasks', task_id => '46f15597-b721-403c-96a1-cce439af63a7' );
310              
311             =head2 $openvas->error
312              
313             Return L class instance.
314              
315             =head2 COMMANDS HELPER
316              
317             L provide a flag (C<-commands>) for import all OpenVAS OMP commands.
318              
319             use Net::OpenVAS::OMP;
320             [...]
321             my $version = $openvas->command('get_version');
322              
323             use Net::OpenVAS::OMP qw( -commands );
324             [...]
325             my $version = $openvas->get_version;
326              
327             Available commands:
328              
329             authenticate commands create_agent create_alert create_asset create_config
330             create_credential create_filter create_group create_note create_override
331             create_permission create_port_list create_port_range create_report
332             create_report_format create_role create_scanner create_schedule create_tag
333             create_target create_task create_user delete_agent delete_asset
334             delete_config delete_alert delete_credential delete_filter delete_group
335             delete_note delete_override delete_report delete_permission delete_port_list
336             delete_port_range delete_report_format delete_role delete_scanner
337             delete_schedule delete_tag delete_target delete_task delete_user
338             describe_auth empty_trashcan get_agents get_configs get_aggregates
339             get_alerts get_assets get_credentials get_feeds get_filters get_groups
340             get_info get_notes get_nvts get_nvt_families get_overrides get_permissions
341             get_port_lists get_preferences get_reports get_report_formats get_results
342             get_roles get_scanners get_schedules get_settings get_system_reports
343             get_tags get_targets get_tasks get_users get_version help modify_agent
344             modify_alert modify_asset modify_auth modify_config modify_credential
345             modify_filter modify_group modify_note modify_override modify_permission
346             modify_port_list modify_report modify_report_format modify_role
347             modify_scanner modify_schedule modify_setting modify_target modify_tag
348             modify_task modify_user move_task restore resume_task run_wizard start_task
349             stop_task sync_cert sync_feed sync_config sync_scap test_alert verify_agent
350             verify_report_format verify_scanner
351              
352             =head1 SUPPORT
353              
354             =head2 Bugs / Feature Requests
355              
356             Please report any bugs or feature requests through the issue tracker
357             at L.
358             You will be notified automatically of any progress on your issue.
359              
360             =head2 Source Code
361              
362             This is open source software. The code repository is available for
363             public review and contribution under the terms of the license.
364              
365             L
366              
367             git clone https://github.com/giterlizzi/perl-Net-OpenVAS.git
368              
369              
370             =head1 AUTHOR
371              
372             =over 4
373              
374             =item * Giuseppe Di Terlizzi
375              
376             =back
377              
378              
379             =head1 LICENSE AND COPYRIGHT
380              
381             This software is copyright (c) 2020 by Giuseppe Di Terlizzi.
382              
383             This is free software; you can redistribute it and/or modify it under
384             the same terms as the Perl 5 programming language system itself.
385              
386             =cut