]> git.proxmox.com Git - proxmox-acme.git/blobdiff - src/PVE/ACME/StandAlone.pm
fix #3390: standalone: explicitly bind to '::'
[proxmox-acme.git] / src / PVE / ACME / StandAlone.pm
index 0b4aaae0cd9618077a882bb7562d7bcf88e0e909..c054c5a9e003b3bb43e9b7eca9769d91dad779f3 100644 (file)
@@ -9,7 +9,7 @@ use HTTP::Response;
 use base qw(PVE::ACME::Challenge);
 
 sub supported_challenge_types {
-    return { 'http-01' => 1 };
+    return ['http-01'];
 }
 
 sub type {
@@ -27,48 +27,33 @@ sub options {
     };
 }
 
-sub extract_challenge {
-    my ($self, $challenge) = @_;
-
-    return PVE::ACME::Challenge->extract_challenge($challenge, 'http-01');
-}
-
 sub setup {
-    my ($class, $acme, $authorization) = @_;
-
-    my $challenges = $authorization->{challenges};
-    die "no challenges defined in authorization\n" if !$challenges;
+    my ($self, $acme, $auth, $data) = @_;
 
-    my $http_challenges = [ grep {$_->{type} eq 'http-01'} @$challenges ];
-    die "no http-01 challenge defined in authorization\n"
-       if ! scalar $http_challenges;
+    print "Setting up webserver\n";
 
-    my $http_challenge = $http_challenges->[0];
+    my $challenge = $self->extract_challenge($auth->{challenges});
+    my $key_auth = $acme->key_authorization($challenge->{token});
 
-    die "no token found in http-01 challenge\n" if !$http_challenge->{token};
-
-    my $key_authorization = $acme->key_authorization($http_challenge->{token});
-
-    my $server = HTTP::Daemon->new(
+    my %sockopts = (
        LocalPort => 80,
        ReuseAddr => 1,
-    ) or die "Failed to initialize HTTP daemon\n";
+       );
+    my $server = HTTP::Daemon->new( LocalHost => '::', V6Only => 0, %sockopts) //
+           HTTP::Daemon->new( LocalHost => '0.0.0.0', %sockopts)
+           or die "Failed to initialize HTTP daemon\n";
+
     my $pid = fork() // die "Failed to fork HTTP daemon - $!\n";
     if ($pid) {
-       my $self = {
-           server => $server,
-           pid => $pid,
-           authorization => $authorization,
-           key_auth => $key_authorization,
-           url => $http_challenge->{url},
-       };
-
-       return bless $self, $class;
+       $data->{server} = $server;
+       $data->{pid} = $pid;
+       $data->{url} = $challenge->{url};
     } else {
        while (my $c = $server->accept()) {
            while (my $r = $c->get_request()) {
-               if ($r->method() eq 'GET' and $r->uri->path eq "/.well-known/acme-challenge/$http_challenge->{token}") {
-                   my $resp = HTTP::Response->new(200, 'OK', undef, $key_authorization);
+               if ($r->method() eq 'GET' and
+                   $r->uri->path eq "/.well-known/acme-challenge/$challenge->{token}") {
+                   my $resp = HTTP::Response->new(200, 'OK', undef, $key_auth);
                    $resp->request($r);
                    $c->send_response($resp);
                } else {
@@ -82,11 +67,11 @@ sub setup {
 }
 
 sub teardown {
-    my ($self) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
-    eval { $self->{server}->close() };
-    kill('KILL', $self->{pid});
-    waitpid($self->{pid}, 0);
+    eval { $data->{server}->close() };
+    kill('KILL', $data->{pid});
+    waitpid($data->{pid}, 0);
 }
 
 1;