Changeset 206


Ignore:
Timestamp:
06/22/09 11:38:07 (8 years ago)
Author:
sander
Message:

Scan uploaded results for viruses

Location:
trunk/server/www/app
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/www/app/controllers/jobs_controller.php

    r204 r206  
    413413         * 
    414414         * @param string $method The XMLRPC method name 
    415          * @param mixed $params The XMLRPC parameters 
     415         * @param mixed &$params The XMLRPC parameters 
    416416         * @param mixed $userdata Data passed from the XMLRPC server 
    417417         * @return array The XMLRPC result or a fault array 
     
    452452                } 
    453453 
    454                 // Decode the document 
    455454                // TODO: The file extension stuff is an ugly kludge. It should do this through the Mimetype model 
    456455                $basename = basename($job['Request']['filename']); 
  • trunk/server/www/app/controllers/results_controller.php

    r102 r206  
    8383        public function view($id = null) 
    8484        { 
     85                $this->helpers[] = 'ResultModel'; 
     86 
    8587                $this->Result->contain(array( 
    8688                        'Job', 
  • trunk/server/www/app/models/result.php

    r88 r206  
    2424class Result extends AppModel 
    2525{ 
     26        /**#@+ 
     27         * Request states 
     28         */ 
     29        const STATE_UPLOADING   = 1; 
     30        const STATE_SCAN_QUEUED = 2; 
     31        const STATE_SCAN_FOUND  = 4; 
     32        const STATE_SCAN_FAILED = 8; 
     33        const STATE_FINISHED    = 16; 
     34        /**#@-*/ 
     35         
    2636        /** @var array A result belongs to a job and a factory that created it */ 
    2737        public $belongsTo = array('Factory', 'Format'); 
     
    3545 
    3646        /** @var array The result is a file */ 
    37         public $actsAs = array('File' => 'files/results', 'Containable'); 
     47        public $actsAs = array('File' => 'files/results', 'Containable', 'BeanStalk.Deferrable'); 
    3848 
    3949        /** @var string Use the filename as the distinguising name */ 
     
    5060                return true; 
    5161        } 
     62 
     63        /** 
     64         * After creating a new result, schedule it for scanning 
     65         */ 
     66        public function afterSave($created) 
     67        { 
     68                if ($created === false || empty($this->data['Result']['path'])) { 
     69                        return; 
     70                } 
     71 
     72                if (!$this->defer('scan')) { 
     73                        $this->log('Failed to queue the result for the virus scanner.', true); 
     74                } 
     75 
     76                $this->saveField('state', self::STATE_SCAN_QUEUED); 
     77        } 
     78 
     79        /** 
     80         * Scan the request for viruses and update the scan status 
     81         * 
     82         * @return None 
     83         */ 
     84        public function scan() 
     85        { 
     86                $this->read(); 
     87 
     88                // Check for the correct state. In case of queue errors a scan could be scheduled multiple times 
     89                if ($this->data['Result']['state'] != self::STATE_SCAN_QUEUED) { 
     90                        $this->log('Result ID ' . $this->id . ' is not queued for scan.'); 
     91                        return; 
     92                } 
     93 
     94                $clamd = new Clamd(); 
     95                $path = $this->getPath(); 
     96                $result = ''; 
     97 
     98                if (!$path) { 
     99                        $this->log('Result could not be scanned. ' . $path . ' (Result ID: ' . $this->id . ') does not exists. '); 
     100                        return; 
     101                } 
     102 
     103                $status = $clamd->scan($path, $result); 
     104                if ($status == Clamd::OK) { 
     105                        // Scan OK. Queue the Request for processing 
     106                        $this->data['Result']['state'] = self::STATE_FINISHED; 
     107                        $this->log('Clamd scanned ' . $path . ' (Result ID: ' . $this->id . '): OK', LOG_DEBUG); 
     108                } elseif ( $status == Clamd::FOUND ) { 
     109                        // Note that the file is *not* deleted. This was we can later check if there really was a virus 
     110                        $this->data['Result']['state'] = self::STATE_SCAN_FOUND; 
     111                        $this->data['Result']['state_info'] = $result; 
     112                        $this->log('Clamd scanned ' . $path . ' (Result ID: ' . $this->id . '): FOUND ' . $result, LOG_DEBUG); 
     113                } else { 
     114                        // There was an error. 
     115                        if ($status === false) { 
     116                                $result = $clamd->lastError(); 
     117                                $status = Clamd::ERROR; 
     118                        } 
     119 
     120                        $this->data['Result']['state'] = self::STATE_SCAN_FAILED; 
     121                        $this->data['Result']['state_info'] = $result; 
     122 
     123                        $this->log('Clamd error scanning ' . $path . ' (Result ID: ' . $this->id . '): ' . $result); 
     124                } 
     125 
     126                $this->save(); 
     127        } 
    52128} 
    53129 
  • trunk/server/www/app/views/helpers/job_model.php

    r205 r206  
    6363 
    6464                if (!empty($job['Job']['Result'])) { 
    65                         return $this->output($this->Html->image('icons/' . $job['Job']['Result']['Mimetype']['icon'], array( 
     65                        if ($job['Job']['Result']['state'] == Result::STATE_SCAN_FOUND) { 
     66                                $icon = 'virus.png'; 
     67                        } else { 
     68                                $icon = $job['Job']['Result']['Mimetype']['icon']; 
     69                        } 
     70 
     71                        return $this->output($this->Html->image('icons/' . $icon, array( 
    6672                                'alt' => $job['Job']['Result']['Format']['name'], 
    6773                                'url' => array('controller'=> 'results', 'action'=>'view', $job['Job']['Result']['id']) 
  • trunk/server/www/app/views/results/view.ctp

    r128 r206  
    99                ) 
    1010));?></span><br /><br /> 
    11         <img src="/img/icons/<?php echo $result['Mimetype']['icon'];?>" alt="" style="float: left;" /> 
     11        <?php if ($result['Result']['state'] == Result::STATE_SCAN_FOUND): ?> 
     12                <img src="/img/icons/virus.png" alt="" style="float: left;" /> 
     13        <?php else: ?> 
     14                <img src="/img/icons/<?php echo $result['Mimetype']['icon'];?>" alt="" style="float: left;" /> 
     15        <?php endif; ?> 
    1216        <dl style="margin-left: 10em;"><?php $i = 0; $class = ' class="altrow"';?> 
    1317                <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Filename'); ?></dt> 
     
    1923                <dd<?php if ($i++ % 2 == 0) echo $class;?>> 
    2024                        <?php echo $result['Format']['name']; ?> 
     25                        &nbsp; 
     26                </dd> 
     27                <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Status'); ?></dt> 
     28                <dd<?php if ($i++ % 2 == 0) echo $class;?>> 
     29                        <?php echo $resultModel->getState($result); ?> 
    2130                        &nbsp; 
    2231                </dd> 
     
    3342                <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Actions'); ?></dt> 
    3443                <dd<?php if ($i++ % 2 == 0) echo $class;?>> 
    35                         <?php echo $html->link(__('Download', true), array('action' => 'download', $result['Result']['id'])); ?> 
     44                        <?php 
     45                                if ($result['Result']['state'] == Result::STATE_SCAN_FOUND) { 
     46                                        echo $html->link( 
     47                                                __('Download', true), 
     48                                                array('action' => 'download', $result['Result']['id']), 
     49                                                array(), 
     50                                                sprintf(__('This document contains the "%s" virus. Are you sure?', true), $result['Result']['state_info']) 
     51                                        ); 
     52                                } else { 
     53                                        echo $html->link(__('Download', true), array('action' => 'download', $result['Result']['id'])); 
     54                                } 
     55                        ?> 
    3656                        <?php if ($canDelete == true) { 
    3757                                echo ' - ' . $html->link(__('Delete', true), array('action' => 'delete', $result['Result']['id'])); 
Note: See TracChangeset for help on using the changeset viewer.