You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Clean up/improve e2e logging
In an attempt to make the rageshake logs a bit more useful, try to make the logging a bit saner. Firstly, make sure we log every decryption failure, and log it exactly once, rather than in several places. Also record when we receive megolm keys. Also add some more explicit logging in the sync loop.
This commit is contained in:
@@ -550,6 +550,9 @@ function _decryptEvent(client, event) {
|
|||||||
try {
|
try {
|
||||||
client._crypto.decryptEvent(event);
|
client._crypto.decryptEvent(event);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.warn(
|
||||||
|
`Error decrypting event (id=${event.getId()}): ${e}`,
|
||||||
|
);
|
||||||
if (!(e instanceof Crypto.DecryptionError)) {
|
if (!(e instanceof Crypto.DecryptionError)) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@@ -404,7 +404,7 @@ function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
|||||||
const signKeyId = "ed25519:" + deviceId;
|
const signKeyId = "ed25519:" + deviceId;
|
||||||
const signKey = deviceResult.keys[signKeyId];
|
const signKey = deviceResult.keys[signKeyId];
|
||||||
if (!signKey) {
|
if (!signKey) {
|
||||||
console.log("Device " + userId + ":" + deviceId +
|
console.warn("Device " + userId + ":" + deviceId +
|
||||||
" has no ed25519 key");
|
" has no ed25519 key");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -414,8 +414,8 @@ function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
|||||||
try {
|
try {
|
||||||
olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);
|
olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Unable to verify signature on device " +
|
console.warn("Unable to verify signature on device " +
|
||||||
userId + ":" + deviceId + ":", e);
|
userId + ":" + deviceId + ":" + e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +431,7 @@ function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
|||||||
// best off sticking with the original keys.
|
// best off sticking with the original keys.
|
||||||
//
|
//
|
||||||
// Should we warn the user about it somehow?
|
// Should we warn the user about it somehow?
|
||||||
console.warn("Ed25519 key for device" + userId + ": " +
|
console.warn("Ed25519 key for device " + userId + ":" +
|
||||||
deviceId + " has changed");
|
deviceId + " has changed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -148,14 +148,42 @@ DecryptionAlgorithm.prototype.importRoomKey = function(session) {
|
|||||||
/**
|
/**
|
||||||
* Exception thrown when decryption fails
|
* Exception thrown when decryption fails
|
||||||
*
|
*
|
||||||
|
* @alias module:crypto/algorithms/base.DecryptionError
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {string} msg message describing the problem
|
* @param {string} msg user-visible message describing the problem
|
||||||
|
*
|
||||||
|
* @param {Object=} details key/value pairs reported in the logs but not shown
|
||||||
|
* to the user.
|
||||||
|
*
|
||||||
* @extends Error
|
* @extends Error
|
||||||
*/
|
*/
|
||||||
module.exports.DecryptionError = function(msg) {
|
const DecryptionError = function(msg, details) {
|
||||||
|
this.name = 'DecryptionError';
|
||||||
this.message = msg;
|
this.message = msg;
|
||||||
|
this.details = details;
|
||||||
};
|
};
|
||||||
utils.inherits(module.exports.DecryptionError, Error);
|
utils.inherits(DecryptionError, Error);
|
||||||
|
|
||||||
|
/** override the string used when logging
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
DecryptionError.prototype.toString = function() {
|
||||||
|
let result = this.name + '[msg: '+ this.message;
|
||||||
|
|
||||||
|
if (this.details) {
|
||||||
|
result += ', ' +
|
||||||
|
Object.keys(this.details).map(
|
||||||
|
(k) => k + ': ' + this.details[k],
|
||||||
|
).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
result += ']';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.DecryptionError = DecryptionError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown specifically when we want to warn the user to consider
|
* Exception thrown specifically when we want to warn the user to consider
|
||||||
|
@@ -544,7 +544,11 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
|
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
|
||||||
this._addEventToPendingList(event);
|
this._addEventToPendingList(event);
|
||||||
}
|
}
|
||||||
throw new base.DecryptionError(e);
|
throw new base.DecryptionError(
|
||||||
|
e.toString(), {
|
||||||
|
session: content.sender_key + '|' + content.session_id,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res === null) {
|
if (res === null) {
|
||||||
@@ -552,6 +556,9 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
this._addEventToPendingList(event);
|
this._addEventToPendingList(event);
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"The sender's device has not sent us the keys for this message.",
|
"The sender's device has not sent us the keys for this message.",
|
||||||
|
{
|
||||||
|
session: content.sender_key + '|' + content.session_id,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,26 +600,27 @@ MegolmDecryption.prototype._addEventToPendingList = function(event) {
|
|||||||
* @param {module:models/event.MatrixEvent} event key event
|
* @param {module:models/event.MatrixEvent} event key event
|
||||||
*/
|
*/
|
||||||
MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||||
console.log("Adding key from ", event);
|
|
||||||
const content = event.getContent();
|
const content = event.getContent();
|
||||||
const senderKey = event.getSenderKey();
|
const senderKey = event.getSenderKey();
|
||||||
|
const sessionId = content.session_id;
|
||||||
|
|
||||||
if (!content.room_id ||
|
if (!content.room_id ||
|
||||||
!content.session_id ||
|
!sessionId ||
|
||||||
!content.session_key ||
|
!content.session_key ||
|
||||||
!senderKey
|
!senderKey
|
||||||
) {
|
) {
|
||||||
console.error("key event is missing fields");
|
console.error(`key event is missing fields`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`Adding key for megolm session ${senderKey}|${sessionId}`);
|
||||||
this._olmDevice.addInboundGroupSession(
|
this._olmDevice.addInboundGroupSession(
|
||||||
content.room_id, senderKey, content.session_id,
|
content.room_id, senderKey, sessionId,
|
||||||
content.session_key, event.getKeysClaimed(),
|
content.session_key, event.getKeysClaimed(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// have another go at decrypting events sent with this session.
|
// have another go at decrypting events sent with this session.
|
||||||
this._retryDecryption(senderKey, content.session_id);
|
this._retryDecryption(senderKey, sessionId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -174,12 +174,12 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
try {
|
try {
|
||||||
payloadString = this._decryptMessage(deviceKey, message);
|
payloadString = this._decryptMessage(deviceKey, message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(
|
throw new base.DecryptionError(
|
||||||
"Failed to decrypt Olm event (id=" +
|
"Bad Encrypted Message", {
|
||||||
event.getId() + ") from " + deviceKey +
|
sender: deviceKey,
|
||||||
": " + e.message,
|
err: e,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError("Bad Encrypted Message");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = JSON.parse(payloadString);
|
const payload = JSON.parse(payloadString);
|
||||||
@@ -187,22 +187,18 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
// check that we were the intended recipient, to avoid unknown-key attack
|
// check that we were the intended recipient, to avoid unknown-key attack
|
||||||
// https://github.com/vector-im/vector-web/issues/2483
|
// https://github.com/vector-im/vector-web/issues/2483
|
||||||
if (payload.recipient != this._userId) {
|
if (payload.recipient != this._userId) {
|
||||||
console.warn(
|
|
||||||
"Event " + event.getId() + ": Intended recipient " +
|
|
||||||
payload.recipient + " does not match our id " + this._userId,
|
|
||||||
);
|
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message was intented for " + payload.recipient,
|
"Message was intented for " + payload.recipient,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload.recipient_keys.ed25519 !=
|
if (payload.recipient_keys.ed25519 != this._olmDevice.deviceEd25519Key) {
|
||||||
this._olmDevice.deviceEd25519Key) {
|
throw new base.DecryptionError(
|
||||||
console.warn(
|
"Message not intended for this device", {
|
||||||
"Event " + event.getId() + ": Intended recipient ed25519 key " +
|
intended: payload.recipient_keys.ed25519,
|
||||||
payload.recipient_keys.ed25519 + " did not match ours",
|
our_key: this._olmDevice.deviceEd25519Key,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError("Message not intended for this device");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that the original sender matches what the homeserver told us, to
|
// check that the original sender matches what the homeserver told us, to
|
||||||
@@ -210,23 +206,19 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
// (this check is also provided via the sender's embedded ed25519 key,
|
// (this check is also provided via the sender's embedded ed25519 key,
|
||||||
// which is checked elsewhere).
|
// which is checked elsewhere).
|
||||||
if (payload.sender != event.getSender()) {
|
if (payload.sender != event.getSender()) {
|
||||||
console.warn(
|
|
||||||
"Event " + event.getId() + ": original sender " + payload.sender +
|
|
||||||
" does not match reported sender " + event.getSender(),
|
|
||||||
);
|
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message forwarded from " + payload.sender,
|
"Message forwarded from " + payload.sender, {
|
||||||
|
reported_sender: event.getSender(),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Olm events intended for a room have a room_id.
|
// Olm events intended for a room have a room_id.
|
||||||
if (payload.room_id !== event.getRoomId()) {
|
if (payload.room_id !== event.getRoomId()) {
|
||||||
console.warn(
|
|
||||||
"Event " + event.getId() + ": original room " + payload.room_id +
|
|
||||||
" does not match reported room " + event.room_id,
|
|
||||||
);
|
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message intended for room " + payload.room_id,
|
"Message intended for room " + payload.room_id, {
|
||||||
|
reported_room: event.room_id,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/sync.js
12
src/sync.js
@@ -360,9 +360,6 @@ SyncApi.prototype.getSyncState = function() {
|
|||||||
* Main entry point
|
* Main entry point
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype.sync = function() {
|
SyncApi.prototype.sync = function() {
|
||||||
debuglog("SyncApi.sync: starting with sync token " +
|
|
||||||
this.client.store.getSyncToken());
|
|
||||||
|
|
||||||
const client = this.client;
|
const client = this.client;
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
@@ -511,11 +508,14 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
// normal timeout= plus buffer time
|
// normal timeout= plus buffer time
|
||||||
const clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
const clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
||||||
|
|
||||||
|
debuglog('Starting sync since=' + syncToken);
|
||||||
this._currentSyncRequest = client._http.authedRequest(
|
this._currentSyncRequest = client._http.authedRequest(
|
||||||
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs,
|
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs,
|
||||||
);
|
);
|
||||||
|
|
||||||
this._currentSyncRequest.done(function(data) {
|
this._currentSyncRequest.done(function(data) {
|
||||||
|
debuglog('Completed sync, next_batch=' + data.next_batch);
|
||||||
|
|
||||||
// set the sync token NOW *before* processing the events. We do this so
|
// set the sync token NOW *before* processing the events. We do this so
|
||||||
// if something barfs on an event we can skip it rather than constantly
|
// if something barfs on an event we can skip it rather than constantly
|
||||||
// polling with the same token.
|
// polling with the same token.
|
||||||
@@ -666,8 +666,10 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
toDeviceEvent.getType() == "m.room.message" &&
|
toDeviceEvent.getType() == "m.room.message" &&
|
||||||
content.msgtype == "m.bad.encrypted"
|
content.msgtype == "m.bad.encrypted"
|
||||||
) {
|
) {
|
||||||
console.warn(
|
// the mapper already logged a warning.
|
||||||
"Unable to decrypt to-device event: " + content.body,
|
console.log(
|
||||||
|
'Ignoring undecryptable to-device event from ' +
|
||||||
|
toDeviceEvent.getSender(),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user