2015-07-27 21:24:46 +00:00
# encoding: utf-8
# copyright: 2015, Vulcano Security GmbH
require 'utils/simpleconfig'
2015-08-03 03:11:01 +00:00
require 'utils/find_files'
2018-03-22 12:25:45 +00:00
require 'utils/file_reader'
2015-07-27 21:24:46 +00:00
2016-03-08 18:06:55 +00:00
module Inspec::Resources
class ApacheConf < Inspec . resource ( 1 )
name 'apache_conf'
2018-02-19 14:26:49 +00:00
supports platform : 'linux'
supports platform : 'debian'
2016-03-08 18:06:55 +00:00
desc 'Use the apache_conf InSpec audit resource to test the configuration settings for Apache. This file is typically located under /etc/apache2 on the Debian and Ubuntu platforms and under /etc/httpd on the Fedora, CentOS, Red Hat Enterprise Linux, and Arch Linux platforms. The configuration settings may vary significantly from platform to platform.'
example "
describe apache_conf do
its ( 'setting_name' ) { should eq 'value' }
end
"
2015-07-27 21:24:46 +00:00
2016-03-08 18:06:55 +00:00
include FindFiles
2018-03-22 12:25:45 +00:00
include FileReader
2015-09-10 09:33:41 +00:00
2018-01-31 10:16:15 +00:00
attr_reader :conf_path
2016-03-08 18:06:55 +00:00
def initialize ( conf_path = nil )
2018-01-31 10:16:15 +00:00
@conf_path = conf_path || default_conf_path
2016-03-08 18:06:55 +00:00
@files_contents = { }
@content = nil
@params = nil
read_content
end
2015-07-27 21:24:46 +00:00
2016-03-08 18:06:55 +00:00
def content
@content || = read_content
end
2015-07-27 21:24:46 +00:00
2016-03-08 18:06:55 +00:00
def params ( * opts )
@params || read_content
res = @params
opts . each do | opt |
res = res [ opt ] unless res . nil?
end
res
2015-07-27 21:24:46 +00:00
end
2016-03-08 18:06:55 +00:00
def method_missing ( name )
# ensure params are loaded
@params || read_content
2016-02-01 16:17:26 +00:00
2016-03-08 18:06:55 +00:00
# extract values
@params [ name . to_s ] unless @params . nil?
end
2016-02-01 16:17:26 +00:00
2016-03-08 18:06:55 +00:00
def filter_comments ( data )
content = ''
data . each_line do | line |
if ! line . match ( / ^ \ s* # / )
content << line
end
2015-07-27 21:24:46 +00:00
end
2016-03-08 18:06:55 +00:00
content
2015-07-27 21:24:46 +00:00
end
2016-03-08 18:06:55 +00:00
def read_content
@content = ''
@params = { }
2015-08-03 03:28:32 +00:00
2018-03-22 12:25:45 +00:00
read_file_content ( conf_path )
2015-08-03 03:28:32 +00:00
2018-01-31 10:16:15 +00:00
to_read = [ conf_path ]
2016-03-08 18:06:55 +00:00
until to_read . empty?
raw_conf = read_file ( to_read [ 0 ] )
@content += raw_conf
2017-12-22 16:07:46 +00:00
# An explaination of the below regular expression.
# Creates two capture groups.
# The first group captures the first group of non-whitespace character
# surrounded whitespace characters.
# The second group contains a conditional with a positive lookahead
# (does the line end with one or more spaces?). If the lookahead succeeds
# a non-greedy capture takes place, if it fails then a greedy capture takes place.
# The regex is terminated by an expression that matches zero or more spaces.
2016-03-08 18:06:55 +00:00
params = SimpleConfig . new (
raw_conf ,
2017-12-22 16:07:46 +00:00
assignment_regex : / ^ \ s*( \ S+) \ s+((?=.* \ s+$).*?|.*) \ s*$ / ,
2016-03-08 18:06:55 +00:00
multiple_values : true ,
) . params
@params . merge! ( params )
to_read = to_read . drop ( 1 )
to_read += include_files ( params ) . find_all do | fp |
not @files_contents . key? fp
end
2015-07-27 21:24:46 +00:00
end
2016-03-08 18:06:55 +00:00
# fiter comments
@content = filter_comments @content
@content
2015-07-27 21:24:46 +00:00
end
2016-03-08 18:06:55 +00:00
def include_files ( params )
# see if there is more config files to include
include_files = params [ 'Include' ] || [ ]
include_files_optional = params [ 'IncludeOptional' ] || [ ]
2015-07-27 21:24:46 +00:00
2016-03-08 18:06:55 +00:00
includes = [ ]
( include_files + include_files_optional ) . each do | f |
2018-01-31 10:16:15 +00:00
id = Pathname . new ( f ) . absolute? ? f : File . join ( conf_dir , f )
2016-03-08 18:06:55 +00:00
files = find_files ( id , depth : 1 , type : 'file' )
2017-01-07 23:54:00 +00:00
files += find_files ( id , depth : 1 , type : 'link' )
2015-09-09 17:15:51 +00:00
2016-03-08 18:06:55 +00:00
includes . push ( files ) if files
end
2015-09-09 17:15:51 +00:00
2016-03-08 18:06:55 +00:00
# [].flatten! == nil
includes . flatten! || [ ]
2015-09-09 17:15:51 +00:00
end
2016-03-08 18:06:55 +00:00
def read_file ( path )
2018-03-22 12:25:45 +00:00
@files_contents [ path ] || = read_file_content ( path )
2016-03-08 18:06:55 +00:00
end
2015-10-12 11:01:58 +00:00
2018-01-31 10:16:15 +00:00
def conf_dir
if inspec . os . debian?
File . dirname ( conf_path )
else
# On RHEL-based systems, the configuration is usually in a /conf directory
# that contains the primary config file. We assume the "config path" is the
# directory that contains the /conf directory, such as /etc/httpd, so that
# the conf.d directory can be properly located.
Pathname . new ( File . dirname ( conf_path ) ) . parent . to_s
end
end
2016-03-08 18:06:55 +00:00
def to_s
2018-01-31 10:16:15 +00:00
" Apache Config #{ conf_path } "
end
private
def default_conf_path
if inspec . os . debian?
'/etc/apache2/apache2.conf'
else
'/etc/httpd/conf/httpd.conf'
end
2016-03-08 18:06:55 +00:00
end
2015-10-12 11:01:58 +00:00
end
2015-07-27 21:24:46 +00:00
end