openvas-omp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/lib/openvas-omp.rb +899 -0
- data/test/helper.rb +18 -0
- data/test/test_openvas-omp.rb +6 -0
- metadata +134 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Vlatko Kosturjak
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= openvas-omp
|
2
|
+
|
3
|
+
This library is used for communication with OpenVAS manager over OMP
|
4
|
+
You can start, stop, pause and resume scan. Watch progress and status of
|
5
|
+
scan, download report, etc.
|
6
|
+
|
7
|
+
== Contributing to openvas-omp
|
8
|
+
|
9
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
10
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
11
|
+
* Fork the project
|
12
|
+
* Start a feature/bugfix branch
|
13
|
+
* Commit and push until you are happy with your contribution
|
14
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
15
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
16
|
+
|
17
|
+
== Copyright
|
18
|
+
|
19
|
+
Copyright (c) 2010 Vlatko Kosturjak. See LICENSE.txt for
|
20
|
+
further details.
|
21
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "openvas-omp"
|
16
|
+
gem.homepage = "http://github.com/kost/openvas-omp"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Communicate with OpenVAS manager through OMP}
|
19
|
+
gem.description = %Q{Communicate with OpenVAS manager through OMP.
|
20
|
+
This library is used for communication with OpenVAS manager over OMP.
|
21
|
+
You can start, stop, pause and resume scan. Watch progress and status of
|
22
|
+
scan, download report, etc.}
|
23
|
+
gem.email = "vlatko.kosturjak@gmail.com"
|
24
|
+
gem.authors = ["Vlatko Kosturjak"]
|
25
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
26
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
27
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
28
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
29
|
+
gem.rubyforge_project = "openvas-omp"
|
30
|
+
end
|
31
|
+
Jeweler::RubygemsDotOrgTasks.new
|
32
|
+
|
33
|
+
require 'rake/testtask'
|
34
|
+
Rake::TestTask.new(:test) do |test|
|
35
|
+
test.libs << 'lib' << 'test'
|
36
|
+
test.pattern = 'test/**/test_*.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'rcov/rcovtask'
|
41
|
+
Rcov::RcovTask.new do |test|
|
42
|
+
test.libs << 'test'
|
43
|
+
test.pattern = 'test/**/test_*.rb'
|
44
|
+
test.verbose = true
|
45
|
+
end
|
46
|
+
|
47
|
+
task :default => :test
|
48
|
+
|
49
|
+
require 'rake/rdoctask'
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
51
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "openvas-omp #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/openvas-omp.rb
ADDED
@@ -0,0 +1,899 @@
|
|
1
|
+
#
|
2
|
+
# = openvas-omp.rb: communicate with OpenVAS manager over OMP
|
3
|
+
#
|
4
|
+
# Author:: Vlatko Kosturjak
|
5
|
+
#
|
6
|
+
# (C) Vlatko Kosturjak, Kost. Distributed under MIT license:
|
7
|
+
# http://www.opensource.org/licenses/mit-license.php
|
8
|
+
#
|
9
|
+
# == What is this library?
|
10
|
+
#
|
11
|
+
# This library is used for communication with OpenVAS manager over OMP
|
12
|
+
# You can start, stop, pause and resume scan. Watch progress and status of
|
13
|
+
# scan, download report, etc.
|
14
|
+
#
|
15
|
+
# == Requirements
|
16
|
+
#
|
17
|
+
# Required libraries are standard Ruby libraries: socket,timeout,openssl,
|
18
|
+
# rexml/document, rexml/text, base64
|
19
|
+
#
|
20
|
+
# == Usage:
|
21
|
+
#
|
22
|
+
# require 'openvas-omp'
|
23
|
+
|
24
|
+
require 'socket'
|
25
|
+
require 'timeout'
|
26
|
+
require 'openssl'
|
27
|
+
require 'rexml/document'
|
28
|
+
require 'rexml/text'
|
29
|
+
require 'base64'
|
30
|
+
|
31
|
+
# OpenVASOMP module
|
32
|
+
#
|
33
|
+
# Usage:
|
34
|
+
#
|
35
|
+
# require 'openvas-omp'
|
36
|
+
|
37
|
+
module OpenVASOMP
|
38
|
+
|
39
|
+
class OMPError < :: RuntimeError
|
40
|
+
attr_accessor :req, :reason
|
41
|
+
def initialize(req, reason = '')
|
42
|
+
self.req = req
|
43
|
+
self.reason = reason
|
44
|
+
end
|
45
|
+
def to_s
|
46
|
+
"OpenVAS OMP: #{self.reason}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class OMPResponseError < OMPError
|
51
|
+
def initialize
|
52
|
+
self.reason = "Error in OMP request/response"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class OMPAuthError < OMPError
|
57
|
+
def initialize
|
58
|
+
self.reason = "Authentication failed"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class XMLParsingError < OMPError
|
63
|
+
def initialize
|
64
|
+
self.reason = "XML parsing failed"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Class which uses standard REXML to parse OpenVAS replies.
|
69
|
+
class OpenVASOMP
|
70
|
+
# initialize object: try to connect to OpenVAS using URL, user and password
|
71
|
+
#
|
72
|
+
# Usage:
|
73
|
+
#
|
74
|
+
# ov=OpenVASOMP.new(user=>'user',password=>'pass')
|
75
|
+
# # default: host=>'localhost', port=>'9390'
|
76
|
+
#
|
77
|
+
def initialize(p={})
|
78
|
+
if p.has_key?("host")
|
79
|
+
@host=p["host"]
|
80
|
+
else
|
81
|
+
@host="localhost"
|
82
|
+
end
|
83
|
+
if p.has_key?("port")
|
84
|
+
@port=p["port"]
|
85
|
+
else
|
86
|
+
@port=9390
|
87
|
+
end
|
88
|
+
if p.has_key?("user")
|
89
|
+
@user=p["user"]
|
90
|
+
else
|
91
|
+
@user="openvas"
|
92
|
+
end
|
93
|
+
if p.has_key?("password")
|
94
|
+
@password=p["password"]
|
95
|
+
else
|
96
|
+
@password="openvas"
|
97
|
+
end
|
98
|
+
if p.has_key?("bufsize")
|
99
|
+
@bufsize=p["bufsize"]
|
100
|
+
else
|
101
|
+
@bufsize=16384
|
102
|
+
end
|
103
|
+
if p.has_key?("debug")
|
104
|
+
@debug=p["debug"]
|
105
|
+
else
|
106
|
+
@debug=0
|
107
|
+
end
|
108
|
+
|
109
|
+
if @debug>3
|
110
|
+
puts "Host: "+@host
|
111
|
+
puts "Port: "+@port.to_s()
|
112
|
+
puts "User: "+@user
|
113
|
+
end
|
114
|
+
if @debug>99
|
115
|
+
puts "Password: "+@password
|
116
|
+
end
|
117
|
+
@areq=''
|
118
|
+
@read_timeout=3
|
119
|
+
if defined? p["noautoconnect"] and not p["noautoconnect"]
|
120
|
+
connect()
|
121
|
+
if defined? p["noautologin"] and not p["noautologin"]
|
122
|
+
login()
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Sets debug level
|
128
|
+
#
|
129
|
+
# Usage:
|
130
|
+
#
|
131
|
+
# ov.debug(3)
|
132
|
+
#
|
133
|
+
def debug (level)
|
134
|
+
@debug=level
|
135
|
+
end
|
136
|
+
|
137
|
+
# Low level method - Connect to SSL socket
|
138
|
+
#
|
139
|
+
# Usage:
|
140
|
+
#
|
141
|
+
# ov.connect()
|
142
|
+
#
|
143
|
+
def connect
|
144
|
+
@plain_socket=TCPSocket.open(@host, @port)
|
145
|
+
ssl_context = OpenSSL::SSL::SSLContext.new()
|
146
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@plain_socket, ssl_context)
|
147
|
+
@socket.sync_close = true
|
148
|
+
@socket.connect
|
149
|
+
end
|
150
|
+
|
151
|
+
# Low level method - Disconnect SSL socket
|
152
|
+
#
|
153
|
+
# Usage:
|
154
|
+
#
|
155
|
+
# ov.disconnect()
|
156
|
+
#
|
157
|
+
def disconnect
|
158
|
+
if @socket
|
159
|
+
@socket.close
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Low level method: Send request and receive response - socket
|
164
|
+
#
|
165
|
+
# Usage:
|
166
|
+
#
|
167
|
+
# ov.connect();
|
168
|
+
# puts ov.sendrecv("<get_version/>")
|
169
|
+
# ov.disconnect();
|
170
|
+
#
|
171
|
+
def sendrecv (tosend)
|
172
|
+
if not @socket
|
173
|
+
connect
|
174
|
+
end
|
175
|
+
|
176
|
+
if @debug>3 then
|
177
|
+
puts "SENDING: "+tosend
|
178
|
+
end
|
179
|
+
@socket.puts(tosend)
|
180
|
+
|
181
|
+
@rbuf=''
|
182
|
+
size=0
|
183
|
+
begin
|
184
|
+
begin
|
185
|
+
timeout(@read_timeout) {
|
186
|
+
a = @socket.sysread(@bufsize)
|
187
|
+
size=a.length
|
188
|
+
# puts "sysread #{size} bytes"
|
189
|
+
@rbuf << a
|
190
|
+
}
|
191
|
+
rescue Timeout::Error
|
192
|
+
size=0
|
193
|
+
rescue EOFError
|
194
|
+
raise OMPResponseError
|
195
|
+
end
|
196
|
+
end while size>=@bufsize
|
197
|
+
response=@rbuf
|
198
|
+
|
199
|
+
if @debug>3 then
|
200
|
+
puts "RECEIVED: "+response
|
201
|
+
end
|
202
|
+
return response
|
203
|
+
end
|
204
|
+
|
205
|
+
# get OMP version (you don't need to be authenticated)
|
206
|
+
#
|
207
|
+
# Usage:
|
208
|
+
#
|
209
|
+
# ov.version_get()
|
210
|
+
#
|
211
|
+
def version_get
|
212
|
+
vreq="<get_version/>"
|
213
|
+
resp=sendrecv(vreq)
|
214
|
+
resp = "<X>"+resp+"</X>"
|
215
|
+
begin
|
216
|
+
docxml = REXML::Document.new(resp)
|
217
|
+
version=''
|
218
|
+
version=docxml.root.elements['get_version_response'].elements['version'].text
|
219
|
+
return version
|
220
|
+
rescue
|
221
|
+
raise XMLParsingError
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# produce single XML element with attributes specified as hash
|
226
|
+
# low-level function
|
227
|
+
#
|
228
|
+
# Usage:
|
229
|
+
#
|
230
|
+
# ov.xml_attr()
|
231
|
+
#
|
232
|
+
def xml_attr(name, opts={})
|
233
|
+
xml = REXML::Element.new(name)
|
234
|
+
opts.keys.each do |k|
|
235
|
+
xml.attributes[k] = opts[k]
|
236
|
+
end
|
237
|
+
return xml
|
238
|
+
end
|
239
|
+
|
240
|
+
# produce multiple XML elements with text specified as hash
|
241
|
+
# low-level function
|
242
|
+
#
|
243
|
+
# Usage:
|
244
|
+
#
|
245
|
+
# ov.xml_ele()
|
246
|
+
#
|
247
|
+
def xml_ele(name, child={})
|
248
|
+
xml = REXML::Element.new(name)
|
249
|
+
child.keys.each do |k|
|
250
|
+
xml.add_element(k)
|
251
|
+
xml.elements[k].text = child[k]
|
252
|
+
end
|
253
|
+
return xml
|
254
|
+
end
|
255
|
+
|
256
|
+
# produce multiple XML elements with text specified as hash
|
257
|
+
# also produce multiple XML elements with attributes
|
258
|
+
# low-level function
|
259
|
+
#
|
260
|
+
# Usage:
|
261
|
+
#
|
262
|
+
# ov.xml_mix()
|
263
|
+
#
|
264
|
+
def xml_mix(name, child, attr, elem)
|
265
|
+
xml = REXML::Element.new(name)
|
266
|
+
child.keys.each do |k|
|
267
|
+
xml.add_element(k)
|
268
|
+
xml.elements[k].text = child[k]
|
269
|
+
end
|
270
|
+
elem.keys.each do |k|
|
271
|
+
xml.add_element(k)
|
272
|
+
xml.elements[k].attributes[attr] = elem[k]
|
273
|
+
end
|
274
|
+
return xml
|
275
|
+
end
|
276
|
+
|
277
|
+
# login to OpenVAS server.
|
278
|
+
# if successful returns authentication XML for further usage
|
279
|
+
# if unsuccessful returns empty string
|
280
|
+
#
|
281
|
+
# Usage:
|
282
|
+
#
|
283
|
+
# ov.login()
|
284
|
+
#
|
285
|
+
def login
|
286
|
+
areq="<authenticate>"+xml_ele("credentials", {"username"=>@user, "password"=>@password}).to_s()+"</authenticate>"
|
287
|
+
resp=sendrecv(areq+"<HELP/>")
|
288
|
+
# wrap it inside tags, so rexml does not complain
|
289
|
+
resp = "<X>"+resp+"</X>"
|
290
|
+
|
291
|
+
begin
|
292
|
+
docxml = REXML::Document.new(resp)
|
293
|
+
status=docxml.root.elements['authenticate_response'].attributes['status'].to_i()
|
294
|
+
rescue
|
295
|
+
raise XMLParsingError
|
296
|
+
end
|
297
|
+
if status == 200
|
298
|
+
@areq=areq
|
299
|
+
else
|
300
|
+
raise OMPAuthError
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# check if we're successful logged in
|
305
|
+
# if successful returns true
|
306
|
+
# if unsuccessful returns false
|
307
|
+
#
|
308
|
+
# Usage:
|
309
|
+
#
|
310
|
+
# if ov.logged_in() then
|
311
|
+
# puts "logged in"
|
312
|
+
# end
|
313
|
+
#
|
314
|
+
def logged_in
|
315
|
+
if @areq == ''
|
316
|
+
return false
|
317
|
+
else
|
318
|
+
return true
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# logout from OpenVAS server.
|
323
|
+
# it actually just sets internal authentication XML to empty str
|
324
|
+
# (as in OMP you have to send username/password each time)
|
325
|
+
# (i.e. there is no session id)
|
326
|
+
#
|
327
|
+
# Usage:
|
328
|
+
#
|
329
|
+
# ov.logout()
|
330
|
+
#
|
331
|
+
def logout
|
332
|
+
disconnect()
|
333
|
+
@areq = ''
|
334
|
+
end
|
335
|
+
|
336
|
+
# OMP low level method - Send string request wrapped with
|
337
|
+
# authentication XML and return response as string
|
338
|
+
#
|
339
|
+
# Usage:
|
340
|
+
#
|
341
|
+
# ov.request_xml("<HELP/")
|
342
|
+
#
|
343
|
+
def omp_request_raw (request)
|
344
|
+
resp=sendrecv(@areq+request)
|
345
|
+
return resp
|
346
|
+
end
|
347
|
+
|
348
|
+
# OMP low level method - Send string request wrapped with
|
349
|
+
# authentication XML and return REXML parsed object
|
350
|
+
#
|
351
|
+
# Usage:
|
352
|
+
#
|
353
|
+
# rexmlobject = ov.request_xml("<HELP/")
|
354
|
+
#
|
355
|
+
def omp_request_xml (request)
|
356
|
+
resp=sendrecv(@areq+request)
|
357
|
+
resp = "<X>"+resp+"</X>"
|
358
|
+
|
359
|
+
begin
|
360
|
+
docxml = REXML::Document.new(resp)
|
361
|
+
status=docxml.root.elements['authenticate_response'].attributes['status'].to_i
|
362
|
+
if status<200 and status>299
|
363
|
+
raise OMPAuthError
|
364
|
+
end
|
365
|
+
return docxml.root
|
366
|
+
rescue
|
367
|
+
raise XMLParsingError
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
# OMP - Create target for scanning
|
372
|
+
#
|
373
|
+
# Usage:
|
374
|
+
#
|
375
|
+
# target_id = ov.target_create("name"=>"localhost",
|
376
|
+
# "hosts"=>"127.0.0.1","comment"=>"yes")
|
377
|
+
#
|
378
|
+
def target_create (p={})
|
379
|
+
xmlreq=xml_ele("create_target", p).to_s()
|
380
|
+
|
381
|
+
begin
|
382
|
+
xr=omp_request_xml(xmlreq)
|
383
|
+
id=xr.elements['create_target_response'].attributes['id']
|
384
|
+
rescue
|
385
|
+
raise OMPResponseError
|
386
|
+
end
|
387
|
+
return id
|
388
|
+
end
|
389
|
+
|
390
|
+
# OMP - Delete target
|
391
|
+
#
|
392
|
+
# Usage:
|
393
|
+
#
|
394
|
+
# ov.target_delete(target_id)
|
395
|
+
#
|
396
|
+
def target_delete (id)
|
397
|
+
xmlreq=xml_attr("delete_task",{"target_id" => id}).to_s()
|
398
|
+
begin
|
399
|
+
xr=omp_request_xml(xmlreq)
|
400
|
+
rescue
|
401
|
+
raise OMPResponseError
|
402
|
+
end
|
403
|
+
return xr
|
404
|
+
end
|
405
|
+
|
406
|
+
# OMP - Get target for scanning and returns rexml object
|
407
|
+
#
|
408
|
+
# Usage:
|
409
|
+
# rexmlobject = target_get_raw("target_id"=>target_id)
|
410
|
+
#
|
411
|
+
def target_get_raw (p={})
|
412
|
+
xmlreq=xml_attr("get_targets", p).to_s()
|
413
|
+
|
414
|
+
begin
|
415
|
+
xr=omp_request_xml(xmlreq)
|
416
|
+
return xr
|
417
|
+
rescue
|
418
|
+
raise OMPResponseError
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
# OMP - Get all targets for scanning and returns array of hashes
|
423
|
+
# with following keys: id,name,comment,hosts,max_hosts,in_use
|
424
|
+
#
|
425
|
+
# Usage:
|
426
|
+
# array_of_hashes = target_get_all()
|
427
|
+
#
|
428
|
+
def target_get_all (p={})
|
429
|
+
begin
|
430
|
+
xr=target_get_raw(p)
|
431
|
+
list=Array.new
|
432
|
+
xr.elements.each('//get_targets_response/target') do |target|
|
433
|
+
td=Hash.new
|
434
|
+
td["id"]=target.attributes["id"]
|
435
|
+
td["name"]=target.elements["name"].text
|
436
|
+
td["comment"]=target.elements["comment"].text
|
437
|
+
td["hosts"]=target.elements["hosts"].text
|
438
|
+
td["max_hosts"]=target.elements["max_hosts"].text
|
439
|
+
td["in_use"]=target.elements["in_use"].text
|
440
|
+
list.push td
|
441
|
+
end
|
442
|
+
return list
|
443
|
+
rescue
|
444
|
+
raise OMPResponseError
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def target_get_byid (id)
|
449
|
+
begin
|
450
|
+
xr=target_get_raw("target_id"=>id)
|
451
|
+
xr.elements.each('//get_targets_response/target') do |target|
|
452
|
+
td=Hash.new
|
453
|
+
td["id"]=target.attributes["id"]
|
454
|
+
td["name"]=target.elements["name"].text
|
455
|
+
td["comment"]=target.elements["comment"].text
|
456
|
+
td["hosts"]=target.elements["hosts"].text
|
457
|
+
td["max_hosts"]=target.elements["max_hosts"].text
|
458
|
+
td["in_use"]=target.elements["in_use"].text
|
459
|
+
return td
|
460
|
+
end
|
461
|
+
return list
|
462
|
+
rescue
|
463
|
+
raise OMPResponseError
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
# OMP - get reports and returns raw rexml object as response
|
468
|
+
#
|
469
|
+
# Usage:
|
470
|
+
#
|
471
|
+
# rexmlobject=ov.report_get_raw("format"=>"PDF")
|
472
|
+
#
|
473
|
+
# rexmlobject=ov.report_get_raw(
|
474
|
+
# "report_id" => "",
|
475
|
+
# "format"=>"PDF")
|
476
|
+
#
|
477
|
+
def report_get_raw (p={})
|
478
|
+
xmlreq=xml_attr("get_reports",p).to_s()
|
479
|
+
begin
|
480
|
+
xr=omp_request_xml(xmlreq)
|
481
|
+
rescue
|
482
|
+
raise OMPResponseError
|
483
|
+
end
|
484
|
+
return xr
|
485
|
+
end
|
486
|
+
|
487
|
+
# OMP - get report by id and format, returns report
|
488
|
+
# (already base64 decoded if needed)
|
489
|
+
#
|
490
|
+
# format can be: HTML, NBE, PDF, ...
|
491
|
+
#
|
492
|
+
# Usage:
|
493
|
+
#
|
494
|
+
# pdf_content=ov.report_get_byid(id,"PDF")
|
495
|
+
# File.open('report.pdf', 'w') {|f| f.write(pdf_content) }
|
496
|
+
#
|
497
|
+
def report_get_byid (id,format)
|
498
|
+
decode=Array["HTML","NBE","PDF"]
|
499
|
+
xr=report_get_raw("report_id"=>id,"format"=>format)
|
500
|
+
resp=xr.elements['get_reports_response'].elements['report'].text
|
501
|
+
if decode.include?(format)
|
502
|
+
resp=Base64.decode64(resp)
|
503
|
+
end
|
504
|
+
return resp
|
505
|
+
end
|
506
|
+
|
507
|
+
# OMP - get report all, returns report
|
508
|
+
#
|
509
|
+
# Usage:
|
510
|
+
#
|
511
|
+
# pdf_content=ov.report_get_all()
|
512
|
+
#
|
513
|
+
def report_get_all ()
|
514
|
+
begin
|
515
|
+
xr=report_get_raw("format"=>"NBE")
|
516
|
+
list=Array.new
|
517
|
+
xr.elements.each('//get_reports_response/report') do |report|
|
518
|
+
td=Hash.new
|
519
|
+
td["id"]=target.attributes["id"]
|
520
|
+
td["name"]=target.elements["name"].text
|
521
|
+
td["comment"]=target.elements["comment"].text
|
522
|
+
td["hosts"]=target.elements["hosts"].text
|
523
|
+
td["max_hosts"]=target.elements["max_hosts"].text
|
524
|
+
td["in_use"]=target.elements["in_use"].text
|
525
|
+
list.push td
|
526
|
+
end
|
527
|
+
return list
|
528
|
+
rescue
|
529
|
+
raise OMPResponseError
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
# OMP - get reports and returns raw rexml object as response
|
534
|
+
#
|
535
|
+
# Usage:
|
536
|
+
#
|
537
|
+
# rexmlobject=ov.result_get_raw("notes"=>0)
|
538
|
+
#
|
539
|
+
def result_get_raw (p={})
|
540
|
+
begin
|
541
|
+
xmlreq=xml_attr("get_results",p).to_s()
|
542
|
+
xr=omp_request_xml(xmlreq)
|
543
|
+
rescue
|
544
|
+
raise OMPResponseError
|
545
|
+
end
|
546
|
+
return xr
|
547
|
+
end
|
548
|
+
|
549
|
+
# OMP - get configs and returns rexml object as response
|
550
|
+
#
|
551
|
+
# Usage:
|
552
|
+
#
|
553
|
+
# rexmldocument=ov.config_get_raw()
|
554
|
+
#
|
555
|
+
def config_get_raw (p={})
|
556
|
+
xmlreq=xml_attr("get_configs",p).to_s()
|
557
|
+
begin
|
558
|
+
xr=omp_request_xml(xmlreq)
|
559
|
+
return xr
|
560
|
+
rescue
|
561
|
+
raise OMPResponseError
|
562
|
+
end
|
563
|
+
return false
|
564
|
+
end
|
565
|
+
|
566
|
+
# OMP - get configs and returns hash as response
|
567
|
+
# hash[config_id]=config_name
|
568
|
+
#
|
569
|
+
# Usage:
|
570
|
+
#
|
571
|
+
# array_of_hashes=ov.config_get_all()
|
572
|
+
#
|
573
|
+
def config_get_all (p={})
|
574
|
+
begin
|
575
|
+
xr=config_get_raw(p)
|
576
|
+
tc=Array.new
|
577
|
+
xr.elements.each('//get_configs_response/config') do |config|
|
578
|
+
c=Hash.new
|
579
|
+
c["id"]=config.attributes["id"]
|
580
|
+
c["name"]=config.elements["name"].text
|
581
|
+
c["comment"]=config.elements["comment"].text
|
582
|
+
tc.push c
|
583
|
+
end
|
584
|
+
return tc
|
585
|
+
rescue
|
586
|
+
raise OMPResponseError
|
587
|
+
end
|
588
|
+
return false
|
589
|
+
end
|
590
|
+
|
591
|
+
# OMP - get configs and returns hash as response
|
592
|
+
# hash[config_id]=config_name
|
593
|
+
#
|
594
|
+
# Usage:
|
595
|
+
#
|
596
|
+
# all_configs_hash=ov.config.get()
|
597
|
+
#
|
598
|
+
# config_id=ov.config_get().index("Full and fast")
|
599
|
+
#
|
600
|
+
def config_get (p={})
|
601
|
+
begin
|
602
|
+
xr=config_get_raw(p)
|
603
|
+
list=Hash.new
|
604
|
+
xr.elements.each('//get_configs_response/config') do |config|
|
605
|
+
id=config.attributes["id"]
|
606
|
+
name=config.elements["name"].text
|
607
|
+
list[id]=name
|
608
|
+
end
|
609
|
+
return list
|
610
|
+
rescue
|
611
|
+
raise OMPResponseError
|
612
|
+
end
|
613
|
+
return false
|
614
|
+
end
|
615
|
+
|
616
|
+
# OMP - copy config with new name and returns new id
|
617
|
+
#
|
618
|
+
# Usage:
|
619
|
+
#
|
620
|
+
# new_config_id=config_copy(config_id,"new_name");
|
621
|
+
#
|
622
|
+
def config_copy (config_id,name)
|
623
|
+
xmlreq=xml_attr("create_config",
|
624
|
+
{"copy"=>config_id,"name"=>name}).to_s()
|
625
|
+
begin
|
626
|
+
xr=omp_request_xml(xmlreq)
|
627
|
+
id=xr.elements['create_config_response'].attributes['id']
|
628
|
+
return id
|
629
|
+
rescue
|
630
|
+
raise OMPResponseError
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
634
|
+
# OMP - create config with specified RC file and returns new id
|
635
|
+
# name = name of new config
|
636
|
+
# rcfile = base64 encoded OpenVAS rcfile
|
637
|
+
#
|
638
|
+
# Usage:
|
639
|
+
#
|
640
|
+
# config_id=config_create("name",rcfile);
|
641
|
+
#
|
642
|
+
def config_create (name,rcfile)
|
643
|
+
xmlreq=xml_attr("create_config",
|
644
|
+
{"name"=>name,"rcfile"=>rcfile}).to_s()
|
645
|
+
begin
|
646
|
+
xr=omp_request_xml(xmlreq)
|
647
|
+
id=xr.elements['create_config_response'].attributes['id']
|
648
|
+
return id
|
649
|
+
rescue
|
650
|
+
raise OMPResponseError
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
# OMP - creates task and returns id of created task
|
655
|
+
#
|
656
|
+
# Parameters which usually fit in p hash and i hash:
|
657
|
+
# p = name,comment,rcfile
|
658
|
+
# i = config,target,escalator,schedule
|
659
|
+
#
|
660
|
+
# Usage:
|
661
|
+
#
|
662
|
+
# task_id=ov.task_create_raw()
|
663
|
+
#
|
664
|
+
def task_create_raw (p={}, i={})
|
665
|
+
xmlreq=xml_mix("create_task",p,"id",i).to_s()
|
666
|
+
begin
|
667
|
+
xr=omp_request_xml(xmlreq)
|
668
|
+
id=xr.elements['create_task_response'].attributes['id']
|
669
|
+
return id
|
670
|
+
rescue
|
671
|
+
raise OMPResponseError
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
# OMP - creates task and returns id of created task
|
676
|
+
#
|
677
|
+
# parameters = name,comment,rcfile,config,target,escalator,
|
678
|
+
# schedule
|
679
|
+
#
|
680
|
+
# Usage:
|
681
|
+
#
|
682
|
+
# config_id=o.config_get().index("Full and fast")
|
683
|
+
# target_id=o.target_create(
|
684
|
+
# {"name"=>"localtarget", "hosts"=>"127.0.0.1", "comment"=>"t"})
|
685
|
+
# task_id=ov.task_create(
|
686
|
+
# {"name"=>"testlocal","comment"=>"test", "target"=>target_id,
|
687
|
+
# "config"=>config_id}
|
688
|
+
#
|
689
|
+
def task_create (p={})
|
690
|
+
specials=Array["config","target","escalator","schedule"]
|
691
|
+
ids = Hash.new
|
692
|
+
specials.each do |spec|
|
693
|
+
if p.has_key?(spec)
|
694
|
+
ids[spec]=p[spec]
|
695
|
+
p.delete(spec)
|
696
|
+
end
|
697
|
+
end
|
698
|
+
return task_create_raw(p,ids)
|
699
|
+
end
|
700
|
+
|
701
|
+
# OMP - deletes task specified by task_id
|
702
|
+
#
|
703
|
+
# Usage:
|
704
|
+
#
|
705
|
+
# ov.task_delete(task_id)
|
706
|
+
#
|
707
|
+
def task_delete (task_id)
|
708
|
+
xmlreq=xml_attr("delete_task",{"task_id" => task_id}).to_s()
|
709
|
+
begin
|
710
|
+
xr=omp_request_xml(xmlreq)
|
711
|
+
rescue
|
712
|
+
raise OMPResponseError
|
713
|
+
end
|
714
|
+
return xr
|
715
|
+
end
|
716
|
+
|
717
|
+
# OMP - get task and returns raw rexml object as response
|
718
|
+
#
|
719
|
+
# Usage:
|
720
|
+
#
|
721
|
+
# rexmlobject=ov.task_get_raw("details"=>"0")
|
722
|
+
#
|
723
|
+
def task_get_raw (p={})
|
724
|
+
xmlreq=xml_attr("get_tasks",p).to_s()
|
725
|
+
begin
|
726
|
+
xr=omp_request_xml(xmlreq)
|
727
|
+
return xr
|
728
|
+
rescue
|
729
|
+
raise OMPResponseError
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
# OMP - get all tasks and returns array with hashes with
|
734
|
+
# following content:
|
735
|
+
# id,name,comment,status,progress,first_report,last_report
|
736
|
+
#
|
737
|
+
# Usage:
|
738
|
+
#
|
739
|
+
# array_of_hashes=ov.task_get_all()
|
740
|
+
#
|
741
|
+
def task_get_all (p={})
|
742
|
+
xr=task_get_raw(p)
|
743
|
+
t=Array.new
|
744
|
+
xr.elements.each('//get_tasks_response/task') do |task|
|
745
|
+
td=Hash.new
|
746
|
+
td["id"]=task.attributes["id"]
|
747
|
+
td["name"]=task.elements["name"].text
|
748
|
+
td["comment"]=task.elements["comment"].text
|
749
|
+
td["status"]=task.elements["status"].text
|
750
|
+
td["progress"]=task.elements["progress"].text
|
751
|
+
if defined? task.elements["first_report"].elements["report"].attributes["id"] then
|
752
|
+
td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"]
|
753
|
+
else
|
754
|
+
td["firstreport"]=nil
|
755
|
+
end
|
756
|
+
if defined? task.elements["last_report"].elements["report"].attributes["id"] then
|
757
|
+
td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"]
|
758
|
+
else
|
759
|
+
td["lastreport"]=nil
|
760
|
+
end
|
761
|
+
t.push td
|
762
|
+
end
|
763
|
+
return t
|
764
|
+
end
|
765
|
+
|
766
|
+
# OMP - get task specified by task_id and returns hash with
|
767
|
+
# following content:
|
768
|
+
# id,name,comment,status,progress,first_report,last_report
|
769
|
+
#
|
770
|
+
# Usage:
|
771
|
+
#
|
772
|
+
# hash=ov.task_get_byid(task_id)
|
773
|
+
#
|
774
|
+
def task_get_byid (id)
|
775
|
+
xr=task_get_raw("task_id"=>id,"details"=>0)
|
776
|
+
xr.elements.each('//get_tasks_response/task') do |task|
|
777
|
+
td=Hash.new
|
778
|
+
td["id"]=task.attributes["id"]
|
779
|
+
td["name"]=task.elements["name"].text
|
780
|
+
td["comment"]=task.elements["comment"].text
|
781
|
+
td["status"]=task.elements["status"].text
|
782
|
+
td["progress"]=task.elements["progress"].text
|
783
|
+
if defined? task.elements["first_report"].elements["report"].attributes["id"] then
|
784
|
+
td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"]
|
785
|
+
else
|
786
|
+
td["firstreport"]=nil
|
787
|
+
end
|
788
|
+
if defined? task.elements["last_report"].elements["report"].attributes["id"] then
|
789
|
+
td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"]
|
790
|
+
else
|
791
|
+
td["lastreport"]=nil
|
792
|
+
end
|
793
|
+
return (td)
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
# OMP - check if task specified by task_id is finished
|
798
|
+
# (it checks if task status is "Done" in OMP)
|
799
|
+
#
|
800
|
+
# Usage:
|
801
|
+
#
|
802
|
+
# if ov.task_finished(task_id)
|
803
|
+
# puts "Task finished"
|
804
|
+
# end
|
805
|
+
#
|
806
|
+
def task_finished (id)
|
807
|
+
xr=task_get_raw("task_id"=>id,"details"=>0)
|
808
|
+
xr.elements.each('//get_tasks_response/task') do |task|
|
809
|
+
if status=task.elements["status"].text == "Done"
|
810
|
+
return true
|
811
|
+
else
|
812
|
+
return false
|
813
|
+
end
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
# OMP - check progress of task specified by task_id
|
818
|
+
# (OMP returns -1 if task is finished, not started, etc)
|
819
|
+
#
|
820
|
+
# Usage:
|
821
|
+
#
|
822
|
+
# print "Progress: "
|
823
|
+
# puts ov.task_progress(task_id)
|
824
|
+
#
|
825
|
+
def task_progress (id)
|
826
|
+
xr=task_get_raw("task_id"=>id,"details"=>0)
|
827
|
+
xr.elements.each('//get_tasks_response/task') do |task|
|
828
|
+
return task.elements["progress"].text.to_i()
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
832
|
+
# OMP - starts task specified by task_id
|
833
|
+
#
|
834
|
+
# Usage:
|
835
|
+
#
|
836
|
+
# ov.task_start(task_id)
|
837
|
+
#
|
838
|
+
def task_start (task_id)
|
839
|
+
xmlreq=xml_attr("start_task",{"task_id" => task_id}).to_s()
|
840
|
+
begin
|
841
|
+
xr=omp_request_xml(xmlreq)
|
842
|
+
rescue
|
843
|
+
raise OMPResponseError
|
844
|
+
end
|
845
|
+
return xr
|
846
|
+
end
|
847
|
+
|
848
|
+
# OMP - stops task specified by task_id
|
849
|
+
#
|
850
|
+
# Usage:
|
851
|
+
#
|
852
|
+
# ov.task_stop(task_id)
|
853
|
+
#
|
854
|
+
def task_stop (task_id)
|
855
|
+
xmlreq=xml_attr("stop_task",{"task_id" => task_id}).to_s()
|
856
|
+
begin
|
857
|
+
xr=omp_request_xml(xmlreq)
|
858
|
+
rescue
|
859
|
+
raise OMPResponseError
|
860
|
+
end
|
861
|
+
return xr
|
862
|
+
end
|
863
|
+
|
864
|
+
# OMP - pauses task specified by task_id
|
865
|
+
#
|
866
|
+
# Usage:
|
867
|
+
#
|
868
|
+
# ov.task_pause(task_id)
|
869
|
+
#
|
870
|
+
def task_pause (task_id)
|
871
|
+
xmlreq=xml_attr("pause_task",{"task_id" => task_id}).to_s()
|
872
|
+
begin
|
873
|
+
xr=omp_request_xml(xmlreq)
|
874
|
+
rescue
|
875
|
+
raise OMPResponseError
|
876
|
+
end
|
877
|
+
return xr
|
878
|
+
end
|
879
|
+
|
880
|
+
# OMP - resumes (or starts) task specified by task_id
|
881
|
+
#
|
882
|
+
# Usage:
|
883
|
+
#
|
884
|
+
# ov.task_resume_or_start(task_id)
|
885
|
+
#
|
886
|
+
def task_resume_or_start (task_id)
|
887
|
+
xmlreq=xml_attr("resume_or_start_task",{"task_id" => task_id}).to_s()
|
888
|
+
begin
|
889
|
+
xr=omp_request_xml(xmlreq)
|
890
|
+
rescue
|
891
|
+
raise OMPResponseError
|
892
|
+
end
|
893
|
+
return xr
|
894
|
+
end
|
895
|
+
|
896
|
+
end # end of Class
|
897
|
+
|
898
|
+
end # of Module
|
899
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'openvas-omp'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: openvas-omp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Vlatko Kosturjak
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-29 00:00:00 +00:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: shoulda
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
prerelease: false
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 1
|
42
|
+
- 0
|
43
|
+
- 0
|
44
|
+
version: 1.0.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: jeweler
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 5
|
58
|
+
- 2
|
59
|
+
version: 1.5.2
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rcov
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
type: :development
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: *id004
|
76
|
+
description: |-
|
77
|
+
Communicate with OpenVAS manager through OMP.
|
78
|
+
This library is used for communication with OpenVAS manager over OMP.
|
79
|
+
You can start, stop, pause and resume scan. Watch progress and status of
|
80
|
+
scan, download report, etc.
|
81
|
+
email: vlatko.kosturjak@gmail.com
|
82
|
+
executables: []
|
83
|
+
|
84
|
+
extensions: []
|
85
|
+
|
86
|
+
extra_rdoc_files:
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.rdoc
|
89
|
+
files:
|
90
|
+
- .document
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.rdoc
|
94
|
+
- Rakefile
|
95
|
+
- VERSION
|
96
|
+
- lib/openvas-omp.rb
|
97
|
+
- test/helper.rb
|
98
|
+
- test/test_openvas-omp.rb
|
99
|
+
has_rdoc: true
|
100
|
+
homepage: http://github.com/kost/openvas-omp
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: -538062157
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
version: "0"
|
125
|
+
requirements: []
|
126
|
+
|
127
|
+
rubyforge_project: openvas-omp
|
128
|
+
rubygems_version: 1.3.7
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Communicate with OpenVAS manager through OMP
|
132
|
+
test_files:
|
133
|
+
- test/helper.rb
|
134
|
+
- test/test_openvas-omp.rb
|