ddr-antivirus 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|