nexpose 0.0.92 → 0.0.93

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.
Files changed (3) hide show
  1. data/lib/nexpose/scan_engine.rb +264 -140
  2. data/nexpose.gemspec +1 -1
  3. metadata +6 -6
@@ -1,124 +1,134 @@
1
1
  module Nexpose
2
2
 
3
- # ==== Description
4
- # Object that represents a listing of all of the scan engines available on to an NSC.
5
- #
6
- class EngineListing
7
- # true if an error condition exists; false otherwise
8
- attr_reader :error
9
- # Error message string
10
- attr_reader :error_msg
11
- # The last XML request sent by this object
12
- attr_reader :request_xml
13
- # The last XML response received by this object
14
- attr_reader :response_xml
15
- # The NSC Connection associated with this object
16
- attr_reader :connection
17
- # Array containing (EngineSummary*)
18
- attr_reader :engines
19
- # The number of scan engines
20
- attr_reader :engine_count
21
-
22
- # Constructor
23
- # EngineListing (connection)
24
- def initialize(connection)
25
- @connection = connection
26
- @engines = []
27
- @engine_count = 0
28
- @error = false
29
- r = @connection.execute('<EngineListingRequest session-id="' + @connection.session_id + '"/>', '1.2')
30
-
31
- if (r.success)
32
- r.res.elements.each('EngineListingResponse/EngineSummary') do |v|
33
- @engines.push(EngineSummary.new(v.attributes['id'], v.attributes['name'], v.attributes['address'],
34
- v.attributes['port'], v.attributes['status']))
35
- end
36
- else
37
- @error = true
38
- @error_msg = 'EngineListingRequest Parse Error'
39
- end
40
- @engine_count = @engines.length
41
- end
42
- end
43
-
44
- # TODO
45
- class EngineActivity
46
- # true if an error condition exists; false otherwise
47
- attr_reader :error
48
- # Error message string
49
- attr_reader :error_msg
50
- # The last XML request sent by this object
51
- attr_reader :request_xml
52
- # The last XML response received by this object
53
- attr_reader :response_xml
54
- # The NSC Connection associated with this object
55
- attr_reader :connection
56
- # The Engine ID
57
- attr_reader :engine_id
58
- # Array containing (ScanSummary*)
59
- attr_reader :scan_summaries
60
- end
61
-
62
- # ==== Description
63
- # Object that represents the summary of a scan engine.
64
- #
65
- # ==== Examples
66
- #
67
- # # Create a new Nexpose Connection on the default port and Login
68
- # nsc = Connection.new("10.1.40.10","nxadmin","password")
69
- # nsc.login()
70
- #
71
- # # Get the engine listing for the connection
72
- # enginelisting = EngineListing.new(nsc)
73
- #
74
- # # Print out the status of the first scan engine
75
- # puts enginelisting.engines[0].status
76
- #
77
- class EngineSummary
78
- # A unique ID that identifies this scan engine
79
- attr_reader :id
80
- # The name of this scan engine
81
- attr_reader :name
82
- # The hostname or IP address of the engine
83
- attr_reader :address
84
- # The port there the engine is listening
85
- attr_reader :port
86
- # The engine status (active|pending-auth| incompatible|not-responding|unknown)
87
- attr_reader :status
88
-
89
- # Constructor
90
- # EngineSummary(id, name, address, port, status)
91
- def initialize(id, name, address, port, status)
92
- @id = id
93
- @name = name
94
- @address = address
95
- @port = port
96
- @status = status
97
- end
98
-
99
- end
100
-
101
- #-------------------------------------------------------------------------------------------------------------------
102
- #
103
- #-------------------------------------------------------------------------------------------------------------------
104
- class EngineConfig
105
- attr_accessor :id
106
- attr_accessor :address
107
- attr_accessor :name
108
- attr_accessor :port
109
- attr_accessor :scope
110
- attr_accessor :sites
111
- attr_accessor :priority
112
-
113
- def initialize(connection, id = -1)
114
- @connection = connection
115
- @id = id
116
- @address = nil
117
- @name = nil
118
- @port = 40814
119
- @scope = 'silo'
120
- @priority = 'normal'
121
- @sites = []
3
+ # ==== Description
4
+ # Object that represents a listing of all of the scan engines available on to an NSC.
5
+ #
6
+ class EngineListing
7
+ # true if an error condition exists; false otherwise
8
+ attr_reader :error
9
+ # Error message string
10
+ attr_reader :error_msg
11
+ # The last XML request sent by this object
12
+ attr_reader :request_xml
13
+ # The last XML response received by this object
14
+ attr_reader :response_xml
15
+ # The NSC Connection associated with this object
16
+ attr_reader :connection
17
+ # Array containing (EngineSummary*)
18
+ attr_reader :engines
19
+ # The number of scan engines
20
+ attr_reader :engine_count
21
+
22
+ # Constructor
23
+ # EngineListing (connection)
24
+ def initialize(connection)
25
+ @connection = connection
26
+ @engines = []
27
+ @engine_count = 0
28
+ @error = false
29
+ r = @connection.execute('<EngineListingRequest session-id="' + @connection.session_id + '"/>', '1.2')
30
+
31
+ if (r.success)
32
+ r.res.elements.each('EngineListingResponse/EngineSummary') do |v|
33
+ @engines.push(EngineSummary.new(v.attributes['id'], v.attributes['name'], v.attributes['address'],
34
+ v.attributes['port'], v.attributes['status']))
35
+ end
36
+ else
37
+ @error = true
38
+ @error_msg = 'EngineListingRequest Parse Error'
39
+ end
40
+ @engine_count = @engines.length
41
+ end
42
+ end
43
+
44
+ # TODO
45
+ class EngineActivity
46
+ # true if an error condition exists; false otherwise
47
+ attr_reader :error
48
+ # Error message string
49
+ attr_reader :error_msg
50
+ # The last XML request sent by this object
51
+ attr_reader :request_xml
52
+ # The last XML response received by this object
53
+ attr_reader :response_xml
54
+ # The NSC Connection associated with this object
55
+ attr_reader :connection
56
+ # The Engine ID
57
+ attr_reader :engine_id
58
+ # Array containing (ScanSummary*)
59
+ attr_reader :scan_summaries
60
+ end
61
+
62
+ # ==== Description
63
+ # Object that represents the summary of a scan engine.
64
+ #
65
+ # ==== Examples
66
+ #
67
+ # # Create a new Nexpose Connection on the default port and Login
68
+ # nsc = Connection.new("10.1.40.10","nxadmin","password")
69
+ # nsc.login()
70
+ #
71
+ # # Get the engine listing for the connection
72
+ # enginelisting = EngineListing.new(nsc)
73
+ #
74
+ # # Print out the status of the first scan engine
75
+ # puts enginelisting.engines[0].status
76
+ #
77
+ class EngineSummary
78
+ # A unique ID that identifies this scan engine
79
+ attr_reader :id
80
+ # The name of this scan engine
81
+ attr_reader :name
82
+ # The hostname or IP address of the engine
83
+ attr_reader :address
84
+ # The port there the engine is listening
85
+ attr_reader :port
86
+ # The engine status (active|pending-auth| incompatible|not-responding|unknown)
87
+ attr_reader :status
88
+ # A parameter that specifies whether the engine has a global
89
+ # or silo-specific scope.
90
+ attr_reader :scope
91
+
92
+ # Constructor
93
+ # EngineSummary(id, name, address, port, status, scope)
94
+ def initialize(id, name, address, port, status, scope = 'silo')
95
+ @id = id
96
+ @name = name
97
+ @address = address
98
+ @port = port
99
+ @status = status
100
+ @scope = scope
101
+ end
102
+
103
+ def to_s
104
+ "Engine: #{@name} [ID: #{@id}] #{@address}:#{@port}, Status: #{@status}, Scope: #{@scope}"
105
+ end
106
+ end
107
+
108
+ #-------------------------------------------------------------------------------------------------------------------
109
+ #
110
+ #-------------------------------------------------------------------------------------------------------------------
111
+ class EngineConfig
112
+ attr_accessor :id
113
+ attr_accessor :address
114
+ attr_accessor :name
115
+ attr_accessor :port
116
+ attr_accessor :scope
117
+ attr_accessor :priority
118
+
119
+ # An array of site IDs. Currently do not support 'name' value,
120
+ # which is optional in the API.
121
+ attr_accessor :sites
122
+
123
+ def initialize(connection, id = -1)
124
+ @connection = connection
125
+ @id = id
126
+ @address = nil
127
+ @name = nil
128
+ @port = 40814
129
+ @scope = 'silo'
130
+ @priority = 'normal'
131
+ @sites = []
122
132
 
123
133
  # If valid ID provided, retrieve data from server.
124
134
  if (id > 0)
@@ -145,6 +155,10 @@ module Nexpose
145
155
  end
146
156
  end
147
157
 
158
+ def add_site(siteID)
159
+ sites << siteID
160
+ end
161
+
148
162
  def to_xml
149
163
  xml = '<EngineConfig'
150
164
  xml << %Q{ id="#{id}"}
@@ -153,8 +167,11 @@ module Nexpose
153
167
  xml << %Q{ port="#{port}"}
154
168
  xml << %Q{ scope="#{scope}"}
155
169
  xml << %Q{ priority="#{priority}"} if (priority)
156
- # TODO: xml << %Q{ sites="#{sites}"} if (sites)
157
- xml << ' />'
170
+ xml << '>'
171
+ #sites.each do |site|
172
+ #xml << %Q{<Site id="#{site}" />}
173
+ #end
174
+ xml << '</EngineConfig>'
158
175
  xml
159
176
  end
160
177
 
@@ -170,44 +187,49 @@ module Nexpose
170
187
  xml << '</EngineSaveRequest>'
171
188
 
172
189
  r = @connection.execute(xml, '1.2')
173
- unless (r.success)
190
+ if (r.success)
191
+ r.res.elements.each('EngineSaveResponse/EngineConfig') do |v|
192
+ @id = v.attributes['id']
193
+ end
194
+ else (r.success)
174
195
  @error = true
175
196
  @error_msg = 'EngineSaveRequest Parse Error'
176
197
  end
177
198
  end
178
199
  end
179
200
 
180
- #-------------------------------------------------------------------------------------------------------------------
181
201
  # Core objects for creating an engine pool
182
202
  # Example usage:
183
203
  # pool = EnginePool.new('East Coast Pool')
184
204
  # pool.add('New York Engine')
185
205
  # pool.add('Georgia Engine')
186
- # id = pool.create(@nsc)
187
- #-------------------------------------------------------------------------------------------------------------------
188
- class EnginePool
189
- attr_accessor :name
190
- attr_accessor :scope
191
- attr_accessor :engines
192
-
193
- def initialize(name, scope = 'silo')
194
- @name = name
195
- @scope = scope
206
+ # pool.create(@nsc)
207
+ class EnginePool
208
+ attr_accessor :id
209
+ attr_accessor :name
210
+ attr_accessor :scope
211
+ # Array containing (EngineSummary*)
212
+ attr_accessor :engines
213
+
214
+ def initialize(name, id = -1, scope = 'silo')
215
+ @name = name
216
+ @id = id
217
+ @scope = scope
196
218
  @engines = []
197
219
  end
198
220
 
199
221
  # Add an engine to the pool by name (not ID).
222
+ # Only use this for creating pools.
200
223
  def add(engine)
201
- engines << engine
224
+ @engines << EngineSummary.new(-1, engine, 'nowhere', 40814, 'unknown')
202
225
  end
203
226
 
204
- # Create an engine pool from the existing configuration.
205
- # Returns the engine ID assigned to the pool, if successful.
227
+ # Creates a new engine pool, and adds scan engines to the pool.
206
228
  def create(connection)
207
229
  xml = '<EnginePoolCreateRequest session-id="' + connection.session_id + '">'
208
- xml << %Q{<EnginePool name="#{name}" scope="#{scope}">}
209
- engines.each do |engine|
210
- xml << %Q{<Engine name="#{engine}" />}
230
+ xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}">}
231
+ @engines.each do |engine|
232
+ xml << %Q{<Engine name="#{engine.name}" />}
211
233
  end
212
234
  xml << '</EnginePool>'
213
235
  xml << '</EnginePoolCreateRequest>'
@@ -215,12 +237,114 @@ module Nexpose
215
237
  r = connection.execute(xml, '1.2')
216
238
  if (r.success)
217
239
  r.res.elements.each('EnginePoolCreateResponse') do |v|
218
- return v.attributes['id']
240
+ @id = v.attributes['id']
219
241
  end
220
242
  else
221
243
  @error = true
222
244
  @error_msg = 'EnginePoolCreateResponse Parse Error'
223
245
  end
224
246
  end
247
+
248
+ # Deletes an engine pool
249
+ def delete(connection)
250
+ xml = '<EnginePoolDeleteRequest session-id="' + connection.session_id + '">'
251
+ xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}" />}
252
+ xml << '</EnginePoolDeleteRequest>'
253
+
254
+ r = connection.execute(xml, '1.2')
255
+ unless (r.success)
256
+ @error = true
257
+ @error_msg = 'EnginePoolDeleteResponse Parse Error'
258
+ end
259
+ end
260
+
261
+ # Updates a specific role with new information. An EnginePoolUpdate is
262
+ # similar to an EnginePoolCreate, except that an EnginePoolUpdate replaces
263
+ # any previously existing information with the new information specified in
264
+ # the EnginePoolUpdateRequest.
265
+ def update(connection)
266
+ xml = '<EnginePoolUpdateRequest session-id="' + connection.session_id + '">'
267
+ xml << %Q{<EnginePool id="#{@id}" name="#{@name}" scope="#{@scope}">}
268
+ @engines.each do |engine|
269
+ xml << %Q{<Engine name="#{engine.name}" />}
270
+ end
271
+ xml << '</EnginePool>'
272
+ xml << '</EnginePoolUpdateRequest>'
273
+
274
+ r = connection.execute(xml, '1.2')
275
+ if (r.success)
276
+ r.res.elements.each('EnginePoolUpdateResponse') do |v|
277
+ @id = v.attributes['id']
278
+ end
279
+ else
280
+ @error = true
281
+ @error_msg = 'EnginePoolCreateResponse Parse Error'
282
+ end
283
+ end
284
+
285
+ # Returns detailed information about a single engine pool.
286
+ def load_details(connection)
287
+ xml = '<EnginePoolDetailsRequest session-id="' + connection.session_id + '">'
288
+ xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}" />}
289
+ xml << '</EnginePoolDetailsRequest>'
290
+
291
+ r = connection.execute(xml, '1.2')
292
+ if (r.success)
293
+ r.res.elements.each('EnginePoolDetailsResponse/EnginePool') do |pool|
294
+ @id = pool.attributes['id']
295
+ @name = pool.attributes['name']
296
+ @scope = pool.attributes['scope']
297
+ @engines = []
298
+ r.res.elements.each('EnginePoolDetailsResponse/EnginePool/EngineSummary') do |summary|
299
+ @engines.push(EngineSummary.new(summary.attributes['id'],
300
+ summary.attributes['name'],
301
+ summary.attributes['address'],
302
+ summary.attributes['port'],
303
+ summary.attributes['status'],
304
+ summary.attributes['scope']))
305
+ end
306
+ end
307
+ else
308
+ @error = true
309
+ @error_msg = 'EnginePoolListingResponse Parse Error'
310
+ end
311
+ end
312
+
313
+ def to_s
314
+ "Engine Pool: #{@name} [ID: #{@id}], Scope: #{@scope}\n" + @engines.map { |engine| " #{engine}" }.join("\n")
315
+ end
316
+ end
317
+
318
+ # A summary of an engine pool.
319
+ class EnginePoolSummary
320
+ attr_reader :id
321
+ attr_reader :name
322
+ attr_reader :scope
323
+
324
+ def initialize(id, name, scope = 'silo')
325
+ @id = id
326
+ @name = name
327
+ @scope = scope
328
+ end
329
+
330
+ def to_s
331
+ "Engine Pool: #{@name} [ID: #{@id}], scope: #{@scope}"
332
+ end
333
+
334
+ # Returns a summary list of all engine pools.
335
+ def self.listing(connection)
336
+ xml = '<EnginePoolListingRequest session-id="' + connection.session_id + '" />'
337
+ r = connection.execute(xml, '1.2')
338
+ if (r.success)
339
+ list = []
340
+ r.res.elements.each('EnginePoolListingResponse/EnginePoolSummary') do |eps|
341
+ list << EnginePoolSummary.new(eps.attributes['id'], eps.attributes['name'], eps.attributes['scope'])
342
+ end
343
+ list
344
+ else
345
+ @error = true
346
+ @error_msg = 'EnginePoolListingResponse Parse Error'
347
+ end
348
+ end
225
349
  end
226
350
  end
data/nexpose.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  APP_NAME = "nexpose"
4
- VERSION = "0.0.92"
4
+ VERSION = "0.0.93"
5
5
  REVISION = "12878"
6
6
 
7
7
  Gem::Specification.new do |s|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexpose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.92
4
+ version: 0.0.93
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-05-02 00:00:00.000000000Z
13
+ date: 2012-05-03 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: librex
17
- requirement: &30053556 !ruby/object:Gem::Requirement
17
+ requirement: &28535568 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.0.32
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *30053556
25
+ version_requirements: *28535568
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rex
28
- requirement: &30053280 !ruby/object:Gem::Requirement
28
+ requirement: &28535292 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 1.0.2
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *30053280
36
+ version_requirements: *28535292
37
37
  description: This gem provides a Ruby API to the NeXpose vulnerability management
38
38
  product by Rapid7. This version is based on Metasploit SVN revision 12878
39
39
  email: