nexpose 0.0.98 → 0.1.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.
- data/README.markdown +17 -7
- data/Rakefile +17 -22
- data/lib/README.md +5 -0
- data/lib/nexpose.rb +104 -130
- data/lib/nexpose/api_request.rb +133 -144
- data/lib/nexpose/common.rb +138 -0
- data/lib/nexpose/connection.rb +117 -106
- data/lib/nexpose/creds.rb +292 -279
- data/lib/nexpose/error.rb +21 -21
- data/lib/nexpose/manage.rb +83 -0
- data/lib/nexpose/misc.rb +85 -122
- data/lib/nexpose/report.rb +783 -603
- data/lib/nexpose/role.rb +27 -0
- data/lib/nexpose/scan.rb +264 -285
- data/lib/nexpose/scan_engine.rb +344 -350
- data/lib/nexpose/silo.rb +348 -347
- data/lib/nexpose/site.rb +826 -898
- data/lib/nexpose/ticket.rb +108 -108
- data/lib/nexpose/user.rb +223 -221
- data/lib/nexpose/util.rb +36 -36
- data/lib/nexpose/vuln.rb +510 -520
- metadata +37 -23
- data/README +0 -0
- data/nexpose.gemspec +0 -20
@@ -0,0 +1,138 @@
|
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# Configuration structure for e-mail notification.
|
4
|
+
#
|
5
|
+
# The send_as and send_to_acl_as attributes are optional, but one of them is
|
6
|
+
# required for sending reports via e-mail. The send_as attribute is required
|
7
|
+
# for sending e-mails to users who are not on the report access list.
|
8
|
+
# The send_to_acl attribute is required for sending e-mails to report access
|
9
|
+
# list members.
|
10
|
+
#
|
11
|
+
# E-mails and attachments are sent via the Internet in clear text and are not
|
12
|
+
# encrypted. If you do not set a valid value for either attribute,
|
13
|
+
# the application will save the report but not send it via e-mail.
|
14
|
+
# If you set a valid value for the send_as attribute but not for the
|
15
|
+
# send_to_acl_as attribute, the application will send the report via e-mail to
|
16
|
+
# non-access-list members only. If you set a valid value for the
|
17
|
+
# send_to_acl_as attribute, the application will send the report via e-mail to
|
18
|
+
# access-list members only. If you set a valid value for both attributes,
|
19
|
+
# the application will send reports via e-mail to access-list members and
|
20
|
+
# non-members.
|
21
|
+
class Email
|
22
|
+
# Send as file attachment or zipped file to individuals who are not members
|
23
|
+
# of the report access list. One of: file|zip
|
24
|
+
attr_accessor :send_as
|
25
|
+
# Send to all the authorized users of sites, groups, and devices.
|
26
|
+
attr_accessor :to_all_authorized
|
27
|
+
# Send to users on the report access list.
|
28
|
+
attr_accessor :send_to_acl_as
|
29
|
+
# Format to send to users on the report access list. One of: file|zip|url
|
30
|
+
attr_accessor :send_to_owner_as
|
31
|
+
|
32
|
+
# Sender that e-mail will be attributed to.
|
33
|
+
attr_accessor :sender
|
34
|
+
# SMTP relay server.
|
35
|
+
attr_accessor :smtp_relay_server
|
36
|
+
# Array of report recipients (i.e., not already on the report access list).
|
37
|
+
attr_accessor :recipients
|
38
|
+
|
39
|
+
def initialize(to_all_authorized, send_to_owner_as, send_to_acl_as, send_as)
|
40
|
+
@to_all_authorized = to_all_authorized
|
41
|
+
@send_to_owner_as = send_to_owner_as
|
42
|
+
@send_to_acl_as = send_to_acl_as
|
43
|
+
@send_as = send_as
|
44
|
+
|
45
|
+
@recipients = []
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_xml
|
49
|
+
xml = '<Email'
|
50
|
+
xml << %Q{ toAllAuthorized='#{@toAllAuthorized ? 1 : 0}'}
|
51
|
+
xml << %Q{ sendToOwnerAs='#{@send_to_owner_as}'} if @send_to_owner_as
|
52
|
+
xml << %Q{ sendToAclAs='#{@send_to_acl_as}'} if @send_to_acl_as
|
53
|
+
xml << %Q{ sendAs='#{@send_as}'} if @send_as
|
54
|
+
xml << '>'
|
55
|
+
xml << %Q{<Sender>#{@sender}</Sender>} if @sender
|
56
|
+
xml << %Q{<SmtpRelayServer>#{@smtp_relay_server}</SmtpRelayServer>} if @smtp_relay_server
|
57
|
+
if @recipients
|
58
|
+
xml << '<Recipients>'
|
59
|
+
@recipients.each do |recipient|
|
60
|
+
xml << %Q{<Recipient>#{recipient}</Recipient>}
|
61
|
+
end
|
62
|
+
xml << '</Recipients>'
|
63
|
+
end
|
64
|
+
xml << '</Email>'
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.parse(xml)
|
68
|
+
xml.elements.each('//Email') do |email|
|
69
|
+
config = Email.new(email.attributes['toAllAuthorized'] == '1',
|
70
|
+
email.attributes['sendToOwnerAs'],
|
71
|
+
email.attributes['sendToAclAs'],
|
72
|
+
email.attributes['sendAs'])
|
73
|
+
|
74
|
+
xml.elements.each('//Sender') do |sender|
|
75
|
+
config.sender = sender.text
|
76
|
+
end
|
77
|
+
xml.elements.each('//SmtpRelayServer') do |server|
|
78
|
+
config.smtp_relay_server = server.text
|
79
|
+
end
|
80
|
+
xml.elements.each('//Recipient') do |recipient|
|
81
|
+
config.recipients << recipient.text
|
82
|
+
end
|
83
|
+
return config
|
84
|
+
end
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Configuration structure for schedules.
|
90
|
+
class Schedule
|
91
|
+
# Whether or not this schedule is enabled.
|
92
|
+
attr_accessor :enabled
|
93
|
+
# Valid schedule types: daily, hourly, monthly-date, monthly-day, weekly.
|
94
|
+
attr_accessor :type
|
95
|
+
# The repeat interval based upon type.
|
96
|
+
attr_accessor :interval
|
97
|
+
# The earliest date to generate the report on (in ISO 8601 format).
|
98
|
+
attr_accessor :start
|
99
|
+
|
100
|
+
# The amount of time, in minutes, to allow execution before stopping.
|
101
|
+
attr_accessor :max_duration
|
102
|
+
# The date after which the schedule is disabled, in ISO 8601 format.
|
103
|
+
attr_accessor :not_valid_after
|
104
|
+
|
105
|
+
# --
|
106
|
+
# TODO These are not captured or put to XML.
|
107
|
+
# ++
|
108
|
+
attr_accessor :incremental
|
109
|
+
attr_accessor :repeater_type
|
110
|
+
|
111
|
+
def initialize(type, interval, start, enabled = true)
|
112
|
+
@type = type
|
113
|
+
@interval = interval
|
114
|
+
@start = start
|
115
|
+
@enabled = enabled
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_xml
|
119
|
+
xml = %Q{<Schedule enabled='#{@enabled ? 1 : 0}' type='#{@type}' interval='#{@interval}' start='#{@start}'}
|
120
|
+
xml << %Q{ maxDuration='#@max_duration'} if @max_duration
|
121
|
+
xml << %Q{ notValidAfter='#@not_valid_after'} if @not_valid_after
|
122
|
+
xml << '/>'
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.parse(xml)
|
126
|
+
xml.elements.each('//Schedule') do |sched|
|
127
|
+
schedule = Schedule.new(sched.attributes['type'],
|
128
|
+
sched.attributes['interval'].to_i,
|
129
|
+
sched.attributes['start'],
|
130
|
+
sched.attributes['enabled'] || true)
|
131
|
+
# Optional parameters.
|
132
|
+
schedule.max_duration = sched.attributes['maxDuration'].to_i if sched.attributes['maxDuration']
|
133
|
+
schedule.not_valid_after = sched.attributes['notValidAfter'] if sched.attributes['notValidAfter']
|
134
|
+
return schedule
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/nexpose/connection.rb
CHANGED
@@ -1,106 +1,117 @@
|
|
1
|
-
module Nexpose
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# === Description
|
4
|
+
# Object that represents a connection to a Nexpose Security Console.
|
5
|
+
#
|
6
|
+
# === Examples
|
7
|
+
# # Create a new Nexpose Connection on the default port
|
8
|
+
# nsc = Connection.new('10.1.40.10', 'nxadmin', 'password')
|
9
|
+
#
|
10
|
+
# # Login to NSC and Establish a Session ID
|
11
|
+
# nsc.login
|
12
|
+
#
|
13
|
+
# # Check Session ID
|
14
|
+
# if nsc.session_id
|
15
|
+
# puts 'Login Successful'
|
16
|
+
# else
|
17
|
+
# puts 'Login Failure'
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # //Logout
|
21
|
+
# logout_success = nsc.logout
|
22
|
+
# if (! logout_success)
|
23
|
+
# puts "Logout Failure" + "<p>" + nsc.error_msg.to_s
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
class Connection
|
27
|
+
include XMLUtils
|
28
|
+
include NexposeAPI
|
29
|
+
|
30
|
+
# true if an error condition exists; false otherwise
|
31
|
+
attr_reader :error
|
32
|
+
# Error message string
|
33
|
+
attr_reader :error_msg
|
34
|
+
# The last XML request sent by this object
|
35
|
+
attr_reader :request_xml
|
36
|
+
# The last XML response received by this object
|
37
|
+
attr_reader :response_xml
|
38
|
+
# Session ID of this connection
|
39
|
+
attr_reader :session_id
|
40
|
+
# The hostname or IP Address of the NSC
|
41
|
+
attr_reader :host
|
42
|
+
# The port of the NSC (default is 3780)
|
43
|
+
attr_reader :port
|
44
|
+
# The username used to login to the NSC
|
45
|
+
attr_reader :username
|
46
|
+
# The password used to login to the NSC
|
47
|
+
attr_reader :password
|
48
|
+
# The URL for communication
|
49
|
+
attr_reader :url
|
50
|
+
|
51
|
+
# Constructor for Connection
|
52
|
+
def initialize(ip, user, pass, port = 3780, silo_id = nil)
|
53
|
+
@host = ip
|
54
|
+
@port = port
|
55
|
+
@username = user
|
56
|
+
@password = pass
|
57
|
+
@silo_id = silo_id
|
58
|
+
@session_id = nil
|
59
|
+
@error = false
|
60
|
+
@url = "https://#{@host}:#{@port}/api/API_VERSION/xml"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Establish a new connection and Session ID
|
64
|
+
def login
|
65
|
+
begin
|
66
|
+
login_hash = {'sync-id' => 0, 'password' => @password, 'user-id' => @username}
|
67
|
+
unless @silo_id.nil?
|
68
|
+
login_hash['silo-id'] = @silo_id
|
69
|
+
end
|
70
|
+
r = execute(make_xml('LoginRequest', login_hash))
|
71
|
+
rescue APIError
|
72
|
+
raise AuthenticationFailed.new(r)
|
73
|
+
end
|
74
|
+
if (r.success)
|
75
|
+
@session_id = r.sid
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Logout of the current connection
|
81
|
+
def logout
|
82
|
+
r = execute(make_xml('LogoutRequest', {'sync-id' => 0}))
|
83
|
+
if (r.success)
|
84
|
+
return true
|
85
|
+
end
|
86
|
+
raise APIError.new(r, 'Logout failed')
|
87
|
+
end
|
88
|
+
|
89
|
+
# Execute an API request
|
90
|
+
def execute(xml, version = '1.1')
|
91
|
+
@api_version = version
|
92
|
+
APIRequest.execute(@url, xml.to_s, @api_version)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Download a specific URL, typically a report.
|
96
|
+
# Include an optional file_name parameter to write the output to a file.
|
97
|
+
#
|
98
|
+
# Note: XML and HTML reports have charts not downloaded by this method.
|
99
|
+
# Would need to do something more sophisticated to grab
|
100
|
+
# all the associated image files.
|
101
|
+
def download(url, file_name = nil)
|
102
|
+
return nil if url.nil? or url.empty?
|
103
|
+
uri = URI.parse(url)
|
104
|
+
http = Net::HTTP.new(@host, @port)
|
105
|
+
http.use_ssl = true
|
106
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # XXX: security issue
|
107
|
+
headers = {'Cookie' => "nexposeCCSessionID=#{@session_id}"}
|
108
|
+
resp = http.get(uri.path, headers)
|
109
|
+
|
110
|
+
if file_name
|
111
|
+
File.open(file_name, 'w') { |file| file.write(resp.body) }
|
112
|
+
else
|
113
|
+
resp.body
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/nexpose/creds.rb
CHANGED
@@ -1,279 +1,292 @@
|
|
1
|
-
module Nexpose
|
2
|
-
|
3
|
-
# Object that represents administrative credentials to be used
|
4
|
-
# during a scan. When
|
5
|
-
# the credentials will be returned as a security blob and can only
|
6
|
-
# be passed back as is during a Site Save operation. This object
|
7
|
-
# can only be used to create a new set of credentials.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
attributes['
|
83
|
-
attributes['
|
84
|
-
attributes['
|
85
|
-
attributes['
|
86
|
-
attributes['
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
xml
|
91
|
-
xml.add_element(@
|
92
|
-
xml
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
@
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# Object that represents administrative credentials to be used
|
4
|
+
# during a scan. When retrieved from an existing site configuration
|
5
|
+
# the credentials will be returned as a security blob and can only
|
6
|
+
# be passed back as is during a Site Save operation. This object
|
7
|
+
# can only be used to create a new set of credentials.
|
8
|
+
class AdminCredentials
|
9
|
+
include XMLUtils
|
10
|
+
|
11
|
+
# Security blob for an existing set of credentials
|
12
|
+
attr_reader :securityblob
|
13
|
+
# Designates if this object contains user defined credentials or a security blob
|
14
|
+
attr_reader :isblob
|
15
|
+
# The service for these credentials. Can be All.
|
16
|
+
attr_reader :service
|
17
|
+
# The host for these credentials. Can be Any.
|
18
|
+
attr_reader :host
|
19
|
+
# The port on which to use these credentials.
|
20
|
+
attr_reader :port
|
21
|
+
# The user id or username
|
22
|
+
attr_reader :userid
|
23
|
+
# The password
|
24
|
+
attr_reader :password
|
25
|
+
# The realm for these credentials
|
26
|
+
attr_reader :realm
|
27
|
+
# When using httpheaders, this represents the set of headers to pass
|
28
|
+
# with the authentication request.
|
29
|
+
attr_reader :headers
|
30
|
+
# When using htmlforms, this represents the tho form to pass the
|
31
|
+
# authentication request to.
|
32
|
+
attr_reader :html_forms
|
33
|
+
|
34
|
+
def initialize(isblob = false)
|
35
|
+
@isblob = isblob
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sets the credentials information for this object.
|
39
|
+
def set_credentials(service, host, port, userid, password, realm)
|
40
|
+
@isblob = false
|
41
|
+
@securityblob = nil
|
42
|
+
@service = service
|
43
|
+
@host = host
|
44
|
+
@port = port
|
45
|
+
@userid = userid
|
46
|
+
@password = password
|
47
|
+
@realm = realm
|
48
|
+
end
|
49
|
+
|
50
|
+
# TODO: add description
|
51
|
+
def set_service(service)
|
52
|
+
@service = service
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_host(host)
|
56
|
+
@host = host
|
57
|
+
end
|
58
|
+
|
59
|
+
# TODO: add description
|
60
|
+
def set_blob(securityblob)
|
61
|
+
@isblob = true
|
62
|
+
@securityblob = securityblob
|
63
|
+
end
|
64
|
+
|
65
|
+
# Add Headers to credentials for httpheaders.
|
66
|
+
def set_headers(headers)
|
67
|
+
@headers = headers
|
68
|
+
end
|
69
|
+
|
70
|
+
def set_html_forms(html_forms)
|
71
|
+
@html_forms = html_forms
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_xml
|
75
|
+
to_xml_elem.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_xml_elem
|
79
|
+
attributes = {}
|
80
|
+
|
81
|
+
attributes['service'] = @service
|
82
|
+
attributes['userid'] = @userid
|
83
|
+
attributes['password'] = @password
|
84
|
+
attributes['realm'] = @realm
|
85
|
+
attributes['host'] = @host
|
86
|
+
attributes['port'] = @port
|
87
|
+
|
88
|
+
data = isblob ? securityblob : ''
|
89
|
+
xml = make_xml('adminCredentials', attributes, data)
|
90
|
+
xml.add_element(@headers.to_xml_elem) if @headers
|
91
|
+
xml.add_element(@html_forms.to_xml_elem) if @html_forms
|
92
|
+
xml
|
93
|
+
end
|
94
|
+
|
95
|
+
include Comparable
|
96
|
+
|
97
|
+
def <=>(other)
|
98
|
+
to_xml <=> other.to_xml
|
99
|
+
end
|
100
|
+
|
101
|
+
def eql?(other)
|
102
|
+
to_xml == other.to_xml
|
103
|
+
end
|
104
|
+
|
105
|
+
def hash
|
106
|
+
to_xml.hash
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Object that represents Header name-value pairs, associated with Web Session Authentication.
|
111
|
+
class Header
|
112
|
+
include XMLUtils
|
113
|
+
# Name, one per Header
|
114
|
+
attr_reader :name
|
115
|
+
# Value, one per Header
|
116
|
+
attr_reader :value
|
117
|
+
|
118
|
+
# Construct with name value pair
|
119
|
+
def initialize(name, value)
|
120
|
+
@name = name
|
121
|
+
@value = value
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_xml_elem
|
125
|
+
attributes = {}
|
126
|
+
attributes['name'] = @name
|
127
|
+
attributes['value'] = @value
|
128
|
+
|
129
|
+
make_xml('Header', attributes)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Object that represents Headers, associated with Web Session Authentication.
|
134
|
+
class Headers
|
135
|
+
include XMLUtils
|
136
|
+
# A regular expression used to match against the response to identify authentication failures.
|
137
|
+
attr_reader :soft403
|
138
|
+
# Base URL of the application for which the form authentication applies.
|
139
|
+
attr_reader :webapproot
|
140
|
+
# When using httpheaders, this represents the set of headers to pass with the authentication request.
|
141
|
+
attr_reader :headers
|
142
|
+
|
143
|
+
def initialize(webapproot, soft403)
|
144
|
+
@headers = []
|
145
|
+
@webapproot = webapproot
|
146
|
+
@soft403 = soft403
|
147
|
+
end
|
148
|
+
|
149
|
+
def add_header(header)
|
150
|
+
@headers.push(header)
|
151
|
+
end
|
152
|
+
|
153
|
+
def to_xml_elem
|
154
|
+
attributes = {}
|
155
|
+
attributes['webapproot'] = @webapproot
|
156
|
+
attributes['soft403'] = @soft403
|
157
|
+
|
158
|
+
xml = make_xml('Headers', attributes)
|
159
|
+
@headers.each do |header|
|
160
|
+
xml.add_element(header.to_xml_elem)
|
161
|
+
end
|
162
|
+
xml
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# When using htmlform, this represents the login form information.
|
168
|
+
class Field
|
169
|
+
include XMLUtils
|
170
|
+
# The name of the HTML field (form parameter).
|
171
|
+
attr_reader :name
|
172
|
+
# The value of the HTML field (form parameter).
|
173
|
+
attr_reader :value
|
174
|
+
# The type of the HTML field (form parameter).
|
175
|
+
attr_reader :type
|
176
|
+
# Is the HTML field (form parameter) dynamically generated? If so,
|
177
|
+
# the login page is requested and the value of the field is extracted
|
178
|
+
# from the response.
|
179
|
+
attr_reader :dynamic
|
180
|
+
# If the HTML field (form parameter) is a radio button, checkbox or select
|
181
|
+
# field, this flag determines if the field should be checked (selected).
|
182
|
+
attr_reader :checked
|
183
|
+
|
184
|
+
def initialize(name, value, type, dynamic, checked)
|
185
|
+
@name = name
|
186
|
+
@value = value
|
187
|
+
@type = type
|
188
|
+
@dynamic = dynamic
|
189
|
+
@checked = checked
|
190
|
+
end
|
191
|
+
|
192
|
+
def to_xml_elem
|
193
|
+
attributes = {}
|
194
|
+
attributes['name'] = @name
|
195
|
+
attributes['value'] = @value
|
196
|
+
attributes['type'] = @type
|
197
|
+
attributes['dynamic'] = @dynamic
|
198
|
+
attributes['checked'] = @checked
|
199
|
+
|
200
|
+
make_xml('Field', attributes)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# When using htmlform, this represents the login form information.
|
205
|
+
class HTMLForm
|
206
|
+
include XMLUtils
|
207
|
+
# The name of the form being submitted.
|
208
|
+
attr_reader :name
|
209
|
+
# The HTTP action (URL) through which to submit the login form.
|
210
|
+
attr_reader :action
|
211
|
+
# The HTTP request method with which to submit the form.
|
212
|
+
attr_reader :method
|
213
|
+
# The HTTP encoding type with which to submit the form.
|
214
|
+
attr_reader :enctype
|
215
|
+
# The fields in the HTML Form
|
216
|
+
attr_reader :fields
|
217
|
+
|
218
|
+
def initialize(name, action, method, enctype)
|
219
|
+
@name = name
|
220
|
+
@action = action
|
221
|
+
@method = method
|
222
|
+
@enctype = enctype
|
223
|
+
@fields = []
|
224
|
+
end
|
225
|
+
|
226
|
+
def add_field(field)
|
227
|
+
@fields << field
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_xml_elem
|
231
|
+
attributes = {}
|
232
|
+
attributes['name'] = @name
|
233
|
+
attributes['action'] = @action
|
234
|
+
attributes['method'] = @method
|
235
|
+
attributes['enctype'] = @enctype
|
236
|
+
|
237
|
+
xml = make_xml('HTMLForm', attributes)
|
238
|
+
|
239
|
+
fields.each() do |field|
|
240
|
+
xml.add_element(field.to_xml_elem)
|
241
|
+
end
|
242
|
+
|
243
|
+
xml
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
# When using htmlform, this represents the login form information.
|
249
|
+
class HTMLForms
|
250
|
+
include XMLUtils
|
251
|
+
# The URL of the login page containing the login form.
|
252
|
+
attr_reader :parentpage
|
253
|
+
# A regular expression used to match against the response to identify
|
254
|
+
# authentication failures.
|
255
|
+
attr_reader :soft403
|
256
|
+
# Base URL of the application for which the form authentication applies.
|
257
|
+
attr_reader :webapproot
|
258
|
+
# The forms to authenticate with
|
259
|
+
attr_reader :html_forms
|
260
|
+
|
261
|
+
def initialize(parentpage, soft403, webapproot)
|
262
|
+
@parentpage = parentpage
|
263
|
+
@soft403 = soft403
|
264
|
+
@webapproot = webapproot
|
265
|
+
@html_forms = []
|
266
|
+
end
|
267
|
+
|
268
|
+
def add_html_form(html_form)
|
269
|
+
@html_forms << html_form
|
270
|
+
end
|
271
|
+
|
272
|
+
def to_xml_elem
|
273
|
+
attributes = {}
|
274
|
+
attributes['parentpage'] = @parentpage
|
275
|
+
attributes['soft403'] = @soft403
|
276
|
+
attributes['webapproot'] = @webapproot
|
277
|
+
|
278
|
+
xml = make_xml('HTMLForms', attributes)
|
279
|
+
|
280
|
+
html_forms.each() do |html_form|
|
281
|
+
xml.add_element(html_form.to_xml_elem)
|
282
|
+
end
|
283
|
+
xml
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
# When using ssh-key, this represents the PEM-format keypair information.
|
289
|
+
class PEMKey
|
290
|
+
# TODO
|
291
|
+
end
|
292
|
+
end
|