
From: Aline Manera <alinefm@br.ibm.com> Some browsers doesn't support well for the usage self-signed certs in the ssl websocket connection. For details, please see: https://github.com/kanaka/websockify/wiki/Encrypted-Connections For chrome browser, the encrypted console connection should work after you login with ssl connection. But for firefox, it does not show a confirmation page for the user the accept the self-signed cert when the HTTPs connection is started from a websocket. So this patch makes use of the Web server in the websockify. The mini Web server in the websockify can serve static contents like html, css and js. This patch add a simple HTMl file (console.html) to pages/websockify and have websockify serve this file. When the user clicks the console icon, Kimchi brings the user to https://host:64667/console.html, which is served by websockify. Then firefox would prompt a confirmation page for the self-signed cert. After the user accept the cert, the user will be redirected to noVNC/SPICE page provided by Kimchi server. It is important to have Kimchi providing the noVNC/SPICE page to be able to add authentication to console pages (vnc_auto.html and spice.html) Signed-off-by: Aline Manera <alinefm@br.ibm.com> Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com> Signed-off-by: Zhou Zheng Sheng <zhshzhou@linux.vnet.ibm.com> --- configure.ac | 1 + contrib/kimchi.spec.fedora.in | 1 + contrib/kimchi.spec.suse.in | 1 + src/kimchi/vnc.py | 3 ++- ui/js/src/kimchi.api.js | 19 ++++++++----------- ui/pages/Makefile.am | 2 +- ui/pages/websockify/Makefile.am | 20 ++++++++++++++++++++ ui/pages/websockify/console.html | 25 +++++++++++++++++++++++++ 8 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 ui/pages/websockify/Makefile.am create mode 100644 ui/pages/websockify/console.html diff --git a/configure.ac b/configure.ac index 7d76f97..cc971e8 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,7 @@ AC_CONFIG_FILES([ ui/pages/help/pt_BR/Makefile ui/pages/help/zh_CN/Makefile ui/pages/tabs/Makefile + ui/pages/websockify/Makefile contrib/Makefile contrib/DEBIAN/Makefile contrib/DEBIAN/control diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in index 104c114..2d4699b 100644 --- a/contrib/kimchi.spec.fedora.in +++ b/contrib/kimchi.spec.fedora.in @@ -180,6 +180,7 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/kimchi/ui/pages/*.html.tmpl %{_datadir}/kimchi/ui/pages/help/*/*.html %{_datadir}/kimchi/ui/pages/tabs/*.html.tmpl +%{_datadir}/kimchi/ui/pages/websockify/*.html %{_sysconfdir}/kimchi/kimchi.conf %{_sysconfdir}/kimchi/nginx.conf.in %{_sysconfdir}/kimchi/distros.d/debian.json diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in index 7704822..165f566 100644 --- a/contrib/kimchi.spec.suse.in +++ b/contrib/kimchi.spec.suse.in @@ -102,6 +102,7 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/kimchi/ui/pages/*.html.tmpl %{_datadir}/kimchi/ui/pages/help/*/*.html %{_datadir}/kimchi/ui/pages/tabs/*.html.tmpl +%{_datadir}/kimchi/ui/pages/websockify/*.html %{_sysconfdir}/kimchi/kimchi.conf %{_sysconfdir}/kimchi/nginx.conf.in %{_sysconfdir}/kimchi/distros.d/debian.json diff --git a/src/kimchi/vnc.py b/src/kimchi/vnc.py index 3251f06..3339014 100644 --- a/src/kimchi/vnc.py +++ b/src/kimchi/vnc.py @@ -44,7 +44,8 @@ def new_ws_proxy(): cmd = os.path.join(os.path.dirname(__file__), 'websockify.py') args = ['python', cmd, config.get('display', 'display_proxy_port'), - '--target-config', WS_TOKENS_DIR, '--cert', cert, '--key', key] + '--target-config', WS_TOKENS_DIR, '--cert', cert, '--key', key, + '--web', os.path.join(paths.ui_dir, 'pages/websockify')] p = subprocess.Popen(args, close_fds=True) return p diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 9431624..2cea751 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -318,20 +318,16 @@ var kimchi = { type : 'GET', dataType : 'json' }).done(function(data, textStatus, xhr) { - http_port = data['http_port']; proxy_port = data['display_proxy_port']; kimchi.requestJSON({ url : "/vms/" + encodeURIComponent(vm) + "/connect", type : "POST", dataType : "json" }).done(function() { - /** - * Due to problems with web sockets and self-signed - * certificates, for now we will always redirect to http - */ - url = 'http://' + location.hostname + ':' + http_port; - url += "/vnc_auto.html?port=" + proxy_port; + url = 'https://' + location.hostname + ':' + proxy_port; + url += "/console.html?url=vnc_auto.html&port=" + proxy_port; url += "&path=?token=" + encodeURIComponent(vm); + url += "&kimchi=" + location.port; url += '&encrypt=1'; window.open(url); }); @@ -346,16 +342,17 @@ var kimchi = { type : 'GET', dataType : 'json' }).done(function(data, textStatus, xhr) { - http_port = data['http_port']; proxy_port = data['display_proxy_port']; kimchi.requestJSON({ url : "/vms/" + encodeURIComponent(vm) + "/connect", type : "POST", dataType : "json" }).done(function(data, textStatus, xhr) { - url = 'http://' + location.hostname + ':' + http_port; - url += "/spice.html?port=" + proxy_port + "&listen=" - + data.graphics.listen + "&token=" + encodeURIComponent(vm); + url = 'https://' + location.hostname + ':' + proxy_port; + url += "/console.html?url=spice.html&port=" + proxy_port; + url += "&listen=" + data.graphics.listen; + url += "&token=" + encodeURIComponent(vm); + url += "&kimchi=" + location.port; url += '&encrypt=1'; window.open(url); }); diff --git a/ui/pages/Makefile.am b/ui/pages/Makefile.am index 0c04a72..7f11555 100644 --- a/ui/pages/Makefile.am +++ b/ui/pages/Makefile.am @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -SUBDIRS = help tabs +SUBDIRS = help tabs websockify htmldir = $(datadir)/kimchi/ui/pages diff --git a/ui/pages/websockify/Makefile.am b/ui/pages/websockify/Makefile.am new file mode 100644 index 0000000..d498242 --- /dev/null +++ b/ui/pages/websockify/Makefile.am @@ -0,0 +1,20 @@ +# +# Kimchi +# +# Copyright IBM, Corp. 2014 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +websockifyhtmldir = $(datadir)/kimchi/ui/pages/websockify + +dist_websockifyhtml_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/websockify/console.html b/ui/pages/websockify/console.html new file mode 100644 index 0000000..a536e38 --- /dev/null +++ b/ui/pages/websockify/console.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <script type="text/javascript"> + redirectToKimchi = function() { + var query = window.location.search; + + var path = /.*url=(.*?)(&|$)/g.exec(query)[1]; + query = query.replace("url=" + path + "&", "") + query = query.replace("url=" + path, "") + + var kimchi_port = /.*kimchi=(.*?)(&|$)/g.exec(query)[1]; + query = query.replace("kimchi=" + kimchi_port + "&", "") + query = query.replace("kimchi=" + kimchi_port, "") + + var url = "https://" + location.hostname + ":" + kimchi_port + "/"; + url += path + query + + window.location.replace(url) + } + </script> + </head> + + <body onload="redirectToKimchi()"/> +</html> -- 1.7.10.4