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
2016-03-31 00:23:23 +00:00
require 'shellwords'
2015-10-26 03:04:18 +00:00
module Inspec::Resources
2016-03-09 09:35:35 +00:00
class FileResource < 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' }
2016-04-20 11:06:40 +00:00
its ( 'mode' ) { should cmp '0644' }
2015-11-27 13:02:38 +00:00
end
"
2015-12-31 00:08:57 +00:00
include MountParser
2015-08-29 07:44:16 +00:00
2016-04-28 16:35:55 +00:00
attr_reader :file , :mount_options
2015-08-30 00:14:17 +00:00
def initialize ( path )
2016-04-28 16:35:55 +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?
2016-04-28 16:35:55 +00:00
symlink? pipe? mode mode? owner owned_by? group grouped_into?
2016-02-22 03:44:49 +00:00
link_path linked_to? mtime size selinux_label immutable?
2015-09-05 14:07:54 +00:00
product_version file_version version? md5sum sha256sum
2016-04-29 17:28:34 +00:00
path basename source source_path uid gid
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
2016-02-22 03:44:49 +00:00
def content
res = file . content
return nil if res . nil?
res . force_encoding ( 'utf-8' )
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
2016-04-28 23:56:13 +00:00
warn " [DEPRECATION] `be_mounted.with and be_mounted.only_with` are deprecated. Please use `mount(' #{ source_path } ')` instead. "
2016-01-02 23:01:54 +00:00
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
2016-04-28 23:56:13 +00:00
" File #{ source_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 )
2016-01-28 22:33:11 +00:00
unless inspec . os . unix?
fail 'Checking file permissions is not supported on your os'
end
2015-12-07 19:41:05 +00:00
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 )
2016-01-28 22:33:11 +00:00
if inspec . os . linux?
2016-04-28 23:56:13 +00:00
perm_cmd = " su -s /bin/sh -c \" test - #{ flag } #{ source_path } \" #{ user } "
2016-01-28 22:33:11 +00:00
elsif inspec . os . bsd? || inspec . os . solaris?
2016-04-28 23:56:13 +00:00
perm_cmd = " sudo -u #{ user } test - #{ flag } #{ source_path } "
2016-01-28 22:33:11 +00:00
elsif inspec . os . aix?
2016-04-28 23:56:13 +00:00
perm_cmd = " su #{ user } -c test - #{ flag } #{ source_path } "
2016-04-26 09:23:28 +00:00
elsif inspec . os . hpux?
2016-04-28 23:56:13 +00:00
perm_cmd = " su #{ user } -c \" test - #{ flag } #{ source_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
2015-08-29 07:44:16 +00:00
end
end