openvas-cli 0.1.1 → 0.2.0

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 (42) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +50 -0
  3. data/VERSION +1 -1
  4. data/lib/openvas-cli/configuration.rb +25 -0
  5. data/lib/openvas-cli/conn_addin.rb +27 -0
  6. data/lib/openvas-cli/immutable_children_validator.rb +15 -0
  7. data/lib/openvas-cli/vas_administrator.rb +7 -0
  8. data/lib/openvas-cli/vas_base.rb +20 -30
  9. data/lib/openvas-cli/vas_config.rb +127 -0
  10. data/lib/openvas-cli/vas_connection.rb +140 -0
  11. data/lib/openvas-cli/vas_exceptions.rb +9 -7
  12. data/lib/openvas-cli/vas_lsc_credential.rb +110 -0
  13. data/lib/openvas-cli/vas_nvt.rb +64 -64
  14. data/lib/openvas-cli/vas_nvt_family.rb +39 -30
  15. data/lib/openvas-cli/vas_override.rb +6 -4
  16. data/lib/openvas-cli/vas_period.rb +89 -0
  17. data/lib/openvas-cli/vas_preference.rb +139 -49
  18. data/lib/openvas-cli/vas_report.rb +110 -103
  19. data/lib/openvas-cli/vas_result.rb +90 -89
  20. data/lib/openvas-cli/vas_schedule.rb +163 -55
  21. data/lib/openvas-cli/vas_target.rb +200 -23
  22. data/lib/openvas-cli/vas_task.rb +229 -30
  23. data/lib/openvas-cli/vas_task_progress.rb +29 -0
  24. data/lib/openvas-cli/xml_addin.rb +34 -0
  25. data/lib/openvas_cli.rb +19 -0
  26. data/openvas-cli.gemspec +28 -6
  27. data/spec/openvas-cli/vas_administrator_spec.rb +6 -0
  28. data/spec/openvas-cli/vas_config_spec.rb +81 -0
  29. data/spec/openvas-cli/vas_lsc_credential_spec.rb +72 -0
  30. data/spec/openvas-cli/vas_nvt_family_spec.rb +7 -5
  31. data/spec/openvas-cli/vas_nvt_spec.rb +30 -26
  32. data/spec/openvas-cli/vas_period_spec.rb +7 -0
  33. data/spec/openvas-cli/vas_preference_spec.rb +23 -21
  34. data/spec/openvas-cli/vas_report_spec.rb +65 -63
  35. data/spec/openvas-cli/vas_result_spec.rb +94 -93
  36. data/spec/openvas-cli/vas_schedule_spec.rb +154 -57
  37. data/spec/openvas-cli/vas_target_spec.rb +140 -28
  38. data/spec/openvas-cli/vas_task_spec.rb +92 -11
  39. data/spec/spec_helper.rb +15 -5
  40. metadata +72 -24
  41. data/lib/openvas-cli/openvas-cli.rb +0 -273
  42. data/spec/openvas-cli/openvas-cli_spec.rb +0 -45
@@ -1,28 +1,205 @@
1
1
  require 'nokogiri'
2
+ require 'ipaddress'
3
+ require 'vas_lsc_credential'
4
+ require 'vas_task'
2
5
 
3
- class VasTarget < VasBase
4
- attr_accessor :vas_id, :name, :hosts, :comment, :credential
5
-
6
- validates :vas_id, :UUID => true
7
-
8
- def self.get_all
9
- req = Nokogiri::XML::Builder.new { |xml|
10
- xml.get_targets(:tasks=>0)
11
- }
12
-
13
- targets = client.send_receive(req.doc)
6
+ module OpenvasCli
7
+ class VasTarget < VasBase
8
+ attr_reader :name
9
+ attr_reader :comment
10
+ attr_reader :port_range
11
+ attr_accessor :in_use
12
+
13
+ define_attribute_methods [:name, :comment, :port_range, :hosts]
14
+
15
+ def name=(val)
16
+ name_will_change! unless val == @name
17
+ @name = val
18
+ end
19
+
20
+ def comment=(val)
21
+ comment_will_change! unless val == @comment
22
+ @comment = val
23
+ end
24
+
25
+ def port_range=(val)
26
+ port_range_will_change! unless val == @port_range
27
+ @port_range = val
28
+ end
29
+
30
+ def changed?
31
+ local_changes = false
32
+ local_changes = !@org_hosts.eql?(@hosts) if @org_hosts
33
+
34
+ unless local_changes == true
35
+ local_changes = credential_changed?(:ssh) || credential_changed?(:smb)
36
+ end
37
+
38
+ local_changes || super
39
+ end
40
+
41
+ validates :id, :UUID => true, :if => Proc.new { |o| o.id }
42
+ validates :name, :presence => true, :length => { :minimum => 1 }
14
43
 
15
- ret = []
16
- targets.xpath('//target').each { |t|
17
- targ = VasTarget.new
18
- targ.vas_id = extract_value_from("@id", t)
19
- targ.name = extract_value_from("name", t)
20
- host_string = extract_value_from("hosts", t)
21
- targ.hosts = host_string.split(", ")
22
- targ.comment = extract_value_from("comment", t)
23
- ret << targ
24
- }
25
-
26
- ret
44
+ def self.get_local_subnets
45
+ adrs = []
46
+ `ifconfig`.split("\n").each { |cmd|
47
+ if cmd =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+.*Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/i
48
+ adrs << IPAddress("#{$1}/#{$2}") unless $1 == '127.0.0.1'
49
+ end
50
+ }
51
+
52
+ adrs.collect{ |a| a.network.to_string }
53
+ end
54
+
55
+ def initialize(params = {})
56
+ @id = params[:id] if params[:id]
57
+ @name = params[:name] if params[:name]
58
+ @hosts = params[:hosts] if params[:hosts]
59
+ @comment = params[:comment] if params[:comment]
60
+ @port_range = params[:port_range] if params[:port_range]
61
+
62
+ @org_hosts = @hosts.collect { |h| h } if @hosts
63
+
64
+ reset_changes
65
+ end
66
+
67
+ def credentials
68
+ @credentials ||= get_credentials
69
+ end
70
+
71
+ def credential_keys
72
+ @credential_keys ||= { :smb => nil, :ssh => nil }
73
+ end
74
+
75
+ def tasks
76
+ @tasks ||= get_tasks
77
+ end
78
+
79
+ def task_keys
80
+ @task_keys ||= []
81
+ end
82
+
83
+ def hosts
84
+ @hosts ||= []
85
+ end
86
+
87
+ def hosts=(val)
88
+ hosts_will_change! unless @hosts.eql?(val)
89
+ @host = val
90
+
91
+ @org_hosts = val.collect { |h| h } if val
92
+ end
93
+
94
+ def save!
95
+ if @id
96
+ destroy!
97
+ end
98
+ req = Nokogiri::XML::Builder.new { |xml|
99
+ xml.create_target {
100
+ xml.name { xml.text(@name) }
101
+ xml.comment { xml.text(@comment) } if @comment
102
+ xml.hosts { xml.text(@hosts.join(', ')) }
103
+ xml.ssh_lsc_credential(:id => credentials[:ssh].id) if credentials[:ssh]
104
+ xml.smb_lsc_credential(:id => credentials[:smb].id) if credentials[:smb]
105
+ xml.port_range { xml.text(@port_range) } if @port_range
106
+ }
107
+ }
108
+ resp = VasTarget.connection.send_receive(req.doc)
109
+
110
+ @id = VasTarget.extract_value_from("create_target_response/@id", resp)
111
+
112
+ reset_changes
113
+ end
114
+
115
+ def destroy!
116
+ return unless @id
117
+
118
+ req = Nokogiri::XML::Builder.new { |xml|
119
+ xml.delete_target(:target_id => @id)
120
+ }
121
+
122
+ VasTarget.connection.send_receive(req.doc)
123
+
124
+ @id = nil
125
+ end
126
+
127
+ def self.create!(params={})
128
+ t = VasTarget.new(params)
129
+ t.save!
130
+
131
+ t
132
+ end
133
+
134
+ def self.get_all(options = {})
135
+ params = {:tasks => 1}
136
+ params[:target_id] = options[:id] if options[:id]
137
+
138
+ req = Nokogiri::XML::Builder.new { |xml|
139
+ xml.get_targets(params)
140
+ }
141
+ ret = []
142
+
143
+ begin
144
+ targets = connection.send_receive(req.doc)
145
+ targets.xpath('//target').each { |t|
146
+ targ = VasTarget.new
147
+ targ.id = extract_value_from("@id", t)
148
+ targ.name = extract_value_from("name", t)
149
+ host_string = extract_value_from("hosts", t)
150
+ targ.hosts << host_string.split(/, /)
151
+ targ.comment = extract_value_from("comment", t)
152
+ targ.port_range = extract_value_from("port_range", t)
153
+ targ.in_use = extract_value_from("in_use", t).to_i > 0
154
+ targ.credential_keys[:ssh] = extract_value_from("ssh_lsc_credential/@id", t)
155
+ targ.credential_keys[:smb] = extract_value_from("smb_lsc_credential/@id", t)
156
+
157
+
158
+ t.xpath('tasks/task').each { |task|
159
+ targ.task_keys << extract_value_from("@id", task)
160
+ }
161
+
162
+ ret << targ
163
+ }
164
+
165
+ rescue VasExceptions::CommandException => e
166
+ raise e unless e.message =~ /Failed to find target/i
167
+ end
168
+
169
+ ret
170
+ end
171
+
172
+ private
173
+ def get_tasks
174
+ ret = []
175
+
176
+ @task_keys.each { |key|
177
+ ret << VasTask.get_all(:task_id => key)
178
+ }
179
+
180
+ ret
181
+ end
182
+
183
+ def get_credentials
184
+ ret = { :ssh => nil, :smb => nil }
185
+
186
+ @credential_keys.each { |key, value|
187
+ ret[key] = VasLscCredential.get_all(:id => value) if value && !value.empty?
188
+ } if @credential_keys
189
+
190
+ ret
191
+ end
192
+
193
+ def credential_changed?(key)
194
+ if credential_keys[key] == nil && credentials[key] != nil
195
+ return true
196
+ elsif credential_keys[key] != nil && credentials[key] == nil
197
+ return true
198
+ elsif credential_keys[key] == nil && credentials[key] == nil
199
+ return false
200
+ else
201
+ return credential_keys[key] != credentials[key].id
202
+ end
203
+ end
27
204
  end
28
205
  end
@@ -1,36 +1,235 @@
1
1
  require 'vas_base'
2
2
  require 'vas_result'
3
3
 
4
- class VasTask < VasBase
5
- attr_accessor :task_id, :task_name, :comment, :status,
6
- :progress, :times_run, :last_report_id
7
-
8
- validates :task_id, :presence => true, :UUID => true
9
-
10
- def self.get_all(options = {})
11
- params = {:apply_overrides => 0, :sort_field => "name"}
12
-
13
- params[:task_id] = options[:task_id] if options[:task_id]
14
-
15
- req = Nokogiri::XML::Builder.new { |xml|
16
- xml.get_tasks
17
- }
18
-
19
- tasks = client.send_receive(req.doc)
20
-
21
- ret = []
22
- tasks.xpath('//task').each { |t|
4
+ module OpenvasCli
5
+ class VasTask < VasBase
6
+ attr_reader :name
7
+ attr_reader :comment
8
+ attr_accessor :status
9
+ attr_accessor :times_run
10
+ attr_accessor :last_report_id
11
+ attr_reader :config_id
12
+ attr_reader :target_id
13
+ attr_reader :schedule_id
14
+
15
+ validates :id, :UUID => true, :if => Proc.new { |t| t.id }
16
+ validates :config_id, :UUID => true, :if => Proc.new { |t| t.config_id }
17
+ validates :target_id, :UUID => true, :if => Proc.new { |t| t.target_id }
18
+ validates_with ImmutableChildrenValidator
19
+
20
+
21
+ define_attribute_methods [:name, :comment, :config_id, :target_id, :schedule_id]
22
+
23
+ def initialize(params = {})
24
+ @name = params[:name] if params[:name]
25
+ @comment = params[:comment] if params[:comment]
26
+ @config_id = params[:config_id] if params[:config_id]
27
+ @target_id = params[:target_id] if params[:target_id]
28
+ @schedule_id = params[:schedule_id] if params[:schedule_id]
29
+ @schedule = params[:schedule] if params[:schedule]
30
+ reset_changes
31
+ end
32
+
33
+ def name=(val)
34
+ name_will_change! unless @name == val
35
+ @name = val
36
+ end
37
+
38
+ def comment=(val)
39
+ comment_will_change! unless @comment == val
40
+ @comment = val
41
+ end
42
+
43
+ def config_id=(v)
44
+ config_id_will_change! unless @config_id == v
45
+ @config_id = v
46
+ end
47
+
48
+ def target_id=(v)
49
+ target_id_will_change! unless @target_id == v
50
+ @target_id = v
51
+ end
52
+
53
+ def schedule_id=(v)
54
+ schedule_id_will_change! unless @schedule_id == v
55
+ @schedule_id = v
56
+ end
57
+
58
+ def schedule
59
+ @schedule || pull_my_schedule
60
+ end
61
+
62
+ def schedule=(v)
63
+ @schedule = v
64
+ schedule_id = v ? v.id : nil
65
+ end
66
+
67
+ def config
68
+ @config || pull_my_config
69
+ end
70
+
71
+ def config=(val)
72
+ @config = val
73
+ config_id = val ? val.id : nil
74
+ end
75
+
76
+ def target
77
+ @target || pull_my_target
78
+ end
79
+
80
+ def target=(val)
81
+ @target = val
82
+ target_id = val ? val.id : nil
83
+ end
84
+
85
+ def save!
86
+ raise "Invalid State" unless valid?
87
+
88
+ if schedule && schedule.changed?
89
+ schedule.save!
90
+ schedule_id = schedule.id
91
+ end
92
+
93
+ if config.changed?
94
+ config.save!
95
+ end
96
+
97
+ req = Nokogiri::XML::Builder.new { |xml|
98
+ if @id
99
+ xml.modify_task(:id => @id) {
100
+ xml.name { xml.text(@name) } if name_changed?
101
+ xml.comment { xml.text(@comment) } if comment_changed?
102
+ xml.schedule(:id => @schedule_id) if schedule_id && schedule_id_changed?
103
+ }
104
+ else
105
+ xml.create_task {
106
+ xml.name { xml.text(@name) } if @name
107
+ xml.comment { xml.text(@comment) } if @comment
108
+ xml.config(:id => @config_id)
109
+ xml.target(:id => @target_id)
110
+ xml.schedule(:id => @schedule_id) if @schedule_id
111
+ }
112
+ end
113
+ }
114
+
115
+ resp = VasTask.connection.send_receive(req.doc)
116
+
117
+ @id = VasTask.extract_value_from("/create_task_response/@id", resp) unless @id
118
+
119
+ reset_changes
120
+ end
121
+
122
+ def destroy!
123
+ req = Nokogiri::XML::Builder.new { |xml|
124
+ xml.delete_task(:task_id => @id)
125
+ }
126
+
127
+ VasTask.connection.send_receive(req.doc)
128
+ end
129
+
130
+ def start
131
+ req = Nokogiri::XML::Builder.new { |xml|
132
+ xml.resume_or_start_task(:task_id => @id)
133
+ }
134
+
135
+ VasTask.connection.send_receive(req.doc)
136
+ end
137
+
138
+ def progress=(val)
139
+ @progress = val
140
+ end
141
+
142
+ def progress(refresh=false)
143
+ if refresh == true || @progress == nil
144
+ params = {:apply_overrides => 0, :sort_field => "name"}
145
+ params[:task_id] = options[:task_id] if options[:task_id]
146
+
147
+ req = Nokogiri::XML::Builder.new { |xml|
148
+ xml.get_tasks
149
+ }
150
+
151
+ task = VasTask.connection.send_receive(req.doc)
152
+
153
+ @progress = VasTaskStatus.from_xml_node task.at_xpath('/get_tasks_response/task/progress')
154
+ end
155
+ @progress
156
+ end
157
+
158
+ def pause
159
+ req = Nokogiri::XML::Builder.new { |xml|
160
+ xml.pause_task(:task_id => @id)
161
+ }
162
+
163
+ VasTask.connection.send_receive(req.doc)
164
+ end
165
+
166
+ def stop
167
+ req = Nokogiri::XML::Builder.new { |xml|
168
+ xml.stop_task(:task_id => @id)
169
+ }
170
+
171
+ VasTask.connection.send_receive(req.doc)
172
+ end
173
+
174
+ def self.get_all(options = {})
175
+ params = {:apply_overrides => 0, :sort_field => "name"}
176
+
177
+ params[:task_id] = options[:task_id] if options[:task_id]
178
+
179
+ req = Nokogiri::XML::Builder.new { |xml|
180
+ xml.get_tasks
181
+ }
182
+
183
+ tasks = connection.send_receive(req.doc)
184
+
185
+ ret = []
186
+ tasks.xpath('//task').each { |t|
187
+ ret << from_xml_node(t)
188
+ }
189
+
190
+ ret
191
+ end
192
+
193
+ def self.from_xml_node(node)
23
194
  t_id = VasTask.new
24
- t_id.task_id = extract_value_from("@id", t)
25
- t_id.task_name = extract_value_from("name", t)
26
- t_id.comment = extract_value_from("comment", t)
27
- t_id.status = extract_value_from("status", t)
28
- t_id.progress = extract_value_from("progress", t)
29
- t_id.times_run = extract_value_from("report_count/finished", t).to_i
30
- t_id.last_report_id = extract_value_from("last_report/report/@id", t)
31
- ret << t_id
32
- }
33
-
34
- ret
195
+ t_id.id = extract_value_from("@id", node)
196
+ t_id.name = extract_value_from("name", node)
197
+ t_id.comment = extract_value_from("comment", node)
198
+ t_id.status = extract_value_from("status", node)
199
+ if node.at_xpath("progress")
200
+ t_id.progress = VasTaskProgress.from_xml_node(node.at_xpath("progress"))
201
+ end
202
+ t_id.times_run = extract_value_from("report_count/finished", node).to_i
203
+ t_id.last_report_id = extract_value_from("last_report/report/@id", node)
204
+ t_id.config_id = extract_value_from("config/@id", node)
205
+ t_id.target_id = extract_value_from("target/@id", node)
206
+
207
+ t_id
208
+ end
209
+
210
+ private
211
+ def pull_my_config
212
+ if @config_id && !@config_id.empty?
213
+ VasConfig.get_all(:id => @config_id)[0]
214
+ else
215
+ nil
216
+ end
217
+ end
218
+
219
+ def pull_my_target
220
+ if @target_id && !@target_id.empty?
221
+ VasTarget.get_all(:id => @target_id)[0]
222
+ else
223
+ nil
224
+ end
225
+ end
226
+
227
+ def pull_my_schedule
228
+ if @schedule_id && !@schedule_id.empty?
229
+ VasSchedule.get_all(:id => @schedule_id)[0]
230
+ else
231
+ nil
232
+ end
233
+ end
35
234
  end
36
235
  end