diff options
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/message.c | 177 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 4 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 5 |
3 files changed, 183 insertions, 3 deletions
diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d578786e..74b6d2ea 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -76,7 +76,6 @@ typedef struct p_message_handle_t { } ProfMessageHandler; static int _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); - static void _handle_error(xmpp_stanza_t *const stanza); static void _handle_groupchat(xmpp_stanza_t *const stanza); static void _handle_muc_user(xmpp_stanza_t *const stanza); @@ -85,9 +84,13 @@ static void _handle_conference(xmpp_stanza_t *const stanza); static void _handle_captcha(xmpp_stanza_t *const stanza); static void _handle_receipt_received(xmpp_stanza_t *const stanza); static void _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam); +static void _handle_ox_chat(xmpp_stanza_t *const stanza, ProfMessage *message, gboolean is_mam); +static void _send_message_stanza(xmpp_stanza_t *const stanza); static gboolean _handle_mam(xmpp_stanza_t *const stanza); -static void _send_message_stanza(xmpp_stanza_t *const stanza); +#ifdef HAVE_LIBGPGME +static xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text); +#endif // HAVE_LIBGPGME static GHashTable *pubsub_event_handlers; @@ -353,6 +356,7 @@ message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean } account_free(account); #else + // ? message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id); xmpp_message_set_body(message, msg); #endif @@ -376,6 +380,71 @@ message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean return id; } +// XEP-0373: OpenPGP for XMPP +char* +message_send_chat_ox(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id) +{ +#ifdef HAVE_LIBGPGME + xmpp_ctx_t * const ctx = connection_get_ctx(); + + char *state = chat_session_get_state(barejid); + char *jid = chat_session_get_jid(barejid); + char *id = connection_create_stanza_id(); + + xmpp_stanza_t *message = NULL; + Jid *jidp = jid_create(jid); + + char *account_name = session_get_account_name(); + ProfAccount *account = accounts_get_account(account_name); + + message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id); + xmpp_message_set_body(message, "This message is encrypted (XEP-0373: OpenPGP for XMPP)."); + + xmpp_stanza_t *openpgp = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(openpgp, STANZA_NAME_OPENPGP); + xmpp_stanza_set_ns(openpgp, STANZA_NS_OPENPGP_0); + + xmpp_stanza_t * signcrypt = _openpgp_signcrypt(ctx, barejid, msg); + char* c; + size_t s; + xmpp_stanza_to_text(signcrypt, &c,&s); + char* signcrypt_e = p_ox_gpg_signcrypt(account->jid, barejid, c); + if( signcrypt_e == NULL ) { + log_error("Message not signcrypted."); + return NULL; + } + // BASE64_OPENPGP_MESSAGE + xmpp_stanza_t* base64_openpgp_message = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(base64_openpgp_message,signcrypt_e); + xmpp_stanza_add_child(openpgp, base64_openpgp_message); + xmpp_stanza_add_child(message, openpgp); + + xmpp_stanza_to_text(message, &c,&s); + + account_free(account); + jid_destroy(jidp); + free(jid); + + if (state) { + stanza_attach_state(ctx, message, state); + } + + if (request_receipt) { + stanza_attach_receipt_request(ctx, message); + } + + if (replace_id) { + stanza_attach_correction(ctx, message, replace_id); + } + + _send_message_stanza(message); + xmpp_stanza_release(message); + + return id; +#endif // HAVE_LIBGPGME + return NULL; +} + char* message_send_chat_otr(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id) { @@ -1140,6 +1209,12 @@ _handle_carbons(xmpp_stanza_t *const stanza) if (x) { message->encrypted = xmpp_stanza_get_text(x); } + // OX + xmpp_stanza_t *ox = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_OPENPGP_0); + if( ox ) { + message->enc=PROF_MSG_ENC_OX; + _handle_ox_chat(message_stanza,message, FALSE); + } //TODO: maybe also add is_carbon maybe even an enum with outgoing/incoming //could be that then we can have sv_ev_carbon no incoming/outgoing @@ -1260,6 +1335,12 @@ _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam) message->encrypted = xmpp_stanza_get_text(encrypted); } + xmpp_stanza_t *ox = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OPENPGP_0); + if( ox ) { + message->enc=PROF_MSG_ENC_OX; + _handle_ox_chat(stanza,message, FALSE); + } + if (message->plain || message->body || message->encrypted) { sv_ev_incoming_message(message); @@ -1290,6 +1371,36 @@ _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam) message_free(message); } + +/*! + * @brief Handle incoming XMMP-OX chat message. + * + * + */ +static void _handle_ox_chat(xmpp_stanza_t *const stanza, ProfMessage *message, gboolean is_mam) { +#ifdef HAVE_LIBGPGME + xmpp_stanza_t *ox = stanza_get_child_by_name_and_ns(stanza, "openpgp", STANZA_NS_OPENPGP_0); + message->plain = p_ox_gpg_decrypt(xmpp_stanza_get_text(ox)); + + // Implementation for libstrophe 0.10. + /* + xmpp_stanza_t *x = xmpp_stanza_new_from_string(connection_get_ctx(), message->plain); + xmpp_stanza_t *p = xmpp_stanza_get_child_by_name(x, "payload"); + xmpp_stanza_t *b = xmpp_stanza_get_child_by_name(p, "body"); + message->plain = xmpp_stanza_get_text(b); + if(message->plain == NULL ) { + message->plain = xmpp_stanza_get_text(stanza); + } + message->encrypted = xmpp_stanza_get_text(ox); + */ + + if(message->plain == NULL ) { + message->plain = xmpp_stanza_get_text(stanza); + } + message->encrypted = xmpp_stanza_get_text(ox); +#endif // HAVE_LIBGPGME +} + static gboolean _handle_mam(xmpp_stanza_t *const stanza) { @@ -1372,3 +1483,65 @@ message_is_sent_by_us(const ProfMessage *const message, bool checkOID) { return ret; } + +#ifdef HAVE_LIBGPGME +xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text) { + + time_t now = time(NULL); + 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'; + } + rpad_data[randnr-1] = '\0'; + + // signcrypt + xmpp_stanza_t *signcrypt = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(signcrypt, "signcrypt"); + xmpp_stanza_set_ns(signcrypt, "urn:xmpp:openpgp:0"); + // to + xmpp_stanza_t *s_to = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(s_to, "to"); + xmpp_stanza_set_attribute(s_to, "jid", to); + // time + xmpp_stanza_t *time = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(time, "time"); + xmpp_stanza_set_attribute(time, "stamp", buf); + xmpp_stanza_set_name(time, "time"); + // rpad + xmpp_stanza_t *rpad = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(rpad, "rpad"); + xmpp_stanza_t *rpad_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(rpad_text, rpad_data); + // payload + xmpp_stanza_t *payload= xmpp_stanza_new(ctx); + xmpp_stanza_set_name(payload, "payload"); + // body + xmpp_stanza_t *body = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(body, "body"); + xmpp_stanza_set_ns(body, "jabber:client"); + // text + xmpp_stanza_t *body_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(body_text, text); + xmpp_stanza_add_child(signcrypt,s_to); + xmpp_stanza_add_child(signcrypt,time); + xmpp_stanza_add_child(signcrypt,rpad); + xmpp_stanza_add_child(rpad,rpad_text); + xmpp_stanza_add_child(signcrypt,payload); + xmpp_stanza_add_child(payload, body); + xmpp_stanza_add_child(body, body_text); + + xmpp_stanza_release(body_text); + xmpp_stanza_release(body); + xmpp_stanza_release(rpad_text); + xmpp_stanza_release(rpad); + xmpp_stanza_release(time); + xmpp_stanza_release(s_to); + + return signcrypt; +} +#endif // HAVE_LIBGPGME + diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index b20af1cd..9d1f6d38 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -62,6 +62,8 @@ #define STANZA_NAME_PRESENCE "presence" #define STANZA_NAME_PRIORITY "priority" #define STANZA_NAME_X "x" +// XEP-0373: OpenPGP for XMPP +#define STANZA_NAME_OPENPGP "openpgp" #define STANZA_NAME_SHOW "show" #define STANZA_NAME_STATUS "status" #define STANZA_NAME_IQ "iq" @@ -192,6 +194,8 @@ #define STANZA_NS_RECEIPTS "urn:xmpp:receipts" #define STANZA_NS_SIGNED "jabber:x:signed" #define STANZA_NS_ENCRYPTED "jabber:x:encrypted" +// XEP-0373: OpenPGP for XMPP +#define STANZA_NS_OPENPGP_0 "urn:xmpp:openpgp:0" #define STANZA_NS_HTTP_UPLOAD "urn:xmpp:http:upload" #define STANZA_NS_X_OOB "jabber:x:oob" #define STANZA_NS_BLOCKING "urn:xmpp:blocking" diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 1444cffe..c097387b 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -126,7 +126,8 @@ typedef enum { PROF_MSG_ENC_NONE, PROF_MSG_ENC_OTR, PROF_MSG_ENC_PGP, - PROF_MSG_ENC_OMEMO + PROF_MSG_ENC_OMEMO, + PROF_MSG_ENC_OX } prof_enc_t; typedef enum { @@ -192,6 +193,8 @@ const char* connection_get_profanity_identifier(void); char* message_send_chat(const char *const barejid, const char *const msg, const char *const oob_url, gboolean request_receipt, const char *const replace_id); char* message_send_chat_otr(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); char* message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); +// XEP-0373: OpenPGP for XMPP +char* message_send_chat_ox(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); char* message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys, const unsigned char *const iv, size_t iv_len, const unsigned char *const ciphertext, size_t ciphertext_len, gboolean request_receipt, gboolean muc, const char *const replace_id); char* message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url); char* message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url, const char *const replace_id); |