nexpose_ticketing 0.0.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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