summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2019-02-15 10:24:41 +0100
committerPierre Ossman <ossman@cendio.se>2019-02-15 10:24:41 +0100
commit3bb15d4aa0abc2e9272fa405bca1aa21cda39150 (patch)
tree164a076be5f9292a85edd2bf141a34ea5fc5d213
parentc13df5ae678f97e62f93bd49adcdb2f7e678e2de (diff)
downloadnovnc-3bb15d4aa0abc2e9272fa405bca1aa21cda39150.tar.gz
Fix security failure reason handling of slow data
Things would break if the security result and security reason did not arrive in the same WebSocket message.
-rw-r--r--core/rfb.js59
1 files changed, 27 insertions, 32 deletions
diff --git a/core/rfb.js b/core/rfb.js
index 49f0638..be2ce3e 100644
--- a/core/rfb.js
+++ b/core/rfb.js
@@ -853,7 +853,10 @@ export default class RFB extends EventTargetMixin {
if (this._sock.rQwait("security type", num_types, 1)) { return false; }
if (num_types === 0) {
- return this._handle_security_failure("no security types");
+ this._rfb_init_state = "SecurityReason";
+ this._security_context = "no security types";
+ this._security_status = 1;
+ return this._init_msg();
}
const types = this._sock.rQshiftBytes(num_types);
@@ -878,6 +881,13 @@ export default class RFB extends EventTargetMixin {
// Server decides
if (this._sock.rQwait("security scheme", 4)) { return false; }
this._rfb_auth_scheme = this._sock.rQshift32();
+
+ if (this._rfb_auth_scheme == 0) {
+ this._rfb_init_state = "SecurityReason";
+ this._security_context = "authentication scheme";
+ this._security_status = 1;
+ return this._init_msg();
+ }
}
this._rfb_init_state = 'Authentication';
@@ -886,28 +896,7 @@ export default class RFB extends EventTargetMixin {
return this._init_msg(); // jump to authentication
}
- /*
- * Get the security failure reason if sent from the server and
- * send the 'securityfailure' event.
- *
- * - The optional parameter context can be used to add some extra
- * context to the log output.
- *
- * - The optional parameter security_result_status can be used to
- * add a custom status code to the event.
- */
- _handle_security_failure(context, security_result_status) {
-
- if (typeof context === 'undefined') {
- context = "";
- } else {
- context = " on " + context;
- }
-
- if (typeof security_result_status === 'undefined') {
- security_result_status = 1; // fail
- }
-
+ _handle_security_reason() {
if (this._sock.rQwait("reason length", 4)) {
return false;
}
@@ -915,23 +904,26 @@ export default class RFB extends EventTargetMixin {
let reason = "";
if (strlen > 0) {
- if (this._sock.rQwait("reason", strlen, 8)) { return false; }
+ if (this._sock.rQwait("reason", strlen, 4)) { return false; }
reason = this._sock.rQshiftStr(strlen);
}
if (reason !== "") {
this.dispatchEvent(new CustomEvent(
"securityfailure",
- { detail: { status: security_result_status, reason: reason } }));
+ { detail: { status: this._security_status,
+ reason: reason } }));
- return this._fail("Security negotiation failed" + context +
+ return this._fail("Security negotiation failed on " +
+ this._security_context +
" (reason: " + reason + ")");
} else {
this.dispatchEvent(new CustomEvent(
"securityfailure",
- { detail: { status: security_result_status } }));
+ { detail: { status: this._security_status } }));
- return this._fail("Security negotiation failed" + context);
+ return this._fail("Security negotiation failed on " +
+ this._security_context);
}
}
@@ -1077,9 +1069,6 @@ export default class RFB extends EventTargetMixin {
_negotiate_authentication() {
switch (this._rfb_auth_scheme) {
- case 0: // connection failed
- return this._handle_security_failure("authentication scheme");
-
case 1: // no auth
if (this._rfb_version >= 3.8) {
this._rfb_init_state = 'SecurityResult';
@@ -1114,7 +1103,10 @@ export default class RFB extends EventTargetMixin {
return this._init_msg();
} else {
if (this._rfb_version >= 3.8) {
- return this._handle_security_failure("security result", status);
+ this._rfb_init_state = "SecurityReason";
+ this._security_context = "security result";
+ this._security_status = status;
+ return this._init_msg();
} else {
this.dispatchEvent(new CustomEvent(
"securityfailure",
@@ -1283,6 +1275,9 @@ export default class RFB extends EventTargetMixin {
case 'SecurityResult':
return this._handle_security_result();
+ case 'SecurityReason':
+ return this._handle_security_reason();
+
case 'ClientInitialisation':
this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation
this._rfb_init_state = 'ServerInitialisation';