Implement timeout and cancel

This commit is contained in:
RMidhunSuresh 2023-03-07 23:38:04 +05:30
parent 0b51fc0168
commit 1f8fb93ba2
No known key found for this signature in database
6 changed files with 41 additions and 25 deletions

View File

@ -166,6 +166,7 @@ export class CrossSigning {
e2eeAccount: this.e2eeAccount,
deviceTracker: this.deviceTracker,
hsApi: this.hsApi,
platform: this.platform,
});
return this.sasVerificationInProgress;
}

View File

@ -21,10 +21,12 @@ import type {DeviceTracker} from "../../e2ee/DeviceTracker.js";
import type * as OlmNamespace from "@matrix-org/olm";
import {IChannel} from "./channel/Channel";
import {HomeServerApi} from "../../net/HomeServerApi";
import {VerificationEventTypes} from "./channel/types";
import {CancelTypes, VerificationEventTypes} from "./channel/types";
import {SendReadyStage} from "./stages/SendReadyStage";
import {SelectVerificationMethodStage} from "./stages/SelectVerificationMethodStage";
import {VerificationCancelledError} from "./VerificationCancelledError";
import {Timeout} from "../../../platform/types/types";
import {Platform} from "../../../platform/web/Platform.js";
type Olm = typeof OlmNamespace;
@ -38,6 +40,7 @@ type Options = {
e2eeAccount: Account;
deviceTracker: DeviceTracker;
hsApi: HomeServerApi;
platform: Platform;
}
export class SASVerification {
@ -45,29 +48,30 @@ export class SASVerification {
private olmSas: Olm.SAS;
public finished: boolean = false;
public readonly channel: IChannel;
private readonly timeout: Timeout;
constructor(options: Options) {
const { ourUser, otherUserId, log, olmUtil, olm, channel, e2eeAccount, deviceTracker, hsApi } = options;
const { olm, channel, platform } = options;
const olmSas = new olm.SAS();
this.olmSas = olmSas;
this.channel = channel;
try {
const options = { ourUser, otherUserId, log, olmSas, olmUtil, channel, e2eeAccount, deviceTracker, hsApi};
let stage: BaseSASVerificationStage;
if (channel.receivedMessages.get(VerificationEventTypes.Start)) {
stage = new SelectVerificationMethodStage(options);
}
else if (channel.receivedMessages.get(VerificationEventTypes.Request)) {
stage = new SendReadyStage(options);
}
else {
stage = new RequestVerificationStage(options);
}
this.startStage = stage;
console.log("startStage", this.startStage);
this.timeout = platform.clock.createTimeout(10 * 60 * 1000);
this.timeout.elapsed().then(() => {
// Cancel verification after 10 minutes
// todo: catch error here?
channel.cancelVerification(CancelTypes.TimedOut);
});
const stageOptions = {...options, olmSas};
if (channel.receivedMessages.get(VerificationEventTypes.Start)) {
this.startStage = new SelectVerificationMethodStage(stageOptions);
}
finally {
else if (channel.receivedMessages.get(VerificationEventTypes.Request)) {
this.startStage = new SendReadyStage(stageOptions);
}
else {
this.startStage = new RequestVerificationStage(stageOptions);
}
console.log("startStage", this.startStage);
}
async start() {
@ -88,6 +92,7 @@ export class SASVerification {
finally {
this.olmSas.free();
this.finished = true;
this.timeout.abort();
}
}
}

View File

@ -96,8 +96,7 @@ export class ToDeviceChannel extends Disposables implements IChannel {
this.platform = options.platform;
this.log = options.log;
this.deviceMessageHandler = options.deviceMessageHandler;
// todo: find a way to dispose this subscription
this.track(this.deviceMessageHandler.disposableOn("message", ({ unencrypted }) => this.handleDeviceMessage(unencrypted)));
this.track(this.deviceMessageHandler.disposableOn("message", async ({ unencrypted }) => await this.handleDeviceMessage(unencrypted)));
this.track(() => {
this.waitMap.forEach((value) => { value.reject(new VerificationCancelledError()); });
});
@ -169,8 +168,18 @@ export class ToDeviceChannel extends Disposables implements IChannel {
}
private handleDeviceMessage(event) {
this.log.wrap("ToDeviceChannel.handleDeviceMessage", (log) => {
private async handleDeviceMessage(event) {
await this.log.wrap("ToDeviceChannel.handleDeviceMessage", async (log) => {
if (event.content.transaction_id !== this.id) {
/**
* When a device receives an unknown transaction_id, it should send an appropriate
* m.key.verification.cancel message to the other device indicating as such.
* This does not apply for inbound m.key.verification.start or m.key.verification.cancel messages.
*/
console.log("Received event with unknown transaction id: ", event);
await this.cancelVerification(CancelTypes.UnknownTransaction);
return;
}
console.log("event", event);
log.set("event", event);
this.resolveAnyWaits(event);

View File

@ -140,9 +140,10 @@ export class CalculateSASStage extends BaseSASVerificationStage {
return sasBytes;
}
emojiMatch(match: boolean) {
async emojiMatch(match: boolean) {
if (!match) {
// cancel the verification
await this.channel.cancelVerification(CancelTypes.MismatchedSAS);
}
}

View File

@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {BaseSASVerificationStage} from "./BaseSASVerificationStage";
// import {FragmentBoundaryEntry} from "../../../room/timeline/entries/FragmentBoundaryEntry.js";
import {SelectVerificationMethodStage} from "./SelectVerificationMethodStage";
import {VerificationEventTypes} from "../channel/types";

View File

@ -16,7 +16,7 @@ limitations under the License.
import {BaseSASVerificationStage} from "./BaseSASVerificationStage";
import anotherjson from "another-json";
import {HASHES_LIST, MAC_LIST, SAS_SET, KEY_AGREEMENT_LIST} from "./constants";
import {VerificationEventTypes} from "../channel/types";
import {CancelTypes, VerificationEventTypes} from "../channel/types";
import {SendKeyStage} from "./SendKeyStage";
export class SendAcceptVerificationStage extends BaseSASVerificationStage {
@ -29,7 +29,8 @@ export class SendAcceptVerificationStage extends BaseSASVerificationStage {
const sasMethods = intersection(content.short_authentication_string, SAS_SET);
if (!(keyAgreement !== undefined && hashMethod !== undefined && macMethod !== undefined && sasMethods.length)) {
// todo: ensure this cancels the verification
throw new Error("Descriptive error here!");
await this.channel.cancelVerification(CancelTypes.UnknownMethod);
return;
}
const ourPubKey = this.olmSAS.get_pubkey();
const commitmentStr = ourPubKey + anotherjson.stringify(content);