File Coverage

blib/lib/NcFTPd/Log/Parse/Session.pm
Criterion Covered Total %
statement 16 20 80.0
branch 2 6 33.3
condition n/a
subroutine 4 5 80.0
pod n/a
total 22 31 70.9


line stmt bran cond sub pod time code
1             package NcFTPd::Log::Parse::Session;
2            
3 2     2   24856 use strict;
  2         3  
  2         67  
4 2     2   10 use warnings;
  2         2  
  2         53  
5 2     2   10 use base 'NcFTPd::Log::Parse::Base';
  2         3  
  2         1065  
6            
7             # From http://www.ncftp.com/ncftpd/doc/sesslog.html#CloseCodes
8             my %CLOSE_CODE_DESCRIPTIONS = (
9             0 => 'Normal disconnect.',
10             1 => 'End-of-file on control connection; the client closed the connection but did not issue a QUIT primitive.',
11             2 => 'Miscellaneous error.',
12             3 => 'Client exceeded idle timeout limit.',
13             4 => 'Client exceeded login timeout.',
14             5 => 'Timed-out while sending to client.',
15             6 => 'Lost connection (broken pipe).',
16             7 => 'Control connection reset by peer.',
17             8 => 'Network I/O error.',
18             9 => 'TCP Wrappers denied the user.',
19             10 => 'Too many users already logged on.',
20             11 => 'Too many users already logged on to domain.',
21             12 => 'Too many users already logged on by the same username.',
22             13 => 'Too many users already logged on by the same IP address.',
23             14 => 'Bad startup directory.',
24             15 => 'Passive data socket failed.',
25             16 => 'Passive data connection accept failed.',
26             17 => 'Passive data connection accept timed-out.',
27             18 => 'Passive data connection accept succeeded, but remote port was under 1024.',
28             19 => 'Passive data connection accept succeeded, but remote address was different from that of the control connection and proxy connections are disabled.',
29             20 => 'Port data connection attempt to client timed-out.',
30             21 => 'Port data connection attempt to client failed.',
31             22 => 'Port data connection specified a different remote address than that of the control connection and proxy connections are disabled.',
32             23 => 'Port data connection specified an internal network address.',
33             24 => 'Port data connection specified a remote port number under 1024.',
34             25 => 'Control connection\'s port number was under 1024.',
35             26 => 'Socket failed.',
36             27 => 'ncftpd_authd exchange state failed.',
37             28 => 'ncftpd_authd denied the user.',
38             29 => 'ncftpd_authd miscellaneous error.',
39             30 => 'Too many failed username/password attempts.',
40             31 => 'No logins are allowed during system maintenance.',
41             32 => 'Anonymous logins not allowed here.',
42             33 => 'Non-anonymous logins not allowed here.',
43             34 => 'Buffer overflow attempted by client.',
44             35 => 'Could not restore user privileges.',
45             36 => 'Domain is marked as disabled.',
46             37 => 'Timed out during data transfer.',
47             38 => 'Wrong protocol used by client.',
48             39 => 'Syntax error in passwd database user record.',
49             40 => 'Malformed User Permssions String in passwd database user record or from Authd.',
50             41 => 'Malformed Umask in passwd database user record or from Authd.'
51             );
52            
53             my $CLOSE_CODES = join '|', keys %CLOSE_CODE_DESCRIPTIONS;
54             my $DIGITS6 = '(\d*?),' x 6;
55             my $DIGITS16 = '(\d*?),' x 16;
56             my %COMMON_REGEX = __PACKAGE__->_common_regex;
57             my @FIELD_NAMES = qw{
58             user
59             email
60             host
61             session_time
62             time_between_commands
63             bytes_retrieved
64             bytes_stored
65             number_of_commands
66             retrieves
67             stores
68             chdirs
69             nlists
70             lists
71             types
72             port_pasv
73             pwd
74             size
75             mdtm
76             site
77             logins
78             failed_data_connections
79             last_transfer_result
80             successful_downloads
81             failed_downloads
82             successful_uploads
83             failed_uploads
84             successful_listings
85             failed_listings
86             close_code
87             session_id
88             };
89            
90             sub _expand_field
91             {
92 0     0   0 my ($self, $name, $value) = @_;
93            
94 0 0       0 if($name eq 'close_code') {
95 0         0 $value = $CLOSE_CODE_DESCRIPTIONS{$value};
96             }
97            
98             $value
99 0         0 }
100            
101             sub _parse_entry
102             {
103 3     3   6 my ($self, $fields) = @_;
104 3         3 my $entry;
105            
106 3 50       7 if($fields) {
107 3         245 my @values = $fields =~ m{
108             ((?:REFUSED|DENIED|.*?)), # Username, sometimes blank, why? Also REFUSED entries have no session id
109             (.*?), # "Email" (anonymous login password)
110             (.*?), # Host
111             (\d*?), # Session time
112             ((?:$COMMON_REGEX{decimal})?), # Time between commands
113             $DIGITS16 # 16 comma separated digits
114             ((?:NONE|$COMMON_REGEX{status})?), # Status of last transfer
115             $DIGITS6 # 6 comma separated digits
116             ($CLOSE_CODES) # Close code i.e. why the conection was closed
117             (?:,($COMMON_REGEX{session})?,)?
118             }x;
119            
120 3 50       15 if(@values) {
121 3         73 @$entry{@FIELD_NAMES} = @values;
122             }
123             }
124            
125 3         14 $entry;
126             }
127            
128             1;
129            
130             __END__