From 4cbfe219147df4dff1e312d542357fa49b4ad3d8 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 17:42:30 +0200 Subject: [PATCH 01/15] Remove developer notes on OX This was done before OX was implemented. In 0.10 ox landed in Profanity and we have the blogpost: https://profanity-im.github.io/blog/post/openpgp-for-xmpp-ox/ to describe the usage. We will have a man page to help users with the setup as well. --- docs/profanity-ox.md | 76 -------------------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 docs/profanity-ox.md diff --git a/docs/profanity-ox.md b/docs/profanity-ox.md deleted file mode 100644 index d9513bae..00000000 --- a/docs/profanity-ox.md +++ /dev/null @@ -1,76 +0,0 @@ -# Profanity - OpenPGP for XMPP - -Implementation of XEP-0373 - OpenPGP for XMPP (OX) in profanity. - -## Overview -The current version (2020-05-23) of profanity provides *XEP-0027: Current Jabber -OpenPGP Usage* via the `/pgp` command. This XEP is *Obsolete*. We should -implement *XEP-0373 - OpenPGP for XMPP (OX)* in profanity. - -## pgp - -``` -14:37:52 - Synopsis -14:37:52 - /pgp libver -14:37:52 - /pgp keys -14:37:52 - /pgp contacts -14:37:52 - /pgp setkey -14:37:52 - /pgp start [] -14:37:52 - /pgp end -14:37:52 - /pgp log on|off|redact -14:37:52 - /pgp char -14:37:52 - -14:37:52 - Description -14:37:52 - Open PGP commands to manage keys, and perform PGP encryption during chat sessions. See the /account command to set your own PGP key. -14:37:52 - -14:37:52 - Arguments -14:37:52 - libver : Show which version of the libgpgme library is being used. -14:37:52 - keys : List all keys known to the system. -14:37:52 - contacts : Show contacts with assigned public keys. -14:37:52 - setkey : Manually associate a contact with a public key. -14:37:52 - start [] : Start PGP encrypted chat, current contact will be used if not specified. -14:37:52 - end : End PGP encrypted chat with the current recipient. -14:37:52 - log on|off : Enable or disable plaintext logging of PGP encrypted messages. -14:37:52 - log redact : Log PGP encrypted messages, but replace the contents with [redacted]. This is the default. -14:37:52 - char : Set the character to be displayed next to PGP encrypted messages. -``` -## OX -We should implement the `/ox` command which can be used for XEP-0373 instead of -XEP-0027. - -``` -/ox keys - List all public keys known to the system (gnupg's keyring) -/ox contacts - Shows contacts with an assigned public key. -``` - -The `keys` command will list all public keys of gnupg's Keyring, independent if -the key is in use for XMPP or not. - -In profanity we are going to implement the key lookup with a XMPP-URI as OpenPGP -User-ID. An OpenPGP public key can only be used, if the owner of the public key -created an User-ID with the XMPP-URI as Name. https://xmpp.org/extensions/xep-0373.html#openpgp-user-ids -It's not required and possible to assign a contact to an public key. - -``` -sec rsa3072 2020-05-01 [SC] [verfällt: 2022-05-01] - 7FA1EB8644BAC07E7F18E7C9F121E6A6F3A0C7A5 -uid [ ultimativ ] Doctor Snuggles -uid [ ultimativ ] xmpp:doctor.snuggles@domain.tld -ssb rsa3072 2020-05-01 [E] [verfällt: 2022-05-01] -``` - -The `contacts` command will show all contacts of the roster with a public key in -the keyring, if there is a xmpp user-id within the public key. - -OX provides the elements: ``, `` and ``. Profanity -implements signcrypt, only. - - -## Keys command -The command `keys` is independent of the XEP. Should we move common commands -(e.g. /pgp keys /ox keys) to /openpgp which will will be the function which are -related to gnupg itself. - -## Appendix - -* https://xmpp.org/extensions/xep-0373.html - 0.4.0 (2018-07-30) From 411887e4434e02cc2a37323b5d34ce5bfa1637d2 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 17:45:54 +0200 Subject: [PATCH 02/15] Add draft of OX setup manpage This man page should help people to set up OX in profanity. We have profanity-ox.1 which is the same as `/help ox` and describes how to use OX. This man page will help with the setup with the external gpg program. Based on the blogpost of Stefan: https://profanity-im.github.io/blog/post/openpgp-for-xmpp-ox/ --- docs/profanity-ox-setup.1 | 153 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 docs/profanity-ox-setup.1 diff --git a/docs/profanity-ox-setup.1 b/docs/profanity-ox-setup.1 new file mode 100644 index 00000000..58f8da41 --- /dev/null +++ b/docs/profanity-ox-setup.1 @@ -0,0 +1,153 @@ +.TH man 1 "2022-05-03" "0.12.1" "Profanity XMPP client" +.SH NAME +Profanity \- a simple console based XMPP chat client. +.SH DESCRIPTION +.ie "\f[CB]x\f[]"x" \{\ +. ftr V B +. ftr VI BI +. ftr VB B +. ftr VBI BI +.\} +.el \{\ +. ftr V CR +. ftr VI CI +. ftr VB CB +. ftr VBI CBI +.\} +.PP +This man page is intended to help you set up XEP-0374: OpenPGP for XMPP +Instant Messaging. +Also known as OX. +.PP +For details on usage see man profanity-ox or \f[V]/help ox\f[R]. +.PP +Profanity wants to give the user a maximum freedom in setting up their +system. +So we won\[cq]t touch your GPG settings directly. +Which means you will need to do some manual steps. +They are described here +.SH Generate OpenPGP key materials +.PP +The first step is to create a OpenPGP key pair. +The key pair generation will be done with the \f[V]gpg\f[R] command of +GnuPG. +.IP +.nf +\f[C] +gpg --quick-generate-key xmpp:alice\[at]domain.tld future-default default 3y +\f[R] +.fi +.PP +This command will generated a OpenPGP key with a UID +\f[V]xmpp:alice\[at]domain.tld\f[R]. +The option \f[V]future-default\f[R] has been used to generate a +ed25519/cv25519 key. +The key is set to expire in threeyears. +.PP +Replace the Jabber ID with your JID and do \f[B]not\f[R] forget the URI +\f[V]xmpp:\f[R] prefix. +.PP +Example output: +.IP +.nf +\f[C] +pub ed25519 2021-09-21 [SC] [verf\[:a]llt: 2024-09-20] + 583BAE703A801095B6B71A56BD801174B1A0B84A +uid xmpp:alice\[at]domain.tld +sub cv25519 2021-09-21 [E] +\f[R] +.fi +.SH Export your public key +.PP +You need to export your public key so you can later upload it into a PEP +node. +It\[cq]s just a way how your chat partners can retrieve the public key +from you. +Use the command below to export public key: +.PP +Example command: +.IP +.nf +\f[C] +gpg --export \[rs] + --export-options export-minimal \[rs] + --export-filter \[aq]keep-uid=uid =\[ti] xmpp:alice\[at]domain.tld\[aq] \[rs] + --export-filter \[aq]drop-subkey=usage =\[ti] a\[aq] \[rs] + 583BAE703A801095B6B71A56BD801174B1A0B84A \[rs] + > /tmp/pep-key.gpg +\f[R] +.fi +.PP +The key will be exported to \f[V]/tmp/pep-key.gpg\f[R]. +You may check the key with the command below: +.PP +\f[V]gpg --show-key --with-sig-list /tmp/pep-key.gpg\f[R] +.PP +Keep in mind: Public keys may have some information (signatures, name, +e-mail address). +Be careful which data will be exported. +The \f[V]export-options\f[R] and \f[V]export-filter\f[R] option of GnuPG +will help you to filter the data. +.SH Publish your key +.PP +You can use profanity to publish your exported key into your account +(PEP). +The \f[V]/ox announce\f[R] command will publish your key. +.IP +.nf +\f[C] +/ox announce /tmp/pep-key.gpg +\f[R] +.fi +.PP +The command will create two PEP node records to store the key. +.SH Discover keys +.PP +To discover public keys of your partners use the \f[V]/ox discover\f[R] +command. +.PP +Example output: +.IP +.nf +\f[C] +/ox discover buddy\[at]domain.tld +Discovering Public Key for buddy\[at]domain.tld +1234567890ABCDEF1234567890ABCDEF12345678 +\f[R] +.fi +.PP +To request and import a key, you can use the \f[V]/ox request\f[R] +command. +.IP +.nf +\f[C] +/ox request buddy\[at]domain.tld 1234567890ABCDEF1234567890ABCDEF12345678 +Requesting Public Key 1234567890ABCDEF1234567890ABCDEF12345678 for buddy\[at]domain.tld +Public Key imported +\f[R] +.fi +.PP +The key will be imported into your gnupg keyring. +.SH Sign the imported key +.PP +The key can been shown via gpg +\f[V]gpg -k xmpp:buddy\[at]domain.tld\f[R]. +Make sure the key is the key of your buddy and sign the key with your +key. +.IP +.nf +\f[C] +gpg --ask-cert-level --default-key 583BAE703A801095B6B71A56BD801174B1A0B84A --sign-key 1234567890ABCDEF1234567890ABCDEF12345678 +\f[R] +.fi +.PP +The command \f[V]/ox contacts\f[R] will show the keys with XMPP-UID. +The command \f[V]/ox keys\f[R] will show all known OpenPGP keys. +.PP +Only once you signed the key you can actually use OX with your partner. +.SH Use OX +.PP +Within a chat window you can start OX via \f[V]/ox start\f[R] and stop +it via \f[V]/ox end\f[R]. +.PP +Messages will be send signed and encrypted. From e9f218cdf6e15f4469d77cbaee59cc8501ed4e82 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 18:20:11 +0200 Subject: [PATCH 03/15] ox: use pubsub acces model open when announce ox public key --- src/xmpp/ox.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index 0fa5cece..ce43ed89 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -143,6 +143,13 @@ ox_announce_public_key(const char* const filename) xmpp_stanza_add_child(publish, item); xmpp_stanza_add_child(pubsub, publish); xmpp_stanza_add_child(iq, pubsub); + + if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) { + stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open"); + } else { + log_debug("[OX] Cannot publish public key: no PUBSUB feature announced"); + } + xmpp_send(connection_get_conn(), iq); _ox_metadata_node__public_key(fp); From 794bd25cd9c81674f0a3cb0db1848a063efe26ab Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 18:27:20 +0200 Subject: [PATCH 04/15] ox: use iq_send_stanza instead of xmpp_send --- src/xmpp/ox.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index ce43ed89..6f767550 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -42,6 +42,7 @@ #include "ui/ui.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" +#include "xmpp/iq.h" #include "pgp/gpg.h" #ifdef HAVE_LIBGPGME @@ -150,7 +151,8 @@ ox_announce_public_key(const char* const filename) log_debug("[OX] Cannot publish public key: no PUBSUB feature announced"); } - xmpp_send(connection_get_conn(), iq); + iq_send_stanza(iq); + xmpp_stanza_release(iq); _ox_metadata_node__public_key(fp); @@ -198,7 +200,8 @@ ox_discover_public_key(const char* const jid) xmpp_stanza_add_child(iq, pubsub); xmpp_id_handler_add(connection_get_conn(), _ox_metadata_result, id, strdup(jid)); - xmpp_send(connection_get_conn(), iq); + iq_send_stanza(iq); + xmpp_stanza_release(iq); } @@ -272,7 +275,9 @@ _ox_metadata_node__public_key(const char* const fingerprint) xmpp_stanza_add_child(publish, item); xmpp_stanza_add_child(pubsub, publish); xmpp_stanza_add_child(iq, pubsub); - xmpp_send(connection_get_conn(), iq); + + iq_send_stanza(iq); + xmpp_stanza_release(iq); } static int @@ -379,7 +384,8 @@ _ox_request_public_key(const char* const jid, const char* const fingerprint) xmpp_id_handler_add(connection_get_conn(), _ox_public_key_result, id, NULL); - xmpp_send(connection_get_conn(), iq); + iq_send_stanza(iq); + xmpp_stanza_release(iq); } /*! From c8daee8c88669f6773aaaf11b08f1c9444da1815 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 18:34:07 +0200 Subject: [PATCH 05/15] ox: use iq_id_handler_add instead of xmpp_id_handler_add --- src/xmpp/ox.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index 6f767550..0cfd4788 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -50,10 +50,10 @@ #define KEYID_LENGTH 40 static void _ox_metadata_node__public_key(const char* const fingerprint); -static int _ox_metadata_result(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata); +static int _ox_metadata_result(xmpp_stanza_t* const stanza, void* const userdata); static void _ox_request_public_key(const char* const jid, const char* const fingerprint); -static int _ox_public_key_result(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata); +static int _ox_public_key_result(xmpp_stanza_t* const stanza, void* const userdata); /*! * \brief Current Date and Time. @@ -199,7 +199,7 @@ ox_discover_public_key(const char* const jid) xmpp_stanza_add_child(pubsub, items); xmpp_stanza_add_child(iq, pubsub); - xmpp_id_handler_add(connection_get_conn(), _ox_metadata_result, id, strdup(jid)); + iq_id_handler_add(xmpp_stanza_get_id(iq), _ox_metadata_result, NULL, NULL); iq_send_stanza(iq); xmpp_stanza_release(iq); @@ -281,7 +281,7 @@ _ox_metadata_node__public_key(const char* const fingerprint) } static int -_ox_metadata_result(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata) +_ox_metadata_result(xmpp_stanza_t* const stanza, void* const userdata) { log_debug("[OX] Processing result %s's metadata.", (char*)userdata); @@ -382,7 +382,7 @@ _ox_request_public_key(const char* const jid, const char* const fingerprint) xmpp_stanza_add_child(pubsub, items); xmpp_stanza_add_child(iq, pubsub); - xmpp_id_handler_add(connection_get_conn(), _ox_public_key_result, id, NULL); + iq_id_handler_add(xmpp_stanza_get_id(iq), _ox_public_key_result, NULL, NULL); iq_send_stanza(iq); xmpp_stanza_release(iq); @@ -413,7 +413,7 @@ _ox_request_public_key(const char* const jid, const char* const fingerprint) */ int -_ox_public_key_result(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata) +_ox_public_key_result(xmpp_stanza_t* const stanza, void* const userdata) { log_debug("[OX] Processing result public key"); From e5998fb63ee27eaa9997847387fa05d1149e340b Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 18:54:20 +0200 Subject: [PATCH 06/15] ox: implement `/ox end` We also need to be able to stop an ox conversation :-) --- src/command/cmd_funcs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index e76831fc..040e1478 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7671,6 +7671,18 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args) chatwin->is_ox = TRUE; win_println(window, THEME_DEFAULT, "!", "OX encryption enabled."); return TRUE; + } else if (g_strcmp0(args[0], "end") == 0) { + if (window->type != WIN_CHAT && args[1] == NULL) { + cons_show("You must be in a regular chat window to stop OX encrpytion."); + return TRUE; + } + + ProfChatWin* chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + + chatwin->is_ox = FALSE; + win_println(window, THEME_DEFAULT, "!", "OX encryption disabled."); + return TRUE; } else if (g_strcmp0(args[0], "announce") == 0) { if (args[1]) { gchar* filename = get_expanded_path(args[1]); From e16bff232860e054d0fe9c1ddc5aa746365e65a5 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 19:54:43 +0200 Subject: [PATCH 07/15] ox: Use connection_create_stanza_id() instead of xmpp_uuid_gen() --- src/xmpp/ox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index 0cfd4788..d6ce9434 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -107,7 +107,7 @@ ox_announce_public_key(const char* const filename) log_info("[OX] Announce OpenPGP Key for Fingerprint: %s", fp); xmpp_ctx_t* const ctx = connection_get_ctx(); - char* id = xmpp_uuid_gen(ctx); + char* id = connection_create_stanza_id(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); xmpp_stanza_set_from(iq, xmpp_conn_get_jid(connection_get_conn())); @@ -183,7 +183,7 @@ ox_discover_public_key(const char* const jid) cons_show("Discovering Public Key for %s", jid); // iq xmpp_ctx_t* const ctx = connection_get_ctx(); - char* id = xmpp_uuid_gen(ctx); + char* id = connection_create_stanza_id(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id); xmpp_stanza_set_from(iq, xmpp_conn_get_jid(connection_get_conn())); xmpp_stanza_set_to(iq, jid); @@ -246,7 +246,7 @@ _ox_metadata_node__public_key(const char* const fingerprint) assert(strlen(fingerprint) == KEYID_LENGTH); // iq xmpp_ctx_t* const ctx = connection_get_ctx(); - char* id = xmpp_uuid_gen(ctx); + char* id = connection_create_stanza_id(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); xmpp_stanza_set_from(iq, xmpp_conn_get_jid(connection_get_conn())); // pubsub @@ -361,7 +361,7 @@ _ox_request_public_key(const char* const jid, const char* const fingerprint) log_info("[OX] Request %s's public key %s.", jid, fingerprint); // iq xmpp_ctx_t* const ctx = connection_get_ctx(); - char* id = xmpp_uuid_gen(ctx); + char* id = connection_create_stanza_id(); xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id); xmpp_stanza_set_from(iq, xmpp_conn_get_jid(connection_get_conn())); xmpp_stanza_set_to(iq, jid); From 7acc044a527fd0d62afb4ff8742fc77e91f17e00 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 21:24:27 +0200 Subject: [PATCH 08/15] ox: use glib date function in _gettimestamp and fix memleak --- src/xmpp/ox.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/xmpp/ox.c b/src/xmpp/ox.c index d6ce9434..fab3d675 100644 --- a/src/xmpp/ox.c +++ b/src/xmpp/ox.c @@ -55,14 +55,13 @@ static int _ox_metadata_result(xmpp_stanza_t* const stanza, void* const userdata static void _ox_request_public_key(const char* const jid, const char* const fingerprint); static int _ox_public_key_result(xmpp_stanza_t* const stanza, void* const userdata); -/*! - * \brief Current Date and Time. +/* Return Current Date and Time. * * XEP-0082: XMPP Date and Time Profiles * https://xmpp.org/extensions/xep-0082.html * - * \return YYYY-MM-DDThh:mm:ssZ - * + * According to ISO8601 + * YYYY-MM-DDThh:mm:ssZ */ static char* _gettimestamp(); @@ -268,7 +267,9 @@ _ox_metadata_node__public_key(const char* const fingerprint) xmpp_stanza_t* pubkeymetadata = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pubkeymetadata, STANZA_NAME_PUBKEY_METADATA); xmpp_stanza_set_attribute(pubkeymetadata, STANZA_ATTR_V4_FINGERPRINT, fingerprint); - xmpp_stanza_set_attribute(pubkeymetadata, STANZA_ATTR_DATE, _gettimestamp()); + char* timestamp = _gettimestamp(); + xmpp_stanza_set_attribute(pubkeymetadata, STANZA_ATTR_DATE, timestamp); + free(timestamp); xmpp_stanza_add_child(publickeyslist, pubkeymetadata); xmpp_stanza_add_child(item, publickeyslist); @@ -476,13 +477,10 @@ _ox_public_key_result(xmpp_stanza_t* const stanza, void* const userdata) char* _gettimestamp() { - time_t now = time(NULL); - struct tm* tm = localtime(&now); - char buf[255]; - strftime(buf, sizeof(buf), "%FT%T", tm); - GString* d = g_string_new(buf); - g_string_append(d, "Z"); - return strdup(d->str); + GDateTime* dt = g_date_time_new_now_local(); + gchar* datestr = g_date_time_format(dt, "%FT%TZ"); + g_date_time_unref(dt); + return datestr; } #endif // HAVE_LIBGPGME From 62018f48c5f1a0410445fce5bca5fdd6a9e4d907 Mon Sep 17 00:00:00 2001 From: Stefan Kropp Date: Sat, 30 Apr 2022 22:04:47 +0200 Subject: [PATCH 09/15] ox_key_is_usable - Logging and owner trust check * Added logging messages (INFO if key can not be used) * Check owner_trust < GPGME_VALIDITY_MARGINAL The key can not be used if the owner_trust is less than MARGINAL. --- src/pgp/gpg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 99d37c64..25704847 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -1110,6 +1110,12 @@ _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret) gboolean result = TRUE; if (key->revoked || key->expired || key->disabled) { + log_info("OX: %s's key is revoked, expired or disabled", barejid); + result = FALSE; + } + + if (key->owner_trust < GPGME_VALIDITY_MARGINAL) { + log_info("OX: Owner trust of %s's key is < GPGME_VALIDITY_MARGINAL", barejid); result = FALSE; } From c9e6a89aeaea87daaf572edefe3f9dc5d48e912e Mon Sep 17 00:00:00 2001 From: Stefan Kropp Date: Sat, 30 Apr 2022 22:10:21 +0200 Subject: [PATCH 10/15] Bugfix OX rpad generation ________________________________________ < No comment - should be much better now > ---------------------------------------- \ \ \ >()_ (__)__ _ --- src/xmpp/message.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/xmpp/message.c b/src/xmpp/message.c index c18f9376..fb58285e 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -1616,11 +1616,13 @@ _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text struct tm* tm = localtime(&now); char buf[255]; strftime(buf, sizeof(buf), "%FT%T%z", tm); - int randnr = rand() % 5; - char rpad_data[randnr]; - for (int i = 0; i < randnr - 1; i++) { - rpad_data[i] = 'c'; + // build rpad + int randnr = (rand() % 100) + 1; + char rpad_data[randnr]; + for (int i = 0; i < randnr; i++) { + int rchar = (rand() % 52) + 65; + rpad_data[i] = rchar; } rpad_data[randnr - 1] = '\0'; From c3deb5d325b7e327e14bdead1fb03de5ba42644a Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 23:11:25 +0200 Subject: [PATCH 11/15] ox: dont require marginal trust level Maybe we can make this configurable later. So users have the freedom to be more strict. This commit partly reverts 62018f48c5f1a0410445fce5bca5fdd6a9e4d907. Example to edit trust level: ``` gpg --edit-key somekeyid gpg (GnuPG) 2.3.4; Copyright (C) 2021 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: SC trust: unknown validity: full sub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: E [ full ] (1). xmpp:user@domain.de gpg> trust pub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: SC trust: unknown validity: full sub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: E [ full ] (1). xmpp:user@domain.de Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 3 pub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: SC trust: marginal validity: full sub rsa4096/keyid created: 2020-06-26 expires: 2022-06-26 usage: E [ full ] (1). xmpp:user@domain.de Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> quit ``` --- src/pgp/gpg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 25704847..bdb00408 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -1114,10 +1114,15 @@ _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret) result = FALSE; } + // This might be a nice features but AFAIK is not defined in the XEP. + // If we add this we need to expand our documentation on how to set the + // trust leven in gpg. I'll add an example to this commit body. + /* if (key->owner_trust < GPGME_VALIDITY_MARGINAL) { log_info("OX: Owner trust of %s's key is < GPGME_VALIDITY_MARGINAL", barejid); result = FALSE; } + */ return result; } From 58911926dee01601887d999dd03be2ae302c8265 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 3 May 2022 23:17:20 +0200 Subject: [PATCH 12/15] ox: print more error messages to UI --- src/pgp/gpg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index bdb00408..a93a8273 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -914,6 +914,7 @@ p_ox_gpg_signcrypt(const char* const sender_barejid, const char* const recipient // lookup own key recp[0] = _ox_key_lookup(sender_barejid, TRUE); if (error != 0) { + cons_show_error("Can't find OX key for %s", xmpp_jid_me); log_error("OX: Key not found for %s. Error: %s", xmpp_jid_me, gpgme_strerror(error)); return NULL; } @@ -927,13 +928,14 @@ p_ox_gpg_signcrypt(const char* const sender_barejid, const char* const recipient // lookup key of recipient recp[1] = _ox_key_lookup(recipient_barejid, FALSE); if (error != 0) { + cons_show_error("Can't find OX key for %s", xmpp_jid_recipient); log_error("OX: Key not found for %s. Error: %s", xmpp_jid_recipient, gpgme_strerror(error)); return NULL; } recp[2] = NULL; - log_debug("%s <%s>", recp[0]->uids->name, recp[0]->uids->email); - log_debug("%s <%s>", recp[1]->uids->name, recp[1]->uids->email); + log_debug("OX: %s <%s>", recp[0]->uids->name, recp[0]->uids->email); + log_debug("OX: %s <%s>", recp[1]->uids->name, recp[1]->uids->email); gpgme_encrypt_flags_t flags = 0; @@ -1110,6 +1112,7 @@ _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret) gboolean result = TRUE; if (key->revoked || key->expired || key->disabled) { + cons_show_error("%s's key is revoked, expired or disabled", barejid); log_info("OX: %s's key is revoked, expired or disabled", barejid); result = FALSE; } @@ -1119,6 +1122,7 @@ _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret) // trust leven in gpg. I'll add an example to this commit body. /* if (key->owner_trust < GPGME_VALIDITY_MARGINAL) { + cons_show_error(" %s's key is has a trust level lower than marginal", barejid); log_info("OX: Owner trust of %s's key is < GPGME_VALIDITY_MARGINAL", barejid); result = FALSE; } From acedd42d7864fd9e7dd4363cd7f354d4ccede40b Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 4 May 2022 00:01:49 +0200 Subject: [PATCH 13/15] ox: print message when `/ox end` is run but not started --- src/command/cmd_funcs.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 040e1478..f1fa37f1 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7650,7 +7650,7 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args) } if (chatwin->is_ox) { - win_println(window, THEME_DEFAULT, "!", "You have already started OX encryption."); + win_println(window, THEME_DEFAULT, "!", "You have already started an OX encrypted session."); return TRUE; } @@ -7673,15 +7673,19 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args) return TRUE; } else if (g_strcmp0(args[0], "end") == 0) { if (window->type != WIN_CHAT && args[1] == NULL) { - cons_show("You must be in a regular chat window to stop OX encrpytion."); + cons_show("You must be in a regular chat window to stop OX encryption."); return TRUE; } ProfChatWin* chatwin = (ProfChatWin*)window; assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); - chatwin->is_ox = FALSE; - win_println(window, THEME_DEFAULT, "!", "OX encryption disabled."); + if (!chatwin->is_ox) { + win_println(window, THEME_DEFAULT, "!", "No OX session has been started."); + } else { + chatwin->is_ox = FALSE; + win_println(window, THEME_DEFAULT, "!", "OX encryption disabled."); + } return TRUE; } else if (g_strcmp0(args[0], "announce") == 0) { if (args[1]) { From 281c8b7d8d5fdf7d600811bd3002d26f8ef02576 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 4 May 2022 00:22:18 +0200 Subject: [PATCH 14/15] Improve ox command help Mention new man page. Correct the usage of /ox request. --- src/command/cmd_defs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index a9e45147..b816ddcc 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1734,7 +1734,8 @@ static struct cmd_t command_defs[] = { CMD_DESC( "OpenPGP (OX) commands to manage keys, and perform OpenPGP encryption during chat sessions. " "Your OpenPGP key needs a user-id with your JID URI (xmpp:local@domain.tld). " - "A key can be generated with \"gpg --quick-gen-key xmpp:local@domain.tld future-default default 3y\".") + "A key can be generated with \"gpg --quick-gen-key xmpp:local@domain.tld future-default default 3y\". " + "See man profanity-ox-setup for details on how to set up OX the first time.") CMD_ARGS( { "keys", "List all keys known to the system." }, { "contacts", "Show contacts with assigned public keys." }, @@ -1745,7 +1746,7 @@ static struct cmd_t command_defs[] = { { "char ", "Set the character to be displayed next to PGP encrypted messages." }, { "announce ", "Announce a public key by pushing it on the XMPP Server" }, { "discover ", "Discover public keys of a jid. The OpenPGP Key IDs will be displayed" }, - { "request ", "Request public keys" }, + { "request ", "Request public key. See /ox discover to to get available key IDs." }, { "sendfile on|off", "Allow /sendfile to send unencrypted files while otherwise using PGP." }) CMD_EXAMPLES( "/ox log off", From e5e661e92d44ac21a4d19ef429091ef8e38203d3 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 4 May 2022 11:35:15 +0200 Subject: [PATCH 15/15] ox: fix mistakes in p_ox_gpg_decrypt() strcpy() can't work here because the data doesn't have to be NULL-terminated. So let's use memcpy. Fix memleak of plain_str. --- src/pgp/gpg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index a93a8273..7dc57d96 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -1195,11 +1195,13 @@ p_ox_gpg_decrypt(char* base64) return NULL; } } + size_t len; char* plain_str = gpgme_data_release_and_get_mem(plain, &len); char* result = malloc(len + 1); - strcpy(result, plain_str); + memcpy(result, plain_str, len); result[len] = '\0'; + gpgme_free(plain_str); return result; }