From cd3be4af882f4967d37ac36b9e90cbe94c259a4a Mon Sep 17 00:00:00 2001 From: John Anderson Date: Wed, 26 Sep 2018 14:27:17 +0200 Subject: [PATCH] extconf.rb now knows how to find /usr/lib/modsecurity which is the default location --- .gitignore | 1 + ext/msc_intervention/extconf.rb | 78 ++++++++++++++++++++++++++++++++- lib/rodsec/version.rb | 2 +- lib/rodsec/wrapper.rb | 4 +- rodsec.gemspec | 2 +- 5 files changed, 83 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5118842..ae42770 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ # local c extensions lib/rodsec/*.so +lib/rodsec/modsec_lib.rb diff --git a/ext/msc_intervention/extconf.rb b/ext/msc_intervention/extconf.rb index 2034aab..cf18294 100644 --- a/ext/msc_intervention/extconf.rb +++ b/ext/msc_intervention/extconf.rb @@ -1,5 +1,81 @@ require 'mkmf' -pkg_config 'modsecurity' + +MODSECURITY_LIB_NAME = 'modsecurity' +SO_FUNC = 'msc_init' + +def so_name + @so_name ||= "lib#{MODSECURITY_LIB_NAME}.#{CONFIG['DLEXT']}" +end + +def intervention_header_name + @intervention_header_name ||= 'modsecurity/intervention.h' +end + +# raise an exception if one of the paths doesn't exist +def confirm_include_lib include_dir, lib_dir + File.realpath(File.join include_dir, intervention_header_name) + File.realpath(File.join lib_dir, so_name) +end + +def create_modsec_lib_rb so_lib_path, dst_ruby_file: 'modsec_lib.rb' + puts "runtime loads #{so_lib_path}" + + # create a direct path to the library, because it's often in a nonstandard location + ruby_lib_dir = File.join CONFIG['srcdir'], '..', '..', 'lib', 'rodsec' + File.open File.join(ruby_lib_dir,dst_ruby_file), 'w' do |io| + io.write <<~EOS + # Generated by extconf.rb + module Rodsec + MODSECURITY_SO_PATH = '#{so_lib_path}' + end + EOS + end +end + +def find_header_and_library include_dir, lib_dir + ok = true + ok &&= find_header intervention_header_name, include_dir + ok &&= find_library MODSECURITY_LIB_NAME, SO_FUNC, lib_dir + ok or abort +end + +STANDARD_DIRS = [ + %w[/usr/local/include /usr/local/lib], + %w[/usr/include /usr/lib], +] + +# get the user config, or failing that the default ModSecurity installation paths +custom_dirs = dir_config 'modsecurity', '/usr/local/modsecurity' + +found_dirs = ([custom_dirs] + STANDARD_DIRS).find do |(include_dir, lib_dir)| + # try to find files from config + begin + confirm_include_lib include_dir, lib_dir + [include_dir, lib_dir] + rescue + puts "#{[include_dir, lib_dir]} not found. Continuing..." + end +end + +unless found_dirs + puts 'Cannot locate libmodsecurity.so' + abort +end + +so_lib_path = +if found_dirs == custom_dirs + # we have custom dirs, set a specific path for the dlload in Wrapper + File.join found_dirs.last, so_name +else + # standard dirs, so do not use a specific path in Wrapper + so_name +end + +# create the file so Wrapper knows where to load the .so +create_modsec_lib_rb so_lib_path + +# finally, use find_header and find_library to add the paths to the Makefile +find_header_and_library *found_dirs # don't need piles of debug info. Or maybe we do. Dunno. CONFIG['debugflags'] = '' diff --git a/lib/rodsec/version.rb b/lib/rodsec/version.rb index bf52b67..3b9dfef 100644 --- a/lib/rodsec/version.rb +++ b/lib/rodsec/version.rb @@ -1,3 +1,3 @@ module Rodsec - VERSION = '0.0.1' + VERSION = '0.0.2' end diff --git a/lib/rodsec/wrapper.rb b/lib/rodsec/wrapper.rb index 0f2da57..47343eb 100644 --- a/lib/rodsec/wrapper.rb +++ b/lib/rodsec/wrapper.rb @@ -1,13 +1,15 @@ require 'fiddle' require 'fiddle/import' +require_relative 'modsec_lib.rb' + module Rodsec module Wrapper extend Fiddle::Importer dlext = RbConfig::CONFIG['DLEXT'] msc_intervention = dlopen File.join __dir__, "msc_intervention.#{dlext}" - dlload msc_intervention, "libmodsecurity.#{dlext}" + dlload msc_intervention, MODSECURITY_SO_PATH ########################### # from modsecurity/modsecurity.h diff --git a/rodsec.gemspec b/rodsec.gemspec index f9db4f8..9dc379c 100644 --- a/rodsec.gemspec +++ b/rodsec.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |spec| end spec.files = `git ls-files -z`.split("\x0").reject do |f| - f.match(%r{^(test|spec(?!/config)|features)/}) + f.match(%r{^(test|spec(?!/config)|features|modsec_lib)/}) end spec.bindir = 'exe' spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }