mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
use simple config for security policy resource
This commit is contained in:
parent
fe9850664d
commit
9c7d06c167
2 changed files with 72 additions and 43 deletions
|
@ -13,72 +13,101 @@
|
|||
# All local GPO parameters can be examined via Registry, but not all security
|
||||
# parameters. Therefore we need a combination of Registry and secedit output
|
||||
|
||||
require 'hashie'
|
||||
|
||||
module Inspec::Resources
|
||||
class SecurityPolicy < Inspec.resource(1)
|
||||
name 'security_policy'
|
||||
desc 'Use the security_policy InSpec audit resource to test security policies on the Microsoft Windows platform.'
|
||||
example "
|
||||
describe security_policy do
|
||||
its('SeNetworkLogonRight') { should eq '*S-1-5-11' }
|
||||
its('SeNetworkLogonRight') { should include 'S-1-5-11' }
|
||||
end
|
||||
"
|
||||
def initialize
|
||||
@loaded = false
|
||||
@policy = nil
|
||||
@exit_status = nil
|
||||
|
||||
def content
|
||||
read_content
|
||||
end
|
||||
|
||||
# load security content
|
||||
def load
|
||||
def params(*opts)
|
||||
opts.inject(read_params) do |res, nxt|
|
||||
res.respond_to?(:key) ? res[nxt] : nil
|
||||
end
|
||||
end
|
||||
|
||||
def method_missing(name)
|
||||
params = read_params
|
||||
return nil if params.nil?
|
||||
|
||||
# deep search for hash key
|
||||
params.extend Hashie::Extensions::DeepFind
|
||||
res = params.deep_find(name.to_s)
|
||||
res
|
||||
end
|
||||
|
||||
def to_s
|
||||
'Security Policy'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_content
|
||||
return @content if defined?(@content)
|
||||
|
||||
# export the security policy
|
||||
cmd = inspec.command('secedit /export /cfg win_secpol.cfg')
|
||||
return nil if cmd.exit_status.to_i != 0
|
||||
|
||||
# store file content
|
||||
cmd = inspec.command('Get-Content win_secpol.cfg')
|
||||
@exit_status = cmd.exit_status.to_i
|
||||
return nil if @exit_status != 0
|
||||
@policy = cmd.stdout
|
||||
@loaded = true
|
||||
|
||||
# returns self
|
||||
self
|
||||
return skip_resource "Can't read security policy" if cmd.exit_status.to_i != 0
|
||||
@content = cmd.stdout
|
||||
|
||||
if @content.empty? && file.size > 0
|
||||
return skip_resource "Can't read security policy"
|
||||
end
|
||||
@content
|
||||
ensure
|
||||
# delete temp file
|
||||
inspec.command('Remove-Item win_secpol.cfg').exit_status.to_i
|
||||
end
|
||||
|
||||
def method_missing(method)
|
||||
# load data if needed
|
||||
if @loaded == false
|
||||
load
|
||||
end
|
||||
def read_params
|
||||
return @params if defined?(@params)
|
||||
return @params = {} if read_content.nil?
|
||||
|
||||
# find line with key
|
||||
key = Regexp.escape(method.to_s)
|
||||
target = ''
|
||||
@policy.each_line {|s|
|
||||
target = s.strip if s =~ /^\s*#{key}\s*=\s*(.*)\b/
|
||||
}
|
||||
|
||||
# extract variable value
|
||||
result = target.match(/[=]{1}\s*(?<value>.*)/)
|
||||
|
||||
if !result.nil?
|
||||
val = result[:value]
|
||||
val = val.to_i if val =~ /^\d+$/
|
||||
else
|
||||
# TODO: we may need to return skip or failure if the
|
||||
# requested value is not available
|
||||
val = nil
|
||||
end
|
||||
|
||||
val
|
||||
conf = SimpleConfig.new(
|
||||
@content,
|
||||
assignment_re: /^\s*(.*)=\s*(\S*)\s*$/,
|
||||
)
|
||||
@params = convert_hash(conf.params)
|
||||
end
|
||||
|
||||
def to_s
|
||||
'Security Policy'
|
||||
# extracts the values, this methods detects:
|
||||
# numbers and SIDs and optimizes them for further usage
|
||||
def extract_value(val)
|
||||
if val =~ /^\d+$/
|
||||
val.to_i
|
||||
# special handling for SID array
|
||||
elsif val =~ /^\*\S/
|
||||
val.split(',').map { |v|
|
||||
v.sub('*S', 'S')
|
||||
}
|
||||
# special handling for string values with "
|
||||
elsif !(m = /^\"(.*)\"$/.match(val)).nil?
|
||||
m[1]
|
||||
else
|
||||
val
|
||||
end
|
||||
end
|
||||
|
||||
def convert_hash(hash)
|
||||
new_hash = {}
|
||||
hash.each do |k, v|
|
||||
v.is_a?(Hash) ? value = convert_hash(v) : value = extract_value(v)
|
||||
new_hash[k.strip] = value
|
||||
end
|
||||
new_hash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ describe 'Inspec::Resources::SecurityPolicy' do
|
|||
resource = load_resource('security_policy')
|
||||
_(resource.MaximumPasswordAge).must_equal 42
|
||||
_(resource.send('MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Setup\RecoveryConsole\SecurityLevel')).must_equal '4,0'
|
||||
_(resource.SeUndockPrivilege).must_equal '*S-1-5-32-544'
|
||||
_(resource.SeRemoteInteractiveLogonRight).must_equal '*S-1-5-32-544,*S-1-5-32-555'
|
||||
_(resource.SeUndockPrivilege).must_equal ["S-1-5-32-544"]
|
||||
_(resource.SeRemoteInteractiveLogonRight).must_equal ["S-1-5-32-544","S-1-5-32-555"]
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue