Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/profanity.1
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,23 @@ You can only enable one of them per correspondent at a time.
OMEMO (/omemo) is defined in XEP-0384. It uses an implementation of the Signal protocol for key management and to synchronize messages among different clients. It works even when other clients are offline. And offers Perfect Forward Secrecy and Plausible deniability. Servers need to support PEP (XEP-0163).
We implement the "siacs" version of OMEMO. Version 0.3.0, which is currently the widest adopted option.
OMEMO is the only encryption option in Profanity that also supports encryption for MUCs (XEP-0045) and file transfer via HTTP upload (XEP-0363).
.PP
The OMEMO session status is shown in the title bar of the chat window:
.br
- \fB[OMEMO] [untrusted]\fR: OMEMO is enabled, but one or more active devices for the contact are untrusted.
.br
- \fB[OMEMO] [trusted]\fR: OMEMO is enabled, and all active devices for the contact are trusted.
.TP
.BR OTR
OTR (/otr) is defined in XEP-0364. It uses a combination of the AES symmetric-key algorithm, the Diffie–Hellman key exchange, and the SHA-1 hash function. It offers deniable authentication and Perfect Forward Secrecy. To initialize a session both clients need to be online at the same time. A session is between two clients, so multiclient chats are not working. Which is a feature not a bug. OTR does by design not work for MUCs.
.PP
The OTR session status is shown in the title bar of the chat window:
.br
- \fB[OTR] [inactive]\fR: OTR is enabled but the secure session is currently inactive or ended (can happen when the contact went offline). Outgoing messages are blocked from being sent in plaintext. You must start OTR again or use \fB/otr end\fR to disable the safety guard.
.br
- \fB[OTR] [untrusted]\fR: OTR session is active but the contact's fingerprint is unverified.
.br
- \fB[OTR] [trusted]\fR: OTR session is active and the contact's identity is authenticated.
.TP
.BR OpenPGP
OpenPGP (/pgp) is defined in XEP-0027. Is uses a public and secret key. It is also known as Legacy OpenPGP and has been deprecated. It doesn't provide protection against replay attacks. MUCs and file transfer via HTTP upload are not specified and thus not supported.
Expand Down
10 changes: 7 additions & 3 deletions src/command/cmd_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,11 @@ static const struct cmd_t command_defs[] = {
"/otr char <char>",
"/otr sendfile on|off")
CMD_DESC(
"Off The Record (OTR) commands to manage keys, and perform OTR encryption during chat sessions.")
"Off The Record (OTR) commands to manage keys, and perform OTR encryption during chat sessions.\n"
"The title bar will show the OTR session status:\n"
"[OTR] [inactive]: session inactive, plaintext blocked\n"
"[OTR] [untrusted]: session active, unverified fingerprint\n"
"[OTR] [trusted]: session active, authenticated.")
CMD_ARGS(
{ "libver", "Show which version of the libotr library is being used." },
{ "gen", "Generate your private key." },
Expand Down Expand Up @@ -2328,8 +2332,8 @@ static const struct cmd_t command_defs[] = {
CMD_DESC(
"OMEMO commands to manage keys, and perform encryption during chat sessions.\n"
"The title bar will show the OMEMO session status:\n"
"[OMEMO][trusted] - All active devices for the contact are trusted.\n"
"[OMEMO][untrusted] - One or more active devices for the contact are untrusted.\n")
"[OMEMO] [trusted] - All active devices for the contact are trusted.\n"
"[OMEMO] [untrusted] - One or more active devices for the contact are untrusted.")
CMD_ARGS(
{ "gen", "Generate OMEMO cryptographic materials for current account." },
{ "start [<contact>]", "Start an OMEMO session with contact, or current recipient if omitted." },
Expand Down
2 changes: 1 addition & 1 deletion src/command/cmd_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -8000,7 +8000,7 @@ cmd_otr_end(ProfWin* window, const char* const command, gchar** args)
return TRUE;
}

chatwin_otr_unsecured(chatwin);
chatwin_otr_unsecured(chatwin, TRUE);
otr_end_session(chatwin->barejid);
return TRUE;
#else
Expand Down
10 changes: 1 addition & 9 deletions src/event/server_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ sv_ev_lost_connection(void)
char* barejid = curr->data;
ProfChatWin* chatwin = wins_get_chat(barejid);
if (chatwin && otr_is_secure(barejid)) {
chatwin_otr_unsecured(chatwin);
chatwin_otr_unsecured(chatwin, FALSE);
otr_end_session(barejid);
}
curr = g_slist_next(curr);
Expand Down Expand Up @@ -798,14 +798,6 @@ sv_ev_contact_offline(char* barejid, char* resource, char* status)
ui_contact_offline(barejid, resource, status);
}

#ifdef HAVE_LIBOTR
ProfChatWin* chatwin = wins_get_chat(barejid);
if (chatwin && otr_is_secure(barejid)) {
chatwin_otr_unsecured(chatwin);
otr_end_session(chatwin->barejid);
}
#endif

rosterwin_roster();
chat_session_remove(barejid);
}
Expand Down
8 changes: 7 additions & 1 deletion src/otr/otr.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ otr_on_message_send(ProfChatWin* chatwin, const char* const message, gboolean re
return TRUE;
}

if (chatwin->is_otr && !otr_is_secure(chatwin->barejid)) {
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "%s", "Failed to send message: OTR session is not active.");
win_println((ProfWin*)chatwin, THEME_DEFAULT, "-", "%s", "Use '/otr end' to intentionally send unencrypted messages.");
return TRUE;
}

// tag and send for policy opportunistic
if (policy == PROF_OTRPOLICY_OPPORTUNISTIC) {
auto_char char* otr_tagged_msg = otr_tag_message(message);
Expand Down Expand Up @@ -691,7 +697,7 @@ otr_decrypt_message(const char* const from, const char* const message, gboolean*
otrl_context_force_plaintext(context);
ProfChatWin* chatwin = wins_get_chat(from);
if (chatwin) {
chatwin_otr_unsecured(chatwin);
chatwin_otr_unsecured(chatwin, FALSE);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ api_encryption_reset(const char* const barejid)

#ifdef HAVE_LIBOTR
if (chatwin->is_otr) {
chatwin_otr_unsecured(chatwin);
chatwin_otr_unsecured(chatwin, TRUE);
otr_end_session(chatwin->barejid);
}
#endif
Expand Down
6 changes: 4 additions & 2 deletions src/ui/chatwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,13 @@ chatwin_otr_secured(ProfChatWin* chatwin, gboolean trusted)
}

void
chatwin_otr_unsecured(ProfChatWin* chatwin)
chatwin_otr_unsecured(ProfChatWin* chatwin, gboolean disable_otr)
{
assert(chatwin != NULL);

chatwin->is_otr = FALSE;
if (disable_otr) {
chatwin->is_otr = FALSE;
}
chatwin->otr_is_trusted = FALSE;

ProfWin* window = (ProfWin*)chatwin;
Expand Down
62 changes: 47 additions & 15 deletions src/ui/titlebar.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#endif
#include "xmpp/roster_list.h"
#include "xmpp/chat_session.h"
#ifdef HAVE_LIBOTR
#include "otr/otr.h"
#endif

static WINDOW* win;
static contact_presence_t current_presence;
Expand Down Expand Up @@ -454,8 +457,10 @@ _show_privacy(ProfChatWin* chatwin)
int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET);
int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED);
int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED);
#if defined(HAVE_LIBOTR) || defined(HAVE_OMEMO)
int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED);
int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED);
#endif

if (chatwin->enctext) {
wprintw(win, " ");
Expand Down Expand Up @@ -491,34 +496,61 @@ _show_privacy(ProfChatWin* chatwin)
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, encrypted_attrs);
wprintw(win, "OTR");
wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
if (chatwin->otr_is_trusted) {
wprintw(win, " ");
#ifdef HAVE_LIBOTR
if (otr_is_secure(chatwin->barejid)) {
wprintw(win, "OTR");
wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "[");
wprintw(win, "]");
wattroff(win, bracket_attrs);
wattron(win, trusted_attrs);
wprintw(win, "trusted");
wattroff(win, trusted_attrs);
if (chatwin->otr_is_trusted) {
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, trusted_attrs);
wprintw(win, "trusted");
wattroff(win, trusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
} else {
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, untrusted_attrs);
wprintw(win, "untrusted");
wattroff(win, untrusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
} else {
wprintw(win, "OTR");
wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
} else {

wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, untrusted_attrs);
wprintw(win, "untrusted");
wattroff(win, untrusted_attrs);
wattron(win, unencrypted_attrs);
wprintw(win, "inactive");
wattroff(win, unencrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
#else
wprintw(win, "OTR");
wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
#endif

return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void chatwin_contact_offline(ProfChatWin* chatwin, char* resource, char* status)
gchar* chatwin_get_string(ProfChatWin* chatwin);
#ifdef HAVE_LIBOTR
void chatwin_otr_secured(ProfChatWin* chatwin, gboolean trusted);
void chatwin_otr_unsecured(ProfChatWin* chatwin);
void chatwin_otr_unsecured(ProfChatWin* chatwin, gboolean disable_otr);
void chatwin_otr_trust(ProfChatWin* chatwin);
void chatwin_otr_untrust(ProfChatWin* chatwin);
void chatwin_otr_smp_event(ProfChatWin* chatwin, prof_otr_smp_event_t event, void* data);
Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/ui/stub_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ chatwin_otr_secured(ProfChatWin* chatwin, gboolean trusted)
{
}
void
chatwin_otr_unsecured(ProfChatWin* chatwin)
chatwin_otr_unsecured(ProfChatWin* chatwin, gboolean disable_otr)
{
}
void
Expand Down
Loading