openvas-cli 0.1.1 → 0.2.0

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