nexpose 0.0.96 → 0.0.97
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/lib/nexpose.rb +1 -0
- data/lib/nexpose/site.rb +1 -1
- data/lib/nexpose/user.rb +221 -0
- data/nexpose.gemspec +1 -1
- metadata +7 -6
data/lib/nexpose.rb
CHANGED
data/lib/nexpose/site.rb
CHANGED
@@ -632,7 +632,7 @@ module Nexpose
|
|
632
632
|
r = @connection.execute('<SiteDeviceListingRequest session-id="' + connection.session_id + '" site-id="' + "#{@site_id}" + '"/>')
|
633
633
|
if r.success
|
634
634
|
r.res.elements.each('SiteDeviceListingResponse/SiteDevices/device') do |d|
|
635
|
-
@devices.push(Device.new(d.
|
635
|
+
@devices.push(Device.new(d.attributes['id'], @site_id, d.attributes["address"], d.attributes["riskfactor"], d.attributes["riskscore"]))
|
636
636
|
end
|
637
637
|
end
|
638
638
|
else
|
data/lib/nexpose/user.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# Summary only returned by API when issuing a listing request.
|
4
|
+
class UserSummary
|
5
|
+
attr_reader :id, :auth_source, :auth_module, :user_name, :full_name, :email
|
6
|
+
attr_reader :is_admin, :is_disabled, :is_locked, :site_count, :group_count
|
7
|
+
|
8
|
+
def initialize(id, auth_source, auth_module, user_name, full_name, email, is_admin, is_disabled, is_locked, site_count, group_count)
|
9
|
+
@id = id
|
10
|
+
@auth_source = auth_source
|
11
|
+
@auth_module = auth_module
|
12
|
+
@user_name = user_name
|
13
|
+
@full_name = full_name
|
14
|
+
@email = email
|
15
|
+
@is_admin = is_admin
|
16
|
+
@is_disabled = is_disabled
|
17
|
+
@is_locked = is_locked
|
18
|
+
@site_count = site_count
|
19
|
+
@group_count = group_count
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
out = "#{@user_name} (#{@full_name}) [ID: #{@id}]"
|
24
|
+
out << " e-mail: #{@email}" unless @email.empty?
|
25
|
+
out << " Administrator" if @is_admin
|
26
|
+
out << " Disabled" if @is_disabled
|
27
|
+
out << " Locked" if @is_locked
|
28
|
+
out << ", sites: #{@site_count}"
|
29
|
+
out << ", groups: #{@group_count}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Provide a list of user accounts and information about those accounts.
|
33
|
+
def self.listing(connection)
|
34
|
+
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
35
|
+
r = connection.execute(xml, '1.1')
|
36
|
+
if r.success
|
37
|
+
res = []
|
38
|
+
r.res.elements.each('UserListingResponse/UserSummary') do |summary|
|
39
|
+
res << UserSummary.new(
|
40
|
+
summary.attributes['id'].to_i,
|
41
|
+
summary.attributes['authSource'],
|
42
|
+
summary.attributes['authModule'],
|
43
|
+
summary.attributes['userName'],
|
44
|
+
summary.attributes['fullName'],
|
45
|
+
summary.attributes['email'],
|
46
|
+
summary.attributes['administrator'].to_s.chomp.eql?('1'),
|
47
|
+
summary.attributes['disabled'].to_s.chomp.eql?('1'),
|
48
|
+
summary.attributes['locked'].to_s.chomp.eql?('1'),
|
49
|
+
summary.attributes['siteCount'].to_i,
|
50
|
+
summary.attributes['groupCount'].to_i)
|
51
|
+
end
|
52
|
+
res
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieve the User ID based upon the user's login name.
|
59
|
+
def self.get_user_id(connection, user_name)
|
60
|
+
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
61
|
+
r = connection.execute(xml, '1.1')
|
62
|
+
if r.success
|
63
|
+
r.res.elements.each('UserListingResponse/UserSummary') do |user|
|
64
|
+
return user.attributes['id'] if user_name.eql? user.attributes['userName']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return -1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class UserConfig
|
72
|
+
# user id, set to -1 to create a new user
|
73
|
+
attr_reader :id
|
74
|
+
# valid roles: global-admin|security-manager|site-admin|system-admin|user|custom
|
75
|
+
attr_accessor :role_name
|
76
|
+
# Required fields
|
77
|
+
attr_reader :name
|
78
|
+
attr_accessor :full_name
|
79
|
+
# Will default to XML (1) for global-admin, Data Source (2) otherwise,
|
80
|
+
# but caller can override (e.g., using LDAP authenticator).
|
81
|
+
attr_accessor :authsrcid
|
82
|
+
# Optional fields
|
83
|
+
attr_accessor :email, :password, :sites, :groups
|
84
|
+
# 1 to enable this user, 0 to disable
|
85
|
+
attr_accessor :enabled
|
86
|
+
# Boolean values
|
87
|
+
attr_accessor :all_sites, :all_groups
|
88
|
+
|
89
|
+
def initialize(name, full_name, password, role_name = 'user', id = -1, enabled = 1, email = nil, all_sites = false, all_groups = false)
|
90
|
+
@name = name
|
91
|
+
@password = password
|
92
|
+
@role_name = role_name
|
93
|
+
@authsrcid = ('global-admin'.eql? @role_name) ? '1' : '2'
|
94
|
+
@id = id
|
95
|
+
@enabled = enabled
|
96
|
+
@full_name = full_name
|
97
|
+
@email = email
|
98
|
+
@all_sites = all_sites || role_name == 'global-admin'
|
99
|
+
@all_groups = all_groups || role_name == 'global-admin'
|
100
|
+
@sites = []
|
101
|
+
@groups = []
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_s
|
105
|
+
out = "#{@user_name} (#{@full_name}) [ID: #{@id}, Role: #{@role_name}]"
|
106
|
+
out << " Disabled" unless @enabled
|
107
|
+
out << " All-Sites" if @all_sites
|
108
|
+
out << " All-Groups" if @all_groups
|
109
|
+
out << " e-mail: #{@email}" unless @email.nil? || @email.empty?
|
110
|
+
out
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_xml
|
114
|
+
xml = "<UserConfig"
|
115
|
+
xml << %Q{ id="#{@id}"}
|
116
|
+
xml << %Q{ authsrcid="#{@authsrcid}"}
|
117
|
+
xml << %Q{ name="#{@name}"}
|
118
|
+
xml << %Q{ fullname="#{@full_name}"}
|
119
|
+
xml << %Q{ role-name="#{@role_name}"}
|
120
|
+
xml << %Q{ password="#{@password}"} if @password
|
121
|
+
xml << %Q{ email="#{@email}"} if @email
|
122
|
+
xml << %Q{ enabled="#{@enabled}"}
|
123
|
+
# These two fields are keying off role_name to work around a defect.
|
124
|
+
xml << %Q{ allGroups="#{@all_groups || @role_name == 'global-admin'}"}
|
125
|
+
xml << %Q{ allSites="#{@all_sites || @role_name == 'global-admin'}"}
|
126
|
+
xml << ">"
|
127
|
+
@sites.each do |site|
|
128
|
+
xml << %Q{<site id="#{site}" />}
|
129
|
+
end
|
130
|
+
@groups.each do |group|
|
131
|
+
xml << %Q{<group id="#{group}" />}
|
132
|
+
end
|
133
|
+
xml << '</UserConfig>'
|
134
|
+
end
|
135
|
+
|
136
|
+
# Save a user configuration. Returns the (new) user ID if successful.
|
137
|
+
def save(connection)
|
138
|
+
xml = '<UserSaveRequest session-id="' + connection.session_id + '">'
|
139
|
+
xml << to_xml
|
140
|
+
xml << '</UserSaveRequest>'
|
141
|
+
r = connection.execute(xml, '1.1')
|
142
|
+
if r.success
|
143
|
+
res = []
|
144
|
+
r.res.elements.each('UserSaveResponse') do |attr|
|
145
|
+
@id = attr.attributes['id'].to_i
|
146
|
+
end
|
147
|
+
@id
|
148
|
+
else
|
149
|
+
-1
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Issue a UserConfigRequest to load an existing UserConfig from Nexpose.
|
154
|
+
def self.load(connection, user_id)
|
155
|
+
xml = '<UserConfigRequest session-id="' + connection.session_id + '"'
|
156
|
+
xml << %Q{ id="#{user_id}"}
|
157
|
+
xml << ' />'
|
158
|
+
r = connection.execute(xml, '1.1')
|
159
|
+
if r.success
|
160
|
+
r.res.elements.each('UserConfigResponse/UserConfig') do |config|
|
161
|
+
id = config.attributes['id']
|
162
|
+
role_name = config.attributes['role-name']
|
163
|
+
authsrcid = config.attributes['authsrcid']
|
164
|
+
name = config.attributes['name']
|
165
|
+
fullname = config.attributes['fullname']
|
166
|
+
|
167
|
+
email = config.attributes['email']
|
168
|
+
password = config.attributes['password']
|
169
|
+
enabled = config.attributes['enabled'].to_i
|
170
|
+
all_sites = config.attributes['allSites'] == 'true' ? true : false
|
171
|
+
all_groups = config.attributes['allGroups'] == 'true' ? true : false
|
172
|
+
# Not trying to load sites and groups.
|
173
|
+
# Looks like API currently doesn't return that info to load.
|
174
|
+
return UserConfig.new(name, fullname, password, role_name, id, enabled, email, all_sites, all_groups)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Delete a user account.
|
180
|
+
def self.delete(connection, user_id)
|
181
|
+
xml = '<UserDeleteRequest session-id="' + connection.session_id + '"'
|
182
|
+
xml << %Q{ id="#{user_id}"}
|
183
|
+
xml << ' />'
|
184
|
+
r = connection.execute(xml, '1.1')
|
185
|
+
if r.success
|
186
|
+
r.res.elements.each('UserConfigResponse/UserConfig') do |config|
|
187
|
+
'1'.eql? config.attributes['id']
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Delete the user account associated with this object.
|
193
|
+
def delete(connection)
|
194
|
+
UserConfig.delete(connection, @id)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class UserAuthenticator
|
199
|
+
attr_reader :id, :auth_source, :auth_module, :external
|
200
|
+
|
201
|
+
def initialize(id, auth_module, auth_source, external = false)
|
202
|
+
@id = id
|
203
|
+
@auth_source = auth_source
|
204
|
+
@auth_module = auth_module
|
205
|
+
@external = external
|
206
|
+
end
|
207
|
+
|
208
|
+
# Provide a list of user authentication sources.
|
209
|
+
# * *Returns* : An array of known user authenticator sources.
|
210
|
+
def self.list(connection)
|
211
|
+
r = connection.execute('<UserAuthenticatorListingRequest session-id="' + connection.session_id + '" />', '1.1')
|
212
|
+
if r.success
|
213
|
+
modules = []
|
214
|
+
r.res.elements.each('UserAuthenticatorListingResponse/AuthenticatorSummary') do |summary|
|
215
|
+
modules << UserAuthenticator.new(summary.attributes['id'], summary.attributes['authModule'], summary.attributes['authSource'], ('1'.eql? summary.attributes['external']))
|
216
|
+
end
|
217
|
+
modules
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
data/nexpose.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "nexpose"
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.97"
|
6
6
|
s.homepage = "https://github.com/rapid7/nexpose-client"
|
7
7
|
s.summary = "Ruby API for Rapid7 NeXpose"
|
8
8
|
s.description = "This gem provides a Ruby API to the NeXpose vulnerability management product by Rapid7."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexpose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.97
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-07-13 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: librex
|
17
|
-
requirement: &
|
17
|
+
requirement: &26808912 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 0.0.32
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *26808912
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rex
|
28
|
-
requirement: &
|
28
|
+
requirement: &26808636 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 1.0.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *26808636
|
37
37
|
description: This gem provides a Ruby API to the NeXpose vulnerability management
|
38
38
|
product by Rapid7.
|
39
39
|
email:
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/nexpose/silo.rb
|
60
60
|
- lib/nexpose/site.rb
|
61
61
|
- lib/nexpose/ticket.rb
|
62
|
+
- lib/nexpose/user.rb
|
62
63
|
- lib/nexpose/util.rb
|
63
64
|
- lib/nexpose/vuln.rb
|
64
65
|
- lib/nexpose.rb
|