package Catalyst::Plugin::ClamAV; use strict; use warnings; use ClamAV::Client; our $VERSION = '0.03'; our $base = 'clamav'; sub clamscan { my ( $c, @names ) = @_; my $scanner = $c->_init_clam(); unless ($scanner) { return -1; } my $found = 0; my @virus; foreach my $name (@names) { my $upload = $c->req->upload( $name ); next unless $upload; my $fh = $upload->fh; if ($fh) { my $virus = $scanner->scan_stream( $fh ); seek( $fh, 0, 0 ); if ( $virus ) { $found++; push @virus, { name => $name, signature => $virus, }; $c->log->warn( __PACKAGE__ . " VIRUS found. signature='$virus'" ); } } } return wantarray ? @virus : $found; } sub _init_clam { my ($c) = shift; my %opt; foreach my $n(qw( socket_name socket_host socket_port )){ $opt{$n} = $c->config->{$base}->{$n} if defined $c->config->{$base}->{$n}; } my ( $scanner, $error ); eval { $scanner = ClamAV::Client->new( %opt ); if ( !$scanner or !$scanner->ping ) { $error = 1; } }; if ( $@ || $error ) { $c->log->error(qq{Cannot connect to ClamAV. $@}); return; } return $scanner; } 1; __END__ =head1 NAME Catalyst::Plugin::ClamAV - ClamAV scanning Plugin for Catalyst =head1 SYNOPSIS use Catalyst; MyApp->setup( qw/ ClamAV / ); # configuration for using unix domain socket MyApp->config->{clamav} = { socket_name => '/var/sock/clam', }; # configuration for using TCP/IP socket MyApp->config->{clamav} = { socket_host => '127.0.0.1', socket_port => '3310', }; # Virus scan upload files. my $found = $c->clamscan('field1', 'field2'); my @found_virus = $c->clamscan('field1', 'field2'); # e.g. @found_virus == ( { name => 'field1', signature => 'VIRUSNAME' } ); =head1 DESCRIPTION This plugin add virus scan method (using ClamAV) for Catalyst. Using ClamAV::Client module. =head1 CONFIGURATION MyApp->config->{clamav}->{socket_name}; # UNIX domain socket MyApp->config->{clamav}->{socket_host}; # TCP/IP host MyApp->config->{clamav}->{socket_port}; # TCP/IP port See ClamAV::Client POD. =head1 METHODS =over 4 =item clamscan Scan uploaded file handles, using ClamAV::Client->scan_stream(). Takes file upload field names as arguments. HTML:
Controller: $found = $c->clamscan('field1', 'field2'); The number of found viruses is returned. If clamd is stopping ( $scanner->ping failed ), -1 returned. To get found virus detail, @found_virus = $c->clamscan('field1', 'field2'); @found_virus is list of hash ref ( e.g. { name => 'fieldname', signature => 'virusname' } ). =back =head1 SEE ALSO L