Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions controls/plist_example.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# copyright: 2018, The Authors

title "Examples for the plist resource"
title 'Examples for the plist resource'

control 'Basic example' do
describe plist('/System/Library/CoreServices/SystemVersion.plist') do
Expand Down Expand Up @@ -31,11 +31,11 @@
control 'Another xpath example' do
describe plist('/Library/Preferences/com.apple.loginwindow.plist', xpath: '/plist/dict/key[text()=\'LoginwindowText\']/following-sibling::*[1]/text()') do
it { should exist }
its("xpath_value") { should match(/^.+/) }
its('xpath_value') { should match(/^.+/) }
end

describe plist('$HOME/Library/Preferences/com.apple.systemuiserver.plist', xpath: '/plist/dict/key[.=\'menuExtras\']/following-sibling::*[1]/string[.=\'/System/Library/CoreServices/Menu Extras/AirPort.menu\']/text()') do
it { should exist }
its("xpath_value") { should cmp '/System/Library/CoreServices/Menu Extras/AirPort.menu' }
its('xpath_value') { should cmp '/System/Library/CoreServices/Menu Extras/AirPort.menu' }
end
end
6 changes: 3 additions & 3 deletions libraries/Plist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def initialize(path, opts = {})
end

def to_s
"plist #{@path}" + (@xpath ? " with xpath: #{@xpath}" : '')
"plist #{@path}" + (@xpath ? " with xpath: #{@xpath}" : '')
end

def exists?
Expand All @@ -28,7 +28,7 @@ def exists?
inspec.file(@path).exist?
end

def method_missing(*args)
def method_missing(*args)
load_json
required_key = args[0].is_a?(Array) ? args[0].map { |x| x.to_s } : args[0].to_s
@json_data.dig(*required_key)
Expand All @@ -45,7 +45,7 @@ def xpath_value

def load_json
begin
@json_data ||= JSON.parse(inspec.command("plutil -convert json -o - #{@path}").stdout)
@json_data ||= JSON.parse(inspec.command("plutil -convert json -o - #{@path}").stdout)
rescue => e
raise Inspec::Exceptions::ResourceFailed, "Failed to read plist data for '#{@path}': #{e.message}"
end
Expand Down
39 changes: 20 additions & 19 deletions libraries/RegistrySecurityDescriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,26 @@ class RegistrySecurityDescriptor < Inspec.resource(1)
'KeyWow6432Key' => 0b1000000000,
'KeyWow6464Key' => 0b100000000,
'KeyWow64Res' => 0b1100000000,
'KeyWrite' => 0b00000000000000110
'KeyWrite' => 0b00000000000000110,
}.freeze

def initialize(path, options = {})
def initialize(path, _options = {})
@path = path
@trustee_access_mask = nil
end

def permissions
fetch_results
return nil unless @trustee_access_mask
return unless @trustee_access_mask
results = {}
@trustee_access_mask.each do |trusteesid, accessmask|
accessrights = {}
ACCESS_RIGHTS_BINARY.each do |k,v|
if accessmask.to_i & v == 0
accessrights[k] = 0
else
accessrights[k] = 1
end
ACCESS_RIGHTS_BINARY.each do |k, v|
accessrights[k] = if accessmask.to_i & v == 0
0
else
1
end
end
results[trusteesid] = accessrights
end
Expand All @@ -79,10 +79,10 @@ def permissions

def permissions_for_trustee(trustee)
fetch_results
return nil unless @trustee_access_mask || trustee
return unless @trustee_access_mask || trustee
results = {}
accessmask = @trustee_access_mask[trustee]
ACCESS_RIGHTS_BINARY.each do |k,v|
ACCESS_RIGHTS_BINARY.each do |k, v|
results[k] = (accessmask.to_i & v == 0) ? 0 : 1
end
results
Expand All @@ -92,27 +92,28 @@ def trustees_with_any_permission
fetch_results
return [] unless @trustee_access_mask
trustees = []
@trustee_access_mask.each do |trusteesid, accessmask|
@trustee_access_mask.each do |trusteesid, _accessmask|
trustees.push(trusteesid)
end
trustees
end

private

def fetch_results
return if @trustee_access_mask
sddl = inspec.powershell("(Get-Acl #{@path}).SDDL").stdout.strip.gsub("\r\n","")
raise "The provided Registry Key '#{@path}' does not have an SDDL associated." if sddl == ""
sddl = inspec.powershell("(Get-Acl #{@path}).SDDL").stdout.strip.gsub("\r\n", '')
raise "The provided Registry Key '#{@path}' does not have an SDDL associated." if sddl == ''
@trustee_access_mask = {}
access_details = inspec.powershell("(Invoke-CimMethod Win32_SecurityDescriptorHelper -MethodName SDDLToWin32SD -Arguments @{ SDDL = '#{sddl}' }).Descriptor.DACL | Select @{Name=\"SID\";Expression={$_.Trustee.SIDString}},AccessMask").stdout.strip.split("\r\n")[2..-1].map { |entry| entry.split }
access_details.each do |access_detail|
trusteesid = access_detail[0]
accessmask = access_detail[1]
if @trustee_access_mask.key?(trusteesid) && @trustee_access_mask[trusteesid]
@trustee_access_mask[trusteesid] = (accessmask.to_i + @trustee_access_mask[trusteesid].to_i).to_s
else
@trustee_access_mask[trusteesid] = accessmask
end
@trustee_access_mask[trusteesid] = if @trustee_access_mask.key?(trusteesid) && @trustee_access_mask[trusteesid]
(accessmask.to_i + @trustee_access_mask[trusteesid].to_i).to_s
else
accessmask
end
end
end
end
14 changes: 7 additions & 7 deletions libraries/SecurityDescriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ class SecurityDescriptor < Inspec.resource(1)
end
"

def initialize(filename, options = {})
def initialize(filename, _options = {})
@filename = filename
@results = nil
end

%w{Read ReadAndExecute Write Modify Sychronize FullControl}.each do |perm|
%w(Read ReadAndExecute Write Modify Sychronize FullControl).each do |perm|
define_method perm do
fetch_results unless @results
# Return keys that have this permission, with the domain stripped
@results.select { |k,v| v.include?(perm) }.keys.map { |key| key.split("\\")[-1] }
@results.select { |_k, v| v.include?(perm) }.keys.map { |key| key.split('\\')[-1] }
end
end

def method_missing(name)
fetch_results unless @results
# Return the results for this entity if it exists (with some domain name) in the result set
entity_key = @results.keys.select { |key| key.split("\\")[-1] == name.to_s }[0]
entity_key = @results.keys.select { |key| key.split('\\')[-1] == name.to_s }[0]
return @results[entity_key] if entity_key
# Entity not in the result set is "no permissions"
[]
Expand All @@ -45,12 +45,12 @@ def fetch_results
raise cmd.stderr.strip unless cmd.stderr == ''
access_details = cmd.stdout.strip.split("\r\n\r\n").map { |entry| entry.split("\r\n") }
access_details.each do |access_detail|
entity = access_detail.select { |a| a =~ %r{^IdentityReference} }[0].tr(' ', '').split(':')[-1]
permissions = access_detail.select { |a| a =~ %r{^FileSystemRights} }[0].tr(' ', '').split(':')[-1].split(',')
entity = access_detail.select { |a| a =~ /^IdentityReference/ }[0].tr(' ', '').split(':')[-1]
permissions = access_detail.select { |a| a =~ /^FileSystemRights/ }[0].tr(' ', '').split(':')[-1].split(',')
# Get-Acl displays entity names in its results rather than SIDs.
# It is preferable to work with SIDs when testing security
# Replace the entity name from Get-Acl with a SID where possible.
entity_id = get_sid(entity.split("\\")[-1])
entity_id = get_sid(entity.split('\\')[-1])
@results[entity_id] = permissions
end
end
Expand Down
2 changes: 1 addition & 1 deletion libraries/SecurityIdentifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def initialize(opts = {})
supported_opt_keys = [:user, :group, :unspecified]
raise "Invalid security_identifier param '#{opts}'. Please pass a hash with these supported keys: #{supported_opt_keys}" unless opts.respond_to?(:keys)
raise "Unsupported security_identifier options '#{opts.keys - supported_opt_keys}'. Supported keys: #[supported_opt_keys]" unless (opts.keys - supported_opt_keys).empty?
raise 'Specifying more than one of :user :group or :unspecified for security_identifier is not supported' unless opts.keys and (opts.keys & supported_opt_keys).length == 1
raise 'Specifying more than one of :user :group or :unspecified for security_identifier is not supported' unless opts.keys && ((opts.keys & supported_opt_keys).length == 1)
if opts[:user]
@type = :user
@name = opts[:user]
Expand Down