YU Jincheng [Thu, 25 Jan 2024 08:28:01 +0000 (16:28 +0800)]
eba: support decoding MAC key provided in base64url format
According to RFC 8555:
> The MAC key SHOULD be provided in base64url-encoded form...
However, currently we are only decoding the MAC key as base64.
This patch chooses the correct function to decode the user provided
MAC key. This can fix authentication error when a user uses command
`pvenode acme account register` and paste the EBA MAC key as prompted.
The first one added a new false-positive where our heuristic matched
the "_acme-challenge " inside the sed arguments, but that clearly
isn't a function.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Stoiko Ivanov [Tue, 21 Feb 2023 13:13:18 +0000 (14:13 +0100)]
tests: add non-word boundary to present functions
noticed that _clearaccountconf_mutable is used in dns_cf.sh, but not
present (it gets masked since we provide _clearaccountconf)
tested with this example.
additionally update missing-functions.expected - _error is not
present in upstream `acme.sh` but used in dns_aws.sh (I expect an
error which is only hit very seldomly)
there's a build cycle between proxmox-acme and pve-common, but proxmox-acme
only uses it for `make check`, so it's possible to break the cycle by using the
nocheck build profile when bootstrapping.
Thomas Lamprecht [Tue, 26 Apr 2022 08:47:32 +0000 (10:47 +0200)]
tests: run missing-function test on build
as we only use a heuristic we maintain a known good expected false
positive list, update that if new ones get added but be sure that no
new function was included!
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Stoiko Ivanov [Tue, 9 Nov 2021 16:36:29 +0000 (17:36 +0100)]
dns-challenge: add 'use-proxy' property
this patch adds an optional 'use-proxy' property to the dns
challenges.
If set to 1 the caller is expected to add the proxy url in the plugin
config, which is then set as 'http_proxy' and 'https_proxy'
environment variable by the plugin caller (and then used by curl)
Tested with the pdns plugin, direct traffic to the pdns server being
dropped, and a configured squid proxy
d/control: acme-perl: downgrade dependency to plugins to recommends
we have some places where we just do not need the plugins and the
perl library has no hard dependency on the plugin stuff, http
challenge and acme protocol implementation are independent of those
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
the current default chains end with an expired root certificate for
maximum compatibility with old Android versions. this breaks some other
older clients (openssl, gnutls) which don't expect chains to contain any
expired certificates, even if they are 'above' the trust anchor.
by setting $root, it is possible to specify which root the ACME provided
certificate chain should end with, downloading alternate chains as
necessary.
Stoiko Ivanov [Fri, 6 Aug 2021 15:44:27 +0000 (17:44 +0200)]
acme client: fix #3536 untaint data returned from acme server
The data returned from the acme server (e.g. boulder) should be
considered tainted.
To see which places might need untainted I checked where $self->{ua}
was used (in $self->do) and a quick scan identified __get_result as
the consumer of the tainted data.
In all but one uses the data is decoded from json (which would die if the
result is not valid json).
The remaining use-case yields a certificate in PEM format (and is
handled at the caller of __get_result).
The issue is currently only visible if a proxy is set, because AFAICT
somewhere in SSLeay (or IO::Socket::SSL, which uses SSLeay) a taint
flag is not set on the return value.
A reproducer for the issue:
```
use strict;
use warnings;
use HTTP::Request;
use LWP::UserAgent;
$ENV{PATH} = "/usr/bin:/bin";
my $ua = LWP::UserAgent->new(env_proxy => 0);
my $request = HTTP::Request->new('GET', 'https://google.com/');
my $resp = $ua->request($request);
my $text = substr($resp->decoded_content, 0, 5);;
system("echo \"$text\""); # does work
$request = HTTP::Request->new('GET', 'http://neverssl.com/');
$resp = $ua->request($request);
$text = substr($resp->decoded_content, 0, 5);;
system("echo \"$text\""); # does not work
```
proxmox-acme is used to call the dns-plugins from acme.sh and has the
config editing (saving/clearing) turned int no-ops.
bash's `return` statement w/o argument returns the value of the last
executed command (the one before our no-op method was called) (see
`help return` in bash).
This leads to unexpected behavior in some plugins, which call one of
the methods as last statement join the next step with `&&`.
As reported in our community forum [0] certain dns plugins use code
from `acme.sh`, which is currently not in our proxmox-acme.
I initially only added _sign and it's callees, but then though about
trying to get all missing methods somehow (only resethttp() was
missing in addition).
The heuristic used to get all missing methods was grepping for '\b_'
in all dns plugins and then removing:
* declarations in proxmox_acme (already present)
* methods declared in the plugins themselves
* $_.* (or ${_.*) - variable use
* comments
Stoiko Ivanov [Wed, 12 May 2021 19:04:52 +0000 (21:04 +0200)]
fix #3390: standalone: explicitly bind to '::'
This patch follows 2f8be3bfda203065b22e60862e5f98d831a46921 from
pve-common:
Instead of not specifying a listen address, we first try to bind on
'::', which usually accepts connections for both ipv4 and ipv6,
and fall back to '0.0.0.0' if this fails (if ipv6 is disabled via
kernel commandline).
The arguments are the same for HTTP::Daemon as for IO::Socket::IP,
since the former has IO::Socket::IP as base.
Additionally, by setting 'V6Only' explicitly to '0', the listening
socket will also accept ipv4 connections, even if the sysctl
'net.ipv6.bindv6only' is set to 1 - the sysctl provides a default
value, which can be overridden by a socket-option (see ipv6(7) -
IPV6_ONLY).
setting this option results in the following setsockopt-call being
added:
setsockopt(3, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
AFAICT the socket option is available and overridable on Linux > 2.4
see [0] for an explanation of why this might not be wanted
Overriding the default setting set by an admin might be debateable,
but considering that the http-listener for the ACME challenge is
rather short-lived I think this is justified. The only other option
would be to create 2 listening sockets and binding on both - which
would mean reorganizing our perl-deamons to deal with multiple listen
sockets.
quickly tested on a publicly reachable test-machine of mine with:
* ipv6.domain.test (only AAAA record)
* ip46.domain.test (both AAAA and A)
* ipv4.domain.test (only A record)
with:
* sysctl net.ipv6.bindv6only=1 (for all 3 domains)
* disabling ipv6 via kernel-commandline (only ipv4 tested)
* disabling ipv6 via sysctl (only ipv4 tested)
* only configuring an ipv6 address (only ipv6 tested)
split into two packages: a perl one and an acme.sh plugin one
Main reason for this split is PBS, which only needs the plugins and
would like to avoid the perl one (which pulls in pve-common too)
This includes a few small changes which are technically not direct
part of the split, but related enough:
* change source name of package from libproxmox-acme-perl to
libproxmox-acme
* make lintian override for script exec permission narrower to avoid
possible false negatives in the future, really only allow the
dnsapi ones.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>