diff --git a/.dir-locals.el b/.dir-locals.el index 178235e..211b59a 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -19,4 +19,4 @@ (flycheck-clang-warnings . ("all" "extra" "error-implicit-function-declaration" "no-missing-field-initializers")) (flycheck-clang-language-standard . "gnu99") (flycheck-checker . c/c++-clang) - (projectile-project-compilation-cmd . "scan-build-3.8 make -j8"))) + (projectile-project-compilation-cmd . "bear -- make -j8"))) diff --git a/connection.c b/connection.c index 1932c3a..1675a6c 100644 --- a/connection.c +++ b/connection.c @@ -86,9 +86,9 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void struct t_account *account = (struct t_account *)userdata; struct t_user *user; struct t_channel *channel; - xmpp_stanza_t *iq__x, *iq__x__item, *iq__c, *iq__status; + xmpp_stanza_t *iq__x_signed, *iq__x_muc_user, *iq__x__item, *iq__c, *iq__status; const char *from, *from_bare, *from_res, *role = NULL, *affiliation = NULL, *jid = NULL; - const char *node = NULL, *ver = NULL; + const char *certificate = NULL, *node = NULL, *ver = NULL; char *clientid = NULL, *status; from = xmpp_stanza_get_from(stanza); @@ -96,11 +96,17 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void return 1; from_bare = xmpp_jid_bare(account->context, from); from_res = xmpp_jid_resource(account->context, from); - iq__x = xmpp_stanza_get_child_by_name_and_ns( + iq__x_signed = xmpp_stanza_get_child_by_name_and_ns( + stanza, "x", "jabber:x:signed"); + if (iq__x_signed) + { + certificate = xmpp_stanza_get_text(iq__x_signed); + } + iq__x_muc_user = xmpp_stanza_get_child_by_name_and_ns( stanza, "x", "http://jabber.org/protocol/muc#user"); - if (iq__x) + if (iq__x_muc_user) { - iq__x__item = xmpp_stanza_get_child_by_name(iq__x, "item"); + iq__x__item = xmpp_stanza_get_child_by_name(iq__x_muc_user, "item"); role = xmpp_stanza_get_attribute(iq__x__item, "role"); affiliation = xmpp_stanza_get_attribute(iq__x__item, "affiliation"); jid = xmpp_stanza_get_attribute(iq__x__item, "jid"); @@ -124,8 +130,14 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void status = iq__status ? xmpp_stanza_get_text(iq__status) : NULL; channel = channel__search(account, from_bare); - if (!iq__x && !channel) + if (!iq__x_muc_user && !channel) channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare); + if (certificate) + { + channel->pgp_id = pgp__verify(account->pgp, certificate); + weechat_printf(channel->buffer, "[PGP]\t%sKey %s from %s", + weechat_color("gray"), channel->pgp_id, from); + } user = user__search(account, from); if (!user) @@ -133,7 +145,7 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void channel && weechat_strcasecmp(from_bare, channel->id) == 0 ? from_res : from); - if (!iq__x) + if (!iq__x_muc_user) { channel__add_member(account, channel, from, clientid, status); } diff --git a/pgp.c b/pgp.c index 7912b3c..fe8b2d3 100644 --- a/pgp.c +++ b/pgp.c @@ -16,6 +16,8 @@ #define PGP_MESSAGE_HEADER "-----BEGIN PGP MESSAGE-----\r\n\r\n" #define PGP_MESSAGE_FOOTER "\r\n-----END PGP MESSAGE-----\r\n" +#define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----\r\n\r\n" +#define PGP_SIGNATURE_FOOTER "\r\n-----END PGP SIGNATURE-----\r\n" const char *PGP_ADVICE = "[PGP encrypted message (XEP-0027)]"; @@ -58,90 +60,6 @@ void pgp__free(struct t_pgp *pgp) } } -/* this simple helper function just prints armored key, searched by userid, to stdout */ -static bool pgp__print_key(rnp_ffi_t rnp, const char *uid, bool secret) -{ - rnp_output_t keydata = NULL; - rnp_key_handle_t key = NULL; - uint32_t flags = RNP_KEY_EXPORT_ARMORED | RNP_KEY_EXPORT_SUBKEYS; - uint8_t * buf = NULL; - size_t buf_len = 0; - bool result = false; - - /* you may search for the key via userid, keyid, fingerprint, grip */ - if (rnp_locate_key(rnp, "userid", uid, &key) != RNP_SUCCESS) { - return false; - } - - if (!key) { - return false; - } - - /* create in-memory output structure to later use buffer */ - if (rnp_output_to_memory(&keydata, 0) != RNP_SUCCESS) { - goto finish; - } - - flags = flags | (secret ? RNP_KEY_EXPORT_SECRET : RNP_KEY_EXPORT_PUBLIC); - if (rnp_key_export(key, keydata, flags) != RNP_SUCCESS) { - goto finish; - } - - /* get key's contents from the output structure */ - if (rnp_output_memory_get_buf(keydata, &buf, &buf_len, false) != RNP_SUCCESS) { - goto finish; - } - weechat_printf(NULL, "pgp: %.*s", (int) buf_len, buf); - - result = true; -finish: - rnp_key_handle_destroy(key); - rnp_output_destroy(keydata); - return result; -} - -static bool pgp__export_key(rnp_ffi_t rnp, const char *uid, bool secret) -{ - rnp_output_t keyfile = NULL; - rnp_key_handle_t key = NULL; - uint32_t flags = RNP_KEY_EXPORT_ARMORED | RNP_KEY_EXPORT_SUBKEYS; - char filename[32] = {0}; - char * keyid = NULL; - bool result = false; - - /* you may search for the key via userid, keyid, fingerprint, grip */ - if (rnp_locate_key(rnp, "userid", uid, &key) != RNP_SUCCESS) { - return false; - } - - if (!key) { - return false; - } - - /* get key's id and build filename */ - if (rnp_key_get_keyid(key, &keyid) != RNP_SUCCESS) { - goto finish; - } - snprintf(filename, sizeof(filename), "key-%s-%s.asc", keyid, secret ? "sec" : "pub"); - rnp_buffer_destroy(keyid); - - /* create file output structure */ - if (rnp_output_to_path(&keyfile, filename) != RNP_SUCCESS) { - goto finish; - } - - flags = flags | (secret ? RNP_KEY_EXPORT_SECRET : RNP_KEY_EXPORT_PUBLIC); - if (rnp_key_export(key, keyfile, flags) != RNP_SUCCESS) { - goto finish; - } - - result = true; -finish: - rnp_key_handle_destroy(key); - rnp_output_destroy(keyfile); - return result; -} - char *pgp__encrypt(struct t_pgp *pgp, const char *target, const char *message) { rnp_op_encrypt_t encrypt = NULL; @@ -267,11 +185,11 @@ decrypt_finish: return result; } -char *pgp__verify(struct t_pgp *pgp) +char *pgp__verify(struct t_pgp *pgp, const char *certificate) { rnp_op_verify_t verify = NULL; rnp_input_t input = NULL; - rnp_output_t output = NULL; + rnp_input_t signature = NULL; uint8_t * buf = NULL; size_t buf_len = 0; size_t sigcount = 0; @@ -279,31 +197,38 @@ char *pgp__verify(struct t_pgp *pgp) rnp_result_t ret; - /* create file input and memory output objects for the signed message and verified - * message */ - if ((ret = rnp_input_from_path(&input, "signed.asc")) != RNP_SUCCESS) { + buf_len = strlen(PGP_SIGNATURE_HEADER) + strlen(certificate) + strlen(PGP_SIGNATURE_FOOTER) + 1; + buf = malloc(sizeof(char) * buf_len); + buf_len = snprintf((char *)buf, buf_len, PGP_SIGNATURE_HEADER "%s" PGP_SIGNATURE_FOOTER, certificate); + + /* create file input memory objects for the signed message and verified message */ + if ((ret = rnp_input_from_memory(&input, buf, buf_len, false)) != RNP_SUCCESS) { const char *reason = rnp_result_to_string(ret); - weechat_printf(NULL, "pgp: failed to open file 'signed.asc'. Did you run the sign example?: %s\n", reason); + weechat_printf(NULL, "pgp: failed to create input object: %s\n", reason); goto verify_finish; } - if ((ret = rnp_output_to_memory(&output, 0)) != RNP_SUCCESS) { + if ((ret = rnp_input_from_memory(&signature, buf, buf_len, false)) != RNP_SUCCESS) { const char *reason = rnp_result_to_string(ret); - weechat_printf(NULL, "pgp: failed to create output object: %s\n", reason); + weechat_printf(NULL, "pgp: failed to create input object: %s\n", reason); goto verify_finish; } - if ((ret = rnp_op_verify_create(&verify, pgp->context, input, output)) != RNP_SUCCESS) { + if ((ret = rnp_op_verify_detached_create(&verify, pgp->context, input, signature)) != RNP_SUCCESS) { const char *reason = rnp_result_to_string(ret); weechat_printf(NULL, "pgp: failed to create verification context: %s\n", reason); goto verify_finish; } - if ((ret = rnp_op_verify_execute(verify)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - weechat_printf(NULL, "pgp: failed to execute verification operation: %s\n", reason); - goto verify_finish; - } + //if (( + ret = rnp_op_verify_execute(verify) + ; + // ) != RNP_ERROR_SIGNATURE_INVALID) + // if (ret != RNP_ERROR_SIGNATURE_INVALID) { + // const char *reason = rnp_result_to_string(ret); + // weechat_printf(NULL, "pgp: failed to execute verification operation: %s\n", reason); + // goto verify_finish; + // } /* now check signatures and get some info about them */ if ((ret = rnp_op_verify_get_signature_count(verify, &sigcount)) != RNP_SUCCESS) { @@ -314,7 +239,6 @@ char *pgp__verify(struct t_pgp *pgp) for (size_t i = 0; i < sigcount; i++) { rnp_op_verify_signature_t sig = NULL; - rnp_result_t sigstatus = RNP_SUCCESS; rnp_key_handle_t key = NULL; char * keyid = NULL; @@ -337,24 +261,16 @@ char *pgp__verify(struct t_pgp *pgp) goto verify_finish; } - sigstatus = rnp_op_verify_signature_get_status(sig); - weechat_printf(NULL, "pgp: Status for signature from key %s : %d\n", keyid, (int)sigstatus); + result = strdup(keyid); rnp_buffer_destroy(keyid); rnp_key_handle_destroy(key); + break; } - /* get the verified message from the output structure */ - if ((ret = rnp_output_memory_get_buf(output, &buf, &buf_len, false)) != RNP_SUCCESS) { - const char *reason = rnp_result_to_string(ret); - (void) reason; - goto verify_finish; - } - weechat_printf(NULL, "pgp: Verified message:\n%.*s\n", (int)buf_len, buf); - verify_finish: rnp_op_verify_destroy(verify); rnp_input_destroy(input); - rnp_output_destroy(output); + rnp_input_destroy(signature); return result; } diff --git a/pgp.h b/pgp.h index 2beac5a..d4942f1 100644 --- a/pgp.h +++ b/pgp.h @@ -19,4 +19,6 @@ char *pgp__decrypt(struct t_pgp *pgp, const char *ciphertext); char *pgp__encrypt(struct t_pgp *pgp, const char *target, const char *message); +char *pgp__verify(struct t_pgp *pgp, const char *certificate); + #endif /*WEECHAT_XMPP_PGP_H*/