Compare commits

...

6 Commits

7 changed files with 86 additions and 95 deletions

View File

@ -1020,7 +1020,7 @@ class DatabaseService {
await batch.commit();
}
Future<void> saveOmemoDevice(Device device) async {
Future<void> saveOmemoDevice(OmemoDevice device) async {
await _db.insert(
omemoDeviceTable,
{
@ -1032,7 +1032,7 @@ class DatabaseService {
);
}
Future<Device?> loadOmemoDevice(String jid) async {
Future<OmemoDevice?> loadOmemoDevice(String jid) async {
final data = await _db.query(
omemoDeviceTable,
where: 'jid = ?',
@ -1055,7 +1055,7 @@ class DatabaseService {
});
}
deviceJson['opks'] = opks;
return Device.fromJson(deviceJson);
return OmemoDevice.fromJson(deviceJson);
}
Future<Map<String, List<int>>> loadOmemoDeviceList() async {

View File

@ -589,9 +589,8 @@ Future<void> performRecreateSessions(RecreateSessionsCommand command, { dynamic
await GetIt.I.get<OmemoService>().removeAllSessions(command.jid);
final conn = GetIt.I.get<XmppConnection>();
await conn.getManagerById<OmemoManager>(omemoManager)!.sendEmptyMessage(
JID.fromString(command.jid),
findNewSessions: true,
await conn.getManagerById<BaseOmemoManager>(omemoManager)!.sendOmemoHeartbeat(
command.jid,
);
}
@ -623,7 +622,7 @@ Future<void> performGetOwnOmemoFingerprints(GetOwnOmemoFingerprintsCommand comma
Future<void> performRemoveOwnDevice(RemoveOwnDeviceCommand command, { dynamic extra }) async {
await GetIt.I.get<XmppConnection>()
.getManagerById<OmemoManager>(omemoManager)!
.getManagerById<BaseOmemoManager>(omemoManager)!
.deleteDevice(command.deviceId);
}

View File

@ -4,15 +4,14 @@ import 'package:moxxyv2/service/conversation.dart';
import 'package:moxxyv2/service/omemo/omemo.dart';
import 'package:omemo_dart/omemo_dart.dart';
class MoxxyOmemoManager extends OmemoManager {
class MoxxyOmemoManager extends BaseOmemoManager {
MoxxyOmemoManager() : super();
@override
Future<OmemoSessionManager> getSessionManager() async {
Future<OmemoManager> getOmemoManager() async {
final os = GetIt.I.get<OmemoService>();
await os.ensureInitialized();
return os.omemoState;
return os.omemoManager;
}
@override

View File

@ -1,13 +1,5 @@
import 'package:moxxyv2/service/moxxmpp/omemo.dart';
import 'package:omemo_dart/omemo_dart.dart';
Future<OmemoSessionManager> generateNewIdentityImpl(String jid) async {
return OmemoSessionManager.generateNewIdentity(
jid,
MoxxyBTBVTrustManager(
<RatchetMapKey, BTBVTrustState>{},
<RatchetMapKey, bool>{},
<String, List<int>>{},
),
);
Future<OmemoDevice> generateNewIdentityImpl(String jid) async {
return OmemoDevice.generateNewDevice(jid);
}

View File

@ -4,12 +4,12 @@ import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:hex/hex.dart';
import 'package:logging/logging.dart';
import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxmpp/moxxmpp.dart' as moxxmpp;
import 'package:moxxyv2/service/database/database.dart';
import 'package:moxxyv2/service/moxxmpp/omemo.dart';
import 'package:moxxyv2/service/omemo/implementations.dart';
import 'package:moxxyv2/service/omemo/types.dart';
import 'package:moxxyv2/shared/models/omemo_device.dart';
import 'package:moxxyv2/shared/models/omemo_device.dart' as model;
import 'package:omemo_dart/omemo_dart.dart';
import 'package:synchronized/synchronized.dart';
@ -28,22 +28,22 @@ class OmemoService {
final Queue<Completer<void>> _waitingForInitialization = Queue<Completer<void>>();
final Map<String, Map<int, String>> _fingerprintCache = {};
late OmemoSessionManager omemoState;
late OmemoManager omemoManager;
Future<void> initializeIfNeeded(String jid) async {
final done = await _lock.synchronized(() => _initialized);
if (done) return;
final db = GetIt.I.get<DatabaseService>();
final device = await db.loadOmemoDevice(jid);
var device = await db.loadOmemoDevice(jid);
if (device == null) {
_log.info('No OMEMO marker found. Generating OMEMO identity...');
// Generate the identity in the background
omemoState = await compute(generateNewIdentityImpl, jid);
device = await compute(generateNewIdentityImpl, jid);
await commitDevice(await omemoState.getDevice());
await commitDevice(device!);
await commitDeviceMap(<String, List<int>>{});
await commitTrustManager(await omemoState.trustManager.toJson());
await commitTrustManager(await omemoManager.trustManager.toJson());
} else {
_log.info('OMEMO marker found. Restoring OMEMO state...');
final ratchetMap = <RatchetMapKey, OmemoDoubleRatchet>{};
@ -53,15 +53,24 @@ class OmemoService {
}
final db = GetIt.I.get<DatabaseService>();
omemoState = OmemoSessionManager(
final om = GetIt.I.get<moxxmpp.XmppConnection>().
getManagerById<moxxmpp.BaseOmemoManager>(moxxmpp.omemoManager)!;
omemoManager = OmemoManager(
device,
await db.loadOmemoDeviceList(),
ratchetMap,
await loadTrustManager(),
om.sendEmptyMessageImpl,
om.fetchDeviceList,
om.fetchDeviceBundle,
om.subscribeToDeviceListImpl,
);
omemoManager.initialize(
ratchetMap,
await db.loadOmemoDeviceList(),
);
}
omemoState.eventStream.listen((event) async {
omemoManager.eventStream.listen((event) async {
if (event is RatchetModifiedEvent) {
await GetIt.I.get<DatabaseService>().saveRatchet(
OmemoDoubleRatchetWrapper(event.ratchet, event.deviceId, event.jid),
@ -69,7 +78,7 @@ class OmemoService {
if (event.added) {
// Cache the fingerprint
final fingerprint = HEX.encode(await event.ratchet.ik.getBytes());
final fingerprint = await event.ratchet.getOmemoFingerprint();
await GetIt.I.get<DatabaseService>().addFingerprintsToCache([
OmemoCacheTriple(
event.jid,
@ -82,14 +91,14 @@ class OmemoService {
_fingerprintCache[event.jid]![event.deviceId] = fingerprint;
}
}
} else if (event is DeviceMapModifiedEvent) {
await commitDeviceMap(event.map);
} else if (event is DeviceListModifiedEvent) {
await commitDeviceMap(event.list);
} else if (event is DeviceModifiedEvent) {
await commitDevice(event.device);
// Publish it
await GetIt.I.get<XmppConnection>()
.getManagerById<OmemoManager>(omemoManager)!
await GetIt.I.get<moxxmpp.XmppConnection>()
.getManagerById<moxxmpp.BaseOmemoManager>(moxxmpp.omemoManager)!
.publishBundle(await event.device.toBundle());
}
});
@ -104,32 +113,32 @@ class OmemoService {
});
}
Future<OmemoDevice> regenerateDevice(String jid) async {
Future<model.OmemoDevice> regenerateDevice(String jid) async {
// Prevent access to the session manager as it is (mostly) guarded ensureInitialized
await _lock.synchronized(() {
_initialized = false;
});
_log.info('No OMEMO marker found. Generating OMEMO identity...');
final oldId = await omemoState.getDeviceId();
final oldId = await omemoManager.getDeviceId();
// Clear the database
await GetIt.I.get<DatabaseService>().emptyOmemoSessionTables();
// Regenerate the identity in the background
omemoState = await compute(generateNewIdentityImpl, jid);
await commitDevice(await omemoState.getDevice());
final device = await compute(generateNewIdentityImpl, jid);
await omemoManager.replaceDevice(device);
await commitDevice(device);
await commitDeviceMap(<String, List<int>>{});
await commitTrustManager(await omemoState.trustManager.toJson());
await commitTrustManager(await omemoManager.trustManager.toJson());
// Remove the old device
final omemo = GetIt.I.get<XmppConnection>()
.getManagerById<OmemoManager>(omemoManager)!;
final omemo = GetIt.I.get<moxxmpp.XmppConnection>()
.getManagerById<moxxmpp.BaseOmemoManager>(moxxmpp.omemoManager)!;
await omemo.deleteDevice(oldId);
// Publish the new one
await omemo.publishBundle(await omemoState.getDeviceBundle());
await omemo.publishBundle(await omemoManager.getDeviceBundle());
// Allow access again
await _lock.synchronized(() {
@ -142,7 +151,7 @@ class OmemoService {
});
// Return the OmemoDevice
return OmemoDevice(
return model.OmemoDevice(
await getDeviceFingerprint(),
true,
true,
@ -173,7 +182,7 @@ class OmemoService {
await GetIt.I.get<DatabaseService>().saveOmemoDeviceList(deviceMap);
}
Future<void> commitDevice(Device device) async {
Future<void> commitDevice(OmemoDevice device) async {
await GetIt.I.get<DatabaseService>().saveOmemoDevice(device);
}
@ -184,46 +193,46 @@ class OmemoService {
await ensureInitialized();
_log.finest('publishDeviceIfNeeded: Done');
final conn = GetIt.I.get<XmppConnection>();
final omemo = conn.getManagerById<OmemoManager>(omemoManager)!;
final dm = conn.getManagerById<DiscoManager>(discoManager)!;
final conn = GetIt.I.get<moxxmpp.XmppConnection>();
final omemo = conn.getManagerById<moxxmpp.BaseOmemoManager>(moxxmpp.omemoManager)!;
final dm = conn.getManagerById<moxxmpp.DiscoManager>(moxxmpp.discoManager)!;
final bareJid = conn.getConnectionSettings().jid.toBare();
final device = await omemoState.getDevice();
final device = await omemoManager.getDevice();
final bundlesRaw = await dm.discoItemsQuery(
bareJid.toString(),
node: omemoBundlesXmlns,
node: moxxmpp.omemoBundlesXmlns,
);
if (bundlesRaw.isType<DiscoError>()) {
if (bundlesRaw.isType<moxxmpp.DiscoError>()) {
await omemo.publishBundle(await device.toBundle());
return bundlesRaw.get<DiscoError>();
return bundlesRaw.get<moxxmpp.DiscoError>();
}
final bundleIds = bundlesRaw
.get<List<DiscoItem>>()
.get<List<moxxmpp.DiscoItem>>()
.where((item) => item.name != null)
.map((item) => int.parse(item.name!));
if (!bundleIds.contains(device.id)) {
final result = await omemo.publishBundle(await device.toBundle());
if (result.isType<OmemoError>()) return result.get<OmemoError>();
if (result.isType<moxxmpp.OmemoError>()) return result.get<moxxmpp.OmemoError>();
return null;
}
final idsRaw = await omemo.getDeviceList(bareJid);
final ids = idsRaw.isType<OmemoError>() ? <int>[] : idsRaw.get<List<int>>();
final ids = idsRaw.isType<moxxmpp.OmemoError>() ? <int>[] : idsRaw.get<List<int>>();
if (!ids.contains(device.id)) {
final result = await omemo.publishBundle(await device.toBundle());
if (result.isType<OmemoError>()) return result.get<OmemoError>();
if (result.isType<moxxmpp.OmemoError>()) return result.get<moxxmpp.OmemoError>();
return null;
}
return null;
}
Future<void> _fetchFingerprintsAndCache(JID jid) async {
Future<void> _fetchFingerprintsAndCache(moxxmpp.JID jid) async {
final bareJid = jid.toBare().toString();
final allDevicesRaw = await GetIt.I.get<XmppConnection>()
.getManagerById<OmemoManager>(omemoManager)!
final allDevicesRaw = await GetIt.I.get<moxxmpp.XmppConnection>()
.getManagerById<moxxmpp.BaseOmemoManager>(moxxmpp.omemoManager)!
.retrieveDeviceBundles(jid);
if (allDevicesRaw.isType<List<OmemoBundle>>()) {
final allDevices = allDevicesRaw.get<List<OmemoBundle>>();
@ -244,7 +253,7 @@ class OmemoService {
}
}
Future<void> _loadOrFetchFingerprints(JID jid) async {
Future<void> _loadOrFetchFingerprints(moxxmpp.JID jid) async {
final bareJid = jid.toBare().toString();
if (!_fingerprintCache.containsKey(bareJid)) {
// First try to load it from the database
@ -267,20 +276,20 @@ class OmemoService {
}
}
Future<List<OmemoDevice>> getOmemoKeysForJid(String jid) async {
Future<List<model.OmemoDevice>> getOmemoKeysForJid(String jid) async {
await ensureInitialized();
// Get finger prints if we have to
await _loadOrFetchFingerprints(JID.fromString(jid));
await _loadOrFetchFingerprints(moxxmpp.JID.fromString(jid));
final keys = List<OmemoDevice>.empty(growable: true);
final tm = omemoState.trustManager as BlindTrustBeforeVerificationTrustManager;
final keys = List<model.OmemoDevice>.empty(growable: true);
final tm = omemoManager.trustManager as BlindTrustBeforeVerificationTrustManager;
final trustMap = await tm.getDevicesTrust(jid);
if (!_fingerprintCache.containsKey(jid)) return [];
for (final deviceId in _fingerprintCache[jid]!.keys) {
keys.add(
OmemoDevice(
model.OmemoDevice(
_fingerprintCache[jid]![deviceId]!,
await tm.isTrusted(jid, deviceId),
trustMap[deviceId] == BTBVTrustState.verified,
@ -316,29 +325,28 @@ class OmemoService {
Future<void> setOmemoKeyEnabled(String jid, int deviceId, bool enabled) async {
await ensureInitialized();
await omemoState.trustManager.setEnabled(jid, deviceId, enabled);
await omemoManager.trustManager.setEnabled(jid, deviceId, enabled);
}
Future<void> removeAllSessions(String jid) async {
await ensureInitialized();
await omemoState.removeAllRatchets(jid);
// TODO(PapaTutuWawa): Reset trust decisions in the TrustManager
await omemoManager.removeAllRatchets(jid);
}
Future<int> getDeviceId() async {
await ensureInitialized();
return omemoState.getDeviceId();
return omemoManager.getDeviceId();
}
Future<String> getDeviceFingerprint() async {
return (await omemoState.getHexFingerprintForDevice()).fingerprint;
}
Future<String> getDeviceFingerprint() => omemoManager.getDeviceFingerprint();
/// Returns a list of OmemoDevices for devices we have sessions with and other devices
/// published on [ownJid]'s devices PubSub node.
/// Note that the list is made so that the current device is excluded.
Future<List<OmemoDevice>> getOwnFingerprints(JID ownJid) async {
Future<List<model.OmemoDevice>> getOwnFingerprints(moxxmpp.JID ownJid) async {
final ownId = await getDeviceId();
final keys = List<OmemoDevice>.from(
final keys = List<model.OmemoDevice>.from(
await getOmemoKeysForJid(ownJid.toString()),
);
final bareJid = ownJid.toBare().toString();
@ -346,7 +354,7 @@ class OmemoService {
// Get fingerprints if we have to
await _loadOrFetchFingerprints(ownJid);
final tm = omemoState.trustManager as BlindTrustBeforeVerificationTrustManager;
final tm = omemoManager.trustManager as BlindTrustBeforeVerificationTrustManager;
final trustMap = await tm.getDevicesTrust(bareJid);
for (final deviceId in _fingerprintCache[bareJid]!.keys) {
@ -354,7 +362,7 @@ class OmemoService {
final fingerprint = _fingerprintCache[bareJid]![deviceId]!;
keys.add(
OmemoDevice(
model.OmemoDevice(
fingerprint,
await tm.isTrusted(bareJid, deviceId),
trustMap[deviceId] == BTBVTrustState.verified,
@ -369,7 +377,7 @@ class OmemoService {
}
Future<void> verifyDevice(int deviceId, String jid) async {
final tm = omemoState.trustManager as BlindTrustBeforeVerificationTrustManager;
final tm = omemoManager.trustManager as BlindTrustBeforeVerificationTrustManager;
await tm.setDeviceTrust(
jid,
deviceId,

View File

@ -836,7 +836,7 @@ packages:
description:
path: "packages/moxxmpp"
ref: HEAD
resolved-ref: "09696c1c4d746b2dddba0fb79d47310db708aa24"
resolved-ref: "62001c1e29b644fcf7fe12618d77571853fd073e"
url: "https://git.polynom.me/Moxxy/moxxmpp.git"
source: git
version: "0.1.6+1"
@ -885,12 +885,10 @@ packages:
omemo_dart:
dependency: "direct main"
description:
path: "."
ref: HEAD
resolved-ref: fe1ba99b14b516ecf6d147c57bd986d8afe7f3fc
url: "https://codeberg.org/PapaTutuWawa/omemo_dart.git"
source: git
version: "0.3.2"
name: omemo_dart
url: "https://git.polynom.me/api/packages/PapaTutuWawa/pub/"
source: hosted
version: "0.4.0"
package_config:
dependency: transitive
description:

View File

@ -75,7 +75,7 @@ dependencies:
native_imaging: 0.1.0
omemo_dart:
hosted: https://git.polynom.me/api/packages/PapaTutuWawa/pub
version: 0.3.1
version: 0.4.0
page_transition: 2.0.9
path: 1.8.2
path_provider: 2.0.11
@ -134,19 +134,14 @@ dependency_overrides:
# NOTE: Leave here for development purposes
# moxxmpp:
# path: ../moxxmpp/packages/moxxmpp
#omemo_dart:
# path: ../../Personal/omemo_dart$
# omemo_dart:
# path: ../../Personal/omemo_dart
moxxmpp:
git:
url: https://git.polynom.me/Moxxy/moxxmpp.git
rev: 09696c1c4d746b2dddba0fb79d47310db708aa24
rev: 62001c1e29b644fcf7fe12618d77571853fd073e
path: packages/moxxmpp
omemo_dart:
git:
url: https://codeberg.org/PapaTutuWawa/omemo_dart.git
rev: fe1ba99b14b516ecf6d147c57bd986d8afe7f3fc
extra_licenses:
- name: undraw.co