lib/ddr/antivirus/adapters/clamd_scanner_adapter.rb in ddr-antivirus-2.0.0 vs lib/ddr/antivirus/adapters/clamd_scanner_adapter.rb in ddr-antivirus-2.1.1
- old
+ new
@@ -1,84 +1,76 @@
-require "open3"
require "fileutils"
require "shellwords"
module Ddr::Antivirus
#
# Adapter for clamd client (clamdscan)
#
class ClamdScannerAdapter < ScannerAdapter
SCANNER = "clamdscan".freeze
+ CONFIG = "clamconf".freeze
+ MAX_FILE_SIZE_RE = Regexp.new('^MaxFileSize = "(\d+)"')
+
def scan(path)
- output, status = clamdscan(path)
+ output, exitcode = clamdscan(path)
result = ScanResult.new(path, output, version: version, scanned_at: Time.now.utc)
- case status.exitstatus
+ case exitcode
when 0
result
when 1
raise VirusFoundError.new(result)
when 2
raise ScannerError.new(result)
end
end
def clamdscan(path)
- make_readable(path) do
- command(path)
+ output = make_readable(path) do
+ command "--fdpass", safe_path(path)
end
+ [ output, $?.exitstatus ]
end
def version
- out, err, status = Open3.capture3(SCANNER, "-V")
- out.strip
+ @version ||= command("-V").strip
end
+ def config
+ @config ||= `#{CONFIG}`
+ end
+
+ def max_file_size
+ if m = MAX_FILE_SIZE_RE.match(config)
+ m[1]
+ end
+ end
+
private
- def command(path)
- safe_path = Shellwords.shellescape(path)
- Open3.capture2e(SCANNER, safe_path)
+ def command(*args)
+ cmd = args.dup.unshift(SCANNER).join(" ")
+ `#{cmd}`
end
def make_readable(path)
changed = false
original = File.stat(path).mode # raises Errno::ENOENT
if !File.world_readable?(path)
changed = FileUtils.chmod("a+r", path)
- logger.info "File #{path} made world-readable for virus scanning."
+ logger.debug "#{self.class} - File \"#{path}\" made world-readable."
end
result = yield
if changed
FileUtils.chmod(original, path)
- logger.info "Mode reset to original #{original} on file #{path}."
+ logger.debug "#{self.class} - Mode on file \"#{path}\" reset to original: #{original}."
end
result
end
- end
-
- # Result of a scan with the ClamdScannerAdapter
- # @api private
- class ClamdScanResult < ScanResult
-
- def virus_found
- if m = /: ([^\s]+) FOUND$/.match(output)
- m[1]
- end
- end
-
- def ok?
- status.exitstatus == 0
- end
-
- def has_virus?
- status.exitstatus == 1
- end
-
- def error?
- status.exitstatus == 2
+ def safe_path(path)
+ Shellwords.shellescape(path)
end
end
end