]> git.proxmox.com Git - pve-http-server.git/blobdiff - PVE/APIServer/AnyEvent.pm
decode_urlencoded: cope with undefined values
[pve-http-server.git] / PVE / APIServer / AnyEvent.pm
old mode 100755 (executable)
new mode 100644 (file)
index 3892136..2e8ca47
@@ -184,6 +184,7 @@ sub response {
     $reqstate->{hdl}->timeout_reset();
     $reqstate->{hdl}->timeout($self->{timeout});
 
+    $nocomp = 1 if !$self->{compression};
     $nocomp = 1 if !$reqstate->{accept_gzip};
 
     my $code = $resp->code;
@@ -552,7 +553,11 @@ sub proxy_request {
 
        $headers->{'cookie'} = PVE::APIServer::Formatter::create_auth_cookie($ticket, $self->{cookie_name}) if $ticket;
        $headers->{'CSRFPreventionToken'} = $token if $token;
-       $headers->{'Accept-Encoding'} = 'gzip' if $reqstate->{accept_gzip};
+       $headers->{'Accept-Encoding'} = 'gzip' if ($reqstate->{accept_gzip} && $self->{compression});
+
+       if (defined(my $host = $reqstate->{request}->header('Host'))) {
+           $headers->{Host} = $host;
+       }
 
        my $content;
 
@@ -573,6 +578,9 @@ sub proxy_request {
            sslv2 => 0,
            sslv3 => 0,
            verify => 1,
+           # be compatible with openssl 1.1, fix for debian bug #923615
+           # remove once libanyeven-perl with this fix transitions to buster
+           dh => 'schmorp2048',
            verify_cb => sub {
                my (undef, undef, undef, $depth, undef, undef, $cert) = @_;
                # we don't care about intermediate or root certificates
@@ -637,16 +645,19 @@ sub decode_urlencoded {
        my ($k, $v) = split(/=/, $kv);
        $k =~s/\+/ /g;
        $k =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
-       $v =~s/\+/ /g;
-       $v =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
 
-       $v = Encode::decode('utf8', $v);
+       if (defined($v)) {
+           $v =~s/\+/ /g;
+           $v =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
 
-       if (defined(my $old = $res->{$k})) {
-           $res->{$k} = "$old\0$v";
-       } else {
-           $res->{$k} = $v;
+           $v = Encode::decode('utf8', $v);
+
+           if (defined(my $old = $res->{$k})) {
+               $v = "$old\0$v";
+           }
        }
+
+       $res->{$k} = $v;
     }
     return $res;
 }
@@ -1190,11 +1201,16 @@ sub unshift_read_header {
 
                my $len = $r->header('Content-Length');
 
+               my $host_header = $r->header('Host');
+               if (my $rpcenv = $self->{rpcenv}) {
+                   $rpcenv->set_request_host($host_header);
+               }
+
                # header processing complete - authenticate now
 
                my $auth = {};
                if ($self->{spiceproxy}) {
-                   my $connect_str = $r->header('Host');
+                   my $connect_str = $host_header;
                    my ($vmid, $node, $port) = $self->verify_spice_connect_url($connect_str);
                    if (!(defined($vmid) && $node && $port)) {
                        $self->error($reqstate, HTTP_UNAUTHORIZED, "invalid ticket");
@@ -1611,6 +1627,7 @@ sub new {
     $self->{base_uri} //= "/api2";
     $self->{dirs} //= {};
     $self->{title} //= 'API Inspector';
+    $self->{compression} //= 1;
 
     # formatter_config: we pass some configuration values to the Formatter
     $self->{formatter_config} = {};
@@ -1621,10 +1638,11 @@ sub new {
        $self->can('generate_csrf_prevention_token');
 
     # add default dirs which includes jquery and bootstrap
-    my $base = '/usr/share/libpve-http-server-perl';
-    add_dirs($self->{dirs}, '/css/' => "$base/css/");
-    add_dirs($self->{dirs}, '/js/' => "$base/js/");
-    add_dirs($self->{dirs}, '/fonts/' => "$base/fonts/");
+    my $jsbase = '/usr/share/javascript';
+    add_dirs($self->{dirs}, '/js/' => "$jsbase/");
+    # libjs-bootstrap uses symlinks for this, which we do not want to allow..
+    my $glyphicons = '/usr/share/fonts/truetype/glyphicons/';
+    add_dirs($self->{dirs}, '/js/bootstrap/fonts/' => "$glyphicons");
 
     # init inotify
     PVE::INotify::inotify_init();
@@ -1644,6 +1662,24 @@ sub new {
     $self->{end_cond} = AnyEvent->condvar;
 
     if ($self->{ssl}) {
+       my $ssl_defaults = {
+           # Note: older versions are considered insecure, for example
+           # search for "Poodle"-Attack
+           method => 'any',
+           sslv2 => 0,
+           sslv3 => 0,
+           cipher_list => 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256',
+           honor_cipher_order => 1,
+       };
+
+       foreach my $k (keys %$ssl_defaults) {
+           $self->{ssl}->{$k} //= $ssl_defaults->{$k};
+       }
+
+       if (!defined($self->{ssl}->{dh_file})) {
+           $self->{ssl}->{dh} = 'skip2048';
+       }
+
        my $tls_ctx_flags = &Net::SSLeay::OP_NO_COMPRESSION | &Net::SSLeay::OP_SINGLE_ECDH_USE | &Net::SSLeay::OP_SINGLE_DH_USE;
        if ( delete $self->{ssl}->{honor_cipher_order} ) {
            $tls_ctx_flags |= &Net::SSLeay::OP_CIPHER_SERVER_PREFERENCE;