mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
OMEMO: Fail if message keys couldn't be encrypted for any recipient device
If the message (key) can't be encrypted for any device, sending the message is refused and an informative error message is presented to the user. Also, don't encrypt for the same device, since the OMEMO XEP disallows this.
This commit is contained in:
parent
9e0d0ed466
commit
e8664e2730
@ -2151,22 +2151,21 @@ cmd_msg(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
ProfChatWin* chatwin = wins_get_chat(barejid);
|
ProfChatWin* chatwin = wins_get_chat(barejid);
|
||||||
if (!chatwin) {
|
if (!chatwin) {
|
||||||
// NOTE: This will also start the new OMEMO session
|
// NOTE: This will also start the new OMEMO session and send a MAM request.
|
||||||
// and send a MAM request.
|
|
||||||
chatwin = chatwin_new(barejid);
|
chatwin = chatwin_new(barejid);
|
||||||
}
|
}
|
||||||
ui_focus_win((ProfWin*)chatwin);
|
ui_focus_win((ProfWin*)chatwin);
|
||||||
|
|
||||||
if (msg) {
|
if (msg) {
|
||||||
// FIXME [OMEMO] We can't be sure whether the
|
// NOTE: In case the message is OMEMO encrypted, we can't be sure
|
||||||
// bundles have already been receieved. Thus, it is
|
// whether the key bundles of the recipient have already been
|
||||||
// possible (and probable) that the recipent can't
|
// received. In the case that *no* bundles have been received yet,
|
||||||
// encrypt the message.
|
// the message won't be sent, and an error is shown to the user.
|
||||||
|
// Other cases are not handled here.
|
||||||
cl_ev_send_msg(chatwin, msg, NULL);
|
cl_ev_send_msg(chatwin, msg, NULL);
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_LIBOTR
|
#ifdef HAVE_LIBOTR
|
||||||
// Start the OTR session after this (i.e. the
|
// Start the OTR session after this (i.e. the first) message was sent
|
||||||
// first) message was sent
|
|
||||||
if (otr_is_secure(barejid)) {
|
if (otr_is_secure(barejid)) {
|
||||||
chatwin_otr_secured(chatwin, otr_is_trusted(barejid));
|
chatwin_otr_secured(chatwin, otr_is_trusted(barejid));
|
||||||
}
|
}
|
||||||
|
@ -705,6 +705,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
memcpy(key_tag, key, AES128_GCM_KEY_LENGTH);
|
memcpy(key_tag, key, AES128_GCM_KEY_LENGTH);
|
||||||
memcpy(key_tag + AES128_GCM_KEY_LENGTH, tag, AES128_GCM_TAG_LENGTH);
|
memcpy(key_tag + AES128_GCM_KEY_LENGTH, tag, AES128_GCM_TAG_LENGTH);
|
||||||
|
|
||||||
|
// List of barejids of the recipients of this message
|
||||||
GList* recipients = NULL;
|
GList* recipients = NULL;
|
||||||
if (muc) {
|
if (muc) {
|
||||||
ProfMucWin* mucwin = (ProfMucWin*)win;
|
ProfMucWin* mucwin = (ProfMucWin*)win;
|
||||||
@ -727,6 +728,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
|
|
||||||
omemo_ctx.identity_key_store.recv = false;
|
omemo_ctx.identity_key_store.recv = false;
|
||||||
|
|
||||||
|
// Encrypt keys for the recipients
|
||||||
GList* recipients_iter;
|
GList* recipients_iter;
|
||||||
for (recipients_iter = recipients; recipients_iter != NULL; recipients_iter = recipients_iter->next) {
|
for (recipients_iter = recipients; recipients_iter != NULL; recipients_iter = recipients_iter->next) {
|
||||||
GList* recipient_device_id = NULL;
|
GList* recipient_device_id = NULL;
|
||||||
@ -772,6 +774,17 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
|
|
||||||
g_list_free_full(recipients, free);
|
g_list_free_full(recipients, free);
|
||||||
|
|
||||||
|
// Don't send the message if no key could be encrypted.
|
||||||
|
// (Since none of the recipients would be able to read the message.)
|
||||||
|
if (keys == NULL) {
|
||||||
|
win_println(win, THEME_ERROR, "!", "This message cannot be decrypted for any recipient.\n"
|
||||||
|
"You should trust your recipients' device fingerprint(s) using \"/omemo fingerprint trust FINGERPRINT\".\n"
|
||||||
|
"It could also be that the key bundle of the recipient(s) have not been received. "
|
||||||
|
"In this case, you could try \"omemo end\", \"omemo start\", and send the message again.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt keys for the sender
|
||||||
if (!muc) {
|
if (!muc) {
|
||||||
GList* sender_device_id = g_hash_table_lookup(omemo_ctx.device_list, jid->barejid);
|
GList* sender_device_id = g_hash_table_lookup(omemo_ctx.device_list, jid->barejid);
|
||||||
for (device_ids_iter = sender_device_id; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) {
|
for (device_ids_iter = sender_device_id; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) {
|
||||||
@ -784,6 +797,12 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
.device_id = GPOINTER_TO_INT(device_ids_iter->data)
|
.device_id = GPOINTER_TO_INT(device_ids_iter->data)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Don't encrypt for this device (according to
|
||||||
|
// <https://xmpp.org/extensions/xep-0384.html#encrypt>).
|
||||||
|
if (address.device_id == omemo_ctx.device_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_error("[OMEMO] cannot create cipher for %s device id %d", address.name, address.device_id);
|
log_error("[OMEMO] cannot create cipher for %s device id %d", address.name, address.device_id);
|
||||||
@ -808,6 +827,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send the message
|
||||||
if (muc) {
|
if (muc) {
|
||||||
ProfMucWin* mucwin = (ProfMucWin*)win;
|
ProfMucWin* mucwin = (ProfMucWin*)win;
|
||||||
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
|
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
|
||||||
|
Loading…
Reference in New Issue
Block a user