interstitial commit

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

@ -49,9 +49,10 @@ use_guix()
libxml2 # Dep (libxml2) libxml2 # Dep (libxml2)
libstrophe # Dep (strophe) libstrophe # Dep (strophe)
libgcrypt # Dep (gcrypt) libgcrypt # Dep (gcrypt)
libsignal-protocol-c # Dep (libsignal) -l libomemo.scm #libsignal-protocol-c # Dep (libsignal)
lmdb # Dep (lmdb) lmdb # Dep (lmdb)
rnp # Dep (rnpgp) rnp # Dep (rnpgp)
glib sqlite minixml
) )
# Thanks <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html> # Thanks <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html>

@ -4,10 +4,10 @@ ifdef DEBUG
endif endif
RM=rm -f RM=rm -f
FIND=find FIND=find
INCLUDES=-Ilibstrophe $(shell xml2-config --cflags) $(shell pkg-config --cflags librnp-0) $(shell pkg-config --cflags libsignal-protocol-c) INCLUDES=-Ilibstrophe $(shell xml2-config --cflags) $(shell pkg-config --cflags librnp-0) $(shell pkg-config --cflags libomemo-c)
CFLAGS+=$(DBGCFLAGS) -fno-omit-frame-pointer -fPIC -std=gnu99 -gdwarf-4 -Wall -Wextra -Werror-implicit-function-declaration -Wno-missing-field-initializers -D_XOPEN_SOURCE=700 $(INCLUDES) CFLAGS+=$(DBGCFLAGS) -fno-omit-frame-pointer -fPIC -std=gnu99 -gdwarf-4 -Wall -Wextra -Werror-implicit-function-declaration -Wno-missing-field-initializers -D_XOPEN_SOURCE=700 $(INCLUDES)
LDFLAGS+=$(DBGLDFLAGS) -shared -g $(DBGCFLAGS) LDFLAGS+=$(DBGLDFLAGS) -shared -g $(DBGCFLAGS)
LDLIBS=-lstrophe -lpthread $(shell xml2-config --libs) $(shell pkg-config --libs librnp-0) $(shell pkg-config --libs libsignal-protocol-c) -lgcrypt -llmdb LDLIBS=-lstrophe -lpthread $(shell xml2-config --libs) $(shell pkg-config --libs librnp-0) $(shell pkg-config --libs libomemo-c) -lgcrypt -llmdb
PREFIX ?= /usr/local PREFIX ?= /usr/local
LIBDIR ?= $(PREFIX)/lib LIBDIR ?= $(PREFIX)/lib

@ -12,6 +12,7 @@
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"
#include "xmpp/stanza.h"
#include "config.h" #include "config.h"
#include "input.h" #include "input.h"
#include "omemo.h" #include "omemo.h"
@ -90,7 +91,7 @@ int account__search_option(const char *option_name)
return -1; return -1;
} }
struct t_account_device *account__search_device(struct t_account *account, int id) struct t_account_device *account__search_device(struct t_account *account, uint32_t id)
{ {
struct t_account_device *ptr_device; struct t_account_device *ptr_device;
@ -118,6 +119,7 @@ void account__add_device(struct t_account *account,
new_device = malloc(sizeof(*new_device)); new_device = malloc(sizeof(*new_device));
new_device->id = device->id; new_device->id = device->id;
new_device->name = strdup(device->name); new_device->name = strdup(device->name);
new_device->label = device->label ? strdup(device->label) : NULL;
new_device->prev_device = account->last_device; new_device->prev_device = account->last_device;
new_device->next_device = NULL; new_device->next_device = NULL;
@ -151,6 +153,8 @@ void account__free_device(struct t_account *account, struct t_account_device *de
(device->next_device)->prev_device = device->prev_device; (device->next_device)->prev_device = device->prev_device;
/* free device data */ /* free device data */
if (device->label)
free(device->label);
if (device->name) if (device->name)
free(device->name); free(device->name);
@ -165,6 +169,60 @@ void account__free_device_all(struct t_account *account)
account__free_device(account, account->devices); account__free_device(account, account->devices);
} }
xmpp_stanza_t *account__get_devicelist(struct t_account *account)
{
xmpp_stanza_t *parent, **children;
struct t_account_device *device;
const char *ns, *node;
char id[64] = {0};
int i = 0;
device = malloc(sizeof(struct t_account_device));
device->id = account->omemo->device_id;
snprintf(id, sizeof(id), "%u", device->id);
device->name = strdup(id);
device->label = strdup("weechat");
children = malloc(sizeof(xmpp_stanza_t *) * 128);
children[i++] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(device->name),
with_noop("weechat"));
free(device->label);
free(device->name);
free(device);
for (device = account->devices; device;
device = device->next_device)
{
if (device->id != account->omemo->device_id)
children[i++] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(device->name), NULL);
}
children[i] = NULL;
node = "eu.siacs.conversations.axolotl";
children[0] = stanza__iq_pubsub_publish_item_list(
account->context, NULL, children, with_noop(node));
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item(
account->context, NULL, children, NULL);
node = "eu.siacs.conversations.axolotl.devicelist";
children[0] = stanza__iq_pubsub_publish(account->context,
NULL, children,
with_noop(node));
ns = "http://jabber.org/protocol/pubsub";
children[0] = stanza__iq_pubsub(account->context, NULL,
children, with_noop(ns));
parent = stanza__iq(account->context, NULL,
children, NULL, strdup("announce1"),
NULL, NULL, strdup("set"));
free(children);
return parent;
}
struct t_account_mam_query *account__add_mam_query(struct t_account *account, struct t_account_mam_query *account__add_mam_query(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id, const char *id,

@ -66,8 +66,9 @@ enum t_account_option
struct t_account_device struct t_account_device
{ {
int id; uint32_t id;
char *name; char *name;
char *label;
struct t_account_device *prev_device; struct t_account_device *prev_device;
struct t_account_device *next_device; struct t_account_device *next_device;
@ -128,10 +129,11 @@ extern char *account_options[][2];
struct t_account *account__search(const char *account_name); struct t_account *account__search(const char *account_name);
struct t_account *account__casesearch (const char *account_name); struct t_account *account__casesearch (const char *account_name);
int account__search_option(const char *option_name); int account__search_option(const char *option_name);
struct t_account_device *account__search_device(struct t_account *account, int id); struct t_account_device *account__search_device(struct t_account *account, uint32_t id);
void account__add_device(struct t_account *account, struct t_account_device *device); void account__add_device(struct t_account *account, struct t_account_device *device);
void account__free_device(struct t_account *account, struct t_account_device *device); void account__free_device(struct t_account *account, struct t_account_device *device);
void account__free_device_all(struct t_account *account); void account__free_device_all(struct t_account *account);
xmpp_stanza_t *account__get_devicelist(struct t_account *account);
struct t_account_mam_query *account__add_mam_query(struct t_account *account, struct t_account_mam_query *account__add_mam_query(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id, const char *id,

@ -2,6 +2,7 @@
// License, version 2.0. If a copy of the MPL was not distributed with this // License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdint.h>
#include <string.h> #include <string.h>
#include <strophe.h> #include <strophe.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>

@ -18,6 +18,7 @@
#include "input.h" #include "input.h"
#include "buffer.h" #include "buffer.h"
#include "pgp.h" #include "pgp.h"
#include "util.h"
const char *channel__transport_name(enum t_channel_transport transport) const char *channel__transport_name(enum t_channel_transport transport)
{ {
@ -276,6 +277,11 @@ struct t_channel *channel__new(struct t_account *account,
new_channel->name = strdup(name); new_channel->name = strdup(name);
new_channel->transport = CHANNEL_TRANSPORT_PLAINTEXT; new_channel->transport = CHANNEL_TRANSPORT_PLAINTEXT;
new_channel->pgp_id = NULL; new_channel->pgp_id = NULL;
new_channel->omemo.session = 0;
new_channel->omemo.devicelist_requests = weechat_hashtable_new(64,
WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_POINTER, NULL, NULL);
new_channel->omemo.bundle_requests = weechat_hashtable_new(64,
WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_POINTER, NULL, NULL);
new_channel->topic.value = NULL; new_channel->topic.value = NULL;
new_channel->topic.creator = NULL; new_channel->topic.creator = NULL;
@ -916,10 +922,13 @@ struct t_channel_member *channel__add_member(struct t_account *account,
user->profile.status_text ? " [" : "", user->profile.status_text ? " [" : "",
user->profile.status_text ? user->profile.status_text : "", user->profile.status_text ? user->profile.status_text : "",
user->profile.status_text ? "]" : "", user->profile.status_text ? "]" : "",
user->profile.pgp_id ? weechat_color("gray") : "", user->profile.pgp_id || user->profile.omemo ? weechat_color("gray") : "",
user->profile.pgp_id ? " with PGP:" : "", user->profile.pgp_id || user->profile.omemo ? " with " : "",
user->profile.pgp_id ? "PGP:" : "",
user->profile.pgp_id ? user->profile.pgp_id : "", user->profile.pgp_id ? user->profile.pgp_id : "",
user->profile.pgp_id ? weechat_color("reset") : ""); user->profile.omemo && user->profile.pgp_id ? " and " : "",
user->profile.omemo ? "OMEMO" : "",
user->profile.pgp_id || user->profile.omemo ? weechat_color("reset") : "");
return member; return member;
} }
@ -999,8 +1008,21 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
xmpp_stanza_set_id(message, id); xmpp_stanza_set_id(message, id);
xmpp_free(account->context, id); xmpp_free(account->context, id);
char *url = strstr(body, "http"); if (account->omemo && channel->omemo.session >= 0)
if (channel->pgp_id) {
xmpp_message_set_body(message, body);
if (channel->transport != CHANNEL_TRANSPORT_OMEMO)
{
channel->transport = CHANNEL_TRANSPORT_OMEMO;
weechat_printf_date_tags(channel->buffer, 0, NULL, "%s%sTransport: %s",
weechat_prefix("network"), weechat_color("gray"),
channel__transport_name(channel->transport));
}
omemo__encode(account->omemo, to, 0, body);
}
else if (channel->pgp_id)
{ {
xmpp_stanza_t *message__x = xmpp_stanza_new(account->context); xmpp_stanza_t *message__x = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__x, "x"); xmpp_stanza_set_name(message__x, "x");
@ -1049,6 +1071,7 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
} }
} }
char *url = strstr(body, "http");
if (url) if (url)
{ {
xmpp_stanza_t *message__x = xmpp_stanza_new(account->context); xmpp_stanza_t *message__x = xmpp_stanza_new(account->context);

@ -64,6 +64,11 @@ struct t_channel
char *name; char *name;
enum t_channel_transport transport; enum t_channel_transport transport;
char *pgp_id; char *pgp_id;
struct {
int session;
struct t_hashtable *devicelist_requests;
struct t_hashtable *bundle_requests;
} omemo;
struct t_channel_topic topic; struct t_channel_topic topic;

@ -4,13 +4,13 @@
#include <strophe.h> #include <strophe.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"
//#include "oauth.h"
#include "account.h" #include "account.h"
#include "user.h" #include "user.h"
#include "channel.h" #include "channel.h"

@ -3,6 +3,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <strophe.h> #include <strophe.h>

@ -3,6 +3,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <strophe.h> #include <strophe.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>

@ -86,7 +86,7 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
struct t_account *account = (struct t_account *)userdata; struct t_account *account = (struct t_account *)userdata;
struct t_user *user; struct t_user *user;
struct t_channel *channel; struct t_channel *channel;
xmpp_stanza_t *iq__x_signed, *iq__x_muc_user, *show, *idle, *iq__x__item, *iq__c, *iq__status; xmpp_stanza_t *pres__x_signed, *pres__x_muc_user, *show, *idle, *pres__x__item, *pres__c, *pres__status;
const char *from, *from_bare, *from_res, *type, *role = NULL, *affiliation = NULL, *jid = NULL; const char *from, *from_bare, *from_res, *type, *role = NULL, *affiliation = NULL, *jid = NULL;
const char *show__text = NULL, *idle__since = NULL, *certificate = NULL, *node = NULL, *ver = NULL; const char *show__text = NULL, *idle__since = NULL, *certificate = NULL, *node = NULL, *ver = NULL;
char *clientid = NULL, *status; char *clientid = NULL, *status;
@ -101,18 +101,18 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
show__text = show ? xmpp_stanza_get_text(show) : NULL; show__text = show ? xmpp_stanza_get_text(show) : NULL;
idle = xmpp_stanza_get_child_by_name_and_ns(stanza, "idle", "urn:xmpp:idle:1"); idle = xmpp_stanza_get_child_by_name_and_ns(stanza, "idle", "urn:xmpp:idle:1");
idle__since = idle ? xmpp_stanza_get_attribute(idle, "since") : NULL; idle__since = idle ? xmpp_stanza_get_attribute(idle, "since") : NULL;
iq__x_signed = xmpp_stanza_get_child_by_name_and_ns( pres__x_signed = xmpp_stanza_get_child_by_name_and_ns(
stanza, "x", "jabber:x:signed"); stanza, "x", "jabber:x:signed");
if (iq__x_signed) if (pres__x_signed)
{ {
certificate = xmpp_stanza_get_text(iq__x_signed); certificate = xmpp_stanza_get_text(pres__x_signed);
} }
iq__c = xmpp_stanza_get_child_by_name_and_ns( pres__c = xmpp_stanza_get_child_by_name_and_ns(
stanza, "c", "http://jabber.org/protocol/caps"); stanza, "c", "http://jabber.org/protocol/caps");
if (iq__c) if (pres__c)
{ {
node = xmpp_stanza_get_attribute(iq__c, "node"); node = xmpp_stanza_get_attribute(pres__c, "node");
ver = xmpp_stanza_get_attribute(iq__c, "ver"); ver = xmpp_stanza_get_attribute(pres__c, "ver");
if (node && ver) if (node && ver)
{ {
int len = strlen(node)+1+strlen(ver); int len = strlen(node)+1+strlen(ver);
@ -120,25 +120,25 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
snprintf(clientid, len, "%s#%s", node, ver); snprintf(clientid, len, "%s#%s", node, ver);
} }
} }
iq__status = xmpp_stanza_get_child_by_name(stanza, "status"); pres__status = xmpp_stanza_get_child_by_name(stanza, "status");
status = iq__status ? xmpp_stanza_get_text(iq__status) : NULL; status = pres__status ? xmpp_stanza_get_text(pres__status) : NULL;
iq__x_muc_user = xmpp_stanza_get_child_by_name_and_ns( pres__x_muc_user = xmpp_stanza_get_child_by_name_and_ns(
stanza, "x", "http://jabber.org/protocol/muc#user"); stanza, "x", "http://jabber.org/protocol/muc#user");
channel = channel__search(account, from_bare); channel = channel__search(account, from_bare);
if (weechat_strcasecmp(type, "unavailable") && !iq__x_muc_user && !channel) if (weechat_strcasecmp(type, "unavailable") != 0 && !pres__x_muc_user && !channel)
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare); channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
if (iq__x_muc_user) if (pres__x_muc_user)
for (iq__x__item = xmpp_stanza_get_children(iq__x_muc_user); for (pres__x__item = xmpp_stanza_get_children(pres__x_muc_user);
iq__x__item; iq__x__item = xmpp_stanza_get_next(iq__x__item)) pres__x__item; pres__x__item = xmpp_stanza_get_next(pres__x__item))
{ {
if (weechat_strcasecmp(xmpp_stanza_get_name(iq__x__item), "item") != 0) if (weechat_strcasecmp(xmpp_stanza_get_name(pres__x__item), "item") != 0)
continue; continue;
role = xmpp_stanza_get_attribute(iq__x__item, "role"); role = xmpp_stanza_get_attribute(pres__x__item, "role");
affiliation = xmpp_stanza_get_attribute(iq__x__item, "affiliation"); affiliation = xmpp_stanza_get_attribute(pres__x__item, "affiliation");
jid = xmpp_stanza_get_attribute(iq__x__item, "jid"); jid = xmpp_stanza_get_attribute(pres__x__item, "jid");
user = user__search(account, from); user = user__search(account, from);
if (!user) if (!user)
@ -209,7 +209,7 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
struct t_account *account = (struct t_account *)userdata; struct t_account *account = (struct t_account *)userdata;
struct t_channel *channel; struct t_channel *channel;
xmpp_stanza_t *x, *body, *delay, *topic, *replace, *request, *markable, *composing, *sent, *received, *result, *forwarded; xmpp_stanza_t *x, *body, *delay, *topic, *replace, *request, *markable, *composing, *sent, *received, *result, *forwarded, *event, *items, *item, *list, *device, *encrypted, **children;
const char *type, *from, *nick, *from_bare, *to, *to_bare, *id, *thread, *replace_id, *timestamp; const char *type, *from, *nick, *from_bare, *to, *to_bare, *id, *thread, *replace_id, *timestamp;
char *text, *intext, *difftext = NULL, *cleartext = NULL; char *text, *intext, *difftext = NULL, *cleartext = NULL;
struct tm time = {0}; struct tm time = {0};
@ -222,6 +222,9 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
if (topic != NULL) if (topic != NULL)
{ {
intext = xmpp_stanza_get_text(topic); intext = xmpp_stanza_get_text(topic);
type = xmpp_stanza_get_type(stanza);
if (type != NULL && strcmp(type, "error") == 0)
return 1;
from = xmpp_stanza_get_from(stanza); from = xmpp_stanza_get_from(stanza);
if (from == NULL) if (from == NULL)
return 1; return 1;
@ -229,7 +232,12 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
from = xmpp_jid_resource(account->context, from); from = xmpp_jid_resource(account->context, from);
channel = channel__search(account, from_bare); channel = channel__search(account, from_bare);
if (!channel) if (!channel)
{
if (weechat_strcasecmp(type, "groupchat") == 0)
channel = channel__new(account, CHANNEL_TYPE_MUC, from_bare, from_bare);
else
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare); channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
}
channel__update_topic(channel, intext ? intext : "", from, 0); channel__update_topic(channel, intext ? intext : "", from, 0);
if (intext != NULL) if (intext != NULL)
xmpp_free(account->context, intext); xmpp_free(account->context, intext);
@ -297,6 +305,69 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
} }
} }
event = xmpp_stanza_get_child_by_name_and_ns(
stanza, "event", "http://jabber.org/protocol/pubsub#event");
if (event)
{
items = xmpp_stanza_get_child_by_name(event, "items");
if (items)
{
const char *items_node = xmpp_stanza_get_attribute(items, "node");
from = xmpp_stanza_get_from(stanza);
to = xmpp_stanza_get_to(stanza);
if (items_node
&& weechat_strcasecmp(items_node,
"eu.siacs.conversations.axolotl.devicelist") == 0)
{
item = xmpp_stanza_get_child_by_name(items, "item");
if (item)
{
list = xmpp_stanza_get_child_by_name_and_ns(
item, "list", "eu.siacs.conversations.axolotl");
if (list)
{
if (account->omemo)
{
omemo__handle_devicelist(account->omemo, from,
items);
}
children = malloc(sizeof(*children) * (3 + 1));
for (device = xmpp_stanza_get_children(list);
device; device = xmpp_stanza_get_next(device))
{
const char *name = xmpp_stanza_get_name(device);
if (weechat_strcasecmp(name, "device") != 0)
continue;
const char *device_id = xmpp_stanza_get_id(device);
char bundle_node[128] = {0};
snprintf(bundle_node, sizeof(bundle_node),
"eu.siacs.conversations.axolotl.bundles:%s",
device_id);
children[1] = NULL;
children[0] =
stanza__iq_pubsub_items(account->context, NULL,
strdup(bundle_node));
children[0] =
stanza__iq_pubsub(account->context, NULL, children,
with_noop("http://jabber.org/protocol/pubsub"));
children[0] =
stanza__iq(account->context, NULL, children, NULL, strdup("fetch1"),
strdup(to), strdup(from), strdup("get"));
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
}
}
}
}
}
}
return 1; return 1;
} }
type = xmpp_stanza_get_type(stanza); type = xmpp_stanza_get_type(stanza);
@ -382,6 +453,12 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
weechat_list_add(channel->unreads, unread->id, WEECHAT_LIST_POS_END, unread); weechat_list_add(channel->unreads, unread->id, WEECHAT_LIST_POS_END, unread);
} }
encrypted = xmpp_stanza_get_child_by_name_and_ns(stanza, "encrypted",
"eu.siacs.conversations.axolotl");
if (encrypted && account->omemo)
{
omemo__decode(account->omemo, from_bare, encrypted);
}
x = xmpp_stanza_get_child_by_name_and_ns(stanza, "x", "jabber:x:encrypted"); x = xmpp_stanza_get_child_by_name_and_ns(stanza, "x", "jabber:x:encrypted");
intext = xmpp_stanza_get_text(body); intext = xmpp_stanza_get_text(body);
if (x) if (x)
@ -557,7 +634,7 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
weechat_string_dyn_concat(dyn_tags, replace_id, -1); weechat_string_dyn_concat(dyn_tags, replace_id, -1);
} }
if (date != 0) if (date != 0 || encrypted)
weechat_string_dyn_concat(dyn_tags, ",notify_none", -1); weechat_string_dyn_concat(dyn_tags, ",notify_none", -1);
else if (channel->type == CHANNEL_TYPE_PM else if (channel->type == CHANNEL_TYPE_PM
&& weechat_strcasecmp(from_bare, account_jid(account)) != 0) && weechat_strcasecmp(from_bare, account_jid(account)) != 0)
@ -609,11 +686,12 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
{ {
struct t_account *account = (struct t_account *)userdata; struct t_account *account = (struct t_account *)userdata;
xmpp_stanza_t *reply, *query, *identity, *feature, *x, *field, *value, *text, *fin; xmpp_stanza_t *reply, *query, *identity, *feature, *x, *field, *value, *text, *fin;
xmpp_stanza_t *pubsub, *items, *item, *list, *device, **children; xmpp_stanza_t *pubsub, *items, *item, *list, *bundle, *device;
xmpp_stanza_t *storage, *conference, *nick; xmpp_stanza_t *storage, *conference, *nick;
static struct utsname osinfo; static struct utsname osinfo;
const char *id = xmpp_stanza_get_id(stanza); const char *id = xmpp_stanza_get_id(stanza);
const char *from = xmpp_stanza_get_from(stanza);
query = xmpp_stanza_get_child_by_name_and_ns( query = xmpp_stanza_get_child_by_name_and_ns(
stanza, "query", "http://jabber.org/protocol/disco#info"); stanza, "query", "http://jabber.org/protocol/disco#info");
const char *type = xmpp_stanza_get_attribute(stanza, "type"); const char *type = xmpp_stanza_get_attribute(stanza, "type");
@ -836,7 +914,7 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
stanza, "pubsub", "http://jabber.org/protocol/pubsub"); stanza, "pubsub", "http://jabber.org/protocol/pubsub");
if (pubsub) if (pubsub)
{ {
const char *items_node, *item_id, *device_id, *ns, *node; const char *items_node, *item_id, *device_id;
items = xmpp_stanza_get_child_by_name(pubsub, "items"); items = xmpp_stanza_get_child_by_name(pubsub, "items");
if (items) if (items)
@ -855,23 +933,24 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
item, "list", "eu.siacs.conversations.axolotl"); item, "list", "eu.siacs.conversations.axolotl");
if (list && account->omemo) if (list && account->omemo)
{ {
account__free_device_all(account); omemo__handle_devicelist(account->omemo, from, items);
if (weechat_strcasecmp(account_jid(account), from) == 0)
{
struct t_account_device *dev; struct t_account_device *dev;
char id[64] = {0}; char id[64] = {0};
int i = 0;
account__free_device_all(account);
dev = malloc(sizeof(struct t_account_device)); dev = malloc(sizeof(struct t_account_device));
dev->id = account->omemo->device_id; dev->id = account->omemo->device_id;
snprintf(id, sizeof(id), "%d", dev->id); snprintf(id, sizeof(id), "%d", dev->id);
dev->name = strdup(id); dev->name = strdup(id);
dev->label = strdup("weechat");
account__add_device(account, dev); account__add_device(account, dev);
children = malloc(sizeof(xmpp_stanza_t *) * 128); free(dev->label);
children[i++] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(dev->name));
free(dev->name); free(dev->name);
free(dev); free(dev);
@ -887,90 +966,42 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
dev = malloc(sizeof(struct t_account_device)); dev = malloc(sizeof(struct t_account_device));
dev->id = atoi(device_id); dev->id = atoi(device_id);
dev->name = strdup(device_id); dev->name = strdup(device_id);
dev->label = NULL;
account__add_device(account, dev); account__add_device(account, dev);
children[i++] = stanza__iq_pubsub_publish_item_list_device( free(dev->label);
account->context, NULL, with_noop(dev->name));
free(dev->name); free(dev->name);
free(dev); free(dev);
} }
children[i] = NULL; reply = account__get_devicelist(account);
node = "eu.siacs.conversations.axolotl";
children[0] = stanza__iq_pubsub_publish_item_list(
account->context, NULL, children, with_noop(node));
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item(
account->context, NULL, children, with_noop("current"));
ns = "http://jabber.org/protocol/pubsub";
children[0] = stanza__iq_pubsub_publish(account->context,
NULL, children,
with_noop(ns));
children[0] = stanza__iq_pubsub(account->context, NULL,
children, with_noop(""));
reply = stanza__iq(account->context, xmpp_stanza_reply(stanza),
children, NULL, strdup("announce1"),
NULL, NULL, strdup("set"));
xmpp_send(conn, reply); xmpp_send(conn, reply);
xmpp_stanza_release(reply); xmpp_stanza_release(reply);
}
char bundle_node[128] = {0}; }
snprintf(bundle_node, sizeof(bundle_node), }
"eu.siacs.conversations.axolotl.bundles:%d", }
account->omemo->device_id); if (items_node
&& strncmp(items_node,
xmpp_stanza_t *textchild[2] = {NULL}; "eu.siacs.conversations.axolotl.bundles",
textchild[0] = xmpp_stanza_new(account->context); strnlen(items_node,
xmpp_stanza_set_text(textchild[0], "b64enc1"); strlen("eu.siacs.conversations.axolotl.bundles"))) == 0)
children[0] = stanza__iq_pubsub_publish_item_bundle_signedPreKeyPublic( {
account->context, NULL, textchild, with_noop("1")); item = xmpp_stanza_get_child_by_name(items, "item");
textchild[0] = xmpp_stanza_new(account->context); if (item)
xmpp_stanza_set_text(textchild[0], "b64enc2"); {
children[1] = stanza__iq_pubsub_publish_item_bundle_signedPreKeySignature( bundle = xmpp_stanza_get_child_by_name_and_ns(item, "bundle", "eu.siacs.conversations.axolotl");
account->context, NULL, textchild); if (bundle)
textchild[0] = xmpp_stanza_new(account->context); {
xmpp_stanza_set_text(textchild[0], "b64enc3"); size_t node_prefix =
children[2] = stanza__iq_pubsub_publish_item_bundle_identityKey( strlen("eu.siacs.conversations.axolotl.bundles:");
account->context, NULL, textchild); if (account->omemo && strlen(items_node) > node_prefix)
textchild[0] = xmpp_stanza_new(account->context); {
xmpp_stanza_set_text(textchild[0], "b64enc4"); omemo__handle_bundle(account->omemo, from,
children[3] = stanza__iq_pubsub_publish_item_bundle_prekeys_preKeyPublic( strtol(items_node+node_prefix,
account->context, NULL, textchild, with_noop("1")); NULL, 10),
textchild[0] = xmpp_stanza_new(account->context); items);
xmpp_stanza_set_text(textchild[0], "b64enc5"); }
children[4] = stanza__iq_pubsub_publish_item_bundle_prekeys_preKeyPublic(
account->context, NULL, textchild, with_noop("2"));
textchild[0] = xmpp_stanza_new(account->context);
xmpp_stanza_set_text(textchild[0], "b64enc6");
children[5] = stanza__iq_pubsub_publish_item_bundle_prekeys_preKeyPublic(
account->context, NULL, textchild, with_noop("3"));
children[6] = NULL;
children[3] = stanza__iq_pubsub_publish_item_bundle_prekeys(
account->context, NULL, &children[3]);
children[4] = NULL;
ns = "eu.siacs.conversations.axolotl";
children[0] = stanza__iq_pubsub_publish_item_bundle(
account->context, NULL, children, with_noop(ns));
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item(
account->context, NULL, children, with_noop("current"));
children[0] = stanza__iq_pubsub_publish(account->context,
NULL, children,
with_noop(bundle_node));
children[0] =
stanza__iq_pubsub(account->context, NULL, children,
with_noop("http://jabber.org/protocol/pubsub"));
children[0] =
stanza__iq(account->context, NULL, children, NULL, strdup("announce2"),
strdup(account_jid(account)), strdup(account_jid(account)),
strdup("set"));
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
free(children);
} }
} }
} }
@ -1185,6 +1216,12 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
omemo__init(account->buffer, &account->omemo, account->name); omemo__init(account->buffer, &account->omemo, account->name);
children[0] =
omemo__get_bundle(account->context,
strdup(account_jid(account)), NULL, account->omemo);
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
(void) weechat_hook_signal_send("xmpp_account_connected", (void) weechat_hook_signal_send("xmpp_account_connected",
WEECHAT_HOOK_SIGNAL_STRING, account->name); WEECHAT_HOOK_SIGNAL_STRING, account->name);
} }

@ -4,6 +4,7 @@
#include <strophe.h> #include <strophe.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"

@ -0,0 +1,126 @@
(define-module (gnu packages messaging)
#:use-module (gnu packages)
#:use-module (gnu packages admin)
#:use-module (gnu packages aidc)
#:use-module (gnu packages aspell)
#:use-module (gnu packages audio)
#:use-module (gnu packages autotools)
#:use-module (gnu packages avahi)
#:use-module (gnu packages base)
#:use-module (gnu packages bash)
#:use-module (gnu packages bison)
#:use-module (gnu packages boost)
#:use-module (gnu packages check)
#:use-module (gnu packages compression)
#:use-module (gnu packages cpp)
#:use-module (gnu packages crypto)
#:use-module (gnu packages curl)
#:use-module (gnu packages cyrus-sasl)
#:use-module (gnu packages databases)
#:use-module (gnu packages docbook)
#:use-module (gnu packages documentation)
#:use-module (gnu packages enchant)
#:use-module (gnu packages fontutils)
#:use-module (gnu packages freedesktop)
#:use-module (gnu packages gettext)
#:use-module (gnu packages glib)
#:use-module (gnu packages gnome)
#:use-module (gnu packages gnupg)
#:use-module (gnu packages golang)
#:use-module (gnu packages gperf)
#:use-module (gnu packages graphviz)
#:use-module (gnu packages gstreamer)
#:use-module (gnu packages gtk)
#:use-module (gnu packages guile)
#:use-module (gnu packages icu4c)
#:use-module (gnu packages image)
#:use-module (gnu packages kde)
#:use-module (gnu packages kerberos)
#:use-module (gnu packages less)
#:use-module (gnu packages libcanberra)
#:use-module (gnu packages libffi)
#:use-module (gnu packages libidn)
#:use-module (gnu packages libreoffice)
#:use-module (gnu packages linux)
#:use-module (gnu packages logging)
#:use-module (gnu packages lua)
#:use-module (gnu packages man)
#:use-module (gnu packages markup)
#:use-module (gnu packages matrix)
#:use-module (gnu packages mono)
#:use-module (gnu packages mpd)
#:use-module (gnu packages ncurses)
#:use-module (gnu packages networking)
#:use-module (gnu packages nss)
#:use-module (gnu packages pcre)
#:use-module (gnu packages perl)
#:use-module (gnu packages photo)
#:use-module (gnu packages php)
#:use-module (gnu packages pkg-config)
#:use-module (gnu packages protobuf)
#:use-module (gnu packages python)
#:use-module (gnu packages python-check)
#:use-module (gnu packages python-crypto)
#:use-module (gnu packages python-web)
#:use-module (gnu packages python-xyz)
#:use-module (gnu packages qt)
#:use-module (gnu packages readline)
#:use-module (gnu packages ruby)
#:use-module (gnu packages sphinx)
#:use-module (gnu packages sqlite)
#:use-module (gnu packages tcl)
#:use-module (gnu packages texinfo)
#:use-module (gnu packages textutils)
#:use-module (gnu packages tls)
#:use-module (gnu packages video)
#:use-module (gnu packages web)
#:use-module (gnu packages xdisorg)
#:use-module (gnu packages xiph)
#:use-module (gnu packages xml)
#:use-module (gnu packages xorg)
#:use-module (guix build-system cmake)
#:use-module (guix build-system go)
#:use-module (guix build-system glib-or-gtk)
#:use-module (guix build-system gnu)
#:use-module (guix build-system meson)
#:use-module (guix build-system perl)
#:use-module (guix build-system python)
#:use-module (guix build-system qt)
#:use-module (guix build-system trivial)
#:use-module (guix download)
#:use-module (guix git-download)
#:use-module (guix hg-download)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (guix packages)
#:use-module (guix utils))
(define-public libomemo-c
(package
(name "libomemo-c")
(version "2.3.3")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/dino/libomemo-c")
(commit "06184660790daa42433e616fa3dee730717d1c1b")))
(file-name (git-file-name name version))
(sha256
(base32
"1wa85r1b54myabsbmbqlq9jz174mmvd02b8zy1j4j0kml0anp6nx"))))
(arguments
`(;; Required for proper linking and for tests to run.
#:configure-flags '("-DBUILD_SHARED_LIBS=on" "-DBUILD_TESTING=1")))
(build-system cmake-build-system)
(inputs `( ;; Required for tests:
("check" ,check)
("openssl" ,openssl)))
(native-inputs `(("pkg-config" ,pkg-config)))
(home-page "https://github.com/WhisperSystems/libsignal-protocol-c")
(synopsis "Implementation of a ratcheting forward secrecy protocol")
(description "libsignal-protocol-c is an implementation of a ratcheting
forward secrecy protocol that works in synchronous and asynchronous
messaging environments. It can be used with messaging software to provide
end-to-end encryption.")
(license license:gpl3+)))
libomemo-c

@ -4,6 +4,7 @@
#include <strophe.h> #include <strophe.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <regex.h> #include <regex.h>

1377
omemo.c

File diff suppressed because it is too large Load Diff

@ -13,20 +13,44 @@ struct t_omemo
struct signal_protocol_store_context *store_context; struct signal_protocol_store_context *store_context;
struct t_omemo_db *db; struct t_omemo_db *db;
char *db_path;
struct ratchet_identity_key_pair *identity; struct ratchet_identity_key_pair *identity;
uint32_t device_id; uint32_t device_id;
}; };
struct t_omemo_bundle_req
{
char *id;
char *jid;
char *device;
char *message_text;
};
struct t_omemo_devicelist_req
{
char *id;
struct t_omemo_bundle_req bundle_req;
};
xmpp_stanza_t *omemo__get_bundle(xmpp_ctx_t *context, char *from, char *to,
struct t_omemo *omemo);
void omemo__init(struct t_gui_buffer *buffer, struct t_omemo **omemo, void omemo__init(struct t_gui_buffer *buffer, struct t_omemo **omemo,
const char *account_name); const char *account_name);
void omemo__serialize(struct t_omemo *omemo, char **device, void omemo__handle_devicelist(struct t_omemo *omemo, const char *jid,
char **identity, size_t *identity_len); xmpp_stanza_t *items);
void omemo__handle_bundle(struct t_omemo *omemo, const char *jid,
uint32_t device_id, xmpp_stanza_t *items);
char *omemo__decode(struct t_omemo *omemo, const char *jid,
xmpp_stanza_t *encrypted);
void omemo__deserialize(struct t_omemo *omemo, const char *device, xmpp_stanza_t *omemo__encode(struct t_omemo *omemo, const char *jid,
const char *identity, size_t identity_len); uint32_t device_id, const char *unencrypted);
void omemo__free(struct t_omemo *omemo); void omemo__free(struct t_omemo *omemo);

@ -3,6 +3,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <strophe.h> #include <strophe.h>

@ -3,6 +3,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <strophe.h> #include <strophe.h>
@ -191,6 +192,7 @@ struct t_user *user__new(struct t_account *account,
new_user->profile.email = NULL; new_user->profile.email = NULL;
new_user->profile.role = NULL; new_user->profile.role = NULL;
new_user->profile.pgp_id = NULL; new_user->profile.pgp_id = NULL;
new_user->profile.omemo = 0;
new_user->updated = 0; new_user->updated = 0;
new_user->is_away = 0; new_user->is_away = 0;

@ -16,6 +16,7 @@ struct t_user_profile
char *role; char *role;
char *affiliation; char *affiliation;
char *pgp_id; char *pgp_id;
int omemo;
}; };
struct t_user struct t_user

@ -193,7 +193,7 @@ xmpp_stanza_t *stanza__iq_pubsub_publish_item_list(xmpp_ctx_t *context, xmpp_sta
} }
xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *id) struct t_string *id, struct t_string *label)
{ {
xmpp_stanza_t *parent = base; xmpp_stanza_t *parent = base;
@ -210,6 +210,13 @@ xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, x
free(id); free(id);
} }
if (label)
{
xmpp_stanza_set_attribute(parent, "label", label->value);
label->finalize(label);
free(label);
}
return parent; return parent;
} }

@ -49,6 +49,22 @@ static inline struct t_string *with_xmpp_free(char *value, xmpp_ctx_t *pointer)
return string; return string;
} }
static inline void stanza__set_text(xmpp_ctx_t *context, xmpp_stanza_t *parent,
struct t_string *value)
{
xmpp_stanza_t *text = xmpp_stanza_new(context);
if (value)
{
xmpp_stanza_set_text(text, value->value);
xmpp_stanza_add_child(parent, text);
value->finalize(value);
free(value);
}
xmpp_stanza_release(text);
}
xmpp_stanza_t *stanza__presence(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__presence(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, const char *ns, xmpp_stanza_t **children, const char *ns,
char *from, char *to, const char *type); char *from, char *to, const char *type);
@ -72,7 +88,7 @@ xmpp_stanza_t *stanza__iq_pubsub_publish_item_list(xmpp_ctx_t *context, xmpp_sta
xmpp_stanza_t **children, struct t_string *ns); xmpp_stanza_t **children, struct t_string *ns);
xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *id); struct t_string *id, struct t_string *label);
xmpp_stanza_t *stanza__iq_pubsub_publish_item_bundle(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_pubsub_publish_item_bundle(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *ns); xmpp_stanza_t **children, struct t_string *ns);

Loading…
Cancel
Save