This commit is contained in:
Devaev Maxim 2020-07-14 12:28:57 +03:00
parent e2f2e8b359
commit 9b3e113772
12 changed files with 410 additions and 242 deletions

View File

@ -132,11 +132,23 @@ run-vnc: testenv
regen: testenv
for file in kvmd/keyboard/mappings.py hid/src/keymap.h; do \
docker run --user `id -u`:`id -g` --rm \
--volume `pwd`:/src \
-it $(TESTENV_IMAGE) bash -c "cd src && ./genmap.py keymap.in $$file.mako $$file"; \
done
docker run --user `id -u`:`id -g` --rm \
--volume `pwd`:/src \
-it $(TESTENV_IMAGE) bash -c "cd src \
&& ./genmap.py keymap.in kvmd/keyboard/mappings.py.mako kvmd/keyboard/mappings.py \
&& ./genmap.py keymap.in hid/src/keymap.h.mako hid/src/keymap.h \
"
pug: testenv
docker run --user `id -u`:`id -g` --rm \
--volume `pwd`:/src \
-it $(TESTENV_IMAGE) bash -c "cd src \
&& pug --pretty web/index.pug -o web \
&& pug --pretty web/login/index.pug -o web/login \
&& pug --pretty web/ipmi/index.pug -o web/ipmi \
&& pug --pretty web/vnc/index.pug -o web/vnc \
"
release:

View File

@ -27,7 +27,9 @@ RUN pacman -Syu --noconfirm \
npm \
&& (pacman -Sc --noconfirm || true)
RUN npm install htmlhint -g
RUN npm install htmlhint -g \
&& npm install pug \
&& npm install pug-cli -g
ARG USTREAMER_MIN_VERSION
ENV USTREAMER_MIN_VERSION $USTREAMER_MIN_VERSION

58
web/base.pug Normal file
View File

@ -0,0 +1,58 @@
doctype html
//
==============================================================================
# #
# KVMD - The main Pi-KVM daemon. #
# #
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
==============================================================================
- var css_dir = "/share/css"
- var js_dir = "/share/js"
- var svg_dir = "/share/svg"
- var title = ""
- var main_js = ""
- var body_class = ""
- var css_list = ["vars", "main"]
block vars
html(lang="en")
head
meta(charset="utf-8")
title #{title}
link(rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png")
link(rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png")
link(rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png")
link(rel="manifest" href="/share/site.webmanifest")
link(rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5")
meta(name="msapplication-TileColor" content="#2b5797")
meta(name="theme-color" content="#ffffff")
each name in css_list
link(rel="stylesheet" href=`${css_dir}/${name}.css`)
if main_js
script(type="module")
| import {main} from "#{js_dir}/#{main_js}.js";
| main();
body(class=body_class)
block body

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<!-- =========================================================================
<!--
==============================================================================
# #
# KVMD - The main Pi-KVM daemon. #
# #
@ -18,82 +19,74 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
========================================================================== -->
==============================================================================
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pi-KVM Index</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="share/css/vars.css">
<link rel="stylesheet" href="share/css/main.css">
<link rel="stylesheet" href="share/css/window.css">
<link rel="stylesheet" href="share/css/modal.css">
<link rel="stylesheet" href="share/css/start.css">
<link rel="stylesheet" href="share/css/index/index.css">
<script type="module">
import {main} from "./share/js/index/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start">
<table>
<tr>
<td valign="top" class="logo">
<img class="svg-gray" src="share/svg/logo.svg" alt="Open Source Hardware" height="40" />
</td>
<td valign="top">
<table>
<tr>
<td colspan="2" class="title">Open Source &amp; Open Hardware IP-KVM</td>
</tr>
<tr>
<td colspan="2" class="copyright">Copyright &copy; 2018 Pi-KVM Developers Team</td>
</tr>
</table>
</td>
</tr>
</table>
<hr>
<table>
<tr class="server">
<td>Server:</td>
<td><a id="kvmd-meta-server-host" target="_blank" href="/api/info"></a></td>
</tr>
</table>
<hr>
<div id="apps-box">
<h4>Loading ...</h4>
</div>
<hr>
<p class="text">
Please note that when you are working with a KVM session or another application that captures the keyboard,
you can't use some keyboard shortcuts such as Ctrl+Alt+Del (which will be caught by your OS) or Ctrl+W (caught by your browser).
</p>
<p class="text">
To override this limitation you can use <a target="_blank" href="https://google.com/chrome">Google Chrome</a>
or <a target="_blank" href="https://chromium.org/Home">Chromium</a> in application mode.
</p>
<div id="app-text" class="code"></div>
<hr>
<p class="text">
Full documentation, source code, hardware schematics and legal information
can be found in our <a target="_blank" href="https://pikvm.org">official website</a>.
</p>
</div>
</div>
</body>
<head>
<meta charset="utf-8">
<title>Pi-KVM Index</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/share/css/vars.css">
<link rel="stylesheet" href="/share/css/main.css">
<link rel="stylesheet" href="/share/css/start.css">
<link rel="stylesheet" href="/share/css/window.css">
<link rel="stylesheet" href="/share/css/modal.css">
<link rel="stylesheet" href="/share/css/index/index.css">
<script type="module">import {main} from "/share/js/index/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start">
<table>
<tr>
<td class="logo" valign="top"><img class="svg-gray" src="/share/svg/logo.svg" alt="Open Source Hardware" height="40"></td>
<td valign="top">
<table>
<tr>
<td class="title" colspan="2">Open Source &amp; Open Hardware IP-KVM</td>
</tr>
<tr>
<td class="copyright" colspan="2">Copyright &copy; 2018 Pi-KVM Developers Team</td>
</tr>
</table>
</td>
</tr>
</table>
<hr>
<table>
<td class="server">
<td>Server:</td>
<td><a id="kvmd-meta-server-host" target="_blank" href="/api/info"></a></td>
</td>
</table>
<hr>
<div id="apps-box">
<h4>Loading ...</h4>
</div>
<hr>
<p class="text">
Please note that when you are working with a KVM session or another application that captures the keyboard,
you can't use some keyboard shortcuts such as Ctrl+Alt+Del (which will be caught by your OS) or Ctrl+W (caught by your browser).
</p>
<p class="text">To override this limitation you can use <a target="_blank" href="https://google.com/chrome">Google Chrome</a>
or <a target="_blank" href="https://chromium.org/Home">Chromium</a> in application mode.
</p>
<div class="code" id="app-text"></div>
<hr>
<p class="text">
Full documentation, source code, hardware schematics and legal information
can be found in our <a target="_blank" href="https://pikvm.org">official website</a>.
</p>
</div>
</div>
</body>
</html>

43
web/index.pug Normal file
View File

@ -0,0 +1,43 @@
extends start.pug
append vars
- title = "Pi-KVM Index"
- main_js = "index/main"
- css_list = css_list.concat(["window", "modal", "index/index"])
block start
table
tr
td(valign="top" class="logo")
img(class="svg-gray" src=`${svg_dir}/logo.svg` alt="Open Source Hardware" height="40")
td(valign="top")
table
tr
td(colspan="2" class="title") Open Source &amp; Open Hardware IP-KVM
tr
td(colspan="2" class="copyright") Copyright &copy; 2018 Pi-KVM Developers Team
hr
table
td(class="server")
td Server:
td
a(id="kvmd-meta-server-host" target="_blank" href="/api/info")
hr
div(id="apps-box")
h4 Loading ...
hr
p(class="text")
| Please note that when you are working with a KVM session or another application that captures the keyboard,
| you can't use some keyboard shortcuts such as Ctrl+Alt+Del (which will be caught by your OS) or Ctrl+W (caught by your browser).
p(class="text")
| To override this limitation you can use #[a(target="_blank" href="https://google.com/chrome") Google Chrome]
| or #[a(target="_blank" href="https://chromium.org/Home") Chromium] in application mode.
div(id="app-text" class="code")
hr
p(class="text")
| Full documentation, source code, hardware schematics and legal information
| can be found in our #[a(target="_blank" href="https://pikvm.org") official website].

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<!-- =========================================================================
<!--
==============================================================================
# #
# KVMD - The main Pi-KVM daemon. #
# #
@ -18,55 +19,44 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
========================================================================== -->
==============================================================================
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pi-KVM IPMI Info</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="../share/css/vars.css">
<link rel="stylesheet" href="../share/css/main.css">
<link rel="stylesheet" href="../share/css/start.css">
<script type="module">
import {main} from "/share/js/ipmi/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start">
<a style="display: inline-block; margin-top: 4px; color:#5c90bc; text-decoration: none;" href="/">
&nbsp;&nbsp;&larr;&nbsp;&nbsp; [ Pi-KVM Index ]
</a>
<hr>
<p class="text">
This Pi-KVM device has running <b>kvmd-ipmi</b> daemon and provides IPMI 2.0 interface for some basic
BMC operations like on/off/reset the server.
</p>
<p class="text">
<b>WARNING!</b> We strongly don't recommend you to use IPMI in untrusted networks because
this protocol is completely unsafe by design. In short, the authentication process for IPMI mandates
that the server send a salted SHA1 or MD5 hash of the requested user's password to the client,
prior to the client authenticating.
</p>
<p class="text">
<b>NEVER</b> use the same passwords for KVMD and IPMI users. And even better not to use IPMI.
Instead, you can directly use KVMD API via curl. We gave here some examples for this:
</p>
<div id="ipmi-text" class="code" style="max-height:200px;"></div>
</div>
</div>
</body>
<head>
<meta charset="utf-8">
<title>Pi-KVM IPMI Info</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/share/css/vars.css">
<link rel="stylesheet" href="/share/css/main.css">
<link rel="stylesheet" href="/share/css/start.css">
<script type="module">import {main} from "/share/js/ipmi/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start"><a style="display:inline-block; margin-top:4px; color:#5c90bc; text-decoration:none" href="/">&nbsp;&nbsp;&larr;&nbsp;&nbsp; [ Pi-KVM Index ]</a>
<hr>
<p class="text">This Pi-KVM device has running <b>kvmd-ipmi</b> daemon and provides IPMI 2.0 interface for some basic
BMC operations like on/off/reset the server.
</p>
<p class="text"><b>WARNING!</b> We strongly don't recommend you to use IPMI in untrusted networks because
this protocol is completely unsafe by design. In short, the authentication process for IPMI mandates
that the server send a salted SHA1 or MD5 hash of the requested user's password to the client,
prior to the client authenticating.
</p>
<p class="text"><b>NEVER</b> use the same passwords for KVMD and IPMI users. And even better not to use IPMI.
Instead, you can directly use KVMD API via curl. Here some examples:
</p>
<div class="code" id="ipmi-text" style="max-height:200px"></div>
</div>
</div>
</body>
</html>

20
web/ipmi/index.pug Normal file
View File

@ -0,0 +1,20 @@
extends ../start.pug
append vars
- title = "Pi-KVM IPMI Info"
- main_js = "ipmi/main"
- index_link = true
block start
p(class="text")
| This Pi-KVM device has running #[b kvmd-ipmi] daemon and provides IPMI 2.0 interface for some basic
| BMC operations like on/off/reset the server.
p(class="text")
| #[b WARNING!] We strongly don't recommend you to use IPMI in untrusted networks because
| this protocol is completely unsafe by design. In short, the authentication process for IPMI mandates
| that the server send a salted SHA1 or MD5 hash of the requested user's password to the client,
| prior to the client authenticating.
p(class="text")
| #[b NEVER] use the same passwords for KVMD and IPMI users. And even better not to use IPMI.
| Instead, you can directly use KVMD API via curl. Here some examples:
div(id="ipmi-text" class="code" style="max-height:200px")

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<!-- =========================================================================
<!--
==============================================================================
# #
# KVMD - The main Pi-KVM daemon. #
# #
@ -18,60 +19,59 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
========================================================================== -->
==============================================================================
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pi-KVM Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="../share/css/vars.css">
<link rel="stylesheet" href="../share/css/main.css">
<link rel="stylesheet" href="../share/css/window.css">
<link rel="stylesheet" href="../share/css/modal.css">
<link rel="stylesheet" href="../share/css/login/login.css">
<script type="module">
import {main} from "/share/js/login/main.js";
main();
</script>
</head>
<body>
<div id="login-box">
<div id="login">
<table>
<tr>
<td>Username:</td>
<td><input type="text" id="user-input"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" id="passwd-input"></td>
</tr>
<tr>
<td></td>
<td><button id="login-button">Login</button></td>
</tr>
</table>
</div>
</div>
<ul class="footer">
<li class="footer-left">
This site is actively using JavaScript.<br>
It doesn't contain ads, but is blocked by some ad filters.<br>
Please turn it off to continue and reload the page.
</li>
</ul>
</body>
<head>
<meta charset="utf-8">
<title>Pi-KVM Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/share/css/vars.css">
<link rel="stylesheet" href="/share/css/main.css">
<link rel="stylesheet" href="/share/css/window.css">
<link rel="stylesheet" href="/share/css/modal.css">
<link rel="stylesheet" href="/share/css/login/login.css">
<script type="module">import {main} from "/share/js/login/main.js";
main();
</script>
</head>
<body>
<div id="login-box">
<div id="login">
<table>
<tr>
<td>Username:</td>
<td>
<input type="text" id="user-input">
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type="password" id="passwd-input">
</td>
</tr>
<tr>
<td></td>
<td>
<button id="login-button">Login</button>
</td>
</tr>
</table>
</div>
</div>
<ul class="footer">
<li class="footer-left">This site is actively using JavaScript.<br>
It doesn't contain ads, but is blocked by some ad filters.<br>
Please turn it off to continue and reload the page.
</li>
</ul>
</body>
</html>

26
web/login/index.pug Normal file
View File

@ -0,0 +1,26 @@
extends ../base.pug
append vars
- title = "Pi-KVM Login"
- main_js = "login/main"
- css_list = css_list.concat(["window", "modal", "login/login"])
block body
div(id="login-box")
div(id="login")
table
tr
td Username:
td #[input(type="text" id="user-input")]
tr
td Password:
td #[input(type="password" id="passwd-input")]
tr
td
td #[button(id="login-button") Login]
ul(class="footer")
li(class="footer-left")
| This site is actively using JavaScript.#[br]
| It doesn't contain ads, but is blocked by some ad filters.#[br]
| Please turn it off to continue and reload the page.

14
web/start.pug Normal file
View File

@ -0,0 +1,14 @@
extends base.pug
append vars
- css_list.push("start")
- var index_link = false
block body
div(class="start-box")
div(class="start")
if index_link
a(style="display:inline-block; margin-top:4px; color:#5c90bc; text-decoration:none" href="/")
| &nbsp;&nbsp;&larr;&nbsp;&nbsp; [ Pi-KVM Index ]
hr
block start

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<!-- =========================================================================
<!--
==============================================================================
# #
# KVMD - The main Pi-KVM daemon. #
# #
@ -18,55 +19,44 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
========================================================================== -->
==============================================================================
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pi-KVM VNC Info</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="../share/css/vars.css">
<link rel="stylesheet" href="../share/css/main.css">
<link rel="stylesheet" href="../share/css/start.css">
<script type="module">
import {main} from "/share/js/vnc/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start">
<a style="display: inline-block; margin-top: 4px; color:#5c90bc; text-decoration: none;" href="/">
&nbsp;&nbsp;&larr;&nbsp;&nbsp; [ Pi-KVM Index ]
</a>
<hr>
<p class="text">
This Pi-KVM device has running <b>kvmd-vnc</b> daemon and provides VNC access to the server.
</p>
<p class="text">
<b>WARNING!</b> We strongly don't recommend you to use VNC in untrusted networks.
The current implementation does not use encryption, and your passwords are transmitted
over the network in a plain text.
</p>
<p class="text">
Your VNC client must support Tight JPEG compression, password authentication and allow
connection without encryption. <a href="https://tigervnc.org">TigerVNC</a> is a good choice.
On Linux, this client will most likely be available for installation from the repository.
It can also be called vncviewer.
</p>
<div id="vnc-text" class="code" style="max-height:200px;"></div>
</div>
</div>
</body>
<head>
<meta charset="utf-8">
<title>Pi-KVM VNC Info</title>
<link rel="apple-touch-icon" sizes="180x180" href="/share/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/share/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/share/favicon-16x16.png">
<link rel="manifest" href="/share/site.webmanifest">
<link rel="mask-icon" href="/share/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#2b5797">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/share/css/vars.css">
<link rel="stylesheet" href="/share/css/main.css">
<link rel="stylesheet" href="/share/css/start.css">
<script type="module">import {main} from "/share/js/vnc/main.js";
main();
</script>
</head>
<body>
<div class="start-box">
<div class="start"><a style="display:inline-block; margin-top:4px; color:#5c90bc; text-decoration:none" href="/">&nbsp;&nbsp;&larr;&nbsp;&nbsp; [ Pi-KVM Index ]</a>
<hr>
<p class="text">This Pi-KVM device has running <b>kvmd-vnc</b> daemon and provides VNC access to the server.</p>
<p class="text"><b>WARNING!</b> We strongly don't recommend you to use VNC in untrusted networks.
The current implementation does not use encryption, and your passwords are transmitted
over the network in a plain text.
</p>
<p class="text">
Your VNC client must support Tight JPEG compression, password authentication and allow
connection without encryption. <a href="https://tigervnc.org">TigerVNC</a> is a good choice.
On Linux, this client will most likely be available for installation from the repository.
It can also be called vncviewer.
</p>
<div class="code" id="vnc-text" style="max-height:200px"></div>
</div>
</div>
</body>
</html>

20
web/vnc/index.pug Normal file
View File

@ -0,0 +1,20 @@
extends ../start.pug
append vars
- title = "Pi-KVM VNC Info"
- main_js = "vnc/main"
- index_link = true
block start
p(class="text")
| This Pi-KVM device has running #[b kvmd-vnc] daemon and provides VNC access to the server.
p(class="text")
| #[b WARNING!] We strongly don't recommend you to use VNC in untrusted networks.
| The current implementation does not use encryption, and your passwords are transmitted
| over the network in a plain text.
p(class="text")
| Your VNC client must support Tight JPEG compression, password authentication and allow
| connection without encryption. #[a(href="https://tigervnc.org") TigerVNC] is a good choice.
| On Linux, this client will most likely be available for installation from the repository.
| It can also be called vncviewer.
div(id="vnc-text" class="code" style="max-height:200px")