nexpose_ticketing 0.0.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ module NexposeTicketing
5
5
  require 'nexpose'
6
6
  require 'nexpose_ticketing/queries'
7
7
 
8
- def nexpose_login (nexpose_data)
8
+ def nexpose_login(nexpose_data)
9
9
  @nsc = Nexpose::Connection.new(nexpose_data[:nxconsole], nexpose_data[:nxuser], nexpose_data[:nxpasswd])
10
10
  @nsc.login
11
11
  end
@@ -32,10 +32,10 @@ module NexposeTicketing
32
32
  # - +csv_file_name+ - CSV File name.
33
33
  #
34
34
  def save_last_scans(csv_file_name, saved_file = nil, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
35
- report_config.add_filter('version', '1.1.0')
35
+ report_config.add_filter('version', '1.2.0')
36
36
  report_config.add_filter('query', Queries.last_scans)
37
37
  report_output = report_config.generate(@nsc)
38
- csv_output = CSV.parse(report_output.chomp, headers: :first_row )
38
+ csv_output = CSV.parse(report_output.chomp, headers: :first_row)
39
39
  saved_file.open(csv_file_name, 'w') { |file| file.puts(csv_output) } unless saved_file.nil?
40
40
  if saved_file.nil?
41
41
  File.open(csv_file_name, 'w') { |file| file.puts(csv_output) }
@@ -48,7 +48,7 @@ module NexposeTicketing
48
48
  # - A hash with site_ids => last_scan_id
49
49
  #
50
50
  def last_scans(report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
51
- report_config.add_filter('version', '1.1.0')
51
+ report_config.add_filter('version', '1.2.0')
52
52
  report_config.add_filter('query', Queries.last_scans)
53
53
  report_output = report_config.generate(@nsc).chomp
54
54
  nexpose_sites = Hash.new(-1)
@@ -64,13 +64,14 @@ module NexposeTicketing
64
64
  # - +site_options+ - A Hash with site(s) and severity level.
65
65
  #
66
66
  # * *Returns* :
67
- # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id| |url| |summary| |fix|
67
+ # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
68
+ # |url| |summary| |fix|
68
69
  #
69
70
  def all_vulns(site_options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
70
71
  sites = Array(site_options[:sites])
71
72
  severity = site_options[:severity].nil? ? 0 : site_options[:severity]
72
- report_config.add_filter('version', '1.1.0')
73
- report_config.add_filter('query', Queries.all_delta_vulns)
73
+ report_config.add_filter('version', '1.2.0')
74
+ report_config.add_filter('query', Queries.all_new_vulns)
74
75
  unless sites.empty?
75
76
  sites.each do |site_id|
76
77
  report_config.add_filter('site', site_id)
@@ -80,21 +81,65 @@ module NexposeTicketing
80
81
  report_config.generate(@nsc)
81
82
  end
82
83
 
83
- # Gets the delta vulns from base scan reported_scan_id and the newest / latest scan from a site.
84
+ # Gets the new vulns from base scan reported_scan_id and the newest / latest scan from a site.
84
85
  #
85
86
  # * *Args* :
86
87
  # - +site_options+ - A Hash with site(s), reported_scan_id and severity level.
87
88
  #
88
89
  # * *Returns* :
89
- # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id| |url| |summary| |fix|
90
+ # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
91
+ # |url| |summary| |fix|
90
92
  #
91
- def delta_vulns_sites(site_options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
93
+ def new_vulns_sites(site_options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
92
94
  site = site_options[:site_id]
93
95
  reported_scan_id = site_options[:scan_id]
94
96
  fail 'Site cannot be null or empty' if site.nil? || reported_scan_id.nil?
95
97
  severity = site_options[:severity].nil? ? 0 : site_options[:severity]
96
- report_config.add_filter('version', '1.1.0')
97
- report_config.add_filter('query', Queries.delta_vulns_since_scan(reported_scan_id))
98
+ report_config.add_filter('version', '1.2.0')
99
+ report_config.add_filter('query', Queries.new_vulns_since_scan(reported_scan_id))
100
+ report_config.add_filter('site', site)
101
+ report_config.add_filter('vuln-severity', severity)
102
+ report_config.generate(@nsc)
103
+ end
104
+
105
+ # Gets the old vulns from base scan reported_scan_id and the newest / latest scan from a site.
106
+ #
107
+ # * *Args* :
108
+ # - +site_options+ - A Hash with site(s), reported_scan_id and severity level.
109
+ #
110
+ # * *Returns* :
111
+ # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
112
+ # |url| |summary| |fix|
113
+ #
114
+ def old_vulns_sites(site_options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
115
+ site = site_options[:site_id]
116
+ reported_scan_id = site_options[:scan_id]
117
+ fail 'Site cannot be null or empty' if site.nil? || reported_scan_id.nil?
118
+ severity = site_options[:severity].nil? ? 0 : site_options[:severity]
119
+ report_config.add_filter('version', '1.2.0')
120
+ report_config.add_filter('query', Queries.old_vulns_since_scan(reported_scan_id))
121
+ report_config.add_filter('site', site)
122
+ report_config.add_filter('vuln-severity', severity)
123
+ report_config.generate(@nsc)
124
+ end
125
+
126
+ # Gets all vulns from base scan reported_scan_id and the newest / latest scan from a site. This is
127
+ # used for IP-based issue updating. Includes the baseline comparision value ('Old','New', or 'Same').
128
+ #
129
+ # * *Args* :
130
+ # - +site_options+ - A Hash with site(s), reported_scan_id and severity level.
131
+ #
132
+ # * *Returns* :
133
+ # - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
134
+ # |url| |summary| |fix| |comparison|
135
+ #
136
+ def all_vulns_sites(site_options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
137
+ site = site_options[:site_id]
138
+ reported_scan_id = site_options[:scan_id]
139
+ fail 'Site cannot be null or empty' if site.nil? || reported_scan_id.nil?
140
+ severity = site_options[:severity].nil? ? 0 : site_options[:severity]
141
+ report_config.add_filter('version', '1.2.0')
142
+ report_config.add_filter('query', Queries.all_vulns_since_scan(reported_scan_id))
98
143
  report_config.add_filter('site', site)
99
144
  report_config.add_filter('vuln-severity', severity)
100
145
  report_config.generate(@nsc)
@@ -53,8 +53,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53
53
  require 'fileutils'
54
54
  require 'nexpose_ticketing/ticket_repository'
55
55
 
56
- TICKET_SERVICE_CONFIG_PATH = File.join(File.dirname(__FILE__),'/config/ticket_service.config')
57
- LOGGER_FILE = File.join(File.dirname(__FILE__),'/log/ticket_service.log')
56
+ TICKET_SERVICE_CONFIG_PATH = File.join(File.dirname(__FILE__), '/config/ticket_service.config')
57
+ LOGGER_FILE = File.join(File.dirname(__FILE__), '/log/ticket_service.log')
58
58
 
59
59
  attr_accessor :helper_data, :nexpose_data, :options, :ticket_repository, :first_time, :nexpose_site_histories
60
60
 
@@ -75,7 +75,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75
75
 
76
76
  # Loads all the helpers.
77
77
  log_message('Loading helpers.')
78
- Dir[File.join(File.dirname(__FILE__),'/helpers/*.rb')].each do |file|
78
+ Dir[File.join(File.dirname(__FILE__), '/helpers/*.rb')].each do |file|
79
79
  log_message("Loading helper: #{file}")
80
80
  require_relative file
81
81
  end
@@ -103,7 +103,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103
103
  end
104
104
 
105
105
  # Prepares all the local and nexpose historical data.
106
- def prepare_historical_data(ticket_repository, options, historical_scan_file = File.join(File.dirname(__FILE__),"#{options[:file_name]}"))
106
+ def prepare_historical_data(ticket_repository, options,
107
+ historical_scan_file = File.join(File.dirname(__FILE__), "#{options[:file_name]}"))
107
108
  if File.exists?(historical_scan_file)
108
109
  log_message("Reading historical CSV file: #{historical_scan_file}.")
109
110
  file_site_histories = ticket_repository.read_last_scans(historical_scan_file)
@@ -118,20 +119,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118
119
  end
119
120
 
120
121
  # Generates a full site(s) report ticket(s).
121
- def all_site_report(ticket_repository, options, helper, historical_scan_file = File.join(File.dirname(__FILE__),"#{options[:file_name]}") )
122
+ def all_site_report(ticket_repository, options, helper,
123
+ historical_scan_file = File.join(File.dirname(__FILE__), "#{options[:file_name]}"))
122
124
  log_message('First time run, generating full vulnerability report.') if @first_time
123
125
  log_message('No site(s) specified, generating full vulnerability report.') if options[:sites].empty?
124
126
  all_delta_vulns = ticket_repository.all_vulns(severity: options[:severity])
125
127
  log_message('Preparing tickets.')
126
- tickets = helper.prepare_tickets(all_delta_vulns)
127
- helper.create_ticket(tickets)
128
+ tickets = helper.prepare_create_tickets(all_delta_vulns)
129
+ helper.create_tickets(tickets)
128
130
  log_message("Done processing, updating historical CSV file #{historical_scan_file}.")
129
131
  ticket_repository.save_last_scans(historical_scan_file)
130
132
  log_message('Done updating historical CSV file, service shutting down.')
131
133
  end
132
134
 
133
135
  # There's possibly a new scan with new data.
134
- def delta_site_report(ticket_repository, options, helper, file_site_histories, historical_scan_file = File.join(File.dirname(__FILE__),"#{options[:file_name]}"))
136
+ def delta_site_report(ticket_repository, options, helper, file_site_histories,
137
+ historical_scan_file = File.join(File.dirname(__FILE__), "#{options[:file_name]}"))
135
138
  # Compares the Scan information from the File && Nexpose.
136
139
  no_processing = true
137
140
  @nexpose_site_histories.each do |site_id, scan_id|
@@ -158,22 +161,56 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
158
161
  log_message("New site id: #{site_id} detected. Generating report.")
159
162
  new_site_vuln = ticket_repository.all_vulns(sites: [site_id], severity: options[:severity])
160
163
  log_message('Report generated, preparing tickets.')
161
- ticket = helper.prepare_tickets(new_site_vuln)
162
- helper.create_ticket(ticket)
164
+ ticket = helper.prepare_create_tickets(new_site_vuln)
165
+ helper.create_tickets(ticket)
163
166
  end
164
167
 
165
168
  # There's a new scan with possibly new vulnerabilities.
166
169
  def delta_site_new_scan(ticket_repository, site_id, options, helper, file_site_histories)
167
170
  log_message("New scan detected for site: #{site_id}. Generating report.")
168
- new_scan_vuln = ticket_repository.delta_vulns_sites(scan_id: file_site_histories[site_id], site_id: site_id, severity: options[:severity])
169
- # Preparse for an empty report: No new vulns between scans.
170
- preparse = CSV.new(new_scan_vuln.chomp, headers: :first_row)
171
- empty_report = preparse.shift.nil?
172
- log_message("No new vulnerabilities found in new scan for site: #{site_id}.") && empty_report
173
- log_message("New vulnerabilities found in new scan for site #{site_id}, preparing tickets.") unless empty_report
174
- unless empty_report
175
- ticket = helper.prepare_tickets(new_scan_vuln)
176
- helper.create_ticket(ticket)
171
+
172
+ if options[:ticket_mode] == 'I'
173
+ # I-mode tickets require updating the tickets in the target system.
174
+ log_message("Scan id for new scan: #{file_site_histories[site_id]}.")
175
+ all_scan_vuln = ticket_repository.all_vulns_sites(scan_id: file_site_histories[site_id],
176
+ site_id: site_id,
177
+ severity: options[:severity])
178
+ if helper.respond_to?("prepare_update_tickets") && helper.respond_to?("update_tickets")
179
+ tickets = helper.prepare_update_tickets(all_scan_vuln)
180
+ helper.update_tickets(tickets)
181
+ else
182
+ log_message("Helper does not implement update methods")
183
+ fail "Helper using 'I' mode must implement prepare_updates and update_tickets"
184
+ end
185
+ else
186
+ # D-mode tickets require creating new tickets and closing old tickets.
187
+ new_scan_vuln = ticket_repository.new_vulns_sites(scan_id: file_site_histories[site_id], site_id: site_id,
188
+ severity: options[:severity])
189
+ preparse = CSV.new(new_scan_vuln.chomp, headers: :first_row)
190
+ empty_report = preparse.shift.nil?
191
+ log_message("No new vulnerabilities found in new scan for site: #{site_id}.") if empty_report
192
+ log_message("New vulnerabilities found in new scan for site #{site_id}, preparing tickets.") unless empty_report
193
+ unless empty_report
194
+ tickets = helper.prepare_create_tickets(new_scan_vuln)
195
+ helper.create_tickets(tickets)
196
+ end
197
+
198
+ if helper.respond_to?("prepare_close_tickets") && helper.respond_to?("close_tickets")
199
+ old_scan_vuln = ticket_repository.old_vulns_sites(scan_id: file_site_histories[site_id], site_id: site_id,
200
+ severity: options[:severity])
201
+ preparse = CSV.new(old_scan_vuln.chomp, headers: :first_row)
202
+ empty_report = preparse.shift.nil?
203
+ log_message("No old (closed) vulnerabilities found in new scan for site: #{site_id}.") if empty_report
204
+ log_message("Old vulnerabilities found in new scan for site #{site_id}, preparing closures.") unless empty_report
205
+ unless empty_report
206
+ tickets = helper.prepare_close_tickets(old_scan_vuln)
207
+ helper.close_tickets(tickets)
208
+ end
209
+ else
210
+ # Create a log message but do not halt execution of the helper if ticket closeing is not
211
+ # supported to allow legacy code to execute normally.
212
+ log_message("Helper does not impelment close methods.")
213
+ end
177
214
  end
178
215
  end
179
216
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'nexpose_ticketing'
5
- s.version = '0.0.1'
5
+ s.version = '0.2.1'
6
6
  s.homepage = 'https://github.com/rapid7/nexpose_ticketing'
7
7
  s.summary = 'Ruby Nexpose Ticketing Engine.'
8
8
  s.description = 'This gem provides a Ruby implementation of different integrations with ticketing services for Nexpose.'
@@ -11,9 +11,10 @@ Gem::Specification.new do |s|
11
11
  s.email = ['damian_finol@rapid7.com']
12
12
  s.files = Dir['[A-Z]*'] + Dir['lib/**/*']
13
13
  s.require_paths = ['lib']
14
- s.extra_rdoc_files = ['README.markdown']
14
+ s.extra_rdoc_files = ['README.md']
15
15
  s.required_ruby_version = '>= 1.9'
16
16
  s.platform = 'ruby'
17
- s.executables << 'nexpose_jira'
17
+ s.executables = ['nexpose_jira','nexpose_servicenow','nexpose_remedy']
18
18
  s.add_dependency('nexpose', '>= 0.6.0')
19
- end
19
+ s.add_dependency('savon', '~> 2.1')
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexpose_ticketing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damian Finol
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-07 00:00:00.000000000 Z
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nexpose
@@ -24,22 +24,47 @@ dependencies:
24
24
  - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: savon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
27
41
  description: This gem provides a Ruby implementation of different integrations with
28
42
  ticketing services for Nexpose.
29
43
  email:
30
44
  - damian_finol@rapid7.com
31
45
  executables:
32
46
  - nexpose_jira
47
+ - nexpose_servicenow
48
+ - nexpose_remedy
33
49
  extensions: []
34
50
  extra_rdoc_files:
35
- - README.markdown
51
+ - README.md
36
52
  files:
37
- - README.markdown
53
+ - README.md
38
54
  - bin/nexpose_jira
55
+ - bin/nexpose_remedy
56
+ - bin/nexpose_servicenow
39
57
  - lib/nexpose_ticketing.rb
40
58
  - lib/nexpose_ticketing/config/jira.config
59
+ - lib/nexpose_ticketing/config/remedy.config
60
+ - lib/nexpose_ticketing/config/remedy_wsdl/HPD_IncidentInterface_Create_WS.xml
61
+ - lib/nexpose_ticketing/config/remedy_wsdl/HPD_IncidentInterface_WS.xml
62
+ - lib/nexpose_ticketing/config/servicenow.config
41
63
  - lib/nexpose_ticketing/config/ticket_service.config
42
64
  - lib/nexpose_ticketing/helpers/jira_helper.rb
65
+ - lib/nexpose_ticketing/helpers/remedy_helper.rb
66
+ - lib/nexpose_ticketing/helpers/servicenow_helper.rb
67
+ - lib/nexpose_ticketing/nx_logger.rb
43
68
  - lib/nexpose_ticketing/queries.rb
44
69
  - lib/nexpose_ticketing/ticket_repository.rb
45
70
  - lib/nexpose_ticketing/ticket_service.rb