prekey is defined as `<xs:attribute name="prekey" type="xs:boolean"/>`
which allows both `true` and `1` as truthy values.
Not checking for `1` breaks omemo encryption when interacting with
clients which set prekey="1", example: psi+ 1.4.983
Regards https://github.com/profanity-im/profanity/issues/1247
So far we removed the avatar feature only after a succesful retrive in
avatar_request_item_by_id() before we are going to retrieve the actual
image.
We should remove it at every `/avatar barejid` call too so in case one
retrieval was unsucessful that we can call it again.
So far it seems like there is no other way to trigger getting the nodes
except announcing that we support the avatar feature.
https://github.com/profanity-im/profanity/issues/1190 had another issue:
Sometimes servers send multiple </delay> and we just checked the first
one we got and only used it if the 'from' attribute was fitting.
However it could be that we actually wanted the second </delay> element
and there the 'from' would have been right.
So we need to loop through them until we get the one with the fitting
'from'.
Fix https://github.com/profanity-im/profanity/issues/1190
The problem is that in _handle_groupchat() we look for
STANZA_NS_STABLE_ID which will result in origin-id or stanza-id.
It seems like prosody servers send origin-id first, so this worked in
all my tests. But actually we cannot be sure of the order.
So far we stopped after the first element was found.
I only found xmpp_stanza_get_child_by_ns() and
xmpp_stanza_get_child_by_name() in libstrophe. But we need a combination
of both.
So I created stanza_get_child_by_name_and_ns() for Profanity. I need to
remember to upstream this to libstrophe later (if they really don't have
such a function).
Fix https://github.com/profanity-im/profanity/issues/1223
Profanity sends the same value for both. Other clients might not.
Safe both since we could need them later.
Once we implement Last Message Correction we will need the regular id.
If we override it with origin-id and another client chooses to not use
the same value for id and origin-id then we can't interpret the id sent
with the LMC request correctly.
Some clients (eg. PSI) are sending the stanzas delimited by whitespace
text nodes, which will fail while looping through the <prekeys/>
children and also print weird errors when iterating through the <list/>
of devices.
When debugging this, I was looking at the XML of Gajim and PSI and first
was somehow confused why Profanity printed "OMEMO: received device
without ID" while the XML looked identical (minus the actual IDs and the
JIDs of course).
However, Gajim was sending the XML without whitespace nodes in between
and PSI did not, so for example the following (with the relevant
whitespace nodes marked with X):
<message type="headline" to="..." from="...">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items type="headline" node="eu.siacs.conversations.axolotl.devicelist">
<item id="...">
<list xmlns="eu.siacs.conversations.axolotl">
X <device id="..."/>
X <device id="..."/> X
</list>
</item>
</items>
</event>
<delay xmlns="urn:xmpp:delay" stamp="..." from="..."/>
</message>
... would result in three times the "OMEMO: received device without ID"
error, because we actually have three XML text nodes here that obviously
don't have an "id" attribute.
Now since the <list/> children above aren't really a problem and only
annoying, text nodes in the <prekeys/> stanza actually cause
omemo_start_device_session_handle_bundle to return failure.
I've fixed this by explicitly matching the stanza names we are
interested in, skipping everything else.
Signed-off-by: aszlig <aszlig@nix.build>
Reported-by: @devhell
Also we initialize mucuser properly.
Now in case of a carbon of a MUC PM we sv_ev_incoming_carbon() which
calls _sv_ev_incoming_plain() and then we log it via chat_log_msg_in()
in there.
But we also get the sv_ev_incoming_private_message() and call
chat_log_msg_in() in there too. So the incoming message get's logged
twice.
This caused the bug mentioned in the PR comment:
```
It seems with the changes done here we get a crash in: src/xmpp/message.c message_handlers_init() when looking up handlers: ProfMessageHandler *handler = g_hash_table_lookup(pubsub_event_handlers, curr->data);.
Steps to reproduce:
open Profanity and connect
/autoping set 10
/autoping timeout 10
stop WiFi/connection
wait for Lost connection
restart wifi
/connect
```
So far only with dummy value.
We will need an identifier that we can hash together with a message ID
and put in as the origin-id.
So when we receive message we can unsplit it and see if it was sent from
this client.
Regards https://github.com/profanity-im/profanity/issues/1207
If we get a private message from a user in a MUC profanity shows this
like:
`profanity@roomsASDF.dismail.de/Martin: Hi`
This was so far logged at:
`~/.local/share/profanity/chatlogs/my-account-at-server/profanity_at_rooms.dismail.de/2019_09_04.log` as:
```
10:48:13 - profanity@rooms.dismail.de: Hi
```
So the nickname was not saved anywhere. This is due to us not knowing
whether we got a regular message from user@server.org/resource or a MUC
PM from room@server.org/user.
We now check for `<x xmlns='http://jabber.org/protocol/muc#user' />` and
add the resourcepart to the logging if we get it.
The file will be created at
`~/.local/share/profanity/chatlogs/my-account-at-server/profanity_at_rooms.dismail.de_nick` and look like:
```
23:59:43 - nick: Hi
```
Fix https://github.com/profanity-im/profanity/issues/1184
We didn't set the variables to NULL, but the rest of the code depends on
this check.
```
==22201== Invalid read of size 8
==22201== at 0x44E560: autocomplete_clear (autocomplete.c:69)
==22201== by 0x427B2C: muc_invites_clear (muc.c:190)
==22201== by 0x461328: ev_disconnect_cleanup (common.c:59)
==22201== by 0x463FB5: cl_ev_disconnect (client_events.c:91)
==22201== by 0x431252: cmd_disconnect (cmd_funcs.c:1234)
==22201== by 0x47E883: clears_chat_sessions
(test_cmd_disconnect.c:28)
==22201== by 0x487E9E1: _run_test (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x487ECCC: _run_tests (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x47F1BE: main (unittests.c:629)
==22201== Address 0x814b690 is 0 bytes inside a block of size 24 free'd
==22201== at 0x48379AB: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==22201== by 0x44E5F7: autocomplete_free (autocomplete.c:90)
==22201== by 0x4278A0: muc_close (muc.c:97)
==22201== by 0x47DBAA: cmd_join_uses_password_when_supplied
(test_cmd_join.c:169)
==22201== by 0x487E9E1: _run_test (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x487ECCC: _run_tests (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x47F1BE: main (unittests.c:629)
==22201== Block was alloc'd at
==22201== at 0x483677F: malloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==22201== by 0x44E51B: autocomplete_new (autocomplete.c:57)
==22201== by 0x427837: muc_init (muc.c:88)
==22201== by 0x47DA77: cmd_join_uses_password_when_supplied
(test_cmd_join.c:154)
==22201== by 0x487E9E1: _run_test (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x487ECCC: _run_tests (in /usr/lib64/libcmocka.so.0.7.0)
==22201== by 0x47F1BE: main (unittests.c:629)
```
https://gultsch.de/dino_multiple.html mentions CVE-2019-16235, CVE-2019-16236 and CVE-2019-16237.
CVE-2019-16235: Is checking the from in carbon messages. We do that.
CVE-2019-16236: Is checking the from in roster pushes. We do that but
didn't log it yet.
CVE-2019-16237: Is checking the form in MAM messages. We don't support
them yet.
Double-check that a <delay/> tag on a groupchat message was actually
added by the MUC service (rather than the sending client) before
assuming it was received from the MUC history.
Fixes#1173.
Fix:
```
==18682== 408 bytes in 17 blocks are definitely lost in loss record
3,279 of 3,632
==18682== at 0x483677F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==18682== by 0x42F602: roster_update_presence (roster_list.c:129)
==18682== by 0x448AA3: sv_ev_contact_online (server_events.c:906)
==18682== by 0x43D2BA: _available_handler (presence.c:674)
==18682== by 0x43C81B: _presence_handler (presence.c:398)
==18682== by 0x5AF118E: handler_fire_stanza (handler.c:124)
==18682== by 0x5AEDBDA: _handle_stream_stanza (conn.c:1253)
==18682== by 0x5AFA43E: _end_element (parser_expat.c:190)
==18682== by 0x6818AA4: doContent (xmlparse.c:2977)
==18682== by 0x681A3AB: contentProcessor (xmlparse.c:2552)
==18682== by 0x681D7EB: XML_ParseBuffer (xmlparse.c:1988)
==18682== by 0x681D7EB: XML_ParseBuffer (xmlparse.c:1957)
==18682== by 0x5AF0A63: xmpp_run_once (event.c:255)
==18682== by 0x432E5D: connection_check_events (connection.c:104)
==18682== by 0x4323B3: session_process_events (session.c:255)
==18682== by 0x42C097: prof_run (profanity.c:128)
==18682== by 0x4B25B9: main (main.c:172)
```
omemo_key_free() was called to free the key.
It free the key->data too. But in same cases this was not set yet. So
we need to set the data to NULL (or use calloc) at initialization so
that omemo_key_free() only frees it if it was actually allocated.
Regards https://github.com/profanity-im/profanity/issues/1148
so far only the key part was freed. We also need to free the actual
handler.
Fix:
```
==21171== 1,128 bytes in 47 blocks are definitely lost in loss record
3,476 of 3,670
==21171== at 0x483677F: malloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21171== by 0x434248: iq_id_handler_add (iq.c:265)
==21171== by 0x4B122E: omemo_devicelist_request (omemo.c:46)
==21171== by 0x4AC411: omemo_start_session (omemo.c:409)
==21171== by 0x4AC37C: omemo_start_sessions (omemo.c:396)
==21171== by 0x447881: sv_ev_roster_received (server_events.c:189)
==21171== by 0x444019: roster_result_handler (roster.c:312)
==21171== by 0x433FC2: _iq_handler (iq.c:202)
==21171== by 0x5AF118E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==21171== by 0x5AEDBDA: ??? (in /usr/lib64/libmesode.so.0.0.0)
==21171== by 0x5AFA43E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==21171== by 0x6818AA4: ??? (in /usr/lib64/libexpat.so.1.6.8)
==21171== by 0x681A3AB: ??? (in /usr/lib64/libexpat.so.1.6.8)
==21171== by 0x681D7EB: XML_ParseBuffer (in
/usr/lib64/libexpat.so.1.6.8)
==21171== by 0x5AF0A63: xmpp_run_once (in
/usr/lib64/libmesode.so.0.0.0)
==21171== by 0x432E5D: connection_check_events (connection.c:104)
==21171== by 0x4323B3: session_process_events (session.c:255)
==21171== by 0x42C097: prof_run (profanity.c:128)
==21171== by 0x4B2627: main (main.c:172)
```
Fix:
```
==20561== 32 bytes in 1 blocks are definitely lost in loss record 1,467
of 3,678
==20561== at 0x483677F: malloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20561== by 0x4B16C9: omemo_start_device_session_handle_bundle
(omemo.c:167)
==20561== by 0x43405E: _iq_handler (iq.c:214)
==20561== by 0x5AF118E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==20561== by 0x5AEDBDA: ??? (in /usr/lib64/libmesode.so.0.0.0)
==20561== by 0x5AFA43E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==20561== by 0x6818AA4: ??? (in /usr/lib64/libexpat.so.1.6.8)
==20561== by 0x681A3AB: ??? (in /usr/lib64/libexpat.so.1.6.8)
==20561== by 0x681D7EB: XML_ParseBuffer (in
/usr/lib64/libexpat.so.1.6.8)
==20561== by 0x5AF0A63: xmpp_run_once (in
/usr/lib64/libmesode.so.0.0.0)
==20561== by 0x432E5D: connection_check_events (connection.c:104)
==20561== by 0x4323B3: session_process_events (session.c:255)
==20561== by 0x42C097: prof_run (profanity.c:128)
==20561== by 0x4B260D: main (main.c:172)
```
In some conditions we just returned without freeing allocated variables.
Should fix following valgrind reported leak:
```
==17941== 19 bytes in 1 blocks are definitely lost in loss record 613 of
3,674
==17941== at 0x483677F: malloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==17941== by 0x5BB0DAA: strdup (strdup.c:42)
==17941== by 0x4B1592: omemo_start_device_session_handle_bundle
(omemo.c:126)
==17941== by 0x43405E: _iq_handler (iq.c:214)
==17941== by 0x5AF118E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==17941== by 0x5AEDBDA: ??? (in /usr/lib64/libmesode.so.0.0.0)
==17941== by 0x5AFA43E: ??? (in /usr/lib64/libmesode.so.0.0.0)
==17941== by 0x6818AA4: ??? (in /usr/lib64/libexpat.so.1.6.8)
==17941== by 0x681A3AB: ??? (in /usr/lib64/libexpat.so.1.6.8)
==17941== by 0x681D7EB: XML_ParseBuffer (in
/usr/lib64/libexpat.so.1.6.8)
==17941== by 0x5AF0A63: xmpp_run_once (in
/usr/lib64/libmesode.so.0.0.0)
==17941== by 0x432E5D: connection_check_events (connection.c:104)
==17941== by 0x4323B3: session_process_events (session.c:255)
==17941== by 0x42C097: prof_run (profanity.c:128)
==17941== by 0x4B2610: main (main.c:172)
```
Probably missing copy of body to plain in carbon and privmessage.
Only covers the incoming message path because goal is OMEMO decryption
of untrusted message.
Cover some of the log functions but not all.
We destory the roster in ev_disconnect_cleanup().
Adding a function to test if the roster has been destroyed and testing
for it in the statusbar.
So now when the connection is lost 'Lost connection' is printed in all
open windows.
We can then reconnect with `/connect accountname`.
Should fix https://github.com/profanity-im/profanity/issues/1083
If Profanity is disconnected in any way before ping response is
received, the autoping timer will expire after the next connection
is established. As result, user will be disconnected immediately.
Cancel autoping timer in ev_disconnect_cleanup(), so it is done
for all kind of disconnections.
If connection loss occurs, it calls session_disconnect() eventually.
This function clears saved account data which is required for
reconnection. Therefore, when reconnect timer expires, we get errors:
02/06/2019 04:53:42: stderr: ERR: (profanity:17115): GLib-CRITICAL **:
04:53:42.305: g_key_file_has_group: assertion
'group_name != NULL' failed
02/06/2019 04:53:43: prof: ERR: Unable to reconnect, account no longer
exists: (null)
To solve it, don't clear the saved data in session_disconnect(). It will
be cleared properly on connection loss if reconnect timer is not
configured. But won't be cleared with /disconnect command.
So, after /disconnect the data will live in memory until the next
/connect.
Also, remove some copy-paste in connection loss path.
When connection is lost, profanity tries to disconnect what leads
to an infinite loop. The loop occurs, because connection_disconnet()
runs xmpp_run_once() separately and waits for XMPP_CONN_DISCONNECT
event. But it doesn't happen, because the connection object is
disconnected.
As solution, don't disconnect after XMPP_CONN_DISCONNECT is received.
Also, don't free libstrophe objects while the event loops executes,
because the event loop continues using objects after callbacks quit.
Presence of contact not found in roster are filtered out.
But sometimes roster is received after a first few presences.
We choose to store presences until we receive roster and then process
this presences.
Fixes#1050
When auto joining a MUC we don't have access to required information so
we just don't start OMEMO at this time.
Once we receive disco info we then try to start OMEMO.
When connecting for the first time or when creating a new account don't
use only 'profanity' as default resource.
Some server don't support having 2 connection with same resource. Using
profanity as default lead to deconnections.
Reflected messages can't be filtered by nick only otherwise you might
ignore messages comming from you on another devices.
Consequently we maintain a list of sent messages id in mucwin.
To be sure the id will be correctly reflected we use the origin-id
stanza.
Ensure we request device_list and remove non conforming handling of
responses.
Move initialisation of iq_handlers before call to sv_ev_login_account_success
Store hints are required has some server might discard messages without
body. Here we ensure OMEMO messages are stored on server and delivered
to client when they connect back.
It's really important since it avoid libsignal to desynchronize
counters.
We try to decrypt all messages, if it's successful we use
sv_ev_incoming_message even for OMEMO messages. We pass an OMEMO
boolean to let UI be aware that message were encrypted.
With all the different kinds of encryption (OMEMO, OTR3 OTR4, PGP in XEP-0027 and XEP-0373) it might be helpful to know which kind of encryption is used.
New tls policy "trust" added to /connect and /account. With the policy
TLS connection is established even with invalid certificate. Note, that
trust policy forces TLS connection and it fails when server doesn't
support TLS.
Examples:
/connect <jid> tls trust
/account <name> set tls trust
Move `p_sha1_hash()` from `common.c` to `xmpp/stanza.c` as it is only
used in this file and now depends on libstrophe so xmpp is a better
namespace folder.
Renaming it as `_stanza_create_sha1_hash()`. And making static since
only used here.
The function cannot be tested in the unit tests anymore.
Once functional tests are working again we should write a test for the
sha1 functionality.
create_unique_id() was changed to use UUIDs instead of a counter in the
last commit. Since now it depends on connection_create_uuid() which is
in the xmpp subfolder the function should also be moved there.
Renamed it to connection_create_stanza_id() and moved it to
src/xmpp/connection.c.
Discussion happened in https://github.com/boothj5/profanity/pull/1010
Add "legacy" tls policy to /account and /connect commands. When this
policy is specified the connection is connected with
XMPP_CONN_LEGACY_SSL flag. Notice, legacy SSL and STARTTLS are not
compatible and user has to know when exactly the new policy should be
used.
To enable it, run one of the next commands:
/connect <jid> tls legacy [server <host>]
/account <name> set tls legacy
Notice, there is no SRV record for legacy SSL. Therefore, you may need
"server" property to connect successfully. Refer to configuration
provided by your server.