diff options
author | Pierre Ossman <ossman@cendio.se> | 2019-02-15 10:24:41 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2019-02-15 10:24:41 +0100 |
commit | 3bb15d4aa0abc2e9272fa405bca1aa21cda39150 (patch) | |
tree | 164a076be5f9292a85edd2bf141a34ea5fc5d213 | |
parent | c13df5ae678f97e62f93bd49adcdb2f7e678e2de (diff) | |
download | novnc-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.js | 59 |
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'; |