Age | Commit message (Collapse) | Author |
|
Functions (Room::Private::)createOlmSession, payloadForUserDevice
and sendRoomKeyToDevices don't have a lot to do with the given Room
object but deal with quite a few things stored in Connection. This
commit moves them to Connection::Private, exposing
sendSessionKeyToDevices (the new name for sendRoomKeyToDevices) in
Connection so that Room could call it from Room::P::sendMegolmSession().
While moving these over, a few additional things were adjusted:
- more functions marked as const
- a few functions could be moved now from Connection
to Connection::Private
- false slots in Connection (such as picklingMode) are moved out of
the slots block
- keys.yml in Matrix CS API definitions has been adjusted to match
the real structure of `/claim` response (see quotient-im/matrix-spec
repo); csapi/keys.h has been regenerated accordingly.
|
|
Notably, replace a multi-level hash map with QMultiHash and factor out
Room::P::createOlmSession().
|
|
|
|
|
|
These are not operations on EncryptedFileMetadata but rather on
a combination of EncryptedFileMetadata and ciphertext. If C++ had
multimethods these could be bound to such a combination.
|
|
|
|
Besides having a misleading name (and it goes back to the spec),
EncryptedFile under `file` key preempts the `url` (or `thumbnail_url`)
string value so only one of the two should exist. This is a case for
using std::variant<> - despite its clumsy syntax, it can actually
simplify and streamline code when all the necessary bits are in place
(such as conversion to JSON and getting the common piece - the URL -
out of it). This commit replaces `FileInfo::url` and `FileInfo::file`
with a common field `source` of type `FileSourceInfo` that is an alias
for a variant type covering both underlying types; and `url()` is
reintroduced as a function instead, to allow simplified access
to whichever URL is available inside the variant.
Oh, and EncryptedFile is EncryptedFileMetadata now, to clarify that it
does not represent the file payload itself but rather the data necessary
to obtain that payload.
|
|
Truncate ciphertext buffer to actual size during file encryption
|
|
Co-authored-by: Alexey Rusakov <Kitsune-Ral@users.sf.net>
|
|
The ciphertext for AES CTR is exactly as large as the plaintext (not
necessarily a multiple of the blocksize!). By truncating the ciphertext,
we do not send bytes that will be decrypted to gibberish.
As a side node, we probably do not need to initialize the ciphertext
buffer larger than the plaintext size at all, but the OpenSSL docs are a
bit vague about that.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Co-authored-by: Alexey Rusakov <Kitsune-Ral@users.sf.net>
|
|
|
|
|
|
Co-authored-by: Alexey Rusakov <Kitsune-Ral@users.sf.net>
|
|
Co-authored-by: Alexey Rusakov <Kitsune-Ral@users.sf.net>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[skip ci]
|
|
As mentioned in the commit introducing `Expected`, `QOlmExpected` is
simply an alias for `Expected<T, QOlmError>`. This simplifies quite
a few function signatures in `QOlm*` classes and collapses unwieldy
`std::holds_alternative<>`/`std::get<>` constructs into a neat
contextual bool cast and an invocation of `operator*` or
`value()`/`error()` accessors that don't need to specify the type.
While refactoring the code, I found a couple of cases of mismatching
`uint32_t` and `qint32_t` in return values; a couple of cases where
`decrypt()` returns `QString` which is in fact `QByteArray` (e.g., in
`QOlmSession::decrypt()`); there's a repetitive algorithm in
`Connection::Private::sessionDecryptPrekey()` and
`sessionDecryptGeneral()`
|
|
There's no particular use in letting `QOlmError` out, only to confirm
that, well, `QOlmError` is just another form of no-match.
|
|
Making Qt signals const is an impossible commitment - once the signal
is out, you can't control if any called slot will change the emitting
class or not. The code compiles but const-ness is not preserved.
|
|
This is a minimal implementation along the lines of `std::expected<>`
introduced in C++23; once compilers catch up with C++23 support, it may
become simply a typedef of std::expected. There are no tests as yet; but
the following commits will introduce QOlmExpected that would replace
the current `std::variant<T, QOlmError>` pattern used throughout `QOlm*`
classes, automatically pulling Expected under the coverage of `QOlm*`
unit tests.
|
|
|
|
|
|
Mainly driven by clang-tidy and SonarCloud warnings (sadly, SonarCloud
doesn't store historical reports so no link can be provided here).
|
|
See https://github.com/matrix-org/matrix-spec/pull/1054.
# Conflicts:
# lib/events/callanswerevent.cpp
# lib/events/callanswerevent.h
|
|
QCoreApplication::processEvents() is well-known to be a _wrong_ solution
to the unresponsive UI problem; despite that, connection.cpp has long
had that call to let UI update itself while processing bulky room
updates (mainly from the initial sync). This commit finally fixes this,
after an (admittedly rare) race condition has been hit, as follows:
0. Pre-requisite: quotest runs all the tests and is about to leave
the room; there's an ongoing sync request.
1. Quotest calls /leave
2. Sync returns, with the batch of _several_ rooms (that's important)
3. The above code handles the first room in the batch
4. processEvents() is called, just in time for the /leave response.
5. The /leave response handler in quotest ends up calling
Connection::logout() (processEvents() still hasn't returned).
6. Connection::logout() calls abandon() on the ongoing SyncJob,
pulling the rug from under onSyncSuccess()/consumeRoomData().
7. processEvents() returns and the above code proceeds to the next
room - only to find that the roomDataList (that is a ref to
a structure owned by SyncJob), is now pointing to garbage.
Morals of the story:
1. processEvents() effectively makes code multi-threaded: one flow is
suspended and another one may run _on the same data_. After the first
flow is resumed, it cannot make any assumptions regarding which data
the second flow touched and/or changed.
2. The library had quite a few cases of using &&-refs, avoiding even
move operations but also leaving ownership of the data with the
original producer (SyncJob). If the lifetime of that producer ends
too soon, those refs become dangling.
The fix makes two important things, respectively:
2. Ownership of room data is now transfered to the processing side,
the moment it is scheduled (see below), in the form of moving
into a lambda capture.
1. Instead of processEvents(), processing of room data is scheduled
via QMetaObject::invokeMethod(), uncoupling the moment when the
data was received in SyncJob from the moment they are processed
in Room::updateData() (and all the numerous signal-slots it calls).
Also: Room::baseStateLoaded now causes Connection::loadedRoomState, not
the other way round - this is more natural and doesn't need Connection
to keep firstTimeRooms map around.
|
|
|
|
To streamline adding of simple getters of content parts.
|
|
QPair is giving way to its STL counterpart, becoming its alias in Qt 6.
|
|
|
|
This macro was defined in accountdataevents.h but adding one more
parameter (base class) makes it applicable to pretty much any event
with the content that has one key-value pair (though state events
already have a non-macro solution in the form of
`StateEvent<EventContent::SingleKeyValue>`). Now CustomEvent definition
in quotest.cpp can be replaced with a single line.
|
|
Not that it was very important, as the two are basically the same thing
(and matrixTypeId() is about to be obsoleted); but formally basicJson()
is supposed to get the former, not the latter.
|
|
This makes it easier and more intuitive to build a minimal JSON payload
for a given event type. A common basicJson() call point is also
convenient in template contexts (see next commits).
|
|
EventContent::Base has been made primarily for the sake of dynamic
polymorphism needed within RoomMessageEvent content (arguably, it might
not be really needed even there, but that's a bigger matter for another
time). When that polymorphism is not needed, it's easier for reading
and maintenance to have toJson() member function (or even specialise
JsonConverter<> outside of the content structure) instead of deriving
from EC::Base and then still having fillJson() member function. This
commit removes EventContent::Base dependency where it's not beneficial.
|