Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- #@(#)$Revision: 1.12 $
- # A Perl script, which demonstrates the capabilities of the QualysGuard
- # API.
- # With this script you can run maps, run maps and store the results
- # on Qualys servers, list, and display the stored maps.
- # Indentation style: 1 tab = 4 spaces
- use HTTP::Request;
- use LWP::UserAgent;
- require XML::Twig;
- my $myname = "getmap";
- my $map_count = 0; # Saved map count, from map_report_list response
- my $request; # HTTP request handle
- my $result; # HTTP response handle
- my $server; # QualysGuard server's FQDN hostname
- my $url; # API access URL
- my $xml; # Twig object handle
- # $server may be read from the shell environment, or defaults to
- # qualysapi.qualys.com otherwise.
- if ($ENV{QWSERV}) {
- $server = $ENV{QWSERV};
- } else {
- $server = "qualysapi.qualys.com";
- }
- # Handlers and helper functions
- sub error {
- my ($xml, $element) = @_;
- my $number = $element->att('number');
- my $message;
- # Some APIs return embedded "<SUMMARY>error summary text</SUMMARY>"
- # elements, so detect and handle accordingly. NOTE: <SUMMARY>
- # elements are usually included for reporting multiple errors with
- # one error element.
- if (!($message = $element->first_child_trimmed_text('SUMMARY'))) {
- $message = $element->trimmed_text;
- }
- if ($number) {
- printf STDERR "Request Status: FAILED\nError Number: %1d\nReason: %s\n", $number, $message;
- } else {
- printf STDERR "Request Status: FAILED\nReason: %s\n", $message;
- }
- exit 255;
- }
- sub generic_return {
- my ($xml, $element) = @_;
- my ($return, $status, $number, $message);
- # This is a GENERIC_RETURN element. So, display the RETURN element,
- # which gives the detailed status.
- if ($return = $element->first_child('RETURN')) {
- $status = $return->att('status');
- $number = $return->att('number');
- $message = $return->trimmed_text;
- if ($number) {
- printf STDERR "Request Status: %s\nError Number: %1d\nReason: %s\n", $status, $number, $message;
- } else {
- printf STDERR "Request Status: %s\nReason: %s\n", $status, $message;
- }
- } else {
- # An XML recognition error; display the XML for the offending
- # element.
- printf STDERR "Unrecognized XML Element:\n%s\n", $element->print;
- }
- exit ($status eq "SUCCESS" ? 0 : 255);
- }
- sub key {
- my ($xml, $element) = @_;
- printf "%s: %s\n", $element->att('value'), $element->trimmed_text;
- }
- sub map {
- my ($xml, $element) = @_;
- # For a map results, just return the XML
- printf "%s\n", $result->content;
- }
- sub map_report {
- my ($xml, $element) = @_;
- $map_count++; # Saw a list element, bump up the count
- printf "Map Ref: %s\n Date: %s\n Domain: %s\n\n", $element->att("ref"), $element->att("date"), $element->att("domain");
- }
- sub map_report_list {
- my ($xml, $element) = @_;
- }
- sub scan_running_list {
- my ($xml, $element) = @_;
- }
- sub scan {
- my ($xml, $element) = @_;
- }
- sub usage {
- printf STDERR "usage: %s username password {{cancel|delete|retrieve} ref|list|running_list|{map|save} domain {iscanner_name}}\n", $myname;
- exit 1;
- }
- # The Perl LWP package gives sufficient capabilities to connect to
- # the QualysGuard API. To support the HTTP "Basic Authentication"
- # scheme, it's necessary to subclass LWP::UserAgent and define a
- # method called "get_basic_credentials", which will be called when
- # the server challenges the script for authentication. This method
- # returns the username and password, which simply are the second and
- # third command line parameters.
- # A subclass of LWP::UserAgent to handle HTTP Basic Authentication.
- {
- package authUserAgent;
- @ISA = qw(LWP::UserAgent);
- sub new {
- my $self = LWP::UserAgent::new(@_);
- $self;
- }
- sub get_basic_credentials {
- return ($ARGV[0], $ARGV[1]);
- }
- }
- # Check for at least username, password, and command
- usage if ($#ARGV < 2);
- my $show_url = 0;
- if ($ARGV[2] eq "-v") {
- splice @ARGV, 2, 1;
- $show_url = 1;
- }
- # XML::Twig is a handy way to process an XML document. We use it to attach
- # various handlers, which are triggered whenever related tags are found
- # in the XML document. We also attach an error() handler, which is
- # triggered whenever Twig finds any errors. Note: The "process comments"
- # attribute is useful to recognize and return the error message
- # text. Finally, the generic_return() handler covers the case where a
- # <GENERIC_RETURN> element is encountered.
- if ($ARGV[2] eq "map" or $ARGV[2] eq "save") {
- usage if ($#ARGV < 3 or $#ARGV > 5); # Need at least a Domain name or list to continue
- # Check for multiple domains to select map-2.php or map.php as appropriate.
- my $map_api = ($ARGV[3] =~ /[,\;:]/) ? "map-2" : "map";
- $url = "https://$server/msp/${map_api}.php?domain=$ARGV[3]"; # map
- $url .= "&save_report=yes" if ($ARGV[2] eq "save"); # save
- # Check if iscanner_name parameter is present.
- if ($#ARGV > 3) {
- if ($#ARGV == 4) {
- $url .= "&iscanner_name=$ARGV[4]"; # appliance
- } else {
- usage;
- }
- }
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- MAP => \&map,
- }
- );
- } elsif ($ARGV[2] eq "list") { # Needs no attributes
- $url = "https://$server/msp/map_report_list.php";
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- MAP_REPORT_LIST => \&map_report_list,
- MAP_REPORT => \&map_report,
- },
- comments => 'keep'
- );
- } elsif ($ARGV[2] eq "retrieve") {
- usage if ($#ARGV != 3); # Need a map ref to continue
- $url = "https://$server/msp/map_report.php?ref=$ARGV[3]";
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- MAP => \&map,
- }
- );
- } elsif ($ARGV[2] eq "delete") {
- usage if ($#ARGV != 3); # Need a map ref to continue
- $url = "https://$server/msp/scan_report_delete.php?ref=$ARGV[3]";
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- },
- comments => 'keep'
- );
- } elsif ($ARGV[2] eq "running_list") { # Needs no attributes
- $url = "https://$server/msp/scan_running_list.php";
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- KEY => \&key,
- SCAN_RUNNING_LIST => \&scan_running_list,
- SCAN => \&scan,
- },
- comments => 'keep'
- );
- } elsif ($ARGV[2] eq "cancel") {
- usage if ($#ARGV != 3); # Need a map ref to continue
- $url = "https://$server/msp/scan_cancel.php?ref=$ARGV[3]";
- $xml = new XML::Twig(
- TwigHandlers => {
- ERROR => \&error,
- GENERIC_RETURN => \&generic_return,
- },
- comments => 'keep'
- );
- } else {
- usage;
- }
- # Setup the request
- $request = new HTTP::Request GET => $url;
- # Create an instance of the authentication user agent
- my $ua = authUserAgent->new;
- # Make the request
- print STDERR $url . "\n" if ($show_url);
- $result = $ua->request($request);
- # Check the result
- if ($result->is_success) {
- # Parse the XML
- $xml->parse($result->content);
- } else {
- # An HTTP related error
- printf STDERR "HTTP Error: %s\n", $result->status_line;
- exit 1;
- }
- if ($ARGV[2] eq "list") {
- if ($map_count) {
- printf "Saved Maps: %1d total\n", $map_count if ($map_count > 1);
- } else {
- print "No saved maps found\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement