@novnc/novnc 1.3.0-g42ec5f3 → 1.3.0-g4cfe0ff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/display.js +12 -0
- package/core/input/keyboard.js +10 -0
- package/core/rfb.js +195 -86
- package/docs/API.md +61 -0
- package/lib/base64.js +19 -33
- package/lib/decoders/copyrect.js +0 -10
- package/lib/decoders/hextile.js +12 -44
- package/lib/decoders/jpeg.js +0 -42
- package/lib/decoders/raw.js +4 -20
- package/lib/decoders/rre.js +0 -14
- package/lib/decoders/tight.js +8 -76
- package/lib/decoders/tightpng.js +2 -24
- package/lib/decoders/zrle.js +2 -51
- package/lib/deflator.js +4 -21
- package/lib/des.js +19 -35
- package/lib/display.js +57 -105
- package/lib/encodings.js +1 -10
- package/lib/inflator.js +1 -17
- package/lib/input/domkeytable.js +77 -48
- package/lib/input/fixedkeys.js +8 -3
- package/lib/input/gesturehandler.js +81 -151
- package/lib/input/keyboard.js +57 -88
- package/lib/input/keysym.js +14 -270
- package/lib/input/keysymdef.js +5 -7
- package/lib/input/util.js +42 -84
- package/lib/input/vkeys.js +0 -3
- package/lib/input/xtscancodes.js +1 -168
- package/lib/ra2.js +37 -261
- package/lib/rfb.js +466 -1005
- package/lib/util/browser.js +16 -25
- package/lib/util/cursor.js +20 -64
- package/lib/util/element.js +3 -5
- package/lib/util/events.js +23 -30
- package/lib/util/eventtarget.js +0 -12
- package/lib/util/int.js +1 -2
- package/lib/util/logging.js +1 -19
- package/lib/util/md5.js +7 -27
- package/lib/util/strings.js +3 -5
- package/lib/vendor/pako/lib/utils/common.js +8 -17
- package/lib/vendor/pako/lib/zlib/adler32.js +3 -7
- package/lib/vendor/pako/lib/zlib/constants.js +2 -5
- package/lib/vendor/pako/lib/zlib/crc32.js +5 -12
- package/lib/vendor/pako/lib/zlib/deflate.js +212 -617
- package/lib/vendor/pako/lib/zlib/gzheader.js +1 -13
- package/lib/vendor/pako/lib/zlib/inffast.js +60 -176
- package/lib/vendor/pako/lib/zlib/inflate.js +397 -887
- package/lib/vendor/pako/lib/zlib/inftrees.js +62 -168
- package/lib/vendor/pako/lib/zlib/messages.js +1 -11
- package/lib/vendor/pako/lib/zlib/trees.js +245 -587
- package/lib/vendor/pako/lib/zlib/zstream.js +2 -18
- package/lib/websock.js +31 -84
- package/package.json +1 -1
- package/core/util/bigint-mod-arith.js +0 -283
- package/lib/util/bigint-mod-arith.js +0 -339
package/core/display.js
CHANGED
|
@@ -224,6 +224,18 @@ export default class Display {
|
|
|
224
224
|
this.viewportChangePos(0, 0);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
getImageData() {
|
|
228
|
+
return this._drawCtx.getImageData(0, 0, this.width, this.height);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
toDataURL(type, encoderOptions) {
|
|
232
|
+
return this._backbuffer.toDataURL(type, encoderOptions);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
toBlob(callback, type, quality) {
|
|
236
|
+
return this._backbuffer.toBlob(callback, type, quality);
|
|
237
|
+
}
|
|
238
|
+
|
|
227
239
|
// Track what parts of the visible canvas that need updating
|
|
228
240
|
_damage(x, y, w, h) {
|
|
229
241
|
if (x < this._damageBounds.left) {
|
package/core/input/keyboard.js
CHANGED
|
@@ -153,6 +153,16 @@ export default class Keyboard {
|
|
|
153
153
|
keysym = this._keyDownList[code];
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// macOS doesn't send proper key releases if a key is pressed
|
|
157
|
+
// while meta is held down
|
|
158
|
+
if ((browser.isMac() || browser.isIOS()) &&
|
|
159
|
+
(e.metaKey && code !== 'MetaLeft' && code !== 'MetaRight')) {
|
|
160
|
+
this._sendKeyEvent(keysym, code, true);
|
|
161
|
+
this._sendKeyEvent(keysym, code, false);
|
|
162
|
+
stopEvent(e);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
156
166
|
// macOS doesn't send proper key events for modifiers, only
|
|
157
167
|
// state change events. That gets extra confusing for CapsLock
|
|
158
168
|
// which toggles on each press, but not on release. So pretend
|
package/core/rfb.js
CHANGED
|
@@ -27,7 +27,6 @@ import XtScancode from "./input/xtscancodes.js";
|
|
|
27
27
|
import { encodings } from "./encodings.js";
|
|
28
28
|
import RSAAESAuthenticationState from "./ra2.js";
|
|
29
29
|
import { MD5 } from "./util/md5.js";
|
|
30
|
-
import { modPow } from "./util/bigint-mod-arith.js";
|
|
31
30
|
|
|
32
31
|
import RawDecoder from "./decoders/raw.js";
|
|
33
32
|
import CopyRectDecoder from "./decoders/copyrect.js";
|
|
@@ -55,6 +54,21 @@ const GESTURE_SCRLSENS = 50;
|
|
|
55
54
|
const DOUBLE_TAP_TIMEOUT = 1000;
|
|
56
55
|
const DOUBLE_TAP_THRESHOLD = 50;
|
|
57
56
|
|
|
57
|
+
// Security types
|
|
58
|
+
const securityTypeNone = 1;
|
|
59
|
+
const securityTypeVNCAuth = 2;
|
|
60
|
+
const securityTypeRA2ne = 6;
|
|
61
|
+
const securityTypeTight = 16;
|
|
62
|
+
const securityTypeVeNCrypt = 19;
|
|
63
|
+
const securityTypeXVP = 22;
|
|
64
|
+
const securityTypeARD = 30;
|
|
65
|
+
|
|
66
|
+
// Special Tight security types
|
|
67
|
+
const securityTypeUnixLogon = 129;
|
|
68
|
+
|
|
69
|
+
// VeNCrypt security types
|
|
70
|
+
const securityTypePlain = 256;
|
|
71
|
+
|
|
58
72
|
// Extended clipboard pseudo-encoding formats
|
|
59
73
|
const extendedClipboardFormatText = 1;
|
|
60
74
|
/*eslint-disable no-unused-vars */
|
|
@@ -80,6 +94,12 @@ export default class RFB extends EventTargetMixin {
|
|
|
80
94
|
throw new Error("Must specify URL, WebSocket or RTCDataChannel");
|
|
81
95
|
}
|
|
82
96
|
|
|
97
|
+
// We rely on modern APIs which might not be available in an
|
|
98
|
+
// insecure context
|
|
99
|
+
if (!window.isSecureContext) {
|
|
100
|
+
Log.Error("noVNC requires a secure context (TLS). Expect crashes!");
|
|
101
|
+
}
|
|
102
|
+
|
|
83
103
|
super();
|
|
84
104
|
|
|
85
105
|
this._target = target;
|
|
@@ -397,7 +417,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
397
417
|
|
|
398
418
|
sendCredentials(creds) {
|
|
399
419
|
this._rfbCredentials = creds;
|
|
400
|
-
|
|
420
|
+
this._resumeAuthentication();
|
|
401
421
|
}
|
|
402
422
|
|
|
403
423
|
sendCtrlAltDel() {
|
|
@@ -470,16 +490,45 @@ export default class RFB extends EventTargetMixin {
|
|
|
470
490
|
this._clipboardText = text;
|
|
471
491
|
RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]);
|
|
472
492
|
} else {
|
|
473
|
-
let
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
493
|
+
let length, i;
|
|
494
|
+
let data;
|
|
495
|
+
|
|
496
|
+
length = 0;
|
|
497
|
+
// eslint-disable-next-line no-unused-vars
|
|
498
|
+
for (let codePoint of text) {
|
|
499
|
+
length++;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
data = new Uint8Array(length);
|
|
503
|
+
|
|
504
|
+
i = 0;
|
|
505
|
+
for (let codePoint of text) {
|
|
506
|
+
let code = codePoint.codePointAt(0);
|
|
507
|
+
|
|
508
|
+
/* Only ISO 8859-1 is supported */
|
|
509
|
+
if (code > 0xff) {
|
|
510
|
+
code = 0x3f; // '?'
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
data[i++] = code;
|
|
477
514
|
}
|
|
478
515
|
|
|
479
516
|
RFB.messages.clientCutText(this._sock, data);
|
|
480
517
|
}
|
|
481
518
|
}
|
|
482
519
|
|
|
520
|
+
getImageData() {
|
|
521
|
+
return this._display.getImageData();
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
toDataURL(type, encoderOptions) {
|
|
525
|
+
return this._display.toDataURL(type, encoderOptions);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
toBlob(callback, type, quality) {
|
|
529
|
+
return this._display.toBlob(callback, type, quality);
|
|
530
|
+
}
|
|
531
|
+
|
|
483
532
|
// ===== PRIVATE METHODS =====
|
|
484
533
|
|
|
485
534
|
_connect() {
|
|
@@ -917,8 +966,15 @@ export default class RFB extends EventTargetMixin {
|
|
|
917
966
|
}
|
|
918
967
|
}
|
|
919
968
|
break;
|
|
969
|
+
case 'connecting':
|
|
970
|
+
while (this._rfbConnectionState === 'connecting') {
|
|
971
|
+
if (!this._initMsg()) {
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
break;
|
|
920
976
|
default:
|
|
921
|
-
|
|
977
|
+
Log.Error("Got data while in an invalid state");
|
|
922
978
|
break;
|
|
923
979
|
}
|
|
924
980
|
}
|
|
@@ -1327,6 +1383,21 @@ export default class RFB extends EventTargetMixin {
|
|
|
1327
1383
|
this._rfbInitState = 'Security';
|
|
1328
1384
|
}
|
|
1329
1385
|
|
|
1386
|
+
_isSupportedSecurityType(type) {
|
|
1387
|
+
const clientTypes = [
|
|
1388
|
+
securityTypeNone,
|
|
1389
|
+
securityTypeVNCAuth,
|
|
1390
|
+
securityTypeRA2ne,
|
|
1391
|
+
securityTypeTight,
|
|
1392
|
+
securityTypeVeNCrypt,
|
|
1393
|
+
securityTypeXVP,
|
|
1394
|
+
securityTypeARD,
|
|
1395
|
+
securityTypePlain,
|
|
1396
|
+
];
|
|
1397
|
+
|
|
1398
|
+
return clientTypes.includes(type);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1330
1401
|
_negotiateSecurity() {
|
|
1331
1402
|
if (this._rfbVersion >= 3.7) {
|
|
1332
1403
|
// Server sends supported list, client decides
|
|
@@ -1337,28 +1408,23 @@ export default class RFB extends EventTargetMixin {
|
|
|
1337
1408
|
this._rfbInitState = "SecurityReason";
|
|
1338
1409
|
this._securityContext = "no security types";
|
|
1339
1410
|
this._securityStatus = 1;
|
|
1340
|
-
return
|
|
1411
|
+
return true;
|
|
1341
1412
|
}
|
|
1342
1413
|
|
|
1343
1414
|
const types = this._sock.rQshiftBytes(numTypes);
|
|
1344
1415
|
Log.Debug("Server security types: " + types);
|
|
1345
1416
|
|
|
1346
|
-
// Look for
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
this.
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
} else if (types.includes(30)) {
|
|
1358
|
-
this._rfbAuthScheme = 30; // ARD Auth
|
|
1359
|
-
} else if (types.includes(19)) {
|
|
1360
|
-
this._rfbAuthScheme = 19; // VeNCrypt Auth
|
|
1361
|
-
} else {
|
|
1417
|
+
// Look for a matching security type in the order that the
|
|
1418
|
+
// server prefers
|
|
1419
|
+
this._rfbAuthScheme = -1;
|
|
1420
|
+
for (let type of types) {
|
|
1421
|
+
if (this._isSupportedSecurityType(type)) {
|
|
1422
|
+
this._rfbAuthScheme = type;
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
if (this._rfbAuthScheme === -1) {
|
|
1362
1428
|
return this._fail("Unsupported security types (types: " + types + ")");
|
|
1363
1429
|
}
|
|
1364
1430
|
|
|
@@ -1372,14 +1438,14 @@ export default class RFB extends EventTargetMixin {
|
|
|
1372
1438
|
this._rfbInitState = "SecurityReason";
|
|
1373
1439
|
this._securityContext = "authentication scheme";
|
|
1374
1440
|
this._securityStatus = 1;
|
|
1375
|
-
return
|
|
1441
|
+
return true;
|
|
1376
1442
|
}
|
|
1377
1443
|
}
|
|
1378
1444
|
|
|
1379
1445
|
this._rfbInitState = 'Authentication';
|
|
1380
1446
|
Log.Debug('Authenticating using scheme: ' + this._rfbAuthScheme);
|
|
1381
1447
|
|
|
1382
|
-
return
|
|
1448
|
+
return true;
|
|
1383
1449
|
}
|
|
1384
1450
|
|
|
1385
1451
|
_handleSecurityReason() {
|
|
@@ -1429,7 +1495,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1429
1495
|
this._rfbCredentials.username +
|
|
1430
1496
|
this._rfbCredentials.target;
|
|
1431
1497
|
this._sock.sendString(xvpAuthStr);
|
|
1432
|
-
this._rfbAuthScheme =
|
|
1498
|
+
this._rfbAuthScheme = securityTypeVNCAuth;
|
|
1433
1499
|
return this._negotiateAuthentication();
|
|
1434
1500
|
}
|
|
1435
1501
|
|
|
@@ -1487,49 +1553,66 @@ export default class RFB extends EventTargetMixin {
|
|
|
1487
1553
|
subtypes.push(this._sock.rQshift32());
|
|
1488
1554
|
}
|
|
1489
1555
|
|
|
1490
|
-
//
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1556
|
+
// Look for a matching security type in the order that the
|
|
1557
|
+
// server prefers
|
|
1558
|
+
this._rfbAuthScheme = -1;
|
|
1559
|
+
for (let type of subtypes) {
|
|
1560
|
+
// Avoid getting in to a loop
|
|
1561
|
+
if (type === securityTypeVeNCrypt) {
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
if (this._isSupportedSecurityType(type)) {
|
|
1566
|
+
this._rfbAuthScheme = type;
|
|
1567
|
+
break;
|
|
1568
|
+
}
|
|
1497
1569
|
}
|
|
1498
|
-
}
|
|
1499
1570
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
if (this._rfbCredentials.username === undefined ||
|
|
1503
|
-
this._rfbCredentials.password === undefined) {
|
|
1504
|
-
this.dispatchEvent(new CustomEvent(
|
|
1505
|
-
"credentialsrequired",
|
|
1506
|
-
{ detail: { types: ["username", "password"] } }));
|
|
1507
|
-
return false;
|
|
1571
|
+
if (this._rfbAuthScheme === -1) {
|
|
1572
|
+
return this._fail("Unsupported security types (types: " + subtypes + ")");
|
|
1508
1573
|
}
|
|
1509
1574
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
(user.length >> 24) & 0xFF,
|
|
1515
|
-
(user.length >> 16) & 0xFF,
|
|
1516
|
-
(user.length >> 8) & 0xFF,
|
|
1517
|
-
user.length & 0xFF
|
|
1518
|
-
]);
|
|
1519
|
-
this._sock.send([
|
|
1520
|
-
(pass.length >> 24) & 0xFF,
|
|
1521
|
-
(pass.length >> 16) & 0xFF,
|
|
1522
|
-
(pass.length >> 8) & 0xFF,
|
|
1523
|
-
pass.length & 0xFF
|
|
1524
|
-
]);
|
|
1525
|
-
this._sock.sendString(user);
|
|
1526
|
-
this._sock.sendString(pass);
|
|
1575
|
+
this._sock.send([this._rfbAuthScheme >> 24,
|
|
1576
|
+
this._rfbAuthScheme >> 16,
|
|
1577
|
+
this._rfbAuthScheme >> 8,
|
|
1578
|
+
this._rfbAuthScheme]);
|
|
1527
1579
|
|
|
1528
|
-
this.
|
|
1580
|
+
this._rfbVeNCryptState == 4;
|
|
1529
1581
|
return true;
|
|
1530
1582
|
}
|
|
1531
1583
|
}
|
|
1532
1584
|
|
|
1585
|
+
_negotiatePlainAuth() {
|
|
1586
|
+
if (this._rfbCredentials.username === undefined ||
|
|
1587
|
+
this._rfbCredentials.password === undefined) {
|
|
1588
|
+
this.dispatchEvent(new CustomEvent(
|
|
1589
|
+
"credentialsrequired",
|
|
1590
|
+
{ detail: { types: ["username", "password"] } }));
|
|
1591
|
+
return false;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
const user = encodeUTF8(this._rfbCredentials.username);
|
|
1595
|
+
const pass = encodeUTF8(this._rfbCredentials.password);
|
|
1596
|
+
|
|
1597
|
+
this._sock.send([
|
|
1598
|
+
(user.length >> 24) & 0xFF,
|
|
1599
|
+
(user.length >> 16) & 0xFF,
|
|
1600
|
+
(user.length >> 8) & 0xFF,
|
|
1601
|
+
user.length & 0xFF
|
|
1602
|
+
]);
|
|
1603
|
+
this._sock.send([
|
|
1604
|
+
(pass.length >> 24) & 0xFF,
|
|
1605
|
+
(pass.length >> 16) & 0xFF,
|
|
1606
|
+
(pass.length >> 8) & 0xFF,
|
|
1607
|
+
pass.length & 0xFF
|
|
1608
|
+
]);
|
|
1609
|
+
this._sock.sendString(user);
|
|
1610
|
+
this._sock.sendString(pass);
|
|
1611
|
+
|
|
1612
|
+
this._rfbInitState = "SecurityResult";
|
|
1613
|
+
return true;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1533
1616
|
_negotiateStdVNCAuth() {
|
|
1534
1617
|
if (this._sock.rQwait("auth challenge", 16)) { return false; }
|
|
1535
1618
|
|
|
@@ -1595,7 +1678,19 @@ export default class RFB extends EventTargetMixin {
|
|
|
1595
1678
|
let exponentHex = "0x"+Array.from(exponent, byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
|
|
1596
1679
|
let modulusHex = "0x"+Array.from(modulus, byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
|
|
1597
1680
|
|
|
1598
|
-
let
|
|
1681
|
+
let b = BigInt(baseHex);
|
|
1682
|
+
let e = BigInt(exponentHex);
|
|
1683
|
+
let m = BigInt(modulusHex);
|
|
1684
|
+
let r = 1n;
|
|
1685
|
+
b = b % m;
|
|
1686
|
+
while (e > 0) {
|
|
1687
|
+
if (e % 2n === 1n) {
|
|
1688
|
+
r = (r * b) % m;
|
|
1689
|
+
}
|
|
1690
|
+
e = e / 2n;
|
|
1691
|
+
b = (b * b) % m;
|
|
1692
|
+
}
|
|
1693
|
+
let hexResult = r.toString(16);
|
|
1599
1694
|
|
|
1600
1695
|
while (hexResult.length/2<exponent.length || (hexResult.length%2 != 0)) {
|
|
1601
1696
|
hexResult = "0"+hexResult;
|
|
@@ -1644,7 +1739,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1644
1739
|
this._rfbCredentials.ardCredentials = encrypted;
|
|
1645
1740
|
this._rfbCredentials.ardPublicKey = clientPublicKey;
|
|
1646
1741
|
|
|
1647
|
-
|
|
1742
|
+
this._resumeAuthentication();
|
|
1648
1743
|
}
|
|
1649
1744
|
|
|
1650
1745
|
_negotiateTightUnixAuth() {
|
|
@@ -1754,12 +1849,12 @@ export default class RFB extends EventTargetMixin {
|
|
|
1754
1849
|
case 'STDVNOAUTH__': // no auth
|
|
1755
1850
|
this._rfbInitState = 'SecurityResult';
|
|
1756
1851
|
return true;
|
|
1757
|
-
case 'STDVVNCAUTH_':
|
|
1758
|
-
this._rfbAuthScheme =
|
|
1759
|
-
return
|
|
1760
|
-
case 'TGHTULGNAUTH':
|
|
1761
|
-
this._rfbAuthScheme =
|
|
1762
|
-
return
|
|
1852
|
+
case 'STDVVNCAUTH_':
|
|
1853
|
+
this._rfbAuthScheme = securityTypeVNCAuth;
|
|
1854
|
+
return true;
|
|
1855
|
+
case 'TGHTULGNAUTH':
|
|
1856
|
+
this._rfbAuthScheme = securityTypeUnixLogon;
|
|
1857
|
+
return true;
|
|
1763
1858
|
default:
|
|
1764
1859
|
return this._fail("Unsupported tiny auth scheme " +
|
|
1765
1860
|
"(scheme: " + authType + ")");
|
|
@@ -1796,7 +1891,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1796
1891
|
}).then(() => {
|
|
1797
1892
|
this.dispatchEvent(new CustomEvent('securityresult'));
|
|
1798
1893
|
this._rfbInitState = "SecurityResult";
|
|
1799
|
-
|
|
1894
|
+
return true;
|
|
1800
1895
|
}).finally(() => {
|
|
1801
1896
|
this._rfbRSAAESAuthenticationState.removeEventListener(
|
|
1802
1897
|
"serververification", this._eventHandlers.handleRSAAESServerVerification);
|
|
@@ -1810,33 +1905,32 @@ export default class RFB extends EventTargetMixin {
|
|
|
1810
1905
|
|
|
1811
1906
|
_negotiateAuthentication() {
|
|
1812
1907
|
switch (this._rfbAuthScheme) {
|
|
1813
|
-
case
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
return true;
|
|
1817
|
-
}
|
|
1818
|
-
this._rfbInitState = 'ClientInitialisation';
|
|
1819
|
-
return this._initMsg();
|
|
1908
|
+
case securityTypeNone:
|
|
1909
|
+
this._rfbInitState = 'SecurityResult';
|
|
1910
|
+
return true;
|
|
1820
1911
|
|
|
1821
|
-
case
|
|
1912
|
+
case securityTypeXVP:
|
|
1822
1913
|
return this._negotiateXvpAuth();
|
|
1823
1914
|
|
|
1824
|
-
case
|
|
1915
|
+
case securityTypeARD:
|
|
1825
1916
|
return this._negotiateARDAuth();
|
|
1826
1917
|
|
|
1827
|
-
case
|
|
1918
|
+
case securityTypeVNCAuth:
|
|
1828
1919
|
return this._negotiateStdVNCAuth();
|
|
1829
1920
|
|
|
1830
|
-
case
|
|
1921
|
+
case securityTypeTight:
|
|
1831
1922
|
return this._negotiateTightAuth();
|
|
1832
1923
|
|
|
1833
|
-
case
|
|
1924
|
+
case securityTypeVeNCrypt:
|
|
1834
1925
|
return this._negotiateVeNCryptAuth();
|
|
1835
1926
|
|
|
1836
|
-
case
|
|
1927
|
+
case securityTypePlain:
|
|
1928
|
+
return this._negotiatePlainAuth();
|
|
1929
|
+
|
|
1930
|
+
case securityTypeUnixLogon:
|
|
1837
1931
|
return this._negotiateTightUnixAuth();
|
|
1838
1932
|
|
|
1839
|
-
case
|
|
1933
|
+
case securityTypeRA2ne:
|
|
1840
1934
|
return this._negotiateRA2neAuth();
|
|
1841
1935
|
|
|
1842
1936
|
default:
|
|
@@ -1846,6 +1940,13 @@ export default class RFB extends EventTargetMixin {
|
|
|
1846
1940
|
}
|
|
1847
1941
|
|
|
1848
1942
|
_handleSecurityResult() {
|
|
1943
|
+
// There is no security choice, and hence no security result
|
|
1944
|
+
// until RFB 3.7
|
|
1945
|
+
if (this._rfbVersion < 3.7) {
|
|
1946
|
+
this._rfbInitState = 'ClientInitialisation';
|
|
1947
|
+
return true;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1849
1950
|
if (this._sock.rQwait('VNC auth response ', 4)) { return false; }
|
|
1850
1951
|
|
|
1851
1952
|
const status = this._sock.rQshift32();
|
|
@@ -1853,13 +1954,13 @@ export default class RFB extends EventTargetMixin {
|
|
|
1853
1954
|
if (status === 0) { // OK
|
|
1854
1955
|
this._rfbInitState = 'ClientInitialisation';
|
|
1855
1956
|
Log.Debug('Authentication OK');
|
|
1856
|
-
return
|
|
1957
|
+
return true;
|
|
1857
1958
|
} else {
|
|
1858
1959
|
if (this._rfbVersion >= 3.8) {
|
|
1859
1960
|
this._rfbInitState = "SecurityReason";
|
|
1860
1961
|
this._securityContext = "security result";
|
|
1861
1962
|
this._securityStatus = status;
|
|
1862
|
-
return
|
|
1963
|
+
return true;
|
|
1863
1964
|
} else {
|
|
1864
1965
|
this.dispatchEvent(new CustomEvent(
|
|
1865
1966
|
"securityfailure",
|
|
@@ -2035,6 +2136,14 @@ export default class RFB extends EventTargetMixin {
|
|
|
2035
2136
|
}
|
|
2036
2137
|
}
|
|
2037
2138
|
|
|
2139
|
+
// Resume authentication handshake after it was paused for some
|
|
2140
|
+
// reason, e.g. waiting for a password from the user
|
|
2141
|
+
_resumeAuthentication() {
|
|
2142
|
+
// We use setTimeout() so it's run in its own context, just like
|
|
2143
|
+
// it originally did via the WebSocket's event handler
|
|
2144
|
+
setTimeout(this._initMsg.bind(this), 0);
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2038
2147
|
_handleSetColourMapMsg() {
|
|
2039
2148
|
Log.Debug("SetColorMapEntries");
|
|
2040
2149
|
|
package/docs/API.md
CHANGED
|
@@ -155,6 +155,15 @@ protocol stream.
|
|
|
155
155
|
[`RFB.clipboardPasteFrom()`](#rfbclipboardpastefrom)
|
|
156
156
|
- Send clipboard contents to server.
|
|
157
157
|
|
|
158
|
+
[`RFB.getImageData()`](#rfbgetimagedata)
|
|
159
|
+
- Return the current content of the screen as an ImageData array.
|
|
160
|
+
|
|
161
|
+
[`RFB.toDataURL()`](#rfbtodataurl)
|
|
162
|
+
- Return the current content of the screen as data-url encoded image file.
|
|
163
|
+
|
|
164
|
+
[`RFB.toBlob()`](#rfbtoblob)
|
|
165
|
+
- Return the current content of the screen as Blob encoded image file.
|
|
166
|
+
|
|
158
167
|
### Details
|
|
159
168
|
|
|
160
169
|
#### RFB()
|
|
@@ -423,3 +432,55 @@ to the remote server.
|
|
|
423
432
|
|
|
424
433
|
**`text`**
|
|
425
434
|
- A `DOMString` specifying the clipboard data to send.
|
|
435
|
+
|
|
436
|
+
#### RFB.getImageData()
|
|
437
|
+
|
|
438
|
+
The `RFB.getImageData()` method is used to return the current content of the
|
|
439
|
+
screen encoded as [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData).
|
|
440
|
+
|
|
441
|
+
##### Syntax
|
|
442
|
+
|
|
443
|
+
RFB.getImageData();
|
|
444
|
+
|
|
445
|
+
#### RFB.toDataURL()
|
|
446
|
+
|
|
447
|
+
The `RFB.toDataURL()` method is used to return the current content of the
|
|
448
|
+
screen encoded as a data URL that could for example be put in the `src` attribute
|
|
449
|
+
of an `img` tag.
|
|
450
|
+
|
|
451
|
+
##### Syntax
|
|
452
|
+
|
|
453
|
+
RFB.toDataURL();
|
|
454
|
+
RFB.toDataURL(type);
|
|
455
|
+
RFB.toDataURL(type, encoderOptions);
|
|
456
|
+
|
|
457
|
+
###### Parameters
|
|
458
|
+
|
|
459
|
+
**`type`** *Optional*
|
|
460
|
+
- A string indicating the requested MIME type of the image
|
|
461
|
+
|
|
462
|
+
**`encoderOptions`** *Optional*
|
|
463
|
+
- A number between 0 and 1 indicating the image quality.
|
|
464
|
+
|
|
465
|
+
#### RFB.toBlob()
|
|
466
|
+
|
|
467
|
+
The `RFB.toBlob()` method is used to return the current content of the
|
|
468
|
+
screen encoded as [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
|
|
469
|
+
|
|
470
|
+
##### Syntax
|
|
471
|
+
|
|
472
|
+
RFB.toDataURL(callback);
|
|
473
|
+
RFB.toDataURL(callback, type);
|
|
474
|
+
RFB.toDataURL(callback, type, quality);
|
|
475
|
+
|
|
476
|
+
###### Parameters
|
|
477
|
+
|
|
478
|
+
**`callback`**
|
|
479
|
+
- A callback function which will receive the resulting [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
|
|
480
|
+
as the single argument
|
|
481
|
+
|
|
482
|
+
**`type`** *Optional*
|
|
483
|
+
- A string indicating the requested MIME type of the image
|
|
484
|
+
|
|
485
|
+
**`encoderOptions`** *Optional*
|
|
486
|
+
- A number between 0 and 1 indicating the image quality.
|