Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
---

Notes:
    versioned breaks/depends with pve-manager and pmg-api

 PVE/APIServer/AnyEvent.pm            | 25 ++++++++++++++++++-------
 PVE/APIServer/Formatter.pm           |  9 +++++++++
 PVE/APIServer/Formatter/Bootstrap.pm |  1 +
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/PVE/APIServer/AnyEvent.pm b/PVE/APIServer/AnyEvent.pm
index 1e5c180..3ce948f 100644
--- a/PVE/APIServer/AnyEvent.pm
+++ b/PVE/APIServer/AnyEvent.pm
@@ -544,7 +544,7 @@ sub websocket_proxy {
 }
 
 sub proxy_request {
-    my ($self, $reqstate, $clientip, $host, $node, $method, $uri, $ticket, 
$token, $params) = @_;
+    my ($self, $reqstate, $clientip, $host, $node, $method, $uri, $auth, 
$params) = @_;
 
     eval {
        my $target;
@@ -564,8 +564,12 @@ sub proxy_request {
            PVEClientIP => $clientip,
        };
 
-       $headers->{'cookie'} = 
PVE::APIServer::Formatter::create_auth_cookie($ticket, $self->{cookie_name}) if 
$ticket;
-       $headers->{'CSRFPreventionToken'} = $token if $token;
+       $headers->{'cookie'} = 
PVE::APIServer::Formatter::create_auth_cookie($auth->{ticket}, 
$self->{cookie_name})
+           if $auth->{ticket};
+       $headers->{'Authorization'} = 
PVE::APIServer::Formatter::create_auth_header($auth->{api_token}, 
$self->{apitoken_name})
+           if $auth->{api_token};
+       $headers->{'CSRFPreventionToken'} = $auth->{token}
+           if $auth->{token};
        $headers->{'Accept-Encoding'} = 'gzip' if ($reqstate->{accept_gzip} && 
$self->{compression});
 
        if (defined(my $host = $reqstate->{request}->header('Host'))) {
@@ -744,7 +748,7 @@ sub handle_api2_request {
            $res->{proxy_params}->{tmpfilename} = $reqstate->{tmpfilename} if 
$upload_state;
 
            $self->proxy_request($reqstate, $clientip, $host, 
$res->{proxynode}, $method,
-                                $r->uri, $auth->{ticket}, $auth->{token}, 
$res->{proxy_params});
+                                $r->uri, $auth, $res->{proxy_params});
            return;
 
        } elsif ($upgrade && ($method eq 'GET') && ($path =~ m|websocket$|)) {
@@ -1238,6 +1242,11 @@ sub unshift_read_header {
                    $ticket = 
PVE::APIServer::Formatter::extract_auth_value($auth_header, 
$self->{cookie_name})
                        if !$ticket;
 
+                   # finally, fallback to API token if no ticket has been 
provided so far
+                   my $api_token;
+                   $api_token = 
PVE::APIServer::Formatter::extract_auth_value($auth_header, 
$self->{apitoken_name})
+                       if !$ticket;
+
                    my ($rel_uri, $format) = &$split_abs_uri($path, 
$self->{base_uri});
                    if (!$format) {
                        $self->error($reqstate, HTTP_NOT_IMPLEMENTED, "no such 
uri");
@@ -1245,7 +1254,7 @@ sub unshift_read_header {
                    }
 
                    eval {
-                       $auth = $self->auth_handler($method, $rel_uri, $ticket, 
$token,
+                       $auth = $self->auth_handler($method, $rel_uri, $ticket, 
$token, $api_token,
                                                    $reqstate->{peer_host});
                    };
                    if (my $err = $@) {
@@ -1639,6 +1648,7 @@ sub new {
     my $self = bless { %args }, $class;
 
     $self->{cookie_name} //= 'PVEAuthCookie';
+    $self->{apitoken_name} //= 'PVEAPIToken';
     $self->{base_uri} //= "/api2";
     $self->{dirs} //= {};
     $self->{title} //= 'API Inspector';
@@ -1646,7 +1656,7 @@ sub new {
 
     # formatter_config: we pass some configuration values to the Formatter
     $self->{formatter_config} = {};
-    foreach my $p (qw(cookie_name base_uri title)) {
+    foreach my $p (qw(apitoken_name cookie_name base_uri title)) {
        $self->{formatter_config}->{$p} = $self->{$p};
     }
     $self->{formatter_config}->{csrfgen_func} =
@@ -1781,7 +1791,7 @@ sub generate_csrf_prevention_token {
 }
 
 sub auth_handler {
-    my ($self, $method, $rel_uri, $ticket, $token, $peer_host) = @_;
+    my ($self, $method, $rel_uri, $ticket, $token, $api_token, $peer_host) = 
@_;
 
     die "implement me";
 
@@ -1791,6 +1801,7 @@ sub auth_handler {
     #    userid => $username,
     #    age => $age,
     #    isUpload => $isUpload,
+    #    api_token => $api_token,
     #};
 }
 
diff --git a/PVE/APIServer/Formatter.pm b/PVE/APIServer/Formatter.pm
index def1932..20455a0 100644
--- a/PVE/APIServer/Formatter.pm
+++ b/PVE/APIServer/Formatter.pm
@@ -95,4 +95,13 @@ sub create_auth_cookie {
     return "${cookie_name}=$encticket; path=/; secure;";
 }
 
+sub create_auth_header {
+    my ($value, $key) = @_;
+
+    return undef if !$key;
+
+    my $encoded = uri_escape($value);
+    return "${key} ${encoded}";
+}
+
 1;
diff --git a/PVE/APIServer/Formatter/Bootstrap.pm 
b/PVE/APIServer/Formatter/Bootstrap.pm
index d61f982..e67554a 100644
--- a/PVE/APIServer/Formatter/Bootstrap.pm
+++ b/PVE/APIServer/Formatter/Bootstrap.pm
@@ -65,6 +65,7 @@ sub new {
        url => $url,
        title => $config->{title},
        cookie_name => $config->{cookie_name},
+       apitoken_name => $config->{apitoken_name},
        js => '',
     };
 
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to