Advertisement
Guest User

Untitled

a guest
Jul 31st, 2012
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.41 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. #@(#)$Revision: 1.12 $
  3.  
  4. # A Perl script, which demonstrates the capabilities of the QualysGuard
  5. # API.
  6.  
  7. # With this script you can run maps, run maps and store the results
  8. # on Qualys servers, list, and display the stored maps.
  9.  
  10. # Indentation style: 1 tab = 4 spaces
  11.  
  12. use HTTP::Request;
  13. use LWP::UserAgent;
  14. require XML::Twig;
  15.  
  16. my $myname = "getmap";
  17.  
  18. my $map_count = 0;  # Saved map count, from map_report_list response
  19. my $request;    # HTTP request handle
  20. my $result;     # HTTP response handle
  21. my $server;     # QualysGuard server's FQDN hostname
  22. my $url;        # API access URL
  23. my $xml;        # Twig object handle
  24.  
  25. # $server may be read from the shell environment, or defaults to
  26. # qualysapi.qualys.com otherwise.
  27.  
  28. if ($ENV{QWSERV}) {
  29.     $server = $ENV{QWSERV};
  30. } else {
  31.     $server = "qualysapi.qualys.com";
  32. }
  33.  
  34. # Handlers and helper functions
  35.  
  36. sub error {
  37.     my ($xml, $element) = @_;
  38.  
  39.     my $number = $element->att('number');
  40.     my $message;
  41.  
  42.     # Some APIs return embedded "<SUMMARY>error summary text</SUMMARY>"
  43.     # elements, so detect and handle accordingly. NOTE: <SUMMARY>
  44.     # elements are usually included for reporting multiple errors with
  45.     # one error element.
  46.  
  47.     if (!($message = $element->first_child_trimmed_text('SUMMARY'))) {
  48.         $message = $element->trimmed_text;
  49.     }
  50.  
  51.     if ($number) {
  52.         printf STDERR "Request Status: FAILED\nError Number: %1d\nReason: %s\n", $number, $message;
  53.     } else {
  54.         printf STDERR "Request Status: FAILED\nReason: %s\n", $message;
  55.     }
  56.  
  57.     exit 255;
  58. }
  59.  
  60. sub generic_return {
  61.     my ($xml, $element) = @_;
  62.  
  63.     my ($return, $status, $number, $message);
  64.  
  65.     # This is a GENERIC_RETURN element. So, display the RETURN element,
  66.     # which gives the detailed status.
  67.  
  68.     if ($return = $element->first_child('RETURN')) {
  69.         $status  = $return->att('status');
  70.         $number  = $return->att('number');
  71.         $message = $return->trimmed_text;
  72.  
  73.         if ($number) {
  74.             printf STDERR "Request Status: %s\nError Number: %1d\nReason: %s\n", $status, $number, $message;
  75.         } else {
  76.             printf STDERR "Request Status: %s\nReason: %s\n", $status, $message;
  77.         }
  78.     } else {
  79.         # An XML recognition error; display the XML for the offending
  80.         # element.
  81.  
  82.         printf STDERR "Unrecognized XML Element:\n%s\n", $element->print;
  83.     }
  84.  
  85.     exit ($status eq "SUCCESS" ? 0 : 255);
  86. }
  87.  
  88. sub key {
  89.     my ($xml, $element) = @_;
  90.  
  91.     printf "%s: %s\n", $element->att('value'), $element->trimmed_text;
  92. }
  93.  
  94. sub map {
  95.     my ($xml, $element) = @_;
  96.  
  97.     # For a map results, just return the XML
  98.  
  99.     printf "%s\n", $result->content;
  100. }
  101.  
  102. sub map_report {
  103.     my ($xml, $element) = @_;
  104.  
  105.     $map_count++;   # Saw a list element, bump up the count
  106.  
  107.     printf "Map Ref: %s\n   Date: %s\n Domain: %s\n\n", $element->att("ref"), $element->att("date"), $element->att("domain");
  108. }
  109.  
  110. sub map_report_list {
  111.     my ($xml, $element) = @_;
  112. }
  113.  
  114. sub scan_running_list {
  115.     my ($xml, $element) = @_;
  116. }
  117.  
  118. sub scan {
  119.     my ($xml, $element) = @_;
  120. }
  121.  
  122. sub usage {
  123.     printf STDERR "usage: %s username password {{cancel|delete|retrieve} ref|list|running_list|{map|save} domain {iscanner_name}}\n", $myname;
  124.     exit 1;
  125. }
  126.  
  127. # The Perl LWP package gives sufficient capabilities to connect to
  128. # the QualysGuard API. To support the HTTP "Basic Authentication"
  129. # scheme, it's necessary to subclass LWP::UserAgent and define a
  130. # method called "get_basic_credentials", which will be called when
  131. # the server challenges the script for authentication. This method
  132. # returns the username and password, which simply are the second and
  133. # third command line parameters.
  134.  
  135. # A subclass of LWP::UserAgent to handle HTTP Basic Authentication.
  136.  
  137. {
  138.     package authUserAgent;
  139.     @ISA = qw(LWP::UserAgent);
  140.  
  141.     sub new {
  142.         my $self = LWP::UserAgent::new(@_);
  143.         $self;
  144.     }
  145.  
  146.     sub get_basic_credentials {
  147.         return ($ARGV[0], $ARGV[1]);
  148.     }
  149. }
  150.  
  151. # Check for at least username, password, and command
  152.  
  153. usage if ($#ARGV < 2);
  154.  
  155. my $show_url = 0;
  156.  
  157. if ($ARGV[2] eq "-v") {
  158.     splice @ARGV, 2, 1;
  159.     $show_url = 1;
  160. }
  161.  
  162. # XML::Twig is a handy way to process an XML document. We use it to attach
  163. # various handlers, which are triggered whenever related tags are found
  164. # in the XML document. We also attach an error() handler, which is
  165. # triggered whenever Twig finds any errors. Note: The "process comments"
  166. # attribute is useful to recognize and return the error message
  167. # text. Finally, the generic_return() handler covers the case where a
  168. # <GENERIC_RETURN> element is encountered.
  169.  
  170. if ($ARGV[2] eq "map" or $ARGV[2] eq "save") {
  171.     usage if ($#ARGV < 3 or $#ARGV > 5);    # Need at least a Domain name or list to continue
  172.  
  173.     # Check for multiple domains to select map-2.php or map.php as appropriate.
  174.  
  175.     my $map_api = ($ARGV[3] =~ /[,\;:]/) ? "map-2" : "map";
  176.  
  177.     $url  = "https://$server/msp/${map_api}.php?domain=$ARGV[3]";   # map
  178.     $url .= "&save_report=yes" if ($ARGV[2] eq "save");             # save
  179.  
  180.     # Check if iscanner_name parameter is present.
  181.  
  182.     if ($#ARGV > 3) {
  183.         if ($#ARGV == 4) {
  184.             $url .= "&iscanner_name=$ARGV[4]";                      # appliance
  185.         } else {
  186.             usage;
  187.         }
  188.     }
  189.  
  190.     $xml = new XML::Twig(
  191.         TwigHandlers => {
  192.             ERROR             => \&error,
  193.             GENERIC_RETURN    => \&generic_return,
  194.             MAP               => \&map,
  195.         }
  196.     );
  197. } elsif ($ARGV[2] eq "list") {  # Needs no attributes
  198.     $url = "https://$server/msp/map_report_list.php";
  199.  
  200.     $xml = new XML::Twig(
  201.         TwigHandlers => {
  202.             ERROR             => \&error,
  203.             GENERIC_RETURN    => \&generic_return,
  204.             MAP_REPORT_LIST   => \&map_report_list,
  205.             MAP_REPORT        => \&map_report,
  206.         },
  207.         comments => 'keep'
  208.     );
  209. } elsif ($ARGV[2] eq "retrieve") {
  210.     usage if ($#ARGV != 3);     # Need a map ref to continue
  211.     $url = "https://$server/msp/map_report.php?ref=$ARGV[3]";
  212.  
  213.     $xml = new XML::Twig(
  214.         TwigHandlers => {
  215.             ERROR             => \&error,
  216.             GENERIC_RETURN    => \&generic_return,
  217.             MAP               => \&map,
  218.         }
  219.     );
  220. } elsif ($ARGV[2] eq "delete") {
  221.     usage if ($#ARGV != 3);     # Need a map ref to continue
  222.     $url = "https://$server/msp/scan_report_delete.php?ref=$ARGV[3]";
  223.  
  224.     $xml = new XML::Twig(
  225.         TwigHandlers => {
  226.             ERROR             => \&error,
  227.             GENERIC_RETURN    => \&generic_return,
  228.         },
  229.         comments => 'keep'
  230.     );
  231. } elsif ($ARGV[2] eq "running_list") {  # Needs no attributes
  232.     $url = "https://$server/msp/scan_running_list.php";
  233.  
  234.     $xml = new XML::Twig(
  235.         TwigHandlers => {
  236.             ERROR             => \&error,
  237.             GENERIC_RETURN    => \&generic_return,
  238.             KEY               => \&key,
  239.             SCAN_RUNNING_LIST => \&scan_running_list,
  240.             SCAN              => \&scan,
  241.         },
  242.         comments => 'keep'
  243.     );
  244. } elsif ($ARGV[2] eq "cancel") {
  245.     usage if ($#ARGV != 3);     # Need a map ref to continue
  246.     $url = "https://$server/msp/scan_cancel.php?ref=$ARGV[3]";
  247.  
  248.     $xml = new XML::Twig(
  249.         TwigHandlers => {
  250.             ERROR             => \&error,
  251.             GENERIC_RETURN    => \&generic_return,
  252.         },
  253.         comments => 'keep'
  254.     );
  255. } else {
  256.     usage;
  257. }
  258.  
  259. # Setup the request
  260.  
  261. $request = new HTTP::Request GET => $url;
  262.  
  263. # Create an instance of the authentication user agent
  264.  
  265. my $ua = authUserAgent->new;
  266.  
  267. # Make the request
  268.  
  269. print STDERR $url . "\n" if ($show_url);
  270. $result = $ua->request($request);
  271.  
  272. # Check the result
  273.  
  274. if ($result->is_success) {
  275.     # Parse the XML
  276.  
  277.     $xml->parse($result->content);
  278. } else {
  279.     # An HTTP related error
  280.  
  281.     printf STDERR "HTTP Error: %s\n", $result->status_line;
  282.     exit 1;
  283. }
  284.  
  285. if ($ARGV[2] eq "list") {
  286.     if ($map_count) {
  287.         printf "Saved Maps: %1d total\n", $map_count if ($map_count > 1);
  288.     } else {
  289.         print  "No saved maps found\n";
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement