mirror of
https://github.com/bqv/weechat-xmpp/
synced 2024-11-19 21:25:33 +00:00
pgp presence
This commit is contained in:
parent
a384787413
commit
6d6d155574
@ -136,7 +136,12 @@
|
||||
* [ ] Delete bookmarks
|
||||
* [ ] Roster
|
||||
* [ ] 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)
|
||||
** TODO [#C] Implement completion engine (milestone v0.3)
|
||||
** TODO [#D] Close all issues (milestone v1.0)
|
||||
|
@ -34,6 +34,7 @@ char *account_options[ACCOUNT_NUM_OPTIONS][2] =
|
||||
{ "status", "probably about to segfault" },
|
||||
{ "pgp_pubring_path", "${weechat_data_dir}/pubring.gpg" },
|
||||
{ "pgp_secring_path", "${weechat_data_dir}/secring.gpg" },
|
||||
{ "pgp_keyid", "" },
|
||||
};
|
||||
|
||||
struct t_account *account__search(const char *name)
|
||||
|
@ -19,6 +19,7 @@ enum t_account_option
|
||||
ACCOUNT_OPTION_STATUS,
|
||||
ACCOUNT_OPTION_PGP_PUBRING_PATH,
|
||||
ACCOUNT_OPTION_PGP_SECRING_PATH,
|
||||
ACCOUNT_OPTION_PGP_KEYID,
|
||||
ACCOUNT_NUM_OPTIONS,
|
||||
};
|
||||
|
||||
@ -60,6 +61,8 @@ enum t_account_option
|
||||
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_PUBRING_PATH])
|
||||
#define account_pgp_secring_path(account) \
|
||||
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
|
||||
{
|
||||
|
@ -662,7 +662,6 @@ int command__pgp(const void *pointer, void *data,
|
||||
{
|
||||
struct t_account *ptr_account = NULL;
|
||||
struct t_channel *ptr_channel = NULL;
|
||||
xmpp_stanza_t *message;
|
||||
char *keyid;
|
||||
|
||||
(void) pointer;
|
||||
|
16
config.c
16
config.c
@ -218,6 +218,22 @@ config__account_new_option (struct t_config_file *config_file,
|
||||
callback_change_data,
|
||||
NULL, NULL, NULL);
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
37
connection.c
37
connection.c
@ -908,7 +908,8 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
|
||||
|
||||
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};
|
||||
|
||||
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,
|
||||
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 */
|
||||
children = malloc(sizeof(*children) * (2 + 1));
|
||||
children = malloc(sizeof(*children) * (3 + 1));
|
||||
|
||||
pres__c = xmpp_stanza_new(account->context);
|
||||
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);
|
||||
|
||||
children[1] = pres__status;
|
||||
|
||||
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,
|
||||
children, NULL, strdup(account_jid(account)),
|
||||
NULL, NULL);
|
||||
@ -1042,13 +1066,6 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
|
||||
weechat_command(account->buffer, *command);
|
||||
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
|
||||
{
|
||||
|
78
pgp.c
78
pgp.c
@ -284,3 +284,81 @@ verify_finish:
|
||||
rnp_input_destroy(signature);
|
||||
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;
|
||||
}
|
||||
|
2
pgp.h
2
pgp.h
@ -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__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message);
|
||||
|
||||
#endif /*WEECHAT_XMPP_PGP_H*/
|
||||
|
Loading…
Reference in New Issue
Block a user