File Coverage

blib/lib/Armadito/Agent/Antivirus/Kaspersky/Win32.pm
Criterion Covered Total %
statement 21 108 19.4
branch 0 32 0.0
condition n/a
subroutine 7 19 36.8
pod 2 10 20.0
total 30 169 17.7


line stmt bran cond sub pod time code
1             package Armadito::Agent::Antivirus::Kaspersky::Win32;
2              
3 1     1   11284858 use strict;
  1         7  
  1         53  
4 1     1   7 use warnings;
  1         10  
  1         63  
5 1     1   4 use English qw(-no_match_vars);
  1         41  
  1         18  
6 1     1   1029 use Armadito::Agent::Tools::Dir qw( readDirectory );
  1         2  
  1         49  
7 1     1   340 use Armadito::Agent::Tools::Time qw( msFiletimeToUnixTimestamp );
  1         2  
  1         50  
8 1     1   701 use DBD::SQLite;
  1         18672  
  1         11  
9 1     1   487 use DBD::SQLite::Constants qw/:file_open/;
  1         541  
  1         1047  
10              
11             sub new {
12 0     0 1   my ( $class, %params ) = @_;
13              
14 0           my $self = { logger => $params{logger}, antivirus => $params{antivirus} };
15              
16 0           bless $self, $class;
17 0           return $self;
18             }
19              
20             sub getProgramPath {
21 0     0 1   my ($self) = @_;
22              
23 0           my $install_path = $self->getInstallPath();
24              
25 0 0         if ( $self->_isProgramInDir($install_path) ) {
26 0           return $self->{program_path};
27             }
28              
29 0           return "";
30             }
31              
32             sub getInstallPath {
33 0     0 0   my ($self) = @_;
34              
35 0           my @programfiles_paths = ( "C:\\Program Files (X86)", "C:\\Program Files" );
36 0           foreach my $path (@programfiles_paths) {
37 0 0         if ( -d $path . "\\Kaspersky Lab" ) {
38 0           return $path . "\\Kaspersky Lab";
39             }
40             }
41             }
42              
43             sub _isProgramInDir {
44 0     0     my ( $self, $path, $program ) = @_;
45              
46 0           my @entries = readDirectory(
47             dirpath => $path,
48             filter => "dirs-only"
49             );
50              
51 0           foreach my $entry (@entries) {
52 0 0         if ( $entry =~ m/^Kaspersky Anti-Virus.*/ ) {
53 0           $self->{logger}->info($entry);
54 0           $self->{program_path} = $path . "\\" . $entry;
55 0           return 1;
56             }
57             }
58              
59 0           return 0;
60             }
61              
62             sub getAlerts {
63 0     0 0   my ($self) = @_;
64              
65 0           my $dbfile = $self->getDataPath() . "detects.db";
66 0 0         if ( !-r $dbfile ) {
67 0           die "Unreadable detects.db file : $dbfile\n";
68             }
69              
70 0 0         my $dbh = DBI->connect(
71             "dbi:SQLite:$dbfile",
72             undef, undef,
73             {
74             sqlite_open_flags => SQLITE_OPEN_READONLY,
75             }
76             ) or die "DBI connection failed to dbi:SQLite:$dbfile ; $DBI::errstr";
77              
78 0           my $stmt = qq(SELECT Id, Threat, Time from detects;);
79 0           my $sth = $dbh->prepare($stmt);
80 0 0         my $rv = $sth->execute() or die $DBI::errstr;
81 0 0         if ( $rv < 0 ) {
82 0           print $DBI::errstr;
83             }
84              
85 0           my $alerts = [];
86              
87 0           while ( my @row = $sth->fetchrow_array() ) {
88 0           my $threat_id = $row[1];
89 0           my $filetime_ts = $row[2];
90              
91 0           my $threat = $self->getThreat( $threat_id, $dbh );
92             my $alert = {
93             name => $threat->{verdict}->{name},
94             filepath => $self->getFilePath( $threat_id, $dbh ),
95             detection_time => msFiletimeToUnixTimestamp( $filetime_ts, "UTC" ),
96             action => $threat->{scanaction},
97             impact_severity => $threat->{verdict}->{danger},
98             info => "status=" . $threat->{verdict}->{status}
99 0           };
100              
101 0 0         if ( $alert->{name} ne "" ) {
102 0           push( @$alerts, $alert );
103             }
104             }
105              
106 0           $dbh->disconnect();
107 0           return $alerts;
108             }
109              
110             sub getFilePath {
111 0     0 0   my ( $self, $threat_id, $dbh ) = @_;
112              
113 0           my $stmt = qq(SELECT Name FROM objects WHERE Id=?;);
114 0           my $sth = $dbh->prepare($stmt);
115 0 0         my $rv = $sth->execute($threat_id) or die $DBI::errstr;
116 0 0         if ( $rv < 0 ) {
117 0           print $DBI::errstr;
118             }
119              
120 0           my @row = $sth->fetchrow_array();
121 0           return $row[0];
122             }
123              
124             sub getThreat {
125 0     0 0   my ( $self, $threat_id, $dbh ) = @_;
126              
127 0           my $threat = $self->getThreatFromDB( $threat_id, $dbh );
128 0           $threat->{verdict} = $self->getVerdictFromDB( $threat->{verdictid}, $dbh );
129              
130 0           return $threat;
131             }
132              
133             sub getVerdictFromDB {
134 0     0 0   my ( $self, $verdict_id, $dbh ) = @_;
135              
136 0           my $verdict = {
137             name => "",
138             danger => "",
139             status => ""
140             };
141              
142 0           my $stmt = qq(SELECT Name, Danger, Status FROM verdicts WHERE Id=?;);
143 0           my $sth = $dbh->prepare($stmt);
144 0 0         my $rv = $sth->execute($verdict_id) or die $DBI::errstr;
145 0 0         if ( $rv < 0 ) {
146 0           print $DBI::errstr;
147             }
148              
149 0           my @row = $sth->fetchrow_array();
150 0           $verdict->{name} = $row[0];
151 0           $verdict->{danger} = $row[1];
152 0           $verdict->{status} = $row[2];
153              
154 0           return $verdict;
155             }
156              
157             sub getThreatFromDB {
158 0     0 0   my ( $self, $threat_id, $dbh ) = @_;
159              
160 0           my $threat = {
161             verdictid => "",
162             scanaction => "",
163             verdict => {}
164             };
165              
166 0           my $stmt = qq(SELECT Verdict, ScanAction FROM threats WHERE Id=?;);
167 0           my $sth = $dbh->prepare($stmt);
168 0 0         my $rv = $sth->execute($threat_id) or die $DBI::errstr;
169 0 0         if ( $rv < 0 ) {
170 0           print $DBI::errstr;
171             }
172              
173 0           my @row = $sth->fetchrow_array();
174 0           $threat->{verdictid} = $row[0];
175 0           $threat->{scanaction} = $self->_actionToString( $row[1] );
176              
177 0           return $threat;
178             }
179              
180             sub getProgramDataPath {
181 0     0 0   my ($self) = @_;
182              
183 0           return "C:\\ProgramData\\Kaspersky Lab\\AVP" . $self->{antivirus}->{version};
184             }
185              
186             sub getDataPath {
187 0     0 0   my ($self) = @_;
188              
189 0           return $self->getProgramDataPath() . "\\Data\\";
190             }
191              
192             sub _actionToString {
193 0     0     my ( $self, $action ) = @_;
194              
195 0           my $string = $action . "(unknown)";
196              
197 0 0         if ( $action == 1 ) {
    0          
198 0           $string = "quarantine";
199             }
200             elsif ( $action == 4 ) {
201 0           $string = "unrepaired";
202             }
203              
204 0           return $string;
205             }
206              
207             1;
208              
209             __END__
210              
211             =head1 NAME
212              
213             Armadito::Agent::Antivirus::Kaspersky::Win32 - Win32 Specific code for Kaspersky Antivirus
214              
215             =head1 DESCRIPTION
216              
217             This class regroup all Kaspersky's Windows stuff.
218              
219             =head1 FUNCTIONS
220              
221             =head2 new ( $self, %params )
222              
223             Instanciate module.
224              
225             =head2 getProgramPath ( $self )
226              
227             Return the path where Kaspersky AV is installed.
228