nexpose 0.0.92 → 0.0.93

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