From a3bb607024a881409a835324e277ac69571049cb Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 14 Jan 2017 13:16:59 +0100 Subject: [PATCH] add new hook function to generate CSRF token This avoid the reference to PVE::AccessControl. --- PVE/APIServer/AnyEvent.pm | 11 +++++++++-- PVE/APIServer/Formatter/Bootstrap.pm | 8 +++----- PVE/APIServer/Formatter/HTML.pm | 12 ++++++------ PVE/APIServer/Formatter/Standard.pm | 10 +++++----- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/PVE/APIServer/AnyEvent.pm b/PVE/APIServer/AnyEvent.pm index 31380ab..4346942 100755 --- a/PVE/APIServer/AnyEvent.pm +++ b/PVE/APIServer/AnyEvent.pm @@ -738,7 +738,8 @@ sub handle_api2_request { $delay = 0 if $delay < 0; } - my ($raw, $ct, $nocomp) = &$formatter($res, $res->{data}, $params, $path, $auth); + my $csrfgen_func = $self->can('generate_csrf_prevention_token'); + my ($raw, $ct, $nocomp) = &$formatter($res, $res->{data}, $params, $path, $auth, $csrfgen_func); my $resp; if (ref($raw) && (ref($raw) eq 'HTTP::Response')) { @@ -1658,6 +1659,13 @@ sub verify_spice_connect_url { #return ($vmid, $node, $port); } +# formatters can call this when the generate a new page +sub generate_csrf_prevention_token { + my ($username) = @_; + + return undef; # do nothing by default +} + sub auth_handler { my ($self, $method, $rel_uri, $ticket, $token) = @_; @@ -1673,7 +1681,6 @@ sub auth_handler { #}; } - sub rest_handler { my ($self, $clientip, $method, $rel_uri, $auth, $params) = @_; diff --git a/PVE/APIServer/Formatter/Bootstrap.pm b/PVE/APIServer/Formatter/Bootstrap.pm index e875b89..7a33d2d 100644 --- a/PVE/APIServer/Formatter/Bootstrap.pm +++ b/PVE/APIServer/Formatter/Bootstrap.pm @@ -6,8 +6,6 @@ use URI::Escape; use HTML::Entities; use JSON; -use PVE::AccessControl; # to generate CSRF token - # Helpers to generate simple html pages using Bootstrap markup. my $jssrc = <<_EOJS; @@ -64,15 +62,15 @@ PVE = { _EOJS sub new { - my ($class, $res, $url, $auth) = @_; + my ($class, $res, $url, $auth, $csrfgen_func) = @_; my $self = bless { url => $url, js => '', }; - if (my $username = $res->{auth}->{userid}) { - $self->{csrftoken} = PVE::AccessControl::assemble_csrf_prevention_token($username); + if (my $username = $auth->{userid}) { + $self->{csrftoken} = &$csrfgen_func($username); } return $self; diff --git a/PVE/APIServer/Formatter/HTML.pm b/PVE/APIServer/Formatter/HTML.pm index ba824aa..ca976c6 100644 --- a/PVE/APIServer/Formatter/HTML.pm +++ b/PVE/APIServer/Formatter/HTML.pm @@ -167,14 +167,14 @@ PVE::APIServer::Formatter::register_login_formatter($portal_format, sub { }); PVE::APIServer::Formatter::register_formatter($portal_format, sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; # fixme: clumsy! PVE::APIServer::Formatter::Standard::prepare_response_data($portal_format, $res); $data = $res->{data}; my $html = ''; - my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth); + my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth, $csrfgen_func); if (!HTTP::Status::is_success($res->{status})) { $html .= $doc->alert(text => "Error $res->{status}: $res->{message}"); @@ -248,9 +248,9 @@ PVE::APIServer::Formatter::register_page_formatter( method => 'GET', path => "/access/ticket", code => sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; - my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth); + my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth, $csrfgen_func); my $html = &$login_form($doc); @@ -263,7 +263,7 @@ PVE::APIServer::Formatter::register_page_formatter( method => 'POST', path => "/access/ticket", code => sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; if (HTTP::Status::is_success($res->{status})) { my $cookie = PVE::APIServer::Formatter::create_auth_cookie( @@ -277,7 +277,7 @@ PVE::APIServer::Formatter::register_page_formatter( # Note: HTTP server redirects to 'GET /access/ticket', so below # output is not really visible. - my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth); + my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path, $auth, $csrfgen_func); my $html = &$login_form($doc); diff --git a/PVE/APIServer/Formatter/Standard.pm b/PVE/APIServer/Formatter/Standard.pm index cf5aac5..b6da526 100644 --- a/PVE/APIServer/Formatter/Standard.pm +++ b/PVE/APIServer/Formatter/Standard.pm @@ -47,7 +47,7 @@ sub prepare_response_data { } PVE::APIServer::Formatter::register_formatter('json', sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; my $nocomp = 0; @@ -62,7 +62,7 @@ PVE::APIServer::Formatter::register_formatter('json', sub { PVE::APIServer::Formatter::register_formatter('extjs', sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; my $nocomp = 0; @@ -76,7 +76,7 @@ PVE::APIServer::Formatter::register_formatter('extjs', sub { }); PVE::APIServer::Formatter::register_formatter('htmljs', sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; my $nocomp = 0; @@ -93,7 +93,7 @@ PVE::APIServer::Formatter::register_formatter('htmljs', sub { PVE::APIServer::Formatter::register_formatter('spiceconfig', sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; my $nocomp = 0; @@ -116,7 +116,7 @@ PVE::APIServer::Formatter::register_formatter('spiceconfig', sub { }); PVE::APIServer::Formatter::register_formatter('png', sub { - my ($res, $data, $param, $path, $auth) = @_; + my ($res, $data, $param, $path, $auth, $csrfgen_func) = @_; my $nocomp = 1;