pgp presence

v1
Tony Olagbaiye 3 years ago
parent a384787413
commit 6d6d155574
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -136,7 +136,12 @@
* [ ] Delete bookmarks * [ ] Delete bookmarks
* [ ] Roster * [ ] Roster
* [ ] OTR (libotr) * [ ] OTR (libotr)
* [ ] PGP (libgpgme) * [X] PGP (rnpgp)
* [X] Use keyrings (e.g. exported from gnupg)
* [X] Presence
* [X] Decryption
* [X] Encryption
* [X] Custom set/clear key (/pgp)
* [ ] Room Explorer (https://search.jabber.network/docs/api) * [ ] Room Explorer (https://search.jabber.network/docs/api)
** TODO [#C] Implement completion engine (milestone v0.3) ** TODO [#C] Implement completion engine (milestone v0.3)
** TODO [#D] Close all issues (milestone v1.0) ** TODO [#D] Close all issues (milestone v1.0)

@ -34,6 +34,7 @@ char *account_options[ACCOUNT_NUM_OPTIONS][2] =
{ "status", "probably about to segfault" }, { "status", "probably about to segfault" },
{ "pgp_pubring_path", "${weechat_data_dir}/pubring.gpg" }, { "pgp_pubring_path", "${weechat_data_dir}/pubring.gpg" },
{ "pgp_secring_path", "${weechat_data_dir}/secring.gpg" }, { "pgp_secring_path", "${weechat_data_dir}/secring.gpg" },
{ "pgp_keyid", "" },
}; };
struct t_account *account__search(const char *name) struct t_account *account__search(const char *name)

@ -19,6 +19,7 @@ enum t_account_option
ACCOUNT_OPTION_STATUS, ACCOUNT_OPTION_STATUS,
ACCOUNT_OPTION_PGP_PUBRING_PATH, ACCOUNT_OPTION_PGP_PUBRING_PATH,
ACCOUNT_OPTION_PGP_SECRING_PATH, ACCOUNT_OPTION_PGP_SECRING_PATH,
ACCOUNT_OPTION_PGP_KEYID,
ACCOUNT_NUM_OPTIONS, ACCOUNT_NUM_OPTIONS,
}; };
@ -60,6 +61,8 @@ enum t_account_option
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_PUBRING_PATH]) weechat_config_string(account->options[ACCOUNT_OPTION_PGP_PUBRING_PATH])
#define account_pgp_secring_path(account) \ #define account_pgp_secring_path(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_SECRING_PATH]) weechat_config_string(account->options[ACCOUNT_OPTION_PGP_SECRING_PATH])
#define account_pgp_keyid(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_KEYID])
struct t_device struct t_device
{ {

@ -662,7 +662,6 @@ int command__pgp(const void *pointer, void *data,
{ {
struct t_account *ptr_account = NULL; struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL; struct t_channel *ptr_channel = NULL;
xmpp_stanza_t *message;
char *keyid; char *keyid;
(void) pointer; (void) pointer;

@ -218,6 +218,22 @@ config__account_new_option (struct t_config_file *config_file,
callback_change_data, callback_change_data,
NULL, NULL, NULL); NULL, NULL, NULL);
break; break;
case ACCOUNT_OPTION_PGP_KEYID:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account PGP Key ID"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_NUM_OPTIONS: case ACCOUNT_NUM_OPTIONS:
break; break;
} }

@ -908,7 +908,8 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
if (status == XMPP_CONN_CONNECT) if (status == XMPP_CONN_CONNECT)
{ {
xmpp_stanza_t *pres, *pres__c, *pres__status, *pres__status__text, **children; xmpp_stanza_t *pres, *pres__c, *pres__status, *pres__status__text,
*pres__x, *pres__x__text, **children;
char cap_hash[28+1] = {0}; char cap_hash[28+1] = {0};
xmpp_handler_add(conn, &connection__version_handler, xmpp_handler_add(conn, &connection__version_handler,
@ -922,8 +923,14 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
xmpp_handler_add(conn, &connection__iq_handler, xmpp_handler_add(conn, &connection__iq_handler,
NULL, "iq", NULL, account); NULL, "iq", NULL, account);
pgp__init(&account->pgp,
weechat_string_eval_expression(account_pgp_pubring_path(account),
NULL, NULL, NULL),
weechat_string_eval_expression(account_pgp_secring_path(account),
NULL, NULL, NULL));
/* Send initial <presence/> so that we appear online to contacts */ /* Send initial <presence/> so that we appear online to contacts */
children = malloc(sizeof(*children) * (2 + 1)); children = malloc(sizeof(*children) * (3 + 1));
pres__c = xmpp_stanza_new(account->context); pres__c = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(pres__c, "c"); xmpp_stanza_set_name(pres__c, "c");
@ -943,8 +950,25 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
xmpp_stanza_release(pres__status__text); xmpp_stanza_release(pres__status__text);
children[1] = pres__status; children[1] = pres__status;
children[2] = NULL; children[2] = NULL;
if (account->pgp)
{
pres__x = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(pres__x, "x");
xmpp_stanza_set_ns(pres__x, "jabber:x:signed");
pres__x__text = xmpp_stanza_new(account->context);
char *signature = pgp__sign(account->buffer, account->pgp, account_pgp_keyid(account), account_status(account));
xmpp_stanza_set_text(pres__x__text, signature ? signature : "");
free(signature);
xmpp_stanza_add_child(pres__x, pres__x__text);
xmpp_stanza_release(pres__x__text);
children[2] = pres__x;
children[3] = NULL;
}
pres = stanza__presence(account->context, NULL, pres = stanza__presence(account->context, NULL,
children, NULL, strdup(account_jid(account)), children, NULL, strdup(account_jid(account)),
NULL, NULL); NULL, NULL);
@ -1042,13 +1066,6 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
weechat_command(account->buffer, *command); weechat_command(account->buffer, *command);
weechat_string_dyn_free(command, 1); weechat_string_dyn_free(command, 1);
} }
pgp__init(&account->pgp,
weechat_string_eval_expression(account_pgp_pubring_path(account),
NULL, NULL, NULL),
weechat_string_eval_expression(account_pgp_secring_path(account),
NULL, NULL, NULL));
} }
else else
{ {

78
pgp.c

@ -284,3 +284,81 @@ verify_finish:
rnp_input_destroy(signature); rnp_input_destroy(signature);
return result; return result;
} }
char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message)
{
rnp_input_t keyfile = NULL;
rnp_input_t input = NULL;
rnp_output_t output = NULL;
rnp_op_sign_t sign = NULL;
rnp_key_handle_t key = NULL;
uint8_t * buf = NULL;
size_t buf_len = 0;
char * result = NULL;
/* create file input and memory output objects for the encrypted message and decrypted
* message */
if (rnp_input_from_memory(&input, (uint8_t *)message, strlen(message), false) !=
RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to create input object\n");
goto sign_finish;
}
if (rnp_output_to_memory(&output, 0) != RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to create output object\n");
goto sign_finish;
}
/* initialize and configure sign operation */
if (rnp_op_sign_detached_create(&sign, pgp->context, input, output) != RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to create sign operation\n");
goto sign_finish;
}
/* armor, file name, compression */
rnp_op_sign_set_armor(sign, true);
rnp_op_sign_set_file_name(sign, "message.txt");
rnp_op_sign_set_file_mtime(sign, time(NULL));
rnp_op_sign_set_compression(sign, "ZIP", 6);
/* signatures creation time - by default will be set to the current time as well */
rnp_op_sign_set_creation_time(sign, time(NULL));
/* signatures expiration time - by default will be 0, i.e. never expire */
rnp_op_sign_set_expiration_time(sign, 365 * 24 * 60 * 60);
/* set hash algorithm - should be compatible for all signatures */
rnp_op_sign_set_hash(sign, RNP_ALGNAME_SHA256);
/* now add signatures. First locate the signing key, then add and setup signature */
if (rnp_locate_key(pgp->context, "keyid", source, &key) != RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to locate signing key: %s\n", source);
goto sign_finish;
}
if (rnp_op_sign_add_signature(sign, key, NULL) != RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to add signature for key: %s\n", source);
goto sign_finish;
}
rnp_key_handle_destroy(key);
key = NULL;
/* finally do signing */
if (rnp_op_sign_execute(sign) != RNP_SUCCESS) {
weechat_printf(buffer, "[PGP]\tfailed to sign with key: %s\n", source);
goto sign_finish;
}
/* get the signature from the output structure */
if (rnp_output_memory_get_buf(output, &buf, &buf_len, false) != RNP_SUCCESS) {
goto sign_finish;
}
result = strndup((char *)buf + strlen(PGP_SIGNATURE_HEADER),
buf_len - strlen(PGP_SIGNATURE_HEADER) - strlen(PGP_SIGNATURE_FOOTER));
sign_finish:
rnp_input_destroy(keyfile);
rnp_key_handle_destroy(key);
rnp_op_sign_destroy(sign);
rnp_input_destroy(input);
rnp_output_destroy(output);
return result;
}

@ -23,4 +23,6 @@ char *pgp__encrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *t
char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *certificate); char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *certificate);
char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message);
#endif /*WEECHAT_XMPP_PGP_H*/ #endif /*WEECHAT_XMPP_PGP_H*/

Loading…
Cancel
Save