File Coverage

blib/lib/Auth/Kokolores.pm
Criterion Covered Total %
statement 21 99 21.2
branch 0 24 0.0
condition 0 9 0.0
subroutine 7 17 41.1
pod 6 9 66.6
total 34 158 21.5


line stmt bran cond sub pod time code
1             package Auth::Kokolores;
2            
3 1     1   775 use strict;
  1         1  
  1         30  
4 1     1   3 use base qw(Net::Server::PreFork);
  1         1  
  1         645  
5              
6             # ABSTRACT: an alternative saslauthd
7             our $VERSION = '1.00'; # VERSION
8              
9 1     1   52333 use Auth::Kokolores::Config;
  1         3  
  1         44  
10 1     1   493 use Auth::Kokolores::Request;
  1         4  
  1         41  
11 1     1   826 use Auth::Kokolores::Response;
  1         3  
  1         37  
12 1     1   412 use Auth::Kokolores::Plugins;
  1         4  
  1         59  
13              
14 1     1   996 use Getopt::Long;
  1         8924  
  1         5  
15              
16             sub print_usage {
17 0     0 0   print "$0 [-h|--help] [-c|--config=<file>] [-f|--foreground] [-l|--loglevel=<level>]\n";
18 0           return;
19             }
20            
21             sub configure {
22 0     0 1   my $self = shift;
23 0           my $server = $self->{'server'};
24              
25 0 0         return if(@_);
26              
27 0 0         if( ! defined $server->{'config_file'} ) {
28 0           $server->{'config_file'} = '/etc/kokolores/kokolores.conf';
29             }
30 0           $self->{'program_name'} = $0;
31              
32 0           $server->{'background'} = 1;
33 0           $server->{'setsid'} = 1;
34 0           $server->{'no_close_by_child'} = 1;
35              
36             # commandline options
37 0           my $cmdline = {};
38 0           GetOptions( $cmdline,
39             "help|h",
40             "config|c:s",
41             "foreground|f",
42             "loglevel|l:i",
43             );
44 0 0         if ($cmdline->{'help'}) {
45 0           $self->print_usage;
46 0           exit 0;
47             }
48 0 0 0       if (defined($cmdline->{'config'}) && $cmdline->{'config'} ne "") {
49 0           $server->{'config_file'} = $cmdline->{'config'};
50             }
51              
52             # read and apply configuration file
53 0           my $config = Auth::Kokolores::Config->new_from_file( $server->{'config_file'} );
54 0           $config->apply_config( $self );
55              
56 0           $server->{'port'} = $self->{'socket_path'}.'|unix';
57              
58 0           $self->{'plugins'} = Auth::Kokolores::Plugins->new_from_config( $self, $config->Plugin );
59              
60             # cmdline values which overwrite config/defaults
61 0 0         if ($cmdline->{'foreground'}) {
62 0           $server->{'background'} = undef;
63 0           $server->{'setsid'} = undef;
64 0           $server->{'log_file'} = undef;
65             }
66 0 0         if( $cmdline->{'loglevel'} ) {
67 0           $server->{'log_level'} = $cmdline->{'loglevel'};
68             }
69              
70 0           return;
71             }
72              
73             sub post_configure_hook {
74 0     0 1   my $self = shift;
75 0           $self->{'plugins'}->init();
76 0           return;
77             }
78              
79             sub post_bind_hook {
80 0     0 1   my $self = shift;
81 0           $self->set_socket_permissions;
82 0           return;
83             }
84              
85             sub set_socket_permissions {
86 0     0 0   my $self = shift;
87 0           my $mode = oct($self->{'socket_mode'});
88              
89 0           $self->log(1, sprintf('setting socket mode to: %o', $mode));
90 0 0         chmod( $mode, $self->{'socket_path'} )
91             or $self->log(1, 'could not change mode of socket: '.$!);
92            
93 0           return;
94             }
95              
96             sub child_init_hook {
97 0     0 1   my $self = shift;
98 0           $self->{'plugins'}->child_init();
99 0           $self->_set_process_stat('virgin child');
100 0           return;
101             }
102              
103             sub child_finish_hook {
104 0     0 1   my $self = shift;
105 0           $self->{'plugins'}->shutdown();
106 0           return;
107             }
108              
109             sub authenticate {
110 0     0 0   my ( $self, $r ) = @_;
111 0           my $matched = 0;
112              
113 0           foreach my $plugin ( $self->{'plugins'}->all_plugins ) {
114 0           my $ok;
115 0           eval { $ok = $plugin->authenticate( $r ); };
  0            
116 0 0         if( $@ ) {
117 0           $self->log(1, 'plugin '.$plugin->name.' failed: '.$@);
118 0           return Auth::Kokolores::Response->new_NO;
119             }
120 0 0         if( $ok ) {
121 0           $self->log(1, 'plugin '.$plugin->name.': success');
122             } else {
123 0           $self->log(1, 'plugin '.$plugin->name.': failed');
124             }
125 0 0 0       if( $ok && $self->{'satisfy'} eq 'any' ) {
    0          
126 0           return Auth::Kokolores::Response->new_OK;
127             } elsif( $ok ) {
128 0           $matched++;
129 0           next;
130             }
131 0           return Auth::Kokolores::Response->new_NO;
132             }
133              
134 0 0 0       if( $matched && $matched == $self->{'plugins'}->num_plugins ) {
135 0           return Auth::Kokolores::Response->new_OK;
136             }
137 0           return Auth::Kokolores::Response->new_NO;
138             }
139            
140             sub process_request {
141 0     0 1   my ( $self, $conn ) = @_;
142 0           $self->log(1, "handling new client...");
143              
144 0           $self->_set_process_stat('waiting request');
145 0           my $r = Auth::Kokolores::Request->new_from_conn( $conn, $self );
146              
147 0           $self->_set_process_stat('processing request');
148              
149 0           my $result = $self->authenticate( $r );
150 0           $conn->print( $result );
151              
152 0           $self->_set_process_stat('idle');
153 0           return;
154             }
155              
156             sub _set_process_stat {
157 0     0     my ( $self, $stat ) = @_;
158 0           $0 = $self->{'program_name'}.' ('.$stat.')';
159             }
160              
161             1;
162              
163             __END__
164              
165             =pod
166              
167             =encoding UTF-8
168              
169             =head1 NAME
170              
171             Auth::Kokolores - an alternative saslauthd
172              
173             =head1 VERSION
174              
175             version 1.00
176              
177             =head1 AUTHOR
178              
179             Markus Benning <ich@markusbenning.de>
180              
181             =head1 COPYRIGHT AND LICENSE
182              
183             This software is Copyright (c) 2016 by Markus Benning <ich@markusbenning.de>.
184              
185             This is free software, licensed under:
186              
187             The GNU General Public License, Version 2, June 1991
188              
189             =cut