2015-07-15 13:15:18 +00:00
# encoding: utf-8
# copyright: 2015, Vulcano Security GmbH
2015-10-06 16:55:44 +00:00
# author: Dominik Richter
# author: Christoph Hartmann
2015-07-15 13:15:18 +00:00
# license: All rights reserved
2015-10-26 03:04:18 +00:00
module Inspec::Resources
2016-01-03 08:49:40 +00:00
class File < Inspec . resource ( 1 ) # rubocop:disable Metrics/ClassLength
2015-08-30 00:14:17 +00:00
name 'file'
2015-11-27 13:02:38 +00:00
desc 'Use the file InSpec audit resource to test all system file types, including files, directories, symbolic links, named pipes, sockets, character devices, block devices, and doors.'
example "
describe file ( 'path' ) do
it { should exist }
it { should be_file }
it { should be_readable }
it { should be_writable }
it { should be_owned_by 'root' }
its ( 'mode' ) { should eq 0644 }
end
"
2015-12-31 00:08:57 +00:00
include MountParser
2015-08-29 07:44:16 +00:00
2015-12-31 00:08:57 +00:00
attr_reader :file , :path , :mount_options
2015-08-30 00:14:17 +00:00
def initialize ( path )
@path = path
2015-10-26 03:04:18 +00:00
@file = inspec . backend . file ( @path )
2015-08-30 00:14:17 +00:00
end
2015-08-29 07:44:16 +00:00
2015-08-30 00:14:17 +00:00
%w{
2015-09-18 10:35:32 +00:00
type exist? file? block_device? character_device? socket? directory?
2015-09-05 14:07:54 +00:00
symlink? pipe? mode mode? owner owned_by? group grouped_into? link_target
2015-12-31 00:08:57 +00:00
link_path linked_to? content mtime size selinux_label immutable?
2015-09-05 14:07:54 +00:00
product_version file_version version? md5sum sha256sum
2015-09-03 14:17:52 +00:00
} . each do | m |
define_method m . to_sym do | * args |
2015-12-07 19:41:05 +00:00
file . method ( m . to_sym ) . call ( * args )
2015-08-30 00:14:17 +00:00
end
2015-08-29 07:44:16 +00:00
end
2015-09-09 16:52:27 +00:00
def contain ( * _ )
2015-10-25 20:47:27 +00:00
fail 'Contain is not supported. Please use standard RSpec matchers.'
2015-08-30 00:14:17 +00:00
end
2015-08-29 07:44:16 +00:00
2015-12-07 19:41:05 +00:00
def readable? ( by_usergroup , by_specific_user )
return false unless exist?
file_permission_granted? ( 'r' , by_usergroup , by_specific_user )
2015-08-30 00:14:17 +00:00
end
2015-08-29 07:44:16 +00:00
2015-12-07 19:41:05 +00:00
def writable? ( by_usergroup , by_specific_user )
return false unless exist?
file_permission_granted? ( 'w' , by_usergroup , by_specific_user )
2015-06-21 09:23:30 +00:00
end
2015-08-29 07:44:16 +00:00
2015-12-07 19:41:05 +00:00
def executable? ( by_usergroup , by_specific_user )
return false unless exist?
file_permission_granted? ( 'x' , by_usergroup , by_specific_user )
2015-08-29 07:44:16 +00:00
end
2015-12-31 00:08:57 +00:00
def mounted? ( expected_options = nil , identical = false )
mounted = file . mounted
# return if no additional parameters have been provided
return file . mounted? if expected_options . nil?
2016-01-02 23:01:54 +00:00
# deprecation warning, this functionality will be removed in future version
warn " [DEPRECATION] `be_mounted.with and be_mounted.only_with` are deprecated. Please use `mount(' #{ path } ')` instead. "
2016-01-02 21:57:52 +00:00
# we cannot read mount data on non-Linux systems
return nil if ! inspec . os . linux?
2015-12-31 00:08:57 +00:00
# parse content if we are on linux
@mount_options || = parse_mount_options ( mounted . stdout , true )
if identical
# check if the options should be identical
@mount_options == expected_options
else
# otherwise compare the selected values
@mount_options . contains ( expected_options )
end
end
2015-08-30 00:14:17 +00:00
def to_s
2015-12-07 19:41:05 +00:00
" File #{ path } "
2015-08-30 00:14:17 +00:00
end
2015-10-25 20:35:35 +00:00
private
2015-12-07 19:41:05 +00:00
def file_permission_granted? ( flag , by_usergroup , by_specific_user )
fail 'Checking file permissions is not supported on your os' unless unix?
2015-12-21 22:12:29 +00:00
if by_specific_user . nil? || by_specific_user . empty?
usergroup = usergroup_for ( by_usergroup , by_specific_user )
2015-12-07 19:41:05 +00:00
check_file_permission_by_mask ( usergroup , flag )
else
check_file_permission_by_user ( by_specific_user , flag )
2015-10-25 20:35:35 +00:00
end
2015-12-07 19:41:05 +00:00
end
def check_file_permission_by_mask ( usergroup , flag )
mask = file . unix_mode_mask ( usergroup , flag )
fail 'Invalid usergroup/owner provided' if mask . nil?
2015-10-25 20:35:35 +00:00
2015-12-07 19:41:05 +00:00
( file . mode & mask ) != 0
end
def check_file_permission_by_user ( user , flag )
if linux?
perm_cmd = " su -s /bin/sh -c \" test - #{ flag } #{ path } \" #{ user } "
2016-01-28 13:22:30 +00:00
elsif family == 'freebsd' || solaris?
2015-12-07 19:41:05 +00:00
perm_cmd = " sudo -u #{ user } test - #{ flag } #{ path } "
2015-12-21 22:12:29 +00:00
elsif family == 'aix'
perm_cmd = " su #{ user } -c test - #{ flag } #{ path } "
2015-10-25 20:35:35 +00:00
else
return skip_resource 'The `file` resource does not support `by_user` on your OS.'
end
2015-12-07 19:41:05 +00:00
cmd = inspec . command ( perm_cmd )
cmd . exit_status == 0 ? true : false
end
def usergroup_for ( usergroup , specific_user )
if usergroup == 'others'
'other'
elsif ( usergroup . nil? || usergroup . empty? ) && specific_user . nil?
'all'
else
usergroup
end
end
def unix?
inspec . os . unix?
end
def linux?
inspec . os . linux?
end
2016-01-28 13:22:30 +00:00
def solaris?
inspec . os . solaris?
end
2015-12-07 19:41:05 +00:00
def family
inspec . os [ :family ]
2015-10-25 20:35:35 +00:00
end
2015-08-29 07:44:16 +00:00
end
end