[pve-devel] r5752 - in pve-manager/pve2: . lib/PVE www/manager www/manager/window
svn-commits at proxmox.com
svn-commits at proxmox.com
Thu Mar 24 11:20:01 CET 2011
Author: dietmar
Date: 2011-03-24 11:20:01 +0100 (Thu, 24 Mar 2011)
New Revision: 5752
Modified:
pve-manager/pve2/ChangeLog
pve-manager/pve2/lib/PVE/APIDaemon.pm
pve-manager/pve2/lib/PVE/REST.pm
pve-manager/pve2/www/manager/PVEUtils.js
pve-manager/pve2/www/manager/index.pl
pve-manager/pve2/www/manager/window/LoginWindow.js
Log:
include the CSRF prevention token
Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/ChangeLog 2011-03-24 10:20:01 UTC (rev 5752)
@@ -1,3 +1,13 @@
+2011-03-24 Proxmox Support Team <support at proxmox.com>
+
+ * www/manager/index.pl: include the CSRF prevention token in the
+ generated page if there is a valid ticket inside the cookie (the
+ JS variable is called 'PVECSRFPreventionToken')
+
+ * lib/PVE/REST.pm (rest_handler): add CSRF prevention Logic. You
+ need to pass the CSRF prevention token in the
+ 'CSRFPreventionToken' header for POST, PUT and DELETE request.
+
2011-03-23 Proxmox Support Team <support at proxmox.com>
* lib/PVE/REST.pm (cookie_string): set 'secure' for auth cookie
Modified: pve-manager/pve2/lib/PVE/APIDaemon.pm
===================================================================
--- pve-manager/pve2/lib/PVE/APIDaemon.pm 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/lib/PVE/APIDaemon.pm 2011-03-24 10:20:01 UTC (rev 5752)
@@ -269,7 +269,8 @@
my $clientip = $headers->header('PVEClientIP');
- my $res = PVE::REST::rest_handler($clientip, $method, $uri, $rel_uri, $ticket, $params);
+ my $res = PVE::REST::rest_handler($clientip, $method, $uri, $rel_uri,
+ $ticket, undef, $params);
if ($res->{proxy}) {
Modified: pve-manager/pve2/lib/PVE/REST.pm
===================================================================
--- pve-manager/pve2/lib/PVE/REST.pm 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/lib/PVE/REST.pm 2011-03-24 10:20:01 UTC (rev 5752)
@@ -11,6 +11,7 @@
use CGI;
use mod_perl2;
use JSON;
+use Digest::SHA;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Status qw(:constants :is status_message);
@@ -177,7 +178,7 @@
}
sub proxy_handler {
- my($r, $clientip, $host, $method, $abs_uri, $ticket, $params) = @_;
+ my($r, $clientip, $host, $method, $abs_uri, $ticket, $token, $params) = @_;
syslog('info', "proxy start $method $host:$abs_uri");
@@ -187,7 +188,7 @@
);
$ua->default_header('cookie' => "${cookie_name}=$ticket") if $ticket;
-
+ $ua->default_header('CSRFPreventionToken' => $token) if $token;
$ua->default_header('PVEDisableProxy' => 'true');
$ua->default_header('PVEClientIP' => $clientip);
@@ -264,16 +265,16 @@
my $path = PVE::Tools::template_replace($perm->{path}, $param);
if (!$rpcenv->check($username, $path, $perm->{privs})) {
my $privstr = join(',', @{$perm->{privs}});
- die "permission check failed ($path, $privstr)\n";
+ die "Permission check failed ($path, $privstr)\n";
}
return 1;
}
- die "permission check failed\n";
+ die "Permission check failed\n";
};
sub rest_handler {
- my ($clientip, $method, $abs_uri, $rel_uri, $ticket, $params) = @_;
+ my ($clientip, $method, $abs_uri, $rel_uri, $ticket, $token, $params) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
@@ -297,17 +298,20 @@
if ($require_auth) {
- return {
- status => HTTP_UNAUTHORIZED,
- message => "No ticket",
- } if !$ticket;
+ eval {
+ die "No ticket\n" if !$ticket;
- ($username, $age) = PVE::AccessControl::verify_ticket($ticket, 1);
+ ($username, $age) = PVE::AccessControl::verify_ticket($ticket);
- return {
- status => HTTP_UNAUTHORIZED,
- message => "Ticket verify failed",
- } if !$username;
+ PVE::AccessControl::verify_csrf_prevention_token($ticket, $token)
+ if ($euid != 0) && ($method ne 'GET');
+ };
+ if (my $err = $@) {
+ return {
+ status => HTTP_UNAUTHORIZED,
+ message => $err,
+ };
+ }
}
my $uri_param = {};
@@ -441,6 +445,7 @@
my $params = $cgi->Vars();
my $cookie = $r->headers_in->{Cookie};
+ my $token = $r->headers_in->{CSRFPreventionToken};
my $ticket = extract_auth_cookie($cookie);
@@ -450,7 +455,8 @@
my ($rel_uri, $format) = split_abs_uri($abs_uri);
return HTTP_NOT_IMPLEMENTED if !$format;
- my $res = rest_handler($clientip, $method, $abs_uri, $rel_uri, $ticket, $params);
+ my $res = rest_handler($clientip, $method, $abs_uri, $rel_uri,
+ $ticket, $token, $params);
if ($res->{proxy}) {
if ($r->headers_in->{'PVEDisableProxy'}) {
@@ -460,7 +466,7 @@
return $res->{status};
}
return proxy_handler($r, $clientip, $res->{proxy}, $method,
- $abs_uri, $ticket, $params);
+ $abs_uri, $ticket, $token, $params);
}
prepare_response_data($format, $res);
Modified: pve-manager/pve2/www/manager/PVEUtils.js
===================================================================
--- pve-manager/pve2/www/manager/PVEUtils.js 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/www/manager/PVEUtils.js 2011-03-24 10:20:01 UTC (rev 5752)
@@ -12,6 +12,14 @@
'Accept': 'application/json'
};
+Ext.Ajax.on('beforerequest', function(conn, options) {
+ if (PVECSRFPreventionToken) {
+ if (!options.headers)
+ options.headers = {};
+ options.headers['CSRFPreventionToken'] = PVECSRFPreventionToken;
+ }
+});
+
// do not send '_dc' parameter
Ext.Ajax.disableCaching = false;
Modified: pve-manager/pve2/www/manager/index.pl
===================================================================
--- pve-manager/pve2/www/manager/index.pl 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/www/manager/index.pl 2011-03-24 10:20:01 UTC (rev 5752)
@@ -4,6 +4,8 @@
use mod_perl2 '1.9922';
use Encode;
use CGI;
+use PVE::AccessControl;
+use PVE::REST;
sub send_output {
my ($r, $data) = @_;
@@ -22,6 +24,15 @@
# so we must be very careful here
my $r = Apache2::RequestUtil->request();
+
+my $token = 'null';
+if (my $cookie = $r->headers_in->{Cookie}) {
+ my $ticket = PVE::REST::extract_auth_cookie($cookie);
+ if (PVE::AccessControl::verify_ticket($ticket, 1)) {
+ $token = PVE::AccessControl::assemble_csrf_prevention_token($ticket);
+ }
+}
+
my $cgi = CGI->new($r);
my %args = $cgi->Vars();
@@ -38,6 +49,7 @@
}
my $jssrc = <<_EOJS;
+PVECSRFPreventionToken = '$token';
Ext.onReady(PVE.Workspace.init, PVE.Workspace);
_EOJS
Modified: pve-manager/pve2/www/manager/window/LoginWindow.js
===================================================================
--- pve-manager/pve2/www/manager/window/LoginWindow.js 2011-03-24 09:03:09 UTC (rev 5751)
+++ pve-manager/pve2/www/manager/window/LoginWindow.js 2011-03-24 10:20:01 UTC (rev 5752)
@@ -20,6 +20,10 @@
},
success: function(f, resp){
self.el.unmask();
+
+ if (resp.result && resp.result.data)
+ PVECSRFPreventionToken = resp.result.data.CSRFPreventionToken;
+
var handler = self.handler || Ext.emptyFn;
handler.call(self);
self.close();
More information about the pve-devel
mailing list