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.
pull/36/head
Pierre Ossman 6 years ago committed by Lauri Kasanen
parent 41e6fedba6
commit ce6d66f030

@ -965,7 +965,10 @@ export default class RFB extends EventTargetMixin {
if (this._sock.rQwait("security type", num_types, 1)) { return false; } if (this._sock.rQwait("security type", num_types, 1)) { return false; }
if (num_types === 0) { 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); const types = this._sock.rQshiftBytes(num_types);
@ -990,6 +993,13 @@ export default class RFB extends EventTargetMixin {
// Server decides // Server decides
if (this._sock.rQwait("security scheme", 4)) { return false; } if (this._sock.rQwait("security scheme", 4)) { return false; }
this._rfb_auth_scheme = this._sock.rQshift32(); 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'; this._rfb_init_state = 'Authentication';
@ -998,28 +1008,7 @@ export default class RFB extends EventTargetMixin {
return this._init_msg(); // jump to authentication return this._init_msg(); // jump to authentication
} }
/* _handle_security_reason() {
* 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
}
if (this._sock.rQwait("reason length", 4)) { if (this._sock.rQwait("reason length", 4)) {
return false; return false;
} }
@ -1027,23 +1016,26 @@ export default class RFB extends EventTargetMixin {
let reason = ""; let reason = "";
if (strlen > 0) { 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); reason = this._sock.rQshiftStr(strlen);
} }
if (reason !== "") { if (reason !== "") {
this.dispatchEvent(new CustomEvent( this.dispatchEvent(new CustomEvent(
"securityfailure", "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 + ")"); " (reason: " + reason + ")");
} else { } else {
this.dispatchEvent(new CustomEvent( this.dispatchEvent(new CustomEvent(
"securityfailure", "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);
} }
} }
@ -1185,9 +1177,6 @@ export default class RFB extends EventTargetMixin {
_negotiate_authentication() { _negotiate_authentication() {
switch (this._rfb_auth_scheme) { switch (this._rfb_auth_scheme) {
case 0: // connection failed
return this._handle_security_failure("authentication scheme");
case 1: // no auth case 1: // no auth
if (this._rfb_version >= 3.8) { if (this._rfb_version >= 3.8) {
this._rfb_init_state = 'SecurityResult'; this._rfb_init_state = 'SecurityResult';
@ -1222,7 +1211,10 @@ export default class RFB extends EventTargetMixin {
return this._init_msg(); return this._init_msg();
} else { } else {
if (this._rfb_version >= 3.8) { 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 { } else {
this.dispatchEvent(new CustomEvent( this.dispatchEvent(new CustomEvent(
"securityfailure", "securityfailure",
@ -1453,6 +1445,9 @@ export default class RFB extends EventTargetMixin {
case 'SecurityResult': case 'SecurityResult':
return this._handle_security_result(); return this._handle_security_result();
case 'SecurityReason':
return this._handle_security_reason();
case 'ClientInitialisation': case 'ClientInitialisation':
this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation
this._rfb_init_state = 'ServerInitialisation'; this._rfb_init_state = 'ServerInitialisation';

Loading…
Cancel
Save