Listen for events and forward to external security scanning services.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

qualys.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package main
  2. /*
  3. qualys - This file includes all of the logic necessary to interact with the
  4. go-qualys library. This is extrapolated out so that a QualysInterface
  5. interface can be passed to functions. Doing this allows testing by mock
  6. classes to be created that can be passed to functions.
  7. Since this is a wrapper around the go-qualys library, this does not need
  8. testing.
  9. */
  10. import (
  11. "errors"
  12. "fmt"
  13. "log"
  14. "net/http"
  15. "net/url"
  16. "git.openstack.org/openstack/osel/qualys"
  17. )
  18. // QualysActioner is an interface for an QualysActions class. Having
  19. // this as an interface allows us to pass in a dummy class for testing that
  20. // just returns mocked data.
  21. type QualysActioner interface {
  22. InitiateScan([]string) (string, error)
  23. DropIPv6() bool
  24. }
  25. // QualysActions is a class that handles all interactions directly with Qualys.
  26. // See the comment on QualysActioner for rationale.
  27. type QualysActions struct {
  28. Options QualysOptions
  29. }
  30. // QualysOptions is a class to convey all of the configurable options for the
  31. // QualysActions class.
  32. type QualysOptions struct {
  33. DropIPv6 bool
  34. MinRemaining int
  35. ProxyURL *url.URL
  36. Password string
  37. QualysURL *url.URL
  38. ScanOptionName string
  39. UserName string
  40. }
  41. // InitiateScan is the main method for the QualysActioner class, it
  42. // makes a call to the Qualys API to start a scan and harvests a scan ID, and
  43. // an optional error string if there is a problem contacting Qualys.
  44. func (s *QualysActions) InitiateScan(targetIPAddresses []string) (string, error) {
  45. var err error
  46. // create client with proxy so the qualys service can be accessed
  47. qualysCreds := qualys.Credentials{
  48. Username: s.Options.UserName,
  49. Password: s.Options.Password,
  50. }
  51. c, err := qualys.NewClient(&http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(s.Options.ProxyURL)}}, &qualysCreds)
  52. if err != nil {
  53. return "", err
  54. }
  55. c.BaseURL = s.Options.QualysURL
  56. // create the options
  57. opts := qualys.LaunchScanOptions{
  58. ScanTitle: "osel",
  59. ScannerName: "External",
  60. OptionTitle: s.Options.ScanOptionName,
  61. IP: targetIPAddresses,
  62. }
  63. // launch the request
  64. launchScanResponse, err := c.LaunchScan(&opts)
  65. if err != nil {
  66. return "", err
  67. }
  68. // process the request response
  69. scanID := launchScanResponse.ScanReference
  70. remainingQualysRequests := launchScanResponse.RateLimitations.Remaining
  71. allowedQualysRequests := launchScanResponse.RateLimitations.Limit
  72. if Debug {
  73. log.Printf("Qualys Rate Limit: %d of %d total requests remaining, concurrency of %d out of %d, %d seconds remaining in limit window and %d seconds until a request can be made again\n",
  74. remainingQualysRequests, allowedQualysRequests, launchScanResponse.RateLimitations.CurrentConcurrency,
  75. launchScanResponse.RateLimitations.ConcurrencyLimit, launchScanResponse.RateLimitations.LimitWindow, launchScanResponse.RateLimitations.WaitingPeriod)
  76. }
  77. if launchScanResponse.Text != "" {
  78. err = errors.New(launchScanResponse.Text)
  79. }
  80. if remainingQualysRequests <= s.Options.MinRemaining {
  81. err = fmt.Errorf("halting Qualys processing! Only %d Qualys calls remain out of a total of %d. Waiting for %d seconds before resuming", remainingQualysRequests,
  82. allowedQualysRequests, launchScanResponse.RateLimitations.LimitWindow)
  83. }
  84. return scanID, err
  85. }
  86. // DropIPv6 is an accessor method to allow other code to make decisions based on whether this flag is enabled.
  87. func (s *QualysActions) DropIPv6() bool {
  88. return s.Options.DropIPv6
  89. }