—package
QualysGuard::Request;
use
warnings;
use
strict;
use
Qualys::Response;
use
LWP::UserAgent;
use
HTTP::Request;
use
URI::Escape;
use
Carp;
our
$VERSION
=
'0.01'
;
my
$QUALYS_FUNCTIONS
= {
'asset_data_report'
=> 1,
'asset_domain'
=> 1,
'asset_domain_list'
=> 1,
'asset_group'
=> 1,
'asset_group_delete'
=> 1,
'asset_group_list'
=> 1,
'asset_ip'
=> 1,
'asset_ip_list'
=> 1,
'asset_range_info'
=> 1,
'asset_search'
=> 1,
'iscanner_list'
=> 1,
'map'
=> 1,
'map-2'
=> 1,
'map_report'
=> 1,
'map_report_list'
=> 1,
'report_template_list'
=> 1,
'scan'
=> 1,
'scan_cancel'
=> 1,
'scan_options'
=> 1,
'scan_report'
=> 1,
'scan_report_delete'
=> 1,
'scan_report_list'
=> 1,
'scan_running_list'
=> 1,
'scan_target_history'
=> 1,
'scheduled_scans'
=> 1,
'ticket_delete'
=> 1,
'ticket_edit'
=> 1,
'ticket_list'
=> 1,
'ticket_list_deleted'
=> 1,
};
$QualysGuard::Request::Username
=
undef
;
$QualysGuard::Request::Password
=
undef
;
# -------------------------------------------------------------------
# new
# -------------------------------------------------------------------
sub
new {
my
(
$class
,
$function
) =
@_
;
my
$self
=
bless
{},
ref
(
$class
) ||
$class
;
if
( !
exists
$QUALYS_FUNCTIONS
->{
$function
} ) {
croak
"Qualys function '$function' does not exist"
;
}
$self
->{function} =
$function
;
return
$self
;
}
# -------------------------------------------------------------------
# attributes
# -------------------------------------------------------------------
sub
attributes {
my
$self
=
shift
;
my
$attr
=
shift
;
while
(
my
(
$a
,
$v
) =
each
(
%$attr
) ) {
$self
->{a}{
lc
(
$a
)} =
$v
;
}
return
$self
->{a};
}
# -------------------------------------------------------------------
# submit
# -------------------------------------------------------------------
sub
submit {
my
$self
=
shift
;
my
$url
=
$self
->_url();
my
$function
=
$self
->{function};
my
$http_request
= HTTP::Request->new(
GET
=>
$url
);
if
( !
defined
$QualysGuard::Request::Username
) {
croak
"Error : Undefined Qualys username."
;
}
if
( !
defined
$QualysGuard::Request::Password
) {
croak
"Error : Undefined Qualys password."
;
}
$http_request
->authorization_basic(
$QualysGuard::Request::Username
,
$QualysGuard::Request::Password
);
my
$ua
= LWP::UserAgent->new();
my
$http_response
=
$ua
->request(
$http_request
);
if
( !
$http_response
->is_success() ) {
croak
"HTTP Error: "
.
$http_response
->status_line();
}
my
$qualys_response
=
$self
->_get_qualys_response_from(
$http_response
);
return
$qualys_response
;
}
# -------------------------------------------------------------------
# _url
# -------------------------------------------------------------------
sub
_url {
my
$self
=
shift
;
my
$attr
=
$self
->attributes();
my
@kvps
= ();
while
(
my
(
$k
,
$v
) =
each
(
%$attr
) ) {
$k
= uri_escape(
$k
);
$v
= uri_escape(
$v
);
push
(
@kvps
,
"$k=$v"
);
}
}
# -------------------------------------------------------------------
# Factory method that creates the appropriate Response Object
# -------------------------------------------------------------------
sub
_get_qualys_response_from {
my
(
$self
,
$http_response
) =
@_
;
my
$function
=
$self
->{function};
my
$xml_content
=
$http_response
->content();
my
$qualys_return
=
undef
;
if
(
$function
eq
'asset_data_report'
) {
$qualys_return
= QualysGuard::Response::AssetDataReport->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_domain'
||
$function
eq
'asset_group'
||
$function
eq
'asset_group_delete'
||
$function
eq
'asset_ip'
||
$function
eq
'scan_cancel'
||
$function
eq
'scan_report_delete'
)
{
$qualys_return
= QualysGuard::Response::GenericReturn->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_domain_list'
) {
$qualys_return
= QualysGuard::Response::AssetDomainList->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_group_list'
) {
$qualys_return
= QualysGuard::Response::AssetGroupList->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_ip_list'
) {
$qualys_return
= QualysGuard::Response::AssetHostList->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_range_info'
) {
$qualys_return
= QualysGuard::Response::AssetRangeInfo->new(
$xml_content
);
}
elsif
(
$function
eq
'asset_search'
) {
$qualys_return
= QualysGuard::Response::AssetSearchReport->new(
$xml_content
);
}
elsif
(
$function
eq
'iscanner_list'
) {
$qualys_return
= QualysGuard::Response::IScannerList->new(
$xml_content
);
}
elsif
(
$function
eq
'map'
||
$function
eq
'map_report'
)
{
$qualys_return
= QualysGuard::Response::MapReport->new(
$xml_content
);
}
elsif
(
$function
eq
'map_report_list'
) {
$qualys_return
= QualysGuard::Response::MapReportList->new(
$xml_content
);
}
elsif
(
$function
eq
'report_template_list'
) {
$qualys_return
= QualysGuard::Response::ReportTemplateList->new(
$xml_content
);
}
elsif
(
$function
eq
'scan'
||
$function
eq
'scan_report'
)
{
$qualys_return
= QualysGuard::Response::ScanReport->new(
$xml_content
);
}
elsif
(
$function
eq
'scan_options'
) {
$qualys_return
= QualysGuard::Response::ScanOptions->new(
$xml_content
);
}
elsif
(
$function
eq
'scan_report_list'
) {
$qualys_return
= QualysGuard::Response::ScanReportList->new(
$xml_content
);
}
elsif
(
$function
eq
'scan_running_list'
) {
$qualys_return
= QualysGuard::Response::ScanRunningList->new(
$xml_content
);
}
elsif
(
$function
eq
'scan_target_history'
) {
$qualys_return
= QualysGuard::Response::ScanTargetHistory->new(
$xml_content
);
}
elsif
(
$function
eq
'scheduled_scans'
) {
$qualys_return
= QualysGuard::Response::ScheduledScans->new(
$xml_content
);
}
elsif
(
$function
eq
'ticket_delete'
) {
$qualys_return
= QualysGuard::Response::TicketDelete->new(
$xml_content
);
}
elsif
(
$function
eq
'ticket_edit'
) {
$qualys_return
= QualysGuard::Response::TicketEdit->new(
$xml_content
);
}
elsif
(
$function
eq
'ticket_list'
) {
$qualys_return
= QualysGuard::Response::TicketList->new(
$xml_content
);
}
elsif
(
$function
eq
'ticket_list_deleted'
) {
$qualys_return
= QualysGuard::Response::TicketListDeleted->new(
$xml_content
);
}
return
$qualys_return
;
}
1;
__END__
=head1 NAME
QualysGuard::Request - Simple interface to QualysGuard API
=head1 VERSION
Version 0.01
=head1 SYNOPSIS
use QualysGuard::Request;
$QualysGuard::Request::Username = "username";
$QualysGuard::Request::Password = "password";
my $qualys_request = QualysGuard::Request->new( 'map_report_list' );
# - provide map_report_list function arguments
$qualys_request->attributes({
'last' => 'yes',
'domain' => 'example.com',
});
# - qualys_response is a Qualys::Response::MapReportList object
my $qualys_response = $qualys_request->submit();
if ( $qualys_response->is_error() ) {
die $qualys_response->get_error();
}
# - Qualys::Response is a subclass of XML::XPath which allows
# - XML::XPath functionality in each of the Qualys::Response subclasses.
# - In short you can extract data using the XML::XPath interface.
my @map_refs = $qualys_response->findnodes('/SOME/XPATH/');
...
=head1 DESCRIPTION
Each XML response from the QualysGuard API has an associated doctype definition (DTD). Therefore each DTD has
an associated subclass of QualysGuard::Response. Below is a list of the QualysGuard functions supported
by QualysGuard::Request.
=over
=item B<Qualys Function> B<QualysGuard::Response Subclass>
=item ------------------ --------------------------------------
=item asset_data_report QualysGuard::Response::AssetDataReport
=item asset_domain QualysGuard::Response::GenericReturn
=item asset_domain_list QualysGuard::Response::AssetDomainList
=item asset_group QualysGuard::Response::GenericReturn
=item asset_group_delete QualysGuard::Response::GenericReturn
=item asset_group_list QualysGuard::Response::AssetGroupList
=item asset_ip QualysGuard::Response::GenericReturn
=item asset_ip_list QualysGuard::Response::AssetHostList
=item asset_range_info QualysGuard::Response::AssetRangeInfo
=item asset_search QualysGuard::Response::AssetSearchReport
=item iscanner_list QualysGuard::Response::IScannerList
=item map QualysGuard::Response::MapReport
=item map-2 QualysGuard::Response::MapReport2
=item map_report QualysGuard::Response::MapReport
=item map_report_list QualysGuard::Response::MapReportList
=item report_template_list QualysGuard::Response::ReportTemplateList
=item scan QualysGuard::Response::ScanReport
=item scan_cancel QualysGuard::Response::GenericReturn
=item scan_options QualysGuard::Response::ScanOptions
=item scan_report QualysGuard::Response::ScanReport
=item scan_report_delete QualysGuard::Response::GenericReturn
=item scan_report_list QualysGuard::Response::ScanReportList
=item scan_running_list QualysGuard::Response::ScanRunningList
=item scan_target_history QualysGuard::Response::ScanTargetHistory
=item scheduled_scans QualysGuard::Response::ScheduledScans
=item ticket_delete QualysGuard::Response::TicketDelete
=item ticket_edit QualysGuard::Response::TicketEdit
=item ticket_list QualysGuard::Response::TicketList
=item ticket_list_deleted QualysGuard::Response::TicketListDeleted
=back
=head1 PUBLIC INTERFACE
=over 4
=item new ( QUALYS_FUNCTION )
Returns a new C<Qualys::Request> object.
=item attributes ( $QUALYS_FUNCTION_ARGS )
The C<attributes> method takes a single hashref argument. The hashref should
contain all of the needed QualysGuard function arguments. Refer to the
QualysGuard API documentation for list of arguments for each of the available
functions.
=item submit ()
Submits the request and returns a new subclass of C<QualysGuard::Response>.
=back
=head1 AUTHOR
Patrick Devlin, C<< <pdevlin at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests to C<bug-qualysguard-request at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=QualysGuard::Request>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc QualysGuard::Request
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker
=item * AnnoCPAN: Annotated CPAN documentation
=item * CPAN Ratings
=item * Search CPAN
=back
=head1 SEE ALSO
L<QualysGuard::Response>
=head1 COPYRIGHT & LICENSE
Copyright 2008 Patrick Devlin, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
Qualys and the QualysGuard product are registered trademarks of Qualys, Inc.