mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-24 18:56:21 +00:00
Feature request - XEP-0373: OpenPGP for XMPP (OX)
Basic implementation of XEP-0373: OpenPGP for XMPP. https://xmpp.org/extensions/xep-0373.html Command /ox Issue: #1331
This commit is contained in:
committed by
Michael Vetter
parent
3afd854dc8
commit
2c94ee5a88
@@ -85,10 +85,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 gboolean _handle_mam(xmpp_stanza_t *const stanza);
|
||||
|
||||
static void _send_message_stanza(xmpp_stanza_t *const stanza);
|
||||
|
||||
static xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text);
|
||||
|
||||
static GHashTable *pubsub_event_handlers;
|
||||
|
||||
static int
|
||||
@@ -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,70 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
char*
|
||||
message_send_chat_otr(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id)
|
||||
{
|
||||
@@ -1140,6 +1208,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 +1334,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 +1370,35 @@ _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) {
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_handle_mam(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
@@ -1372,3 +1481,64 @@ message_is_sent_by_us(const ProfMessage *const message, bool checkOID) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user