aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog1
-rwxr-xr-xclient8
-rwxr-xr-xlacme116
-rwxr-xr-xlacme-accountd16
4 files changed, 71 insertions, 70 deletions
diff --git a/Changelog b/Changelog
index ac8102c..cda155f 100644
--- a/Changelog
+++ b/Changelog
@@ -27,6 +27,7 @@ lacme (0.7.1) upstream;
+ Add support for TLS Feature extension from RFC 7633; this is mostly
useful for OCSP Must-Staple.
+ client: use "lacme-client/$VERSION" as User-Agent header.
+ + Consolidate error messages for consistency.
- lacme: delay webserver socket shutdown to after the process has
terminated.
- documentation: suggest to generate private key material with
diff --git a/client b/client
index e29d2a0..a5490f8 100755
--- a/client
+++ b/client
@@ -97,7 +97,7 @@ my $NONCE;
my $CONFIG = do {
my $conf = do { local $/ = undef; <$CONFFILE> };
- close $CONFFILE or die "Can't close: $!";
+ close $CONFFILE or die "close: $!";
my $h = Config::Tiny::->read_string($conf) or die Config::Tiny::->errstr()."\n";
$h->{_} //= {};
$h->{client}->{$_} //= $h->{_}->{$_} foreach keys %{$h->{_}}; # add defaults
@@ -303,11 +303,11 @@ elsif ($COMMAND eq 'newOrder') {
# serve $keyAuthorization at http://$domain/.well-known/acme-challenge/$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: $!";
+ $fh->close() or die "close: $!";
} elsif ($! == EEXIST) {
print STDERR "WARNING: File exists: $challenge->{token}\n";
} else {
- die "Can't open $challenge->{token}: $!";
+ die "open($challenge->{token}): $!";
}
my $r = acme($challenge->{url}, {});
request_json_decode($r);
@@ -378,7 +378,7 @@ elsif ($COMMAND eq 'newOrder') {
elsif ($COMMAND eq 'revokeCert') {
die if @ARGV;
my $der = do { local $/ = undef; <STDIN> };
- close STDIN or die "Can't close: $!";
+ close STDIN or die "close: $!";
# send a KID if the request is signed with the acccount key, otherwise send a JWK
set_kid(0);
diff --git a/lacme b/lacme
index 33f947c..f0beac1 100755
--- a/lacme
+++ b/lacme
@@ -159,7 +159,7 @@ sub gen_csr(%) {
$config->print("keyUsage = critical, $args{keyUsage}\n") if defined $args{keyUsage};
$config->print("subjectAltName = $args{subjectAltName}\n") if defined $args{subjectAltName};
$config->print("tlsfeature = $args{tlsfeature}\n") if defined $args{tlsfeature};
- $config->close() or die "Can't close: $!";
+ $config->close() or die "close: $!";
my @args = (qw/-new -batch -key/, $args{'certificate-key'});
push @args, "-$args{hash}" if defined $args{hash};
@@ -167,20 +167,20 @@ sub gen_csr(%) {
open my $fh, '-|', qw/openssl req -outform DER/, @args or die "fork: $!";
my $csr = do { local $/ = undef; <$fh> };
- close $fh or $! ? die "Can't close: $!" : return;
+ close $fh or $! ? die "close: $!" : return;
if ($OPTS{debug}) {
# print out the CSR in text form
pipe my $rd, my $wd or die "pipe: $!";
my $pid = fork // die "fork: $!";
unless ($pid) {
- open STDIN, '<&', $rd or die "Can't dup: $!";
- open STDOUT, '>&', \*STDERR or die "Can't dup: $!";
+ open STDIN, '<&', $rd or die "dup: $!";
+ open STDOUT, '>&', \*STDERR or die "dup: $!";
exec qw/openssl req -noout -text -inform DER/ or die;
}
- $rd->close() or die "Can't close: $!";
+ $rd->close() or die "close: $!";
$wd->print($csr);
- $wd->close() or die "Can't close: $!";
+ $wd->close() or die "close: $!";
waitpid $pid => 0;
die $? if $? > 0;
@@ -220,21 +220,21 @@ sub drop_privileges($$$) {
# set effective and real gid; also set the list of supplementary gids to that single gid
if ($group ne '') {
- my $gid = getgrnam($group) // die "Can't getgrnam($group): $!";
+ my $gid = getgrnam($group) // die "getgrnam($group): $!";
$) = "$gid $gid";
- die "Can't setgroups: $!" if $@;
- POSIX::setgid($gid) or die "Can't setgid: $!";
+ die "setgroups: $!" if $@;
+ POSIX::setgid($gid) or die "setgid: $!";
die "Couldn't setgid/setguid" unless $( eq "$gid $gid" and $) eq "$gid $gid"; # safety check
}
# set effective and real uid
if ($user ne '') {
- my $uid = getpwnam($user) // die "Can't getpwnam($user): $!";
- POSIX::setuid($uid) or die "Can't setuid: $!";
+ my $uid = getpwnam($user) // die "getpwnam($user): $!";
+ POSIX::setuid($uid) or die "setuid: $!";
die "Couldn't setuid/seteuid" unless $< == $uid and $> == $uid; # safety check
}
- chdir $dir or die "Can't chdir to $dir: $!";
+ chdir $dir or die "chdir($dir): $!";
}
@@ -243,10 +243,10 @@ sub drop_privileges($$$) {
#
sub set_FD_CLOEXEC($$) {
my ($fd, $set) = @_;
- my $flags = fcntl($fd, F_GETFD, 0) or die "Can't fcntl F_GETFD: $!";
+ my $flags = fcntl($fd, F_GETFD, 0) or die "fcntl F_GETFD: $!";
my $flags2 = $set ? ($flags | FD_CLOEXEC) : ($flags & ~FD_CLOEXEC);
return if $flags == $flags2;
- fcntl($fd, F_SETFD, $flags2) or die "Can't fcntl F_SETFD: $!";
+ fcntl($fd, F_SETFD, $flags2) or die "fcntl F_SETFD: $!";
}
@@ -321,10 +321,10 @@ sub spawn_webserver() {
# create a temporary directory; give write access to the ACME client
# and read access to the webserver
my $tmpdir = File::Temp::->newdir(CLEANUP => 1, TMPDIR => 1) // die;
- chmod 0755, $tmpdir or die "Can't chmod: $!";
+ chmod 0755, $tmpdir or die "chmod: $!";
if ((my $username = $CONFIG->{client}->{user}) ne '') {
- my $uid = getpwnam($username) // die "Can't getpwnam($username): $!";
- chown($uid, -1, $tmpdir) or die "Can't chown: $!";
+ my $uid = getpwnam($username) // die "getpwnam($username): $!";
+ chown($uid, -1, $tmpdir) or die "chown: $!";
}
# create socket(s) and spawn webserver(s)
@@ -353,7 +353,7 @@ sub spawn_webserver() {
bind($sock, $sockaddr) or die "Couldn't bind to $p: $!";
push @CLEANUP, sub() {
print STDERR "Unlinking $path\n" if $OPTS{debug};
- unlink $path or warn "Warning: Can't unlink $path: $!";
+ unlink $path or warn "Warning: Couldn't unlink $path: $!";
};
umask($umask) // die "umask: $!";
}
@@ -428,8 +428,8 @@ sub iptables_save($@) {
my $pid = fork() // die "fork: $!";
unless ($pid) {
- open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!";
- open STDOUT, '>&', $iptables_tmp or die "Can't dup: $!";
+ open STDIN, '<', '/dev/null' or die "open(/dev/null): $!";
+ open STDOUT, '>&', $iptables_tmp or die "dup: $!";
$| = 1; # turn off buffering for STDOUT
exec "/usr/sbin/$iptables_bin-save", "-c" or die;
}
@@ -440,14 +440,14 @@ sub iptables_save($@) {
# handle and not from the file. XXX if there was a way in Perl to
# use open(2) with the O_TMPFILE flag we would use that to avoid
# creating a file to start with
- seek($iptables_tmp, SEEK_SET, 0) or die "Can't seek: $!";
+ seek($iptables_tmp, SEEK_SET, 0) or die "seek: $!";
push @CLEANUP, sub() {
print STDERR "[$$] Restoring $iptables_bin\n" if $OPTS{debug};
my $pid = fork() // die "fork: $!";
unless ($pid) {
- open STDIN, '<&', $iptables_tmp or die "Can't dup: $!";
- open STDOUT, '>', '/dev/null' or die "Can't open /dev/null: $!";
+ open STDIN, '<&', $iptables_tmp or die "dup: $!";
+ open STDOUT, '>', '/dev/null' or die "open(/dev/null): $!";
exec "/usr/sbin/$iptables_bin-restore", "-c" or die;
}
waitpid $pid => 0;
@@ -496,7 +496,7 @@ sub acme_client($@) {
unless ($pid) {
drop_privileges($accountd->{user}, $accountd->{group}, '/');
set_FD_CLOEXEC($s, 0);
- $client->close() or die "Can't close: $!";
+ $client->close() or die "close: $!";
my @cmd = ($accountd->{command}, '--conn-fd='.fileno($s));
push @cmd, '--config='.$accountd->{config} if defined $accountd->{config};
push @cmd, '--privkey='.$accountd->{privkey} if defined $accountd->{privkey};
@@ -505,7 +505,7 @@ sub acme_client($@) {
exec { $cmd[0] } @cmd or die;
}
print STDERR "[$$] Forking lacme-accountd, child PID $pid\n" if $OPTS{debug};
- $s->close() or die "Can't close: $!";
+ $s->close() or die "close: $!";
$cleanup = sub() {
print STDERR "[$$] Shutting down lacme-accountd\n" if $OPTS{debug};
shutdown($client, SHUT_RDWR) or warn "shutdown: $!";
@@ -520,11 +520,11 @@ sub acme_client($@) {
# ensure we're the only user with write access to the parent dir
my $dirname = $sockname =~ s/[^\/]+$//r;
- @stat = stat($dirname) or die "Can't stat $dirname: $!";
+ @stat = stat($dirname) or die "stat($dirname): $!";
die "Error: insecure permissions on $dirname\n" if ($stat[2] & 0022) != 0;
# ensure we're the only user with read/write access to the socket
- @stat = stat($sockname) or die "Can't stat $sockname: $! (Is lacme-accountd running?)\n";
+ @stat = stat($sockname) or die "Can't stat $sockname: $! (Is lacme-accountd running?)\n";
die "Error: insecure permissions on $sockname\n" if ($stat[2] & 0066) != 0;
# connect(2) to the socket
@@ -543,7 +543,7 @@ sub acme_client($@) {
my $rv = spawn({in => $args->{in}, out => $args->{out}, child => sub() {
drop_privileges($conf->{user}, $conf->{group}, $args->{chdir} // '/');
set_FD_CLOEXEC($_, 0) foreach ($CONFFILE, $client);
- seek($CONFFILE, SEEK_SET, 0) or die "Can't seek: $!";
+ seek($CONFFILE, SEEK_SET, 0) or die "seek: $!";
$ENV{DEBUG} = $OPTS{debug};
}}, $conf->{command}, $COMMAND, @fileno, @args);
@@ -572,18 +572,18 @@ sub spawn($@) {
# child
$args->{child}->() if defined $args->{child};
if (defined $args->{in}) {
- close $in_wd or die "Can't close: $!";
- open STDIN, '<&', $in_rd or die "Can't dup: $!";
+ close $in_wd or die "close: $!";
+ open STDIN, '<&', $in_rd or die "dup: $!";
} else {
- open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!";
+ open STDIN, '<', '/dev/null' or die "open(/dev/null): $!";
}
if (!defined $args->{out}) {
- open STDOUT, '>', '/dev/null' or die "Can't open /dev/null: $!";
+ open STDOUT, '>', '/dev/null' or die "open(/dev/null): $!";
} elsif (ref $args->{out} ne 'GLOB') {
- close $out_rd or die "Can't close: $!";
- open STDOUT, '>&', $out_wd or die "Can't dup: $!";
+ close $out_rd or die "close: $!";
+ open STDOUT, '>&', $out_wd or die "dup: $!";
} elsif (fileno(STDOUT) != fileno($args->{out})) {
- open STDOUT, '>&', $args->{out} or die "Can't dup: $!";
+ open STDOUT, '>&', $args->{out} or die "dup: $!";
}
exec { $exec[0] } @exec or die;
}
@@ -595,18 +595,18 @@ sub spawn($@) {
# parent
print STDERR "[$$] Forking $exec[0], child PID $pid\n" if $OPTS{debug};
if (defined $args->{in}) {
- $in_rd->close() or die "Can't close: $!";
+ $in_rd->close() or die "close: $!";
$in_wd->print($args->{in});
- $in_wd->close() or die "Can't close: $!";
+ $in_wd->close() or die "close: $!";
}
if (defined $args->{out} and ref $args->{out} ne 'GLOB') {
- $out_wd->close() or die "Can't close: $!";
+ $out_wd->close() or die "close: $!";
if (ref $args->{out} eq 'CODE') {
$args->{out}->($out_rd);
} elsif (ref $args->{out} eq 'SCALAR') {
${$args->{out}} = do { local $/ = undef; $out_rd->getline() };
}
- $out_rd->close() or die "Can't close: $!";
+ $out_rd->close() or die "close: $!";
}
waitpid $pid => 0;
pop @CLEANUP;
@@ -631,31 +631,31 @@ sub install_cert($$;$) {
chmod(0644 &~ $umask, $fh) or die "chmod: $!";
if ($leafonly) {
# keep only the leaf certificate
- pipe my $rd, my $wd or die "Can't pipe: $!";
- my $pid = fork // die "Can't fork: $!";
+ pipe my $rd, my $wd or die "pipe: $!";
+ my $pid = fork // die "fork: $!";
unless ($pid) {
- open STDIN, '<&', $rd or die "Can't dup: $!";
- open STDOUT, '>&', $fh or die "Can't dup: $!";
+ open STDIN, '<&', $rd or die "dup: $!";
+ open STDOUT, '>&', $fh or die "dup: $!";
exec qw/openssl x509 -outform PEM/ or die;
}
- $rd->close() or die "Can't close: $!";
+ $rd->close() or die "close: $!";
$wd->print($chain);
- $wd->close() or die "Can't close: $!";
+ $wd->close() or die "close: $!";
waitpid $pid => 0;
die $? if $? > 0;
} else {
- $fh->print($chain) or die "Can't print: $!";
+ $fh->print($chain) or die "print: $!";
}
- $fh->close() or die "Can't close: $!";
+ $fh->close() or die "close: $!";
};
my $path = $fh->filename();
if ($@) {
print STDERR "Unlinking $path\n" if $OPTS{debug};
- unlink $path or warn "Can't unlink $path: $!";
+ unlink $path or warn "unlink($path): $!";
die $@;
}
- rename($path, $filename) or die "Can't rename $path to $filename: $!";
+ rename($path, $filename) or die "rename($path, $filename): $!";
}
@@ -687,7 +687,7 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') {
unless ($conffile =~ s#/\z## or -d $conffile) {
@filenames = ($conffile);
} else {
- opendir my $dh, $conffile or die "Can't opendir $conffile: $!\n";
+ opendir my $dh, $conffile or die "opendir($conffile): $!\n";
while (readdir $dh) {
if (/\.conf\z/) {
push @filenames, "$conffile/$_";
@@ -723,7 +723,7 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') {
if ($OPTS{debug}) {
print STDERR "Configuration option for $s:\n";
- print " $_ = $conf->{$_}\n" foreach grep { defined $conf->{$_} } (sort keys %$conf);
+ print STDERR " $_ = $conf->{$_}\n" foreach grep { defined $conf->{$_} } (sort keys %$conf);
}
my $certtype = first { defined $conf->{$_} } qw/certificate certificate-chain/;
@@ -809,16 +809,16 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') {
if (defined $conf->{chown}) {
my ($user, $group) = split /:/, $conf->{chown}, 2;
- my $uid = getpwnam($user) // die "Can't getpwnam($user): $!";
- my $gid = defined $group ? (getgrnam($group) // die "Can't getgrnam($group): $!") : -1;
+ my $uid = getpwnam($user) // die "getpwnam($user): $!";
+ my $gid = defined $group ? (getgrnam($group) // die "getgrnam($group): $!") : -1;
foreach (grep defined, @$conf{qw/certificate certificate-chain/}) {
- chown($uid, $gid, $_) or die "Can't chown: $!";
+ chown($uid, $gid, $_) or die "chown: $!";
}
}
if (defined $conf->{chmod}) {
my $mode = oct($conf->{chmod}) // die;
foreach (grep defined, @$conf{qw/certificate certificate-chain/}) {
- chmod($mode, $_) or die "Can't chown: $!";
+ chmod($mode, $_) or die "chown: $!";
}
}
@@ -827,7 +827,7 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') {
or die "fork: $!";
print $fh $x509;
close $fh or die $! ?
- "Can't close: $!" :
+ "close: $!" :
"Error: x509(1ssl) exited with value ".($? >> 8)."\n";
if (defined $conf->{notify}) {
@@ -857,7 +857,7 @@ elsif ($COMMAND eq 'revokeCert' or $COMMAND eq 'revoke-cert') {
open my $fh, '-|', qw/openssl x509 -outform DER -in/, $filename or die "fork: $!";
my $der = do { local $/ = undef; <$fh> };
close $fh or die $! ?
- "Can't close: $!" :
+ "close: $!" :
"Error: x509(1ssl) exited with value ".($? >> 8)."\n";
my @certopts = join ',', qw/no_header no_version no_pubkey no_sigdump no_extensions/;
@@ -865,7 +865,7 @@ elsif ($COMMAND eq 'revokeCert' or $COMMAND eq 'revoke-cert') {
or die "fork: $!";
print $fh2 $der;
close $fh2 or die $! ?
- "Can't close: $!" :
+ "close: $!" :
"Error: x509(1ssl) exited with value ".($? >> 8)."\n";
if (acme_client({in => $der})) {
diff --git a/lacme-accountd b/lacme-accountd
index 36e9d9f..c00530f 100755
--- a/lacme-accountd
+++ b/lacme-accountd
@@ -106,7 +106,7 @@ if ($OPTS{privkey} =~ /\A(file|gpg):(\p{Print}+)\z/) {
my $str = do {local $/ = undef; <$fh>};
close $fh or die $! ?
- "Can't close: $!" :
+ "close: $!" :
"Error: $command[0] exited with value ".($? >> 8)."\n";
require 'Crypt/OpenSSL/RSA.pm';
@@ -140,7 +140,7 @@ my $JWK_STR = JSON::->new->encode($JWK);
if (defined $OPTS{'conn-fd'}) {
die "Invalid file descriptor" unless $OPTS{'conn-fd'} =~ /\A(\d+)\z/;
# untaint and fdopen(3) our end of the socket pair
- open ($S, '+<&=', $1+0) or die "fdopen $1: $!";
+ open ($S, '+<&=', $1+0) or die "fdopen($1): $!";
} else {
my $sockname = $OPTS{socket} // (defined $ENV{XDG_RUNTIME_DIR} ? "$ENV{XDG_RUNTIME_DIR}/S.lacme" : undef);
die "Missing socket option\n" unless defined $sockname;
@@ -148,7 +148,7 @@ if (defined $OPTS{'conn-fd'}) {
# ensure we're the only user with write access to the parent dir
my $dirname = $sockname =~ s/[^\/]+$//r;
- my @stat = stat($dirname) or die "Can't stat $dirname: $!";
+ my @stat = stat($dirname) or die "stat($dirname): $!";
die "Error: insecure permissions on $dirname\n" if ($stat[2] & 0022) != 0;
my $umask = umask(0177) // die "umask: $!";
@@ -172,14 +172,14 @@ if (defined $OPTS{'conn-fd'}) {
sub conn($;$) {
my $conn = shift;
my $count = shift;
- $conn->printflush( "$PROTOCOL_VERSION OK", "\r\n", $JWK_STR, "\r\n" );
+ $conn->printflush( "$PROTOCOL_VERSION OK", "\r\n", $JWK_STR, "\r\n" ) or warn "print: $!";
# sign whatever comes in
while (defined (my $data = $conn->getline())) {
$data =~ s/\r\n\z// or die;
print STDERR "[$count] >>> Issuing SHA-256 signature for: $data\n" unless $OPTS{quiet};
my $sig = $SIGN->($data);
- $conn->printflush( encode_base64url($sig), "\r\n" );
+ $conn->printflush( encode_base64url($sig), "\r\n" ) or warn "print: $!";
}
}
@@ -195,7 +195,7 @@ if (defined $OPTS{'conn-fd'}) {
print STDERR "[$count] >>> Accepted new connection\n" unless $OPTS{quiet};
conn($conn, $count);
print STDERR "[$count] >>> Connection terminated\n" unless $OPTS{quiet};
- close $conn or warn "Can't close: $!";
+ $conn->close() or warn "close: $!";
}
}
@@ -205,11 +205,11 @@ if (defined $OPTS{'conn-fd'}) {
END {
if (defined $SOCKNAME and -S $SOCKNAME) {
print STDERR "Unlinking $SOCKNAME\n" if $OPTS{debug};
- unlink $SOCKNAME or print STDERR "Can't unlink $SOCKNAME: $!\n";
+ unlink $SOCKNAME or print STDERR "Couldn't unlink $SOCKNAME: $!\n";
}
if (defined $S) {
print STDERR "Shutting down and closing lacme Account Key Manager\n" unless $OPTS{quiet};
shutdown($S, SHUT_RDWR) or warn "shutdown: $!";
- close $S or print STDERR "Can't close: $!\n";
+ close $S or print STDERR "close: $!\n";
}
}