nexpose 0.0.98 → 0.1.0

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