File Coverage

blib/lib/Protocol/ACME/Challenge/LocalFile.pm
Criterion Covered Total %
statement 15 55 27.2
branch 0 12 0.0
condition n/a
subroutine 5 9 55.5
pod 3 3 100.0
total 23 79 29.1


line stmt bran cond sub pod time code
1             package Protocol::ACME::Challenge::LocalFile;
2              
3             =head1 NAME
4              
5             Protocol::ACME::Challenge::LocalFile - Challenge handler for simpleHttp via a local file
6              
7             =head1 SYNOPSIS
8              
9             use Protocol::ACME::Challenge::LocalFile;
10              
11             my $args = { 'www_root' => "/path/to/htdocs/or/equivalent" };
12             my $challenge = Protocol::ACME::Challenge::LocalFile->new( $args );
13              
14             ...
15              
16             $acme->handle_challenge( $challenges->{$domain} );
17              
18             =head1 DESCRIPTION
19              
20             The C class is a handler intended
21             to be run when the ACME script is run on the same local machine as the
22             web server. This is a logical choice to use for self contained web
23             server / Let's Encypt integration.
24              
25             =head1 CONSTRUCTOR METHODS
26              
27             The following constructor methods are available:
28              
29             =over 4
30              
31             =item $acme = Protcol::ACME::Challenge::LocalFile->new( %options )
32              
33             This method constructs a new C object
34             and returns it. Key/value pair arguments may be provided to set up the
35             initial state. The may be passed in as a hash or a hashref. The following
36             options correspond to attribute methods described below. Items markes with
37             a * are required.
38              
39             KEY DEFAULT
40             ----------- --------------------
41             *www_root path to web root that will handle the HTTP
42             challenge
43              
44             =back
45              
46             =head2 METHODS
47              
48             =over
49              
50             =item handle( $challenge, $fingerprint )
51              
52             This is intended to be called indirectly via the ACME driver class.
53             C will take care of all of the conditions necessary to satisfy
54             the challenge sent by Let's Encrypt.
55              
56             =item cleanup
57              
58             C will remove the challenge file.
59              
60             =back
61              
62             =cut
63              
64 1     1   926 use strict;
  1         3  
  1         27  
65 1     1   4 use warnings;
  1         2  
  1         27  
66              
67 1     1   5 use parent qw ( Protocol::ACME::Challenge );
  1         2  
  1         5  
68 1     1   72 use Carp;
  1         2  
  1         91  
69 1     1   475 use IO::File;
  1         1882  
  1         546  
70              
71             our $VERSION = '1.02';
72              
73             sub new
74             {
75 0     0 1   my $class = shift;
76 0           my $self = {};
77 0           bless $self, $class;
78 0           $self->_init( @_ );
79 0           return $self;
80             }
81              
82             sub _init
83             {
84 0     0     my $self = shift;
85 0           my $args;
86              
87 0 0         if ( @_ == 1 )
88             {
89 0           $args = shift;
90 0 0         if ( ref $args ne "HASH" )
91             {
92 0           croak "Must pass a hash or hashref to challenge constructor";
93             }
94             }
95             else
96             {
97 0           $args = \%_;
98             }
99              
100 0           for my $required_arg ( qw ( www_root ) )
101             {
102 0 0         if ( ! exists $args->{$required_arg} )
103             {
104 0           croak "Require arg $required_arg missing from chalenge constructor";
105             }
106             else
107             {
108 0           $self->{$required_arg} = $args->{$required_arg};
109             }
110             }
111              
112 0           $self->{filename} = undef;
113              
114             }
115              
116              
117             sub handle
118             {
119 0     0 1   my $self = shift;
120 0           my $challenge = shift;
121 0           my $fingerprint = shift;
122              
123             # TODO: put the 'well known path' in a global variable somewhere
124 0 0         if (not -d $self->{www_root}){
125 0           carp "$self->{www_root} does not exist\n";
126             }
127             # if we are root this will make us into the correct user for the site
128 0           my ($uid,$gid) = (stat $self->{www_root})[4,5];
129 0           local $) = $gid;local $> = $uid;
  0            
130 0           umask 022;
131 0           my $dir = "$self->{www_root}/.well-known/acme-challenge";
132 0           system "mkdir","-p",$dir;
133 0           my $filename = "$dir/$challenge";
134 0           my $content = "$challenge.$fingerprint";
135              
136 0           my $fh = IO::File->new( $filename, "w" );
137 0 0         if ( ! $fh )
138             {
139 0           carp "Could not open $filename for write";
140 0           return 1;
141             }
142              
143 0           print $fh $content;
144 0           $fh->close();
145              
146 0           $self->{filename} = $filename;
147              
148 0           return 0;
149             }
150              
151             sub cleanup
152             {
153 0     0 1   my $self = shift;
154 0 0         unlink $self->{filename} if defined $self->{filename};
155             }
156              
157             =head1 AUTHOR
158              
159             Stephen Ludin, C<< >>
160              
161             =head1 BUGS
162              
163             Please report any bugs or feature requests to C, or through
164             the web interface at L. I will be notified, and then you'll
165             automatically be notified of progress on your bug as I make changes.
166              
167              
168              
169              
170             =head1 ACKNOWLEDGEMENTS
171              
172              
173             =head1 LICENSE AND COPYRIGHT
174              
175             Copyright 2015 Stephen Ludin.
176              
177             This program is free software; you can redistribute it and/or modify it
178             under the terms of the the Artistic License (2.0). You may obtain a
179             copy of the full license at:
180              
181             L
182              
183             Any use, modification, and distribution of the Standard or Modified
184             Versions is governed by this Artistic License. By using, modifying or
185             distributing the Package, you accept this license. Do not use, modify,
186             or distribute the Package, if you do not accept this license.
187              
188             If your Modified Version has been derived from a Modified Version made
189             by someone other than you, you are nevertheless required to ensure that
190             your Modified Version complies with the requirements of this license.
191              
192             This license does not grant you the right to use any trademark, service
193             mark, tradename, or logo of the Copyright Holder.
194              
195             This license includes the non-exclusive, worldwide, free-of-charge
196             patent license to make, have made, use, offer to sell, sell, import and
197             otherwise transfer the Package with respect to any patent claims
198             licensable by the Copyright Holder that are necessarily infringed by the
199             Package. If you institute patent litigation (including a cross-claim or
200             counterclaim) against any party alleging that the Package constitutes
201             direct or contributory patent infringement, then this Artistic License
202             to you shall terminate on the date that such litigation is filed.
203              
204             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
205             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
206             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
207             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
208             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
209             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
210             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
211             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
212              
213              
214             =cut
215              
216             1;