/
app.rb
124 lines (86 loc) · 3.5 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env ruby
require 'rubygems'
require 'bundler/setup'
require 'ruby-debug'
require 'sinatra'
require 'datyl/logger'
require 'datyl/config'
require 'uuid'
require 'fileutils'
include Datyl
# TODO have index form for individual use
# TODO investigate http://github.com/eagleas/clamav
def get_config
raise "No DAITSS_CONFIG environment variable has been set, so there's no configuration file to read" unless ENV['DAITSS_CONFIG']
raise "The DAITSS_CONFIG environment variable points to a non-existant file, (#{ENV['DAITSS_CONFIG']})" unless File.exists? ENV['DAITSS_CONFIG']
raise "The DAITSS_CONFIG environment variable points to a directory instead of a file (#{ENV['DAITSS_CONFIG']})" if File.directory? ENV['DAITSS_CONFIG']
raise "The DAITSS_CONFIG environment variable points to an unreadable file (#{ENV['DAITSS_CONFIG']})" unless File.readable? ENV['DAITSS_CONFIG']
Datyl::Config.new(ENV['DAITSS_CONFIG'], :defaults, ENV['VIRTUAL_HOSTNAME'])
end
configure do |s|
config = get_config
disable :logging # Stop CommonLogger from logging to STDERR; we'll set it up ourselves.
disable :dump_errors # Normally set to true in 'classic' style apps (of which this is one) regardless of :environment; it adds a backtrace to STDERR on all raised errors (even those we properly handle). Not so good.
set :environment, :production # Get some exceptional defaults.
set :raise_errors, false # Handle our own exceptions.
set :clamd, config.clamd
Datyl::Logger.setup('VirusCheck', ENV['VIRTUAL_HOSTNAME'])
if not (config.log_syslog_facility or config.log_filename)
Datyl::Logger.stderr # log to STDERR
end
Datyl::Logger.facility = config.log_syslog_facility if config.log_syslog_facility
Datyl::Logger.filename = config.log_filename if config.log_filename
Datyl::Logger.info "Starting up viruscheck service"
Datyl::Logger.info "Using temp directory #{ENV['TMPDIR']}"
use Rack::CommonLogger, Datyl::Logger.new(:info, 'Rack:')
end #of configure
helpers do
def clambin
# settings.clamd ? 'clamdscan' : 'clamscan'
settings.clamd ? 'clamdscan' : '/bin/true'
end
def clamscan data
# write to a tempfile
tf = params['data'][:tempfile]
# needed for clamav to read the file as a different user
FileUtils.chmod 0644, tf.path
# virus scan it
@output = `#{clambin} #{tf.path} 2>&1`
# check its status
@infected = case $?.exitstatus
when 0 then false
when 1 then true
else raise <<-MESSAGE
problem with #{clambin} (#{$?.exitstatus}):
#{@output}
MESSAGE
end
end
end # of helpers
error do
e = @env['sinatra.error']
request.body.rewind if request.body.respond_to?('rewind') # work around for verbose passenger warning
Datyl::Logger.err "Caught exception #{e.class}: '#{e.message}'; backtrace follows", @env
e.backtrace.each { |line| Datyl::Logger.err line, @env }
halt 500, { 'Content-Type' => 'text/plain' }, e.message + "\n"
end
not_found do
request.body.rewind if request.body.respond_to?(:rewind)
content_type 'text/plain'
"Not Found\n"
end
get '/' do
erb :index
end
post '/' do
# check the parameters
error 400, "Missing Data" unless params['data']
error 400, "Missing Data" if params['data'].empty?
clamscan params['data']
# make an event id
@event_id = UUID.generate :urn
erb :results
end
get '/status' do
[ 200, {'Content-Type' => 'application/xml'}, "<status/>\n" ]
end