ddr-antivirus 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/README.md +15 -7
- data/lib/ddr/antivirus.rb +30 -20
- data/lib/ddr/antivirus/adapters.rb +6 -6
- data/lib/ddr/antivirus/adapters/clamd_scanner_adapter.rb +53 -0
- data/lib/ddr/antivirus/adapters/scanner_adapter.rb +4 -0
- data/lib/ddr/antivirus/version.rb +1 -1
- data/spec/fixtures/blue-devil.png +0 -0
- data/spec/shared_examples_for_scan_results.rb +15 -1
- data/spec/unit/clamav_scanner_adapter_spec.rb +3 -2
- data/spec/unit/clamd_scanner_adapter_spec.rb +39 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9424fb9fcce9fd87db0354060b80873112d923bb
|
4
|
+
data.tar.gz: 4e190d50edeba08eec311c2ed6e38189fec3eb29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f2dc02d2c56c5f5e4d0d2669517578b6905b6e300ca6b9afef71243c44540f89cdd630549e386ed15d9b7911a53d05d9030a2801c11503e2b5dd549de02fc84
|
7
|
+
data.tar.gz: b32e01dc33aba340e8ac87f7030c431518d24d387992fc42addbe1131c5355c8eef8e35e2ac38b67ef2b223686647bceb09fca26d0a47fbb5c38e5b382d69b76
|
data/.travis.yml
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install:
|
3
3
|
- sudo apt-get update -qq
|
4
|
-
- sudo apt-get install -y libclamav-dev clamav clamav-freshclam
|
4
|
+
- sudo apt-get install -y libclamav-dev clamav clamav-daemon clamav-freshclam
|
5
|
+
before_script:
|
5
6
|
- sudo freshclam
|
7
|
+
- sudo /etc/init.d/clamav-daemon start
|
6
8
|
rvm:
|
7
9
|
- 2.1
|
8
10
|
cache:
|
data/README.md
CHANGED
@@ -19,16 +19,20 @@ Or install it yourself as:
|
|
19
19
|
|
20
20
|
$ gem install ddr-antivirus
|
21
21
|
|
22
|
-
## ClamAV
|
22
|
+
## ClamAV
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
Ddr::Antivirus intentionally does *not* include `clamav` as a runtime dependency. Rather you should add to you application's Gemfile:
|
24
|
+
Ddr::Antivirus does *not* include the `clamav` gem as a runtime dependency. Add to your application's Gemfile:
|
27
25
|
|
28
26
|
gem 'clamav'
|
29
27
|
|
28
|
+
For system dependencies, see https://github.com/eagleas/clamav.
|
29
|
+
|
30
30
|
Ddr::Antivirus will automatically use an adapter class for ClamAV if the Ruby gem is installed.
|
31
31
|
|
32
|
+
## ClamAV Daemon Client (clamdscan)
|
33
|
+
|
34
|
+
Ddr::Antivirus will automatically use an adapter class for `clamdscan` if the executable is on the user's path.
|
35
|
+
|
32
36
|
## Usage
|
33
37
|
|
34
38
|
### Scanning ###
|
@@ -47,10 +51,14 @@ Ddr::Antivirus::Scanner.new do |scanner|
|
|
47
51
|
end
|
48
52
|
```
|
49
53
|
|
54
|
+
The scanner raises an exception (Ddr::Antivirus::VirusFoundError) if a virus is found.
|
55
|
+
|
50
56
|
### Results
|
51
57
|
|
52
58
|
Class: `Ddr::Antivirus::ScanResult`
|
53
59
|
|
60
|
+
A scanner adapter may subclass the base class to parse the raw result properly.
|
61
|
+
|
54
62
|
```ruby
|
55
63
|
>> require "ddr-antivirus"
|
56
64
|
=> true
|
@@ -74,14 +82,14 @@ Class: `Ddr::Antivirus::ScanResult`
|
|
74
82
|
>> result.raw
|
75
83
|
=> 0 # ClamAV example
|
76
84
|
|
77
|
-
# String representation
|
85
|
+
# String representation (example)
|
78
86
|
>> puts result.to_s
|
79
|
-
|
87
|
+
=> /path/to/blue-devil.png: OK (ClamAV 0.98.3/19559/Thu Oct 30 06:39:46 2014)
|
80
88
|
```
|
81
89
|
|
82
90
|
### The NullScannerAdapter
|
83
91
|
|
84
|
-
In order to avoid the overhead of ClamAV in test and/or development environments, the package provides a no-op adapter that logs a message and returns a
|
92
|
+
In order to avoid the overhead of ClamAV in test and/or development environments, the package provides a no-op adapter that logs a message and returns a scan result object (instance of Ddr::Antivirus::ScanResult).
|
85
93
|
|
86
94
|
```ruby
|
87
95
|
>> Ddr::Antivirus.scanner_adapter = :null
|
data/lib/ddr/antivirus.rb
CHANGED
@@ -1,42 +1,52 @@
|
|
1
1
|
require "ddr/antivirus/version"
|
2
|
+
require "ddr/antivirus/scanner"
|
3
|
+
require "ddr/antivirus/scan_result"
|
4
|
+
require "ddr/antivirus/adapters"
|
5
|
+
|
2
6
|
require "active_support/core_ext/module/attribute_accessors"
|
3
|
-
require "active_support/dependencies/autoload"
|
4
|
-
require "logger"
|
5
7
|
|
6
8
|
module Ddr
|
7
9
|
module Antivirus
|
8
|
-
extend ActiveSupport::Autoload
|
9
10
|
|
10
11
|
class VirusFoundError < ::StandardError; end
|
11
12
|
|
12
|
-
def self.clamav_installed?
|
13
|
-
begin
|
14
|
-
require 'clamav'
|
15
|
-
rescue LoadError
|
16
|
-
false
|
17
|
-
else
|
18
|
-
true
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
13
|
def self.configure
|
23
14
|
yield self
|
24
15
|
end
|
25
16
|
|
26
|
-
|
27
|
-
autoload :ScanResult
|
28
|
-
autoload :Adapters
|
29
|
-
|
17
|
+
#
|
30
18
|
# Custom logger
|
19
|
+
#
|
31
20
|
# Defaults to Rails logger if Rails is loaded; otherwise logs to STDERR.
|
21
|
+
#
|
32
22
|
mattr_accessor :logger do
|
33
|
-
defined?(Rails) && Rails.logger
|
23
|
+
if defined?(Rails) && Rails.logger
|
24
|
+
Rails.logger
|
25
|
+
else
|
26
|
+
require "logger"
|
27
|
+
Logger.new(STDERR)
|
28
|
+
end
|
34
29
|
end
|
35
30
|
|
31
|
+
#
|
36
32
|
# Scanner adapter
|
37
|
-
#
|
33
|
+
#
|
34
|
+
# Defaults to:
|
35
|
+
# - :clamav adapter if the 'clamav' gem is installed;
|
36
|
+
# - :clamd adapter if the 'clamdscan' executable is available;
|
37
|
+
# - otherwise, the :null adapter.
|
38
|
+
#
|
38
39
|
mattr_accessor :scanner_adapter do
|
39
|
-
|
40
|
+
begin
|
41
|
+
require "clamav"
|
42
|
+
:clamav
|
43
|
+
rescue LoadError
|
44
|
+
if system "which -s clamdscan"
|
45
|
+
:clamd
|
46
|
+
else
|
47
|
+
:null
|
48
|
+
end
|
49
|
+
end
|
40
50
|
end
|
41
51
|
|
42
52
|
end
|
@@ -1,15 +1,11 @@
|
|
1
|
-
|
1
|
+
require_relative "./adapters/scanner_adapter"
|
2
2
|
|
3
3
|
module Ddr
|
4
4
|
module Antivirus
|
5
5
|
module Adapters
|
6
|
-
extend ActiveSupport::Autoload
|
7
|
-
|
8
|
-
autoload :ScannerAdapter
|
9
|
-
autoload :NullScannerAdapter
|
10
|
-
autoload :ClamavScannerAdapter if Ddr::Antivirus.clamav_installed?
|
11
6
|
|
12
7
|
def self.get_adapter
|
8
|
+
require_relative adapter_module
|
13
9
|
klass = self.const_get(adapter_name.to_sym, false)
|
14
10
|
klass.new
|
15
11
|
end
|
@@ -18,6 +14,10 @@ module Ddr
|
|
18
14
|
"#{Ddr::Antivirus.scanner_adapter.to_s.capitalize}ScannerAdapter"
|
19
15
|
end
|
20
16
|
|
17
|
+
def self.adapter_module
|
18
|
+
"./adapters/#{Ddr::Antivirus.scanner_adapter}_scanner_adapter"
|
19
|
+
end
|
20
|
+
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Ddr
|
2
|
+
module Antivirus
|
3
|
+
module Adapters
|
4
|
+
#
|
5
|
+
# ClamdScannerAdapter uses an external ClamAV daemon (clamd)
|
6
|
+
#
|
7
|
+
# See https://github.com/soundarapandian/clamd for configuration method and options.
|
8
|
+
#
|
9
|
+
class ClamdScannerAdapter < ScannerAdapter
|
10
|
+
|
11
|
+
def scan(path)
|
12
|
+
raw = clamdscan(path)
|
13
|
+
ClamdScanResult.new(raw, path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def clamdscan(path)
|
17
|
+
`clamdscan --no-summary #{path}`.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
class ClamdScanResult < Ddr::Antivirus::ScanResult
|
21
|
+
|
22
|
+
def virus_found
|
23
|
+
if m = /: ([^\s]+) FOUND$/.match(raw)
|
24
|
+
m[1]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_virus?
|
29
|
+
raw =~ / FOUND$/
|
30
|
+
end
|
31
|
+
|
32
|
+
def error?
|
33
|
+
raw =~ / ERROR$/
|
34
|
+
end
|
35
|
+
|
36
|
+
def ok?
|
37
|
+
raw =~ / OK$/
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"#{raw} (#{version})"
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_version
|
45
|
+
`sigtool --version`.strip
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
Binary file
|
@@ -9,7 +9,7 @@ shared_examples "a scan result" do
|
|
9
9
|
expect(subject.scanned_at).to be_a(Time)
|
10
10
|
end
|
11
11
|
it "should have a string representation" do
|
12
|
-
expect(subject.to_s).
|
12
|
+
expect(subject.to_s).not_to be_nil
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -36,6 +36,13 @@ shared_examples "an error scan result" do
|
|
36
36
|
it "should have an error" do
|
37
37
|
expect(subject).to be_error
|
38
38
|
end
|
39
|
+
it "shoud not have a virus" do
|
40
|
+
expect(subject.virus_found).to be_nil
|
41
|
+
expect(subject).not_to have_virus
|
42
|
+
end
|
43
|
+
it "should not be ok" do
|
44
|
+
expect(subject).not_to be_ok
|
45
|
+
end
|
39
46
|
end
|
40
47
|
|
41
48
|
shared_examples "a virus scan result" do
|
@@ -43,6 +50,13 @@ shared_examples "a virus scan result" do
|
|
43
50
|
expect(subject.status).to match(/^FOUND/)
|
44
51
|
end
|
45
52
|
it "shoud have a virus" do
|
53
|
+
expect(subject.virus_found).not_to be_nil
|
46
54
|
expect(subject).to have_virus
|
47
55
|
end
|
56
|
+
it "should not have an error" do
|
57
|
+
expect(subject).not_to be_error
|
58
|
+
end
|
59
|
+
it "should not be ok" do
|
60
|
+
expect(subject).not_to be_ok
|
61
|
+
end
|
48
62
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
1
|
+
require "shared_examples_for_scan_results"
|
2
|
+
require "ddr/antivirus/adapters/clamav_scanner_adapter"
|
2
3
|
|
3
4
|
module Ddr
|
4
5
|
module Antivirus
|
5
6
|
module Adapters
|
6
7
|
RSpec.describe ClamavScannerAdapter do
|
7
8
|
|
8
|
-
let(:path) { File.expand_path(File.join("..", "fixtures", "blue-devil.png"), __FILE__) }
|
9
|
+
let(:path) { File.expand_path(File.join("..", "..", "fixtures", "blue-devil.png"), __FILE__) }
|
9
10
|
|
10
11
|
describe "#scan" do
|
11
12
|
context "when the db is already loaded" do
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "shared_examples_for_scan_results"
|
2
|
+
require "ddr/antivirus/adapters/clamd_scanner_adapter"
|
3
|
+
|
4
|
+
module Ddr
|
5
|
+
module Antivirus
|
6
|
+
module Adapters
|
7
|
+
RSpec.describe ClamdScannerAdapter do
|
8
|
+
|
9
|
+
let(:path) { File.expand_path(File.join("..", "..", "fixtures", "blue-devil.png"), __FILE__) }
|
10
|
+
|
11
|
+
describe "result" do
|
12
|
+
subject { adapter.scan(path) }
|
13
|
+
let(:adapter) { described_class.new }
|
14
|
+
it "should be a scan result" do
|
15
|
+
expect(subject).to be_a(Ddr::Antivirus::ScanResult)
|
16
|
+
end
|
17
|
+
context "when a virus is found" do
|
18
|
+
before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: Bad-boy-35 FOUND" } }
|
19
|
+
it "should have a virus_found" do
|
20
|
+
expect(subject.virus_found).to eq "Bad-boy-35"
|
21
|
+
end
|
22
|
+
it_should_behave_like "a virus scan result"
|
23
|
+
end
|
24
|
+
context "when there is an error" do
|
25
|
+
before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: ERROR" } }
|
26
|
+
it "should not have a virus" do
|
27
|
+
expect(subject).not_to have_virus
|
28
|
+
end
|
29
|
+
it_should_behave_like "an error scan result"
|
30
|
+
end
|
31
|
+
context "success" do
|
32
|
+
before { allow(adapter).to receive(:clamdscan).with(path) { "#{path}: OK" } }
|
33
|
+
it_should_behave_like "a successful scan result"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddr-antivirus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chandek-Stark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -99,14 +99,17 @@ files:
|
|
99
99
|
- lib/ddr/antivirus.rb
|
100
100
|
- lib/ddr/antivirus/adapters.rb
|
101
101
|
- lib/ddr/antivirus/adapters/clamav_scanner_adapter.rb
|
102
|
+
- lib/ddr/antivirus/adapters/clamd_scanner_adapter.rb
|
102
103
|
- lib/ddr/antivirus/adapters/null_scanner_adapter.rb
|
103
104
|
- lib/ddr/antivirus/adapters/scanner_adapter.rb
|
104
105
|
- lib/ddr/antivirus/scan_result.rb
|
105
106
|
- lib/ddr/antivirus/scanner.rb
|
106
107
|
- lib/ddr/antivirus/version.rb
|
108
|
+
- spec/fixtures/blue-devil.png
|
107
109
|
- spec/shared_examples_for_scan_results.rb
|
108
110
|
- spec/spec_helper.rb
|
109
111
|
- spec/unit/clamav_scanner_adapter_spec.rb
|
112
|
+
- spec/unit/clamd_scanner_adapter_spec.rb
|
110
113
|
- spec/unit/scan_result_spec.rb
|
111
114
|
- spec/unit/scanner_spec.rb
|
112
115
|
homepage: https://github.com/duke-libraries/ddr-antivirus
|
@@ -134,8 +137,10 @@ signing_key:
|
|
134
137
|
specification_version: 4
|
135
138
|
summary: Antivirus scanning service.
|
136
139
|
test_files:
|
140
|
+
- spec/fixtures/blue-devil.png
|
137
141
|
- spec/shared_examples_for_scan_results.rb
|
138
142
|
- spec/spec_helper.rb
|
139
143
|
- spec/unit/clamav_scanner_adapter_spec.rb
|
144
|
+
- spec/unit/clamd_scanner_adapter_spec.rb
|
140
145
|
- spec/unit/scan_result_spec.rb
|
141
146
|
- spec/unit/scanner_spec.rb
|