From 7c7e01fa8d8623145078cc352c3617ad43ebe326 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 29 Jun 2017 10:52:01 +0200 Subject: Remove potential race when creating ACME challenge response files. --- Changelog | 2 ++ client | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Changelog b/Changelog index 1fd6762..5252fd2 100644 --- a/Changelog +++ b/Changelog @@ -28,6 +28,8 @@ lacme (0.3) upstream; vulnerability. - lacme(1), lacme-accountd(1): fix version number shown with --version. + - client: remove potential race when creating ACME challenge response + files. -- Guilhem Moulin Sun, 19 Feb 2017 13:08:41 +0100 diff --git a/client b/client index cd94ed8..333ae3b 100755 --- a/client +++ b/client @@ -44,10 +44,13 @@ use warnings; my $PROTOCOL_VERSION = 1; -use LWP::UserAgent (); +use Errno 'EEXIST'; +use Fcntl qw/O_CREAT O_EXCL O_WRONLY/; +use Digest::SHA qw/sha256 sha256_hex/; use MIME::Base64 qw/encode_base64 encode_base64url/; + +use LWP::UserAgent (); use JSON (); -use Digest::SHA qw/sha256 sha256_hex/; use Config::Tiny (); @@ -266,18 +269,19 @@ elsif ($COMMAND eq 'new-cert') { @{request_json_decode($r)->{challenges} // []}; die "Missing 'http-01' challenge in server response" unless defined $challenge; die "Invalid challenge token ".($challenge->{token} // '')."\n" + # ensure we don't write outside the cwd unless ($challenge->{token} // '') =~ /\A[A-Za-z0-9_\-]+\z/; my $keyAuthorization = $challenge->{token}.'.'.$JWK_thumbprint; # serve $keyAuthorization at http://$domain/.well-known/acme-challenge/$challenge->{token} - if (-e $challenge->{token}) { - print STDERR "WARNING: File exists: $challenge->{token}\n"; - } - else { - open my $fh, '>', $challenge->{token} or die "Can't open $challenge->{token}: $!"; + if (sysopen(my $fh, $challenge->{token}, O_CREAT|O_EXCL|O_WRONLY, 0644)) { $fh->print($keyAuthorization); $fh->close() or die "Can't close: $!"; + } elsif ($! == EEXIST) { + print STDERR "WARNING: File exists: $challenge->{token}\n"; + } else { + die "Can't open $challenge->{token}: $!"; } $r = acme($challenge->{uri}, { -- cgit v1.2.3