]> git.proxmox.com Git - proxmox-acme.git/commitdiff
plugins: refactor setup/teardown signatures
authorFabian Grünbichler <f.gruenbichler@proxmox.com>
Fri, 17 Apr 2020 07:39:50 +0000 (09:39 +0200)
committerFabian Grünbichler <f.gruenbichler@proxmox.com>
Fri, 17 Apr 2020 12:29:43 +0000 (14:29 +0200)
and move handling of tokens/key_auths to plugins, since it's not bound
to be identical for all challenge types forever.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
src/PVE/ACME/Challenge.pm
src/PVE/ACME/DNSChallenge.pm
src/PVE/ACME/StandAlone.pm

index 3fb8ab9cde5186232634ec67e2faaa38044cfb12..0137cf22274fe85dc98b7a8592dbfbe8437a9e70 100644 (file)
@@ -70,14 +70,23 @@ sub get_subplugins {
     return [];
 }
 
+# acme => PVE::ACME instance
+# auth => authorization object returned by ACME server
+# $data => {
+#   plugin => plugin config data
+#   alias => optional domain alias
+# }
+# needs to set $data->{url} to URL of the challenge which has been set up
+# can set other $data keys needed by teardown sub
 sub setup {
-    my ($class, $acme, $authorization) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
     die "implement me\n";
 }
 
+# see setup
 sub teardown {
-    my ($self) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
     die "implement me\n";
 }
index 98a183e6728300107b5f71cc25a21d4232c05717..041bc791b5cd13434784e56b3b0ac8eedbb229c9 100644 (file)
@@ -143,11 +143,6 @@ sub options {
     };
 }
 
-my $outfunc = sub {
-    my $line = shift;
-    print "$line\n";
-};
-
 sub extract_challenge {
     my ($self, $challenge) = @_;
 
@@ -158,44 +153,53 @@ sub get_subplugins {
     return $api_name_list;
 }
 
-# The order of the parameters passed to proxmox-acme is important
-# proxmox-acme setup $plugin [$domain|$alias] $txtvalue $plugin_conf_string
-sub setup {
-    my ($self, $data) = @_;
+my $proxmox_acme_command = sub {
+    my ($self, $acme, $auth, $data, $action) = @_;
 
     die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
-    my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
-    my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
+
+    my $alias = $data->{alias};
+    my $domain = $auth->{identifier}->{value};
+
+    my $challenge = $self->extract_challenge($auth->{challenges});
+    my $key_auth = $acme->key_authorization($challenge->{token});
+
+    my $txtvalue = PVE::ACME::encode(sha256($key_auth));
     my $dnsplugin = $data->{plugin}->{api};
     my $plugin_conf_string = $data->{plugin}->{data};
 
     # for security reasons, we execute the command as nobody
     # we can't verify that the code of the DNSPlugins are harmless.
     my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
-    push @$cmd, "/bin/bash", $ACME_PATH, "setup", $dnsplugin, $domain;
-    push @$cmd,        $txtvalue, $plugin_conf_string;
 
-    PVE::Tools::run_command($cmd, outfunc => $outfunc);
+    # The order of the parameters passed to proxmox-acme is important
+    # proxmox-acme <setup|teardown> $plugin <$domain|$alias> $txtvalue [$plugin_conf_string]
+    push @$cmd, "/bin/bash", $ACME_PATH, $action, $dnsplugin;
+    if ($alias) {
+       push @$cmd, $alias;
+    } else {
+       push @$cmd, $domain;
+    }
+    push @$cmd, $txtvalue, $plugin_conf_string;
+
+    PVE::Tools::run_command($cmd);
+
+    $data->{url} = $challenge->{url};
+
+    return $domain;
+};
+
+sub setup {
+    my ($self, $acme, $auth, $data) = @_;
+
+    my $domain = $proxmox_acme_command->($self, $acme, $auth, $data, 'setup');
     print "Add TXT record: _acme-challenge.$domain\n";
 }
 
-# The order of the parameters passed to proxmox-acme is important
-# proxmox-acme teardown $plugin [$domain|$alias] $txtvalue $plugin_conf_string
 sub teardown {
-    my ($self, $data) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
-    die "No plugin data for DNSChallenge\n" if !defined($data->{plugin});
-    my $domain = $data->{plugin}->{alias} ? $data->{plugin}->{alias} : $data->{domain};
-    my $txtvalue = PVE::ACME::encode(sha256($data->{key_authorization}));
-    my $dnsplugin = $data->{plugin}->{api};
-    my $plugin_conf_string = $data->{plugin}->{data};
-    
-    # for security reasons, we execute the command as nobody
-    # we can't verify that the code of the DNSPlugins are harmless.
-    my $cmd = ["setpriv", "--reuid", "nobody", "--regid", "nogroup", "--clear-groups", "--"];
-    push @$cmd, "/bin/bash", "$ACME_PATH", "teardown",  $dnsplugin, $domain ;
-    push @$cmd, $txtvalue, $plugin_conf_string;
-    PVE::Tools::run_command($cmd, outfunc => $outfunc);
+    my $domain = $proxmox_acme_command->($self, $acme, $auth, $data, 'teardown');
     print "Remove TXT record: _acme-challenge.$domain\n";
 }
 
index 310e62710863e8e5f1e29f82919dc857173f186d..b47a927a082201708e206edb68352440a6e784b5 100644 (file)
@@ -38,11 +38,12 @@ sub get_subplugins {
 }
 
 sub setup {
-    my ($class, $data) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
     print "Setting up webserver\n";
 
-    my $key_auth = $data->{key_authorization};
+    my $challenge = $self->extract_challenge($auth->{challenges});
+    my $key_auth = $acme->key_authorization($challenge->{token});
 
     my $server = HTTP::Daemon->new(
        LocalPort => 80,
@@ -52,11 +53,12 @@ sub setup {
     if ($pid) {
        $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/$data->{token}") {
+                   $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);
@@ -71,7 +73,7 @@ sub setup {
 }
 
 sub teardown {
-    my ($self, $data) = @_;
+    my ($self, $acme, $auth, $data) = @_;
 
     eval { $data->{server}->close() };
     kill('KILL', $data->{pid});