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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e09e6bc593db830915157ce7ed38e9c05702ec8
4
- data.tar.gz: 66f916b33a1e8e336d5b3172a145007eeba312dd
3
+ metadata.gz: 9424fb9fcce9fd87db0354060b80873112d923bb
4
+ data.tar.gz: 4e190d50edeba08eec311c2ed6e38189fec3eb29
5
5
  SHA512:
6
- metadata.gz: dc8b5c988bb1e6f1b3b50e9439611a965b2291526586ea18670265f6ac4282a6556966b7ac4c1667f107007c8fee198a0fef745fe2fd5328f79413e2d71987d6
7
- data.tar.gz: 91c7a1a590026094a67255a253939ec779a46689637adf813a28e0c728139b58fc1cfe85f881c73e4e8eb98cf3c05fb4c4e035b5f01f66b7313f5fca749003f7
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 Dependencies
22
+ ## ClamAV
23
23
 
24
- For system dependencies, see https://github.com/eagleas/clamav.
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
- Virus scan: OK - /path/to/blue-devil.png (ClamAV 0.98.3/19559/Thu Oct 30 06:39:46 2014)
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 normal scan result (instance of Ddr::Antivirus::ScanResult).
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
- autoload :Scanner
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 ? Rails.logger : Logger.new(STDERR)
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
- # Defaults to :clamav adapter if ClamAV is installed; otherwise uses the :null adapter
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
- clamav_installed? ? :clamav : :null
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
- require "active_support/dependencies/autoload"
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
@@ -10,6 +10,10 @@ module Ddr
10
10
  raise NotImplementedError
11
11
  end
12
12
 
13
+ def config
14
+ Ddr::Antivirus.adapter_config
15
+ end
16
+
13
17
  end
14
18
  end
15
19
  end
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Antivirus
3
- VERSION = "1.0.2"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  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).to match(/^Virus scan:/)
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 'shared_examples_for_scan_results'
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.2
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-10-31 00:00:00.000000000 Z
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