]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/Ticket.pm
bump version to 8.2.1
[pve-common.git] / src / PVE / Ticket.pm
index 76d2ea515113dde4bc1019d2f1fddd5084f4c49e..c5508edd17aabca076a020c3a62c8c666b014595 100644 (file)
@@ -6,20 +6,22 @@ use warnings;
 use Crypt::OpenSSL::Random;
 use Crypt::OpenSSL::RSA;
 use MIME::Base64;
-use MIME::Base32; #libmime-base32-perl
 use Digest::SHA;
 use Time::HiRes qw(gettimeofday);
+use URI::Escape;
 
-use PVE::Exception qw(raise_perm_exc);
+use PVE::Exception qw(raise);
 
 Crypt::OpenSSL::RSA->import_random_seed();
 
+use constant HTTP_UNAUTHORIZED => 401;
+
 sub assemble_csrf_prevention_token {
     my ($secret, $username) = @_;
 
     my $timestamp = sprintf("%08X", time());
 
-    my $digest = Digest::SHA::sha1_base64("$timestamp:$username", $secret);
+    my $digest = Digest::SHA::hmac_sha256_base64("$timestamp:$username", $secret);
 
     return "$timestamp:$digest";
 }
@@ -32,14 +34,15 @@ sub verify_csrf_prevention_token {
        my $timestamp = $1;
        my $ttime = hex($timestamp);
 
-       my $digest = Digest::SHA::sha1_base64("$timestamp:$username", $secret);
+       my $digest = Digest::SHA::hmac_sha256_base64("$timestamp:$username", $secret);
 
        my $age = time() - $ttime;
        return 1 if ($digest eq $sig) && ($age > $min_age) &&
            ($age < $max_age);
     }
 
-    raise_perm_exc("Permission denied - invalid csrf token") if !$noerr;
+    raise("Permission denied - invalid csrf token\n", code => HTTP_UNAUTHORIZED)
+       if !$noerr;
 
     return undef;
 }
@@ -52,7 +55,10 @@ sub assemble_rsa_ticket {
 
     my $plain = "$prefix:";
 
-    $plain .= "$data:" if defined($data);
+    if (defined($data)) {
+       $data = uri_escape($data, ':');
+       $plain .= "$data:";
+    }
 
     $plain .= $timestamp;
 
@@ -80,6 +86,10 @@ sub verify_rsa_ticket {
 
                my $age = time() - $ttime;
 
+               if (defined($data)) {
+                   $data = uri_unescape($data);
+               }
+
                if (($age > $min_age) && ($age < $max_age)) {
                    if (defined($data)) {
                        return wantarray ? ($data, $age) : $data;
@@ -91,7 +101,8 @@ sub verify_rsa_ticket {
        }
     }
 
-    raise_perm_exc("permission denied - invalid $prefix ticket") if !$noerr;
+    raise("permission denied - invalid $prefix ticket\n", code => HTTP_UNAUTHORIZED)
+       if !$noerr;
 
     return undef;
 }
@@ -122,14 +133,14 @@ sub assemble_spice_ticket {
     # Note: data needs to be lower case only, because virt-viewer needs that
     # Note: RSA signature are too long (>=256 charaters) and make problems with remote-viewer
 
-    my $plain = "pvespiceproxy:$timestamp:$vmid:" . lc($node);
+    my $plain = "pvespiceproxy:${timestamp}:${vmid}:" . lc($node);
 
     # produces 40 characters
     my $sig = unpack("H*", Digest::SHA::sha1($plain, $secret));
 
     #my $sig =  unpack("H*", $rsa_priv->sign($plain)); # this produce too long strings (512)
 
-    my $proxyticket = "$plain::$sig";
+    my $proxyticket = "${plain}::${sig}";
 
     return ($ticket, $proxyticket);
 }