File Coverage

blib/lib/Plack/Middleware/ClientCert.pm
Criterion Covered Total %
statement 29 29 100.0
branch 4 4 100.0
condition 1 2 50.0
subroutine 5 5 100.0
pod 1 2 50.0
total 40 42 95.2


line stmt bran cond sub pod time code
1             package Plack::Middleware::ClientCert;
2             # ABSTRACT: Parse digital client certificates for Perl's PSGI web servers.
3             $Plack::Middleware::ClientCert::VERSION = '0.01';
4 3     3   1824 use strict;
  3         9  
  3         102  
5 3     3   18 use warnings;
  3         4  
  3         120  
6              
7 3     3   1654 use parent qw(Plack::Middleware);
  3         1035  
  3         15  
8              
9             sub client_cert
10             {
11 3     3 0 4 my ($env) = @_;
12 3         5 my %cert = ();
13 3         4 my $prefix = 'client_';
14              
15 3         2 my $ssl_env = "SSL_CLIENT_S_DN";
16              
17 3   50     28 my $dn = $env->{ CERT_SUBJECT } || $env->{ $ssl_env } || '';
18              
19             #
20             # Apache on Linux does the parsing for us. The parts to the DN are
21             # all in SSL_CLIENT_S_DN_xx
22             #
23 3         5 my @keys = grep s/^${ssl_env}_(.*)/$1/, (keys %{ $env });
  3         57  
24 3 100       16 if (@keys) {
    100          
25 1         3 for my $key (@keys) {
26 4         9 $env->{ $prefix . lc( $key ) } = $env->{ "${ssl_env}_${key}" };
27             }
28             }
29             #
30             # The DN can be delimited by commas or slashes (/). Assume commas unless
31             # the very first character is a slash.
32             #
33             elsif ($dn =~ /^\//) {
34             # Iterate through the DN while there are still 'field=value' pairs
35 1         7 while ($dn =~ /=/) {
36             #
37             # Match the leading slash, then the field name, equals sign,
38             # and value. Finally, match the next slash seperator or the
39             # end of the line.
40             #
41 4         18 $dn =~ s/^\/(.*?)=(.*?)(\/|$)/$3/;
42 4         18 $env->{ $prefix . lc( $1 ) } = $2;
43             }
44             }
45             else {
46             # Iterate through the DN while there are still 'field=value' pairs
47 1         4 while ($dn =~ /=/) {
48             #
49             # The first match is the field. Then match 0 or 1 quotation mark(s).
50             # The third match is the value. Match the closed quote (or nothing).
51             # Finally, match the comma seperator and blank space, or the end
52             #
53 4         18 $dn =~ s/^(.*?)=(\"*)(.*?)\2(,\s*|$)//;
54 4         14 $env->{ $prefix . lc( $1 ) } = $3;
55             }
56             }
57              
58 3         5 return;
59              
60             } # End of client_cert()
61              
62             sub call {
63 3     3 1 1812 my($self, $env) = @_;
64              
65 3         9 client_cert( $env );
66              
67 3         19 return $self->app->($env);
68             }
69              
70             1;
71              
72             __END__