SPB Git

spb/admin-ka

Public

Fix noVNC: utiliser la version ESM (core/) au lieu du CommonJS lib/ (erreur can find variable export)

Simon-Pierre Boucher committed (Aug 23, 2026) parent 545e941 Browse files

76 changed files +11,181 −8,814

76 changed files
modified public/app.js +1 −1
@@ -80,7 +80,7 @@
80 80 statusEl.textContent = 'connexion…';
81 81 try {
82 82 const pw = await (await fetch('/api/social/vncpw')).json();
83 − const { default: RFB } = await import('/vendor/novnc/rfb.js');
83 + const { default: RFB } = await import('/vendor/novnc/core/rfb.js');
84 84 const url = (location.protocol === 'https:' ? 'wss://' : 'ws://') + location.host + '/vncws';
85 85 panel.style.display = 'block';
86 86 _rfb = new RFB(panel, url, { credentials: { password: pw.password } });
deleted public/vendor/novnc/base64.js +0 −100
@@ -1,100 +0,0 @@
1 −"use strict";
2 −
3 −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4 −Object.defineProperty(exports, "__esModule", {
5 − value: true
6 −});
7 −exports["default"] = void 0;
8 −var Log = _interopRequireWildcard(require("./util/logging.js"));
9 −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
10 −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
11 −/* This Source Code Form is subject to the terms of the Mozilla Public
12 − * License, v. 2.0. If a copy of the MPL was not distributed with this
13 − * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
14 −// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
15 −var _default = exports["default"] = {
16 − /* Convert data (an array of integers) to a Base64 string. */
17 − toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
18 − base64Pad: '=',
19 − encode: function encode(data) {
20 − "use strict";
21 −
22 − var result = '';
23 − var length = data.length;
24 − var lengthpad = length % 3;
25 − // Convert every three bytes to 4 ascii characters.
26 −
27 − for (var i = 0; i < length - 2; i += 3) {
28 − result += this.toBase64Table[data[i] >> 2];
29 − result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
30 − result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
31 − result += this.toBase64Table[data[i + 2] & 0x3f];
32 − }
33 −
34 − // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
35 − var j = length - lengthpad;
36 − if (lengthpad === 2) {
37 − result += this.toBase64Table[data[j] >> 2];
38 − result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
39 − result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
40 − result += this.toBase64Table[64];
41 − } else if (lengthpad === 1) {
42 − result += this.toBase64Table[data[j] >> 2];
43 − result += this.toBase64Table[(data[j] & 0x03) << 4];
44 − result += this.toBase64Table[64];
45 − result += this.toBase64Table[64];
46 − }
47 − return result;
48 − },
49 − /* Convert Base64 data to a string */
50 − /* eslint-disable comma-spacing */
51 − toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
52 − /* eslint-enable comma-spacing */decode: function decode(data) {
53 − var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
54 − var dataLength = data.indexOf('=') - offset;
55 − if (dataLength < 0) {
56 − dataLength = data.length - offset;
57 − }
58 −
59 − /* Every four characters is 3 resulting numbers */
60 − var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5);
61 − var result = new Array(resultLength);
62 −
63 − // Convert one by one.
64 −
65 − var leftbits = 0; // number of bits decoded, but yet to be appended
66 − var leftdata = 0; // bits decoded, but yet to be appended
67 − for (var idx = 0, i = offset; i < data.length; i++) {
68 − var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
69 − var padding = data.charAt(i) === this.base64Pad;
70 − // Skip illegal characters and whitespace
71 − if (c === -1) {
72 − Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
73 − continue;
74 − }
75 −
76 − // Collect data into leftdata, update bitcount
77 − leftdata = leftdata << 6 | c;
78 − leftbits += 6;
79 −
80 − // If we have 8 or more bits, append 8 bits to the result
81 − if (leftbits >= 8) {
82 − leftbits -= 8;
83 − // Append if not padding.
84 − if (!padding) {
85 − result[idx++] = leftdata >> leftbits & 0xff;
86 − }
87 − leftdata &= (1 << leftbits) - 1;
88 − }
89 − }
90 −
91 − // If there are any bits left, the base64 string was corrupted
92 − if (leftbits) {
93 − var err = new Error('Corrupted base64 string');
94 − err.name = 'Base64-Error';
95 − throw err;
96 − }
97 − return result;
98 − }
99 −};
100 −/* End of Base64 namespace */
\ No newline at end of file
added public/vendor/novnc/core/base64.js +104 −0
@@ -0,0 +1,104 @@
1 +/* This Source Code Form is subject to the terms of the Mozilla Public
2 + * License, v. 2.0. If a copy of the MPL was not distributed with this
3 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 +
5 +// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
6 +
7 +import * as Log from './util/logging.js';
8 +
9 +export default {
10 + /* Convert data (an array of integers) to a Base64 string. */
11 + toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
12 + base64Pad: '=',
13 +
14 + encode(data) {
15 + "use strict";
16 + let result = '';
17 + const length = data.length;
18 + const lengthpad = (length % 3);
19 + // Convert every three bytes to 4 ascii characters.
20 +
21 + for (let i = 0; i < (length - 2); i += 3) {
22 + result += this.toBase64Table[data[i] >> 2];
23 + result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
24 + result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
25 + result += this.toBase64Table[data[i + 2] & 0x3f];
26 + }
27 +
28 + // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
29 + const j = length - lengthpad;
30 + if (lengthpad === 2) {
31 + result += this.toBase64Table[data[j] >> 2];
32 + result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
33 + result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
34 + result += this.toBase64Table[64];
35 + } else if (lengthpad === 1) {
36 + result += this.toBase64Table[data[j] >> 2];
37 + result += this.toBase64Table[(data[j] & 0x03) << 4];
38 + result += this.toBase64Table[64];
39 + result += this.toBase64Table[64];
40 + }
41 +
42 + return result;
43 + },
44 +
45 + /* Convert Base64 data to a string */
46 + /* eslint-disable comma-spacing */
47 + toBinaryTable: [
48 + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
49 + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
50 + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
51 + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
52 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
53 + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
54 + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
55 + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
56 + ],
57 + /* eslint-enable comma-spacing */
58 +
59 + decode(data, offset = 0) {
60 + let dataLength = data.indexOf('=') - offset;
61 + if (dataLength < 0) { dataLength = data.length - offset; }
62 +
63 + /* Every four characters is 3 resulting numbers */
64 + const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
65 + const result = new Array(resultLength);
66 +
67 + // Convert one by one.
68 +
69 + let leftbits = 0; // number of bits decoded, but yet to be appended
70 + let leftdata = 0; // bits decoded, but yet to be appended
71 + for (let idx = 0, i = offset; i < data.length; i++) {
72 + const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
73 + const padding = (data.charAt(i) === this.base64Pad);
74 + // Skip illegal characters and whitespace
75 + if (c === -1) {
76 + Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
77 + continue;
78 + }
79 +
80 + // Collect data into leftdata, update bitcount
81 + leftdata = (leftdata << 6) | c;
82 + leftbits += 6;
83 +
84 + // If we have 8 or more bits, append 8 bits to the result
85 + if (leftbits >= 8) {
86 + leftbits -= 8;
87 + // Append if not padding.
88 + if (!padding) {
89 + result[idx++] = (leftdata >> leftbits) & 0xff;
90 + }
91 + leftdata &= (1 << leftbits) - 1;
92 + }
93 + }
94 +
95 + // If there are any bits left, the base64 string was corrupted
96 + if (leftbits) {
97 + const err = new Error('Corrupted base64 string');
98 + err.name = 'Base64-Error';
99 + throw err;
100 + }
101 +
102 + return result;
103 + }
104 +}; /* End of Base64 namespace */
added public/vendor/novnc/core/crypto/aes.js +178 −0
@@ -0,0 +1,178 @@
1 +export class AESECBCipher {
2 + constructor() {
3 + this._key = null;
4 + }
5 +
6 + get algorithm() {
7 + return { name: "AES-ECB" };
8 + }
9 +
10 + static async importKey(key, _algorithm, extractable, keyUsages) {
11 + const cipher = new AESECBCipher;
12 + await cipher._importKey(key, extractable, keyUsages);
13 + return cipher;
14 + }
15 +
16 + async _importKey(key, extractable, keyUsages) {
17 + this._key = await window.crypto.subtle.importKey(
18 + "raw", key, {name: "AES-CBC"}, extractable, keyUsages);
19 + }
20 +
21 + async encrypt(_algorithm, plaintext) {
22 + const x = new Uint8Array(plaintext);
23 + if (x.length % 16 !== 0 || this._key === null) {
24 + return null;
25 + }
26 + const n = x.length / 16;
27 + for (let i = 0; i < n; i++) {
28 + const y = new Uint8Array(await window.crypto.subtle.encrypt({
29 + name: "AES-CBC",
30 + iv: new Uint8Array(16),
31 + }, this._key, x.slice(i * 16, i * 16 + 16))).slice(0, 16);
32 + x.set(y, i * 16);
33 + }
34 + return x;
35 + }
36 +}
37 +
38 +export class AESEAXCipher {
39 + constructor() {
40 + this._rawKey = null;
41 + this._ctrKey = null;
42 + this._cbcKey = null;
43 + this._zeroBlock = new Uint8Array(16);
44 + this._prefixBlock0 = this._zeroBlock;
45 + this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
46 + this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
47 + }
48 +
49 + get algorithm() {
50 + return { name: "AES-EAX" };
51 + }
52 +
53 + async _encryptBlock(block) {
54 + const encrypted = await window.crypto.subtle.encrypt({
55 + name: "AES-CBC",
56 + iv: this._zeroBlock,
57 + }, this._cbcKey, block);
58 + return new Uint8Array(encrypted).slice(0, 16);
59 + }
60 +
61 + async _initCMAC() {
62 + const k1 = await this._encryptBlock(this._zeroBlock);
63 + const k2 = new Uint8Array(16);
64 + const v = k1[0] >>> 6;
65 + for (let i = 0; i < 15; i++) {
66 + k2[i] = (k1[i + 1] >> 6) | (k1[i] << 2);
67 + k1[i] = (k1[i + 1] >> 7) | (k1[i] << 1);
68 + }
69 + const lut = [0x0, 0x87, 0x0e, 0x89];
70 + k2[14] ^= v >>> 1;
71 + k2[15] = (k1[15] << 2) ^ lut[v];
72 + k1[15] = (k1[15] << 1) ^ lut[v >> 1];
73 + this._k1 = k1;
74 + this._k2 = k2;
75 + }
76 +
77 + async _encryptCTR(data, counter) {
78 + const encrypted = await window.crypto.subtle.encrypt({
79 + name: "AES-CTR",
80 + counter: counter,
81 + length: 128
82 + }, this._ctrKey, data);
83 + return new Uint8Array(encrypted);
84 + }
85 +
86 + async _decryptCTR(data, counter) {
87 + const decrypted = await window.crypto.subtle.decrypt({
88 + name: "AES-CTR",
89 + counter: counter,
90 + length: 128
91 + }, this._ctrKey, data);
92 + return new Uint8Array(decrypted);
93 + }
94 +
95 + async _computeCMAC(data, prefixBlock) {
96 + if (prefixBlock.length !== 16) {
97 + return null;
98 + }
99 + const n = Math.floor(data.length / 16);
100 + const m = Math.ceil(data.length / 16);
101 + const r = data.length - n * 16;
102 + const cbcData = new Uint8Array((m + 1) * 16);
103 + cbcData.set(prefixBlock);
104 + cbcData.set(data, 16);
105 + if (r === 0) {
106 + for (let i = 0; i < 16; i++) {
107 + cbcData[n * 16 + i] ^= this._k1[i];
108 + }
109 + } else {
110 + cbcData[(n + 1) * 16 + r] = 0x80;
111 + for (let i = 0; i < 16; i++) {
112 + cbcData[(n + 1) * 16 + i] ^= this._k2[i];
113 + }
114 + }
115 + let cbcEncrypted = await window.crypto.subtle.encrypt({
116 + name: "AES-CBC",
117 + iv: this._zeroBlock,
118 + }, this._cbcKey, cbcData);
119 +
120 + cbcEncrypted = new Uint8Array(cbcEncrypted);
121 + const mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16);
122 + return mac;
123 + }
124 +
125 + static async importKey(key, _algorithm, _extractable, _keyUsages) {
126 + const cipher = new AESEAXCipher;
127 + await cipher._importKey(key);
128 + return cipher;
129 + }
130 +
131 + async _importKey(key) {
132 + this._rawKey = key;
133 + this._ctrKey = await window.crypto.subtle.importKey(
134 + "raw", key, {name: "AES-CTR"}, false, ["encrypt", "decrypt"]);
135 + this._cbcKey = await window.crypto.subtle.importKey(
136 + "raw", key, {name: "AES-CBC"}, false, ["encrypt"]);
137 + await this._initCMAC();
138 + }
139 +
140 + async encrypt(algorithm, message) {
141 + const ad = algorithm.additionalData;
142 + const nonce = algorithm.iv;
143 + const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
144 + const encrypted = await this._encryptCTR(message, nCMAC);
145 + const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
146 + const mac = await this._computeCMAC(encrypted, this._prefixBlock2);
147 + for (let i = 0; i < 16; i++) {
148 + mac[i] ^= nCMAC[i] ^ adCMAC[i];
149 + }
150 + const res = new Uint8Array(16 + encrypted.length);
151 + res.set(encrypted);
152 + res.set(mac, encrypted.length);
153 + return res;
154 + }
155 +
156 + async decrypt(algorithm, data) {
157 + const encrypted = data.slice(0, data.length - 16);
158 + const ad = algorithm.additionalData;
159 + const nonce = algorithm.iv;
160 + const mac = data.slice(data.length - 16);
161 + const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
162 + const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
163 + const computedMac = await this._computeCMAC(encrypted, this._prefixBlock2);
164 + for (let i = 0; i < 16; i++) {
165 + computedMac[i] ^= nCMAC[i] ^ adCMAC[i];
166 + }
167 + if (computedMac.length !== mac.length) {
168 + return null;
169 + }
170 + for (let i = 0; i < mac.length; i++) {
171 + if (computedMac[i] !== mac[i]) {
172 + return null;
173 + }
174 + }
175 + const res = await this._decryptCTR(encrypted, nCMAC);
176 + return res;
177 + }
178 +}
added public/vendor/novnc/core/crypto/bigint.js +34 −0
@@ -0,0 +1,34 @@
1 +export function modPow(b, e, m) {
2 + let r = 1n;
3 + b = b % m;
4 + while (e > 0n) {
5 + if ((e & 1n) === 1n) {
6 + r = (r * b) % m;
7 + }
8 + e = e >> 1n;
9 + b = (b * b) % m;
10 + }
11 + return r;
12 +}
13 +
14 +export function bigIntToU8Array(bigint, padLength=0) {
15 + let hex = bigint.toString(16);
16 + if (padLength === 0) {
17 + padLength = Math.ceil(hex.length / 2);
18 + }
19 + hex = hex.padStart(padLength * 2, '0');
20 + const length = hex.length / 2;
21 + const arr = new Uint8Array(length);
22 + for (let i = 0; i < length; i++) {
23 + arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
24 + }
25 + return arr;
26 +}
27 +
28 +export function u8ArrayToBigInt(arr) {
29 + let hex = '0x';
30 + for (let i = 0; i < arr.length; i++) {
31 + hex += arr[i].toString(16).padStart(2, '0');
32 + }
33 + return BigInt(hex);
34 +}
added public/vendor/novnc/core/crypto/crypto.js +90 −0
@@ -0,0 +1,90 @@
1 +import { AESECBCipher, AESEAXCipher } from "./aes.js";
2 +import { DESCBCCipher, DESECBCipher } from "./des.js";
3 +import { RSACipher } from "./rsa.js";
4 +import { DHCipher } from "./dh.js";
5 +import { MD5 } from "./md5.js";
6 +
7 +// A single interface for the cryptographic algorithms not supported by SubtleCrypto.
8 +// Both synchronous and asynchronous implmentations are allowed.
9 +class LegacyCrypto {
10 + constructor() {
11 + this._algorithms = {
12 + "AES-ECB": AESECBCipher,
13 + "AES-EAX": AESEAXCipher,
14 + "DES-ECB": DESECBCipher,
15 + "DES-CBC": DESCBCCipher,
16 + "RSA-PKCS1-v1_5": RSACipher,
17 + "DH": DHCipher,
18 + "MD5": MD5,
19 + };
20 + }
21 +
22 + encrypt(algorithm, key, data) {
23 + if (key.algorithm.name !== algorithm.name) {
24 + throw new Error("algorithm does not match");
25 + }
26 + if (typeof key.encrypt !== "function") {
27 + throw new Error("key does not support encryption");
28 + }
29 + return key.encrypt(algorithm, data);
30 + }
31 +
32 + decrypt(algorithm, key, data) {
33 + if (key.algorithm.name !== algorithm.name) {
34 + throw new Error("algorithm does not match");
35 + }
36 + if (typeof key.decrypt !== "function") {
37 + throw new Error("key does not support encryption");
38 + }
39 + return key.decrypt(algorithm, data);
40 + }
41 +
42 + importKey(format, keyData, algorithm, extractable, keyUsages) {
43 + if (format !== "raw") {
44 + throw new Error("key format is not supported");
45 + }
46 + const alg = this._algorithms[algorithm.name];
47 + if (typeof alg === "undefined" || typeof alg.importKey !== "function") {
48 + throw new Error("algorithm is not supported");
49 + }
50 + return alg.importKey(keyData, algorithm, extractable, keyUsages);
51 + }
52 +
53 + generateKey(algorithm, extractable, keyUsages) {
54 + const alg = this._algorithms[algorithm.name];
55 + if (typeof alg === "undefined" || typeof alg.generateKey !== "function") {
56 + throw new Error("algorithm is not supported");
57 + }
58 + return alg.generateKey(algorithm, extractable, keyUsages);
59 + }
60 +
61 + exportKey(format, key) {
62 + if (format !== "raw") {
63 + throw new Error("key format is not supported");
64 + }
65 + if (typeof key.exportKey !== "function") {
66 + throw new Error("key does not support exportKey");
67 + }
68 + return key.exportKey();
69 + }
70 +
71 + digest(algorithm, data) {
72 + const alg = this._algorithms[algorithm];
73 + if (typeof alg !== "function") {
74 + throw new Error("algorithm is not supported");
75 + }
76 + return alg(data);
77 + }
78 +
79 + deriveBits(algorithm, key, length) {
80 + if (key.algorithm.name !== algorithm.name) {
81 + throw new Error("algorithm does not match");
82 + }
83 + if (typeof key.deriveBits !== "function") {
84 + throw new Error("key does not support deriveBits");
85 + }
86 + return key.deriveBits(algorithm, length);
87 + }
88 +}
89 +
90 +export default new LegacyCrypto;
added public/vendor/novnc/core/crypto/des.js +330 −0
@@ -0,0 +1,330 @@
1 +/*
2 + * Ported from Flashlight VNC ActionScript implementation:
3 + * http://www.wizhelp.com/flashlight-vnc/
4 + *
5 + * Full attribution follows:
6 + *
7 + * -------------------------------------------------------------------------
8 + *
9 + * This DES class has been extracted from package Acme.Crypto for use in VNC.
10 + * The unnecessary odd parity code has been removed.
11 + *
12 + * These changes are:
13 + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
14 + *
15 + * This software is distributed in the hope that it will be useful,
16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 + *
19 +
20 + * DesCipher - the DES encryption method
21 + *
22 + * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
23 + *
24 + * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
25 + *
26 + * Permission to use, copy, modify, and distribute this software
27 + * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
28 + * without fee is hereby granted, provided that this copyright notice is kept
29 + * intact.
30 + *
31 + * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
32 + * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
33 + * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
34 + * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
35 + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
36 + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
37 + *
38 + * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
39 + * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
40 + * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
41 + * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
42 + * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
43 + * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
44 + * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
45 + * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
46 + * HIGH RISK ACTIVITIES.
47 + *
48 + *
49 + * The rest is:
50 + *
51 + * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
52 + *
53 + * Redistribution and use in source and binary forms, with or without
54 + * modification, are permitted provided that the following conditions
55 + * are met:
56 + * 1. Redistributions of source code must retain the above copyright
57 + * notice, this list of conditions and the following disclaimer.
58 + * 2. Redistributions in binary form must reproduce the above copyright
59 + * notice, this list of conditions and the following disclaimer in the
60 + * documentation and/or other materials provided with the distribution.
61 + *
62 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
63 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
66 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 + * SUCH DAMAGE.
73 + *
74 + * Visit the ACME Labs Java page for up-to-date versions of this and other
75 + * fine Java utilities: http://www.acme.com/java/
76 + */
77 +
78 +/* eslint-disable comma-spacing */
79 +
80 +// Tables, permutations, S-boxes, etc.
81 +const PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
82 + 25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
83 + 50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ],
84 + totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28];
85 +
86 +const z = 0x0;
87 +let a,b,c,d,e,f;
88 +a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e;
89 +const SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d,
90 + z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z,
91 + a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f,
92 + c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d];
93 +a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e;
94 +const SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d,
95 + a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f,
96 + z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z,
97 + z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e];
98 +a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e;
99 +const SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f,
100 + b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z,
101 + c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d,
102 + b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e];
103 +a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e;
104 +const SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d,
105 + z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f,
106 + b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e,
107 + c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e];
108 +a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e;
109 +const SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z,
110 + a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f,
111 + z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e,
112 + c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d];
113 +a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e;
114 +const SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f,
115 + z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z,
116 + b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z,
117 + a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f];
118 +a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e;
119 +const SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f,
120 + b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e,
121 + b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e,
122 + z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d];
123 +a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e;
124 +const SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d,
125 + c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z,
126 + a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f,
127 + z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e];
128 +
129 +/* eslint-enable comma-spacing */
130 +
131 +class DES {
132 + constructor(password) {
133 + this.keys = [];
134 +
135 + // Set the key.
136 + const pc1m = [], pcr = [], kn = [];
137 +
138 + for (let j = 0, l = 56; j < 56; ++j, l -= 8) {
139 + l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
140 + const m = l & 0x7;
141 + pc1m[j] = ((password[l >>> 3] & (1<<m)) !== 0) ? 1: 0;
142 + }
143 +
144 + for (let i = 0; i < 16; ++i) {
145 + const m = i << 1;
146 + const n = m + 1;
147 + kn[m] = kn[n] = 0;
148 + for (let o = 28; o < 59; o += 28) {
149 + for (let j = o - 28; j < o; ++j) {
150 + const l = j + totrot[i];
151 + pcr[j] = l < o ? pc1m[l] : pc1m[l - 28];
152 + }
153 + }
154 + for (let j = 0; j < 24; ++j) {
155 + if (pcr[PC2[j]] !== 0) {
156 + kn[m] |= 1 << (23 - j);
157 + }
158 + if (pcr[PC2[j + 24]] !== 0) {
159 + kn[n] |= 1 << (23 - j);
160 + }
161 + }
162 + }
163 +
164 + // cookey
165 + for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
166 + const raw0 = kn[rawi++];
167 + const raw1 = kn[rawi++];
168 + this.keys[KnLi] = (raw0 & 0x00fc0000) << 6;
169 + this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
170 + this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
171 + this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
172 + ++KnLi;
173 + this.keys[KnLi] = (raw0 & 0x0003f000) << 12;
174 + this.keys[KnLi] |= (raw0 & 0x0000003f) << 16;
175 + this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
176 + this.keys[KnLi] |= (raw1 & 0x0000003f);
177 + ++KnLi;
178 + }
179 + }
180 +
181 + // Encrypt 8 bytes of text
182 + enc8(text) {
183 + const b = text.slice();
184 + let i = 0, l, r, x; // left, right, accumulator
185 +
186 + // Squash 8 bytes to 2 ints
187 + l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
188 + r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
189 +
190 + x = ((l >>> 4) ^ r) & 0x0f0f0f0f;
191 + r ^= x;
192 + l ^= (x << 4);
193 + x = ((l >>> 16) ^ r) & 0x0000ffff;
194 + r ^= x;
195 + l ^= (x << 16);
196 + x = ((r >>> 2) ^ l) & 0x33333333;
197 + l ^= x;
198 + r ^= (x << 2);
199 + x = ((r >>> 8) ^ l) & 0x00ff00ff;
200 + l ^= x;
201 + r ^= (x << 8);
202 + r = (r << 1) | ((r >>> 31) & 1);
203 + x = (l ^ r) & 0xaaaaaaaa;
204 + l ^= x;
205 + r ^= x;
206 + l = (l << 1) | ((l >>> 31) & 1);
207 +
208 + for (let i = 0, keysi = 0; i < 8; ++i) {
209 + x = (r << 28) | (r >>> 4);
210 + x ^= this.keys[keysi++];
211 + let fval = SP7[x & 0x3f];
212 + fval |= SP5[(x >>> 8) & 0x3f];
213 + fval |= SP3[(x >>> 16) & 0x3f];
214 + fval |= SP1[(x >>> 24) & 0x3f];
215 + x = r ^ this.keys[keysi++];
216 + fval |= SP8[x & 0x3f];
217 + fval |= SP6[(x >>> 8) & 0x3f];
218 + fval |= SP4[(x >>> 16) & 0x3f];
219 + fval |= SP2[(x >>> 24) & 0x3f];
220 + l ^= fval;
221 + x = (l << 28) | (l >>> 4);
222 + x ^= this.keys[keysi++];
223 + fval = SP7[x & 0x3f];
224 + fval |= SP5[(x >>> 8) & 0x3f];
225 + fval |= SP3[(x >>> 16) & 0x3f];
226 + fval |= SP1[(x >>> 24) & 0x3f];
227 + x = l ^ this.keys[keysi++];
228 + fval |= SP8[x & 0x0000003f];
229 + fval |= SP6[(x >>> 8) & 0x3f];
230 + fval |= SP4[(x >>> 16) & 0x3f];
231 + fval |= SP2[(x >>> 24) & 0x3f];
232 + r ^= fval;
233 + }
234 +
235 + r = (r << 31) | (r >>> 1);
236 + x = (l ^ r) & 0xaaaaaaaa;
237 + l ^= x;
238 + r ^= x;
239 + l = (l << 31) | (l >>> 1);
240 + x = ((l >>> 8) ^ r) & 0x00ff00ff;
241 + r ^= x;
242 + l ^= (x << 8);
243 + x = ((l >>> 2) ^ r) & 0x33333333;
244 + r ^= x;
245 + l ^= (x << 2);
246 + x = ((r >>> 16) ^ l) & 0x0000ffff;
247 + l ^= x;
248 + r ^= (x << 16);
249 + x = ((r >>> 4) ^ l) & 0x0f0f0f0f;
250 + l ^= x;
251 + r ^= (x << 4);
252 +
253 + // Spread ints to bytes
254 + x = [r, l];
255 + for (i = 0; i < 8; i++) {
256 + b[i] = (x[i>>>2] >>> (8 * (3 - (i % 4)))) % 256;
257 + if (b[i] < 0) { b[i] += 256; } // unsigned
258 + }
259 + return b;
260 + }
261 +}
262 +
263 +export class DESECBCipher {
264 + constructor() {
265 + this._cipher = null;
266 + }
267 +
268 + get algorithm() {
269 + return { name: "DES-ECB" };
270 + }
271 +
272 + static importKey(key, _algorithm, _extractable, _keyUsages) {
273 + const cipher = new DESECBCipher;
274 + cipher._importKey(key);
275 + return cipher;
276 + }
277 +
278 + _importKey(key, _extractable, _keyUsages) {
279 + this._cipher = new DES(key);
280 + }
281 +
282 + encrypt(_algorithm, plaintext) {
283 + const x = new Uint8Array(plaintext);
284 + if (x.length % 8 !== 0 || this._cipher === null) {
285 + return null;
286 + }
287 + const n = x.length / 8;
288 + for (let i = 0; i < n; i++) {
289 + x.set(this._cipher.enc8(x.slice(i * 8, i * 8 + 8)), i * 8);
290 + }
291 + return x;
292 + }
293 +}
294 +
295 +export class DESCBCCipher {
296 + constructor() {
297 + this._cipher = null;
298 + }
299 +
300 + get algorithm() {
301 + return { name: "DES-CBC" };
302 + }
303 +
304 + static importKey(key, _algorithm, _extractable, _keyUsages) {
305 + const cipher = new DESCBCCipher;
306 + cipher._importKey(key);
307 + return cipher;
308 + }
309 +
310 + _importKey(key) {
311 + this._cipher = new DES(key);
312 + }
313 +
314 + encrypt(algorithm, plaintext) {
315 + const x = new Uint8Array(plaintext);
316 + let y = new Uint8Array(algorithm.iv);
317 + if (x.length % 8 !== 0 || this._cipher === null) {
318 + return null;
319 + }
320 + const n = x.length / 8;
321 + for (let i = 0; i < n; i++) {
322 + for (let j = 0; j < 8; j++) {
323 + y[j] ^= plaintext[i * 8 + j];
324 + }
325 + y = this._cipher.enc8(y);
326 + x.set(y, i * 8);
327 + }
328 + return x;
329 + }
330 +}
added public/vendor/novnc/core/crypto/dh.js +55 −0
@@ -0,0 +1,55 @@
1 +import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
2 +
3 +class DHPublicKey {
4 + constructor(key) {
5 + this._key = key;
6 + }
7 +
8 + get algorithm() {
9 + return { name: "DH" };
10 + }
11 +
12 + exportKey() {
13 + return this._key;
14 + }
15 +}
16 +
17 +export class DHCipher {
18 + constructor() {
19 + this._g = null;
20 + this._p = null;
21 + this._gBigInt = null;
22 + this._pBigInt = null;
23 + this._privateKey = null;
24 + }
25 +
26 + get algorithm() {
27 + return { name: "DH" };
28 + }
29 +
30 + static generateKey(algorithm, _extractable) {
31 + const cipher = new DHCipher;
32 + cipher._generateKey(algorithm);
33 + return { privateKey: cipher, publicKey: new DHPublicKey(cipher._publicKey) };
34 + }
35 +
36 + _generateKey(algorithm) {
37 + const g = algorithm.g;
38 + const p = algorithm.p;
39 + this._keyBytes = p.length;
40 + this._gBigInt = u8ArrayToBigInt(g);
41 + this._pBigInt = u8ArrayToBigInt(p);
42 + this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes));
43 + this._privateKeyBigInt = u8ArrayToBigInt(this._privateKey);
44 + this._publicKey = bigIntToU8Array(modPow(
45 + this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes);
46 + }
47 +
48 + deriveBits(algorithm, length) {
49 + const bytes = Math.ceil(length / 8);
50 + const pkey = new Uint8Array(algorithm.public);
51 + const len = bytes > this._keyBytes ? bytes : this._keyBytes;
52 + const secret = modPow(u8ArrayToBigInt(pkey), this._privateKeyBigInt, this._pBigInt);
53 + return bigIntToU8Array(secret, len).slice(0, len);
54 + }
55 +}
added public/vendor/novnc/core/crypto/md5.js +82 −0
@@ -0,0 +1,82 @@
1 +/*
2 + * noVNC: HTML5 VNC client
3 + * Copyright (C) 2021 The noVNC authors
4 + * Licensed under MPL 2.0 (see LICENSE.txt)
5 + *
6 + * See README.md for usage and integration instructions.
7 + */
8 +
9 +/*
10 + * Performs MD5 hashing on an array of bytes, returns an array of bytes
11 + */
12 +
13 +export async function MD5(d) {
14 + let s = "";
15 + for (let i = 0; i < d.length; i++) {
16 + s += String.fromCharCode(d[i]);
17 + }
18 + return M(V(Y(X(s), 8 * s.length)));
19 +}
20 +
21 +function M(d) {
22 + let f = new Uint8Array(d.length);
23 + for (let i=0;i<d.length;i++) {
24 + f[i] = d.charCodeAt(i);
25 + }
26 + return f;
27 +}
28 +
29 +function X(d) {
30 + let r = Array(d.length >> 2);
31 + for (let m = 0; m < r.length; m++) r[m] = 0;
32 + for (let m = 0; m < 8 * d.length; m += 8) r[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32;
33 + return r;
34 +}
35 +
36 +function V(d) {
37 + let r = "";
38 + for (let m = 0; m < 32 * d.length; m += 8) r += String.fromCharCode(d[m >> 5] >>> m % 32 & 255);
39 + return r;
40 +}
41 +
42 +function Y(d, g) {
43 + d[g >> 5] |= 128 << g % 32, d[14 + (g + 64 >>> 9 << 4)] = g;
44 + let m = 1732584193, f = -271733879, r = -1732584194, i = 271733878;
45 + for (let n = 0; n < d.length; n += 16) {
46 + let h = m,
47 + t = f,
48 + g = r,
49 + e = i;
50 + f = ii(f = ii(f = ii(f = ii(f = hh(f = hh(f = hh(f = hh(f = gg(f = gg(f = gg(f = gg(f = ff(f = ff(f = ff(f = ff(f, r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = add(m, h), f = add(f, t), r = add(r, g), i = add(i, e);
51 + }
52 + return Array(m, f, r, i);
53 +}
54 +
55 +function cmn(d, g, m, f, r, i) {
56 + return add(rol(add(add(g, d), add(f, i)), r), m);
57 +}
58 +
59 +function ff(d, g, m, f, r, i, n) {
60 + return cmn(g & m | ~g & f, d, g, r, i, n);
61 +}
62 +
63 +function gg(d, g, m, f, r, i, n) {
64 + return cmn(g & f | m & ~f, d, g, r, i, n);
65 +}
66 +
67 +function hh(d, g, m, f, r, i, n) {
68 + return cmn(g ^ m ^ f, d, g, r, i, n);
69 +}
70 +
71 +function ii(d, g, m, f, r, i, n) {
72 + return cmn(m ^ (g | ~f), d, g, r, i, n);
73 +}
74 +
75 +function add(d, g) {
76 + let m = (65535 & d) + (65535 & g);
77 + return (d >> 16) + (g >> 16) + (m >> 16) << 16 | 65535 & m;
78 +}
79 +
80 +function rol(d, g) {
81 + return d << g | d >>> 32 - g;
82 +}
added public/vendor/novnc/core/crypto/rsa.js +132 −0
@@ -0,0 +1,132 @@
1 +import Base64 from "../base64.js";
2 +import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
3 +
4 +export class RSACipher {
5 + constructor() {
6 + this._keyLength = 0;
7 + this._keyBytes = 0;
8 + this._n = null;
9 + this._e = null;
10 + this._d = null;
11 + this._nBigInt = null;
12 + this._eBigInt = null;
13 + this._dBigInt = null;
14 + this._extractable = false;
15 + }
16 +
17 + get algorithm() {
18 + return { name: "RSA-PKCS1-v1_5" };
19 + }
20 +
21 + _base64urlDecode(data) {
22 + data = data.replace(/-/g, "+").replace(/_/g, "/");
23 + data = data.padEnd(Math.ceil(data.length / 4) * 4, "=");
24 + return Base64.decode(data);
25 + }
26 +
27 + _padArray(arr, length) {
28 + const res = new Uint8Array(length);
29 + res.set(arr, length - arr.length);
30 + return res;
31 + }
32 +
33 + static async generateKey(algorithm, extractable, _keyUsages) {
34 + const cipher = new RSACipher;
35 + await cipher._generateKey(algorithm, extractable);
36 + return { privateKey: cipher };
37 + }
38 +
39 + async _generateKey(algorithm, extractable) {
40 + this._keyLength = algorithm.modulusLength;
41 + this._keyBytes = Math.ceil(this._keyLength / 8);
42 + const key = await window.crypto.subtle.generateKey(
43 + {
44 + name: "RSA-OAEP",
45 + modulusLength: algorithm.modulusLength,
46 + publicExponent: algorithm.publicExponent,
47 + hash: {name: "SHA-256"},
48 + },
49 + true, ["encrypt", "decrypt"]);
50 + const privateKey = await window.crypto.subtle.exportKey("jwk", key.privateKey);
51 + this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes);
52 + this._nBigInt = u8ArrayToBigInt(this._n);
53 + this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes);
54 + this._eBigInt = u8ArrayToBigInt(this._e);
55 + this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes);
56 + this._dBigInt = u8ArrayToBigInt(this._d);
57 + this._extractable = extractable;
58 + }
59 +
60 + static async importKey(key, _algorithm, extractable, keyUsages) {
61 + if (keyUsages.length !== 1 || keyUsages[0] !== "encrypt") {
62 + throw new Error("only support importing RSA public key");
63 + }
64 + const cipher = new RSACipher;
65 + await cipher._importKey(key, extractable);
66 + return cipher;
67 + }
68 +
69 + async _importKey(key, extractable) {
70 + const n = key.n;
71 + const e = key.e;
72 + if (n.length !== e.length) {
73 + throw new Error("the sizes of modulus and public exponent do not match");
74 + }
75 + this._keyBytes = n.length;
76 + this._keyLength = this._keyBytes * 8;
77 + this._n = new Uint8Array(this._keyBytes);
78 + this._e = new Uint8Array(this._keyBytes);
79 + this._n.set(n);
80 + this._e.set(e);
81 + this._nBigInt = u8ArrayToBigInt(this._n);
82 + this._eBigInt = u8ArrayToBigInt(this._e);
83 + this._extractable = extractable;
84 + }
85 +
86 + async encrypt(_algorithm, message) {
87 + if (message.length > this._keyBytes - 11) {
88 + return null;
89 + }
90 + const ps = new Uint8Array(this._keyBytes - message.length - 3);
91 + window.crypto.getRandomValues(ps);
92 + for (let i = 0; i < ps.length; i++) {
93 + ps[i] = Math.floor(ps[i] * 254 / 255 + 1);
94 + }
95 + const em = new Uint8Array(this._keyBytes);
96 + em[1] = 0x02;
97 + em.set(ps, 2);
98 + em.set(message, ps.length + 3);
99 + const emBigInt = u8ArrayToBigInt(em);
100 + const c = modPow(emBigInt, this._eBigInt, this._nBigInt);
101 + return bigIntToU8Array(c, this._keyBytes);
102 + }
103 +
104 + async decrypt(_algorithm, message) {
105 + if (message.length !== this._keyBytes) {
106 + return null;
107 + }
108 + const msgBigInt = u8ArrayToBigInt(message);
109 + const emBigInt = modPow(msgBigInt, this._dBigInt, this._nBigInt);
110 + const em = bigIntToU8Array(emBigInt, this._keyBytes);
111 + if (em[0] !== 0x00 || em[1] !== 0x02) {
112 + return null;
113 + }
114 + let i = 2;
115 + for (; i < em.length; i++) {
116 + if (em[i] === 0x00) {
117 + break;
118 + }
119 + }
120 + if (i === em.length) {
121 + return null;
122 + }
123 + return em.slice(i + 1, em.length);
124 + }
125 +
126 + async exportKey() {
127 + if (!this._extractable) {
128 + throw new Error("key is not extractable");
129 + }
130 + return { n: this._n, e: this._e, d: this._d };
131 + }
132 +}
added public/vendor/novnc/core/decoders/copyrect.js +27 −0
@@ -0,0 +1,27 @@
1 +/*
2 + * noVNC: HTML5 VNC client
3 + * Copyright (C) 2019 The noVNC authors
4 + * Licensed under MPL 2.0 (see LICENSE.txt)
5 + *
6 + * See README.md for usage and integration instructions.
7 + *
8 + */
9 +
10 +export default class CopyRectDecoder {
11 + decodeRect(x, y, width, height, sock, display, depth) {
12 + if (sock.rQwait("COPYRECT", 4)) {
13 + return false;
14 + }
15 +
16 + let deltaX = sock.rQshift16();
17 + let deltaY = sock.rQshift16();
18 +
19 + if ((width === 0) || (height === 0)) {
20 + return true;
21 + }
22 +
23 + display.copyImage(deltaX, deltaY, x, y, width, height);
24 +
25 + return true;
26 + }
27 +}
added public/vendor/novnc/core/decoders/h264.js +321 −0
@@ -0,0 +1,321 @@
1 +/*
2 + * noVNC: HTML5 VNC client
3 + * Copyright (C) 2024 The noVNC authors
4 + * Licensed under MPL 2.0 (see LICENSE.txt)
5 + *
6 + * See README.md for usage and integration instructions.
7 + *
8 + */
9 +
10 +import * as Log from '../util/logging.js';
11 +
12 +export class H264Parser {
13 + constructor(data) {
14 + this._data = data;
15 + this._index = 0;
16 + this.profileIdc = null;
17 + this.constraintSet = null;
18 + this.levelIdc = null;
19 + }
20 +
21 + _getStartSequenceLen(index) {
22 + let data = this._data;
23 + if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 0 && data[index + 3] == 1) {
24 + return 4;
25 + }
26 + if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 1) {
27 + return 3;
28 + }
29 + return 0;
30 + }
31 +
32 + _indexOfNextNalUnit(index) {
33 + let data = this._data;
34 + for (let i = index; i < data.length; ++i) {
35 + if (this._getStartSequenceLen(i) != 0) {
36 + return i;
37 + }
38 + }
39 + return -1;
40 + }
41 +
42 + _parseSps(index) {
43 + this.profileIdc = this._data[index];
44 + this.constraintSet = this._data[index + 1];
45 + this.levelIdc = this._data[index + 2];
46 + }
47 +
48 + _parseNalUnit(index) {
49 + const firstByte = this._data[index];
50 + if (firstByte & 0x80) {
51 + throw new Error('H264 parsing sanity check failed, forbidden zero bit is set');
52 + }
53 + const unitType = firstByte & 0x1f;
54 +
55 + switch (unitType) {
56 + case 1: // coded slice, non-idr
57 + return { slice: true };
58 + case 5: // coded slice, idr
59 + return { slice: true, key: true };
60 + case 6: // sei
61 + return {};
62 + case 7: // sps
63 + this._parseSps(index + 1);
64 + return {};
65 + case 8: // pps
66 + return {};
67 + default:
68 + Log.Warn("Unhandled unit type: ", unitType);
69 + break;
70 + }
71 + return {};
72 + }
73 +
74 + parse() {
75 + const startIndex = this._index;
76 + let isKey = false;
77 +
78 + while (this._index < this._data.length) {
79 + const startSequenceLen = this._getStartSequenceLen(this._index);
80 + if (startSequenceLen == 0) {
81 + throw new Error('Invalid start sequence in bit stream');
82 + }
83 +
84 + const { slice, key } = this._parseNalUnit(this._index + startSequenceLen);
85 +
86 + let nextIndex = this._indexOfNextNalUnit(this._index + startSequenceLen);
87 + if (nextIndex == -1) {
88 + this._index = this._data.length;
89 + } else {
90 + this._index = nextIndex;
91 + }
92 +
93 + if (key) {
94 + isKey = true;
95 + }
96 + if (slice) {
97 + break;
98 + }
99 + }
100 +
101 + if (startIndex === this._index) {
102 + return null;
103 + }
104 +
105 + return {
106 + frame: this._data.subarray(startIndex, this._index),
107 + key: isKey,
108 + };
109 + }
110 +}
111 +
112 +export class H264Context {
113 + constructor(width, height) {
114 + this.lastUsed = 0;
115 + this._width = width;
116 + this._height = height;
117 + this._profileIdc = null;
118 + this._constraintSet = null;
119 + this._levelIdc = null;
120 + this._decoder = null;
121 + this._pendingFrames = [];
122 + }
123 +
124 + _handleFrame(frame) {
125 + let pending = this._pendingFrames.shift();
126 + if (pending === undefined) {
127 + throw new Error("Pending frame queue empty when receiving frame from decoder");
128 + }
129 +
130 + if (pending.timestamp != frame.timestamp) {
131 + throw new Error("Video frame timestamp mismatch. Expected " +
132 + frame.timestamp + " but but got " + pending.timestamp);
133 + }
134 +
135 + pending.frame = frame;
136 + pending.ready = true;
137 + pending.resolve();
138 +
139 + if (!pending.keep) {
140 + frame.close();
141 + }
142 + }
143 +
144 + _handleError(e) {
145 + throw new Error("Failed to decode frame: " + e.message);
146 + }
147 +
148 + _configureDecoder(profileIdc, constraintSet, levelIdc) {
149 + if (this._decoder === null || this._decoder.state === 'closed') {
150 + this._decoder = new VideoDecoder({
151 + output: frame => this._handleFrame(frame),
152 + error: e => this._handleError(e),
153 + });
154 + }
155 + const codec = 'avc1.' +
156 + profileIdc.toString(16).padStart(2, '0') +
157 + constraintSet.toString(16).padStart(2, '0') +
158 + levelIdc.toString(16).padStart(2, '0');
159 + this._decoder.configure({
160 + codec: codec,
161 + codedWidth: this._width,
162 + codedHeight: this._height,
163 + optimizeForLatency: true,
164 + });
165 + }
166 +
167 + _preparePendingFrame(timestamp) {
168 + let pending = {
169 + timestamp: timestamp,
170 + promise: null,
171 + resolve: null,
172 + frame: null,
173 + ready: false,
174 + keep: false,
175 + };
176 + pending.promise = new Promise((resolve) => {
177 + pending.resolve = resolve;
178 + });
179 + this._pendingFrames.push(pending);
180 +
181 + return pending;
182 + }
183 +
184 + decode(payload) {
185 + let parser = new H264Parser(payload);
186 + let result = null;
187 +
188 + // Ideally, this timestamp should come from the server, but we'll just
189 + // approximate it instead.
190 + let timestamp = Math.round(window.performance.now() * 1e3);
191 +
192 + while (true) {
193 + let encodedFrame = parser.parse();
194 + if (encodedFrame === null) {
195 + break;
196 + }
197 +
198 + if (parser.profileIdc !== null) {
199 + self._profileIdc = parser.profileIdc;
200 + self._constraintSet = parser.constraintSet;
201 + self._levelIdc = parser.levelIdc;
202 + }
203 +
204 + if (this._decoder === null || this._decoder.state !== 'configured') {
205 + if (!encodedFrame.key) {
206 + Log.Warn("Missing key frame. Can't decode until one arrives");
207 + continue;
208 + }
209 + if (self._profileIdc === null) {
210 + Log.Warn('Cannot config decoder. Have not received SPS and PPS yet.');
211 + continue;
212 + }
213 + this._configureDecoder(self._profileIdc, self._constraintSet,
214 + self._levelIdc);
215 + }
216 +
217 + result = this._preparePendingFrame(timestamp);
218 +
219 + const chunk = new EncodedVideoChunk({
220 + timestamp: timestamp,
221 + type: encodedFrame.key ? 'key' : 'delta',
222 + data: encodedFrame.frame,
223 + });
224 +
225 + try {
226 + this._decoder.decode(chunk);
227 + } catch (e) {
228 + Log.Warn("Failed to decode:", e);
229 + }
230 + }
231 +
232 + // We only keep last frame of each payload
233 + if (result !== null) {
234 + result.keep = true;
235 + }
236 +
237 + return result;
238 + }
239 +}
240 +
241 +export default class H264Decoder {
242 + constructor() {
243 + this._tick = 0;
244 + this._contexts = {};
245 + }
246 +
247 + _contextId(x, y, width, height) {
248 + return [x, y, width, height].join(',');
249 + }
250 +
251 + _findOldestContextId() {
252 + let oldestTick = Number.MAX_VALUE;
253 + let oldestKey = undefined;
254 + for (const [key, value] of Object.entries(this._contexts)) {
255 + if (value.lastUsed < oldestTick) {
256 + oldestTick = value.lastUsed;
257 + oldestKey = key;
258 + }
259 + }
260 + return oldestKey;
261 + }
262 +
263 + _createContext(x, y, width, height) {
264 + const maxContexts = 64;
265 + if (Object.keys(this._contexts).length >= maxContexts) {
266 + let oldestContextId = this._findOldestContextId();
267 + delete this._contexts[oldestContextId];
268 + }
269 + let context = new H264Context(width, height);
270 + this._contexts[this._contextId(x, y, width, height)] = context;
271 + return context;
272 + }
273 +
274 + _getContext(x, y, width, height) {
275 + let context = this._contexts[this._contextId(x, y, width, height)];
276 + return context !== undefined ? context : this._createContext(x, y, width, height);
277 + }
278 +
279 + _resetContext(x, y, width, height) {
280 + delete this._contexts[this._contextId(x, y, width, height)];
281 + }
282 +
283 + _resetAllContexts() {
284 + this._contexts = {};
285 + }
286 +
287 + decodeRect(x, y, width, height, sock, display, depth) {
288 + const resetContextFlag = 1;
289 + const resetAllContextsFlag = 2;
290 +
291 + if (sock.rQwait("h264 header", 8)) {
292 + return false;
293 + }
294 +
295 + const length = sock.rQshift32();
296 + const flags = sock.rQshift32();
297 +
298 + if (sock.rQwait("h264 payload", length, 8)) {
299 + return false;
300 + }
301 +
302 + if (flags & resetAllContextsFlag) {
303 + this._resetAllContexts();
304 + } else if (flags & resetContextFlag) {
305 + this._resetContext(x, y, width, height);
306 + }
307 +
308 + let context = this._getContext(x, y, width, height);
309 + context.lastUsed = this._tick++;
310 +
311 + if (length !== 0) {
312 + let payload = sock.rQshiftBytes(length, false);
313 + let frame = context.decode(payload);
314 + if (frame !== null) {
315 + display.videoFrame(x, y, width, height, frame);
316 + }
317 + }
318 +
319 + return true;
320 + }
321 +}
added public/vendor/novnc/core/decoders/hextile.js +181 −0
@@ -0,0 +1,181 @@
1 +/*
2 + * noVNC: HTML5 VNC client
3 + * Copyright (C) 2019 The noVNC authors
4 + * Licensed under MPL 2.0 (see LICENSE.txt)
5 + *
6 + * See README.md for usage and integration instructions.
7 + *
8 + */
9 +
10 +import * as Log from '../util/logging.js';
11 +
12 +export default class HextileDecoder {
13 + constructor() {
14 + this._tiles = 0;
15 + this._lastsubencoding = 0;
16 + this._tileBuffer = new Uint8Array(16 * 16 * 4);
17 + }
18 +
19 + decodeRect(x, y, width, height, sock, display, depth) {
20 + if (this._tiles === 0) {
21 + this._tilesX = Math.ceil(width / 16);
22 + this._tilesY = Math.ceil(height / 16);
23 + this._totalTiles = this._tilesX * this._tilesY;
24 + this._tiles = this._totalTiles;
25 + }
26 +
27 + while (this._tiles > 0) {
28 + let bytes = 1;
29 +
30 + if (sock.rQwait("HEXTILE", bytes)) {
31 + return false;
32 + }
33 +
34 + let subencoding = sock.rQpeek8();
35 + if (subencoding > 30) { // Raw
36 + throw new Error("Illegal hextile subencoding (subencoding: " +
37 + subencoding + ")");
38 + }
39 +
40 + const currTile = this._totalTiles - this._tiles;
41 + const tileX = currTile % this._tilesX;
42 + const tileY = Math.floor(currTile / this._tilesX);
43 + const tx = x + tileX * 16;
44 + const ty = y + tileY * 16;
45 + const tw = Math.min(16, (x + width) - tx);
46 + const th = Math.min(16, (y + height) - ty);
47 +
48 + // Figure out how much we are expecting
49 + if (subencoding & 0x01) { // Raw
50 + bytes += tw * th * 4;
51 + } else {
52 + if (subencoding & 0x02) { // Background
53 + bytes += 4;
54 + }
55 + if (subencoding & 0x04) { // Foreground
56 + bytes += 4;
57 + }
58 + if (subencoding & 0x08) { // AnySubrects
59 + bytes++; // Since we aren't shifting it off
60 +
61 + if (sock.rQwait("HEXTILE", bytes)) {
62 + return false;
63 + }
64 +
65 + let subrects = sock.rQpeekBytes(bytes).at(-1);
66 + if (subencoding & 0x10) { // SubrectsColoured
67 + bytes += subrects * (4 + 2);
68 + } else {
69 + bytes += subrects * 2;
70 + }
71 + }
72 + }
73 +
74 + if (sock.rQwait("HEXTILE", bytes)) {
75 + return false;
76 + }
77 +
78 + // We know the encoding and have a whole tile
79 + sock.rQshift8();
80 + if (subencoding === 0) {
81 + if (this._lastsubencoding & 0x01) {
82 + // Weird: ignore blanks are RAW
83 + Log.Debug(" Ignoring blank after RAW");
84 + } else {
85 + display.fillRect(tx, ty, tw, th, this._background);
86 + }
87 + } else if (subencoding & 0x01) { // Raw
88 + let pixels = tw * th;
89 + let data = sock.rQshiftBytes(pixels * 4, false);
90 + // Max sure the image is fully opaque
91 + for (let i = 0;i < pixels;i++) {
92 + data[i * 4 + 3] = 255;
93 + }
94 + display.blitImage(tx, ty, tw, th, data, 0);
95 + } else {
96 + if (subencoding & 0x02) { // Background
97 + this._background = new Uint8Array(sock.rQshiftBytes(4));
98 + }
99 + if (subencoding & 0x04) { // Foreground
100 + this._foreground = new Uint8Array(sock.rQshiftBytes(4));
101 + }
102 +
103 + this._startTile(tx, ty, tw, th, this._background);
104 + if (subencoding & 0x08) { // AnySubrects
105 + let subrects = sock.rQshift8();
106 +
107 + for (let s = 0; s < subrects; s++) {
108 + let color;
109 + if (subencoding & 0x10) { // SubrectsColoured
110 + color = sock.rQshiftBytes(4);
111 + } else {
112 + color = this._foreground;
113 + }
114 + const xy = sock.rQshift8();
115 + const sx = (xy >> 4);
116 + const sy = (xy & 0x0f);
117 +
118 + const wh = sock.rQshift8();
119 + const sw = (wh >> 4) + 1;
120 + const sh = (wh & 0x0f) + 1;
121 +
122 + this._subTile(sx, sy, sw, sh, color);
123 + }
124 + }
125 + this._finishTile(display);
126 + }
127 + this._lastsubencoding = subencoding;
128 + this._tiles--;
129 + }
130 +
131 + return true;
132 + }
133 +
134 + // start updating a tile
135 + _startTile(x, y, width, height, color) {
136 + this._tileX = x;
137 + this._tileY = y;
138 + this._tileW = width;
139 + this._tileH = height;
140 +
141 + const red = color[0];
142 + const green = color[1];
143 + const blue = color[2];
144 +
145 + const data = this._tileBuffer;
146 + for (let i = 0; i < width * height * 4; i += 4) {
147 + data[i] = red;
148 + data[i + 1] = green;
149 + data[i + 2] = blue;
150 + data[i + 3] = 255;
151 + }
152 + }
153 +
154 + // update sub-rectangle of the current tile
155 + _subTile(x, y, w, h, color) {
156 + const red = color[0];
157 + const green = color[1];
158 + const blue = color[2];
159 + const xend = x + w;
160 + const yend = y + h;
161 +
162 + const data = this._tileBuffer;
163 + const width = this._tileW;
164 + for (let j = y; j < yend; j++) {
165 + for (let i = x; i < xend; i++) {
166 + const p = (i + (j * width)) * 4;
167 + data[p] = red;
168 + data[p + 1] = green;
169 + data[p + 2] = blue;
170 + data[p + 3] = 255;
171 + }
172 + }
173 + }
174 +
175 + // draw the current tile to the screen
176 + _finishTile(display) {
177 + display.blitImage(this._tileX, this._tileY,
178 + this._tileW, this._tileH,
179 + this._tileBuffer, 0);
180 + }
181 +}
added public/vendor/novnc/core/decoders/jpeg.js +146 −0
Large diff (146 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/raw.js +59 −0
Large diff (59 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/rre.js +44 −0
Large diff (44 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/tight.js +393 −0
Large diff (393 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/tightpng.js +27 −0
Large diff (27 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/zlib.js +51 −0
Large diff (51 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/decoders/zrle.js +185 −0
Large diff (185 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/deflator.js +84 −0
Large diff (84 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/display.js +575 −0
Large diff (575 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/encodings.js +54 −0
Large diff (54 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/inflator.js +65 −0
Large diff (65 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/domkeytable.js +311 −0
Large diff (311 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/fixedkeys.js +129 −0
Large diff (129 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/gesturehandler.js +567 −0
Large diff (567 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/keyboard.js +294 −0
Large diff (294 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/keysym.js +616 −0
Large diff (616 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/keysymdef.js +688 −0
Large diff (688 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/util.js +191 −0
Large diff (191 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/vkeys.js +116 −0
Large diff (116 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/input/xtscancodes.js +173 −0
Large diff (173 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/ra2.js +312 −0
Large diff (312 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/rfb.js +3415 −0
Large diff (3,415 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/browser.js +233 −0
Large diff (233 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/cursor.js +249 −0
Large diff (249 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/element.js +32 −0
Large diff (32 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/events.js +138 −0
Large diff (138 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/eventtarget.js +35 −0
Large diff (35 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/int.js +15 −0
Large diff (15 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/logging.js +56 −0
Large diff (56 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/util/strings.js +28 −0
Large diff (28 lines) is not loaded by default to keep the page fast.Load diff
added public/vendor/novnc/core/websock.js +365 −0
Large diff (365 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/aes.js +0 −481
Large diff (482 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/bigint.js +0 −41
Large diff (42 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/crypto.js +0 −109
Large diff (110 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/des.js +0 −374
Large diff (375 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/dh.js +0 −81
Large diff (82 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/md5.js +0 −97
Large diff (98 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/crypto/rsa.js +0 −312
Large diff (313 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/copyrect.js +0 −40
Large diff (41 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/h264.js +0 −349
Large diff (350 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/hextile.js +0 −195
Large diff (196 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/jpeg.js +0 −175
Large diff (176 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/raw.js +0 −66
Large diff (67 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/rre.js +0 −52
Large diff (53 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/tight.js +0 −363
Large diff (364 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/tightpng.js +0 −51
Large diff (52 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/zlib.js +0 −57
Large diff (58 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/decoders/zrle.js +0 −192
Large diff (193 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/deflator.js +0 −88
Large diff (89 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/display.js +0 −588
Large diff (589 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/encodings.js +0 −70
Large diff (71 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/inflator.js +0 −77
Large diff (78 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/domkeytable.js +0 −313
Large diff (314 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/fixedkeys.js +0 −127
Large diff (128 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/gesturehandler.js +0 −573
Large diff (574 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/keyboard.js +0 −293
Large diff (294 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/keysym.js +0 −878
Large diff (879 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/keysymdef.js +0 −1351
Large diff (1,352 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/util.js +0 −217
Large diff (218 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/vkeys.js +0 −121
Large diff (122 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/input/xtscancodes.js +0 −343
Large diff (344 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/ra2.js +0 −535
Large diff (536 lines) is not loaded by default to keep the page fast.Load diff
deleted public/vendor/novnc/rfb.js +0 −104
Large diff (104 lines) is not loaded by default to keep the page fast.Load diff

Diff truncated — file too large.

Menu

Theme