fetch devicelist

v1
Tony Olagbaiye 4 years ago
parent 2190c0a075
commit ee16eaaa7a
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -38,6 +38,7 @@ use_guix()
make cmake gcc-toolchain pkg-config patchelf make cmake gcc-toolchain pkg-config patchelf
weechat libxml2 libstrophe weechat libxml2 libstrophe
glib libsignal-protocol-c sqlite glib libsignal-protocol-c 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>

@ -7,7 +7,7 @@ FIND=find
INCLUDES=-Ilibstrophe $(shell xml2-config --cflags) $(shell pkg-config --cflags glib-2.0) $(shell pkg-config --cflags libsignal-protocol-c) INCLUDES=-Ilibstrophe $(shell xml2-config --cflags) $(shell pkg-config --cflags glib-2.0) $(shell pkg-config --cflags libsignal-protocol-c)
CFLAGS+=$(DBGCFLAGS) -fno-omit-frame-pointer -fPIC -std=gnu99 -g -Wall -Wextra -Werror-implicit-function-declaration -Wno-missing-field-initializers -D_XOPEN_SOURCE=700 $(INCLUDES) CFLAGS+=$(DBGCFLAGS) -fno-omit-frame-pointer -fPIC -std=gnu99 -g -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 glib-2.0) $(shell pkg-config --libs libsignal-protocol-c) LDLIBS=-lstrophe -lpthread $(shell xml2-config --libs) $(shell pkg-config --libs glib-2.0) $(shell pkg-config --libs libsignal-protocol-c) -lmxml
PREFIX ?= /usr/local PREFIX ?= /usr/local
LIBDIR ?= $(PREFIX)/lib LIBDIR ?= $(PREFIX)/lib
@ -27,7 +27,7 @@ SRCS=plugin.c \
xmpp/presence.c \ xmpp/presence.c \
xmpp/iq.c \ xmpp/iq.c \
DEPS=axc/build/libaxc.a DEPS=omemo/build/libomemo-conversations.a axc/build/libaxc.a
OBJS=$(subst .c,.o,$(SRCS)) OBJS=$(subst .c,.o,$(SRCS))
all: weechat-xmpp all: weechat-xmpp
@ -39,6 +39,10 @@ xmpp.so: $(OBJS) $(DEPS)
patchelf --set-rpath $(LIBRARY_PATH):$(shell realpath $(shell dirname $(shell gcc --print-libgcc-file-name))/../../../) xmpp.so && \ patchelf --set-rpath $(LIBRARY_PATH):$(shell realpath $(shell dirname $(shell gcc --print-libgcc-file-name))/../../../) xmpp.so && \
patchelf --shrink-rpath xmpp.so || true patchelf --shrink-rpath xmpp.so || true
omemo/build/libomemo-conversations.a:
$(MAKE) -C omemo
omemo: omemo/build/libomemo-conversations.a
axc/build/libaxc.a: axc/build/libaxc.a:
$(MAKE) -C axc $(MAKE) -C axc
axc: axc/build/libaxc.a axc: axc/build/libaxc.a
@ -62,6 +66,7 @@ tidy:
clean: clean:
$(RM) -f $(OBJS) $(RM) -f $(OBJS)
$(MAKE) -C omemo clean || true
$(MAKE) -C axc clean || true $(MAKE) -C axc clean || true
git submodule foreach --recursive git clean -xfd || true git submodule foreach --recursive git clean -xfd || true
git submodule foreach --recursive git reset --hard || true git submodule foreach --recursive git reset --hard || true

@ -122,10 +122,12 @@
* [ ] [#A] Send typing notifications * [ ] [#A] Send typing notifications
* [ ] [#A] Recv typing notifications * [ ] [#A] Recv typing notifications
* [ ] [#C] Read receipts * [ ] [#C] Read receipts
* [ ] Message Carbons
* [ ] Service Disco * [ ] Service Disco
* [ ] Bookmarks / Roster * [ ] Bookmarks / Roster
* [ ] OTR (libotr) * [ ] OTR (libotr)
* [ ] PGP (libgpgme) * [ ] PGP (libgpgme)
* [ ] Room Explorer (https://search.jabber.network/docs/api)
** TODO [#C] Implement completion engine (milestone v0.3) ** TODO [#C] Implement completion engine (milestone v0.3)
** TODO [#D] Close all issues (milestone v1.0) ** TODO [#D] Close all issues (milestone v1.0)
* [ ] Absorb libomemo / axc, and drop glib * [ ] Absorb libomemo / axc, and drop glib

@ -13,6 +13,7 @@
#include "plugin.h" #include "plugin.h"
#include "config.h" #include "config.h"
#include "input.h" #include "input.h"
#include "omemo.h"
#include "account.h" #include "account.h"
#include "connection.h" #include "connection.h"
#include "user.h" #include "user.h"
@ -86,6 +87,81 @@ int account__search_option(const char *option_name)
return -1; return -1;
} }
struct t_device *account__search_device(struct t_account *account, int id)
{
struct t_device *ptr_device;
if (!account)
return NULL;
for (ptr_device = account->devices; ptr_device;
ptr_device = ptr_device->next_device)
{
if (ptr_device->id == id)
return ptr_device;
}
return NULL;
}
void account__add_device(struct t_account *account,
struct t_device *device)
{
struct t_device *new_device;
new_device = account__search_device(account, device->id);
if (!new_device)
{
new_device = malloc(sizeof(*new_device));
new_device->id = device->id;
new_device->name = strdup(device->name);
new_device->prev_device = account->last_device;
new_device->next_device = NULL;
if (account->last_device)
(account->last_device)->next_device = new_device;
else
account->devices = new_device;
account->last_device = new_device;
}
}
void account__free_device(struct t_account *account, struct t_device *device)
{
struct t_device *new_devices;
if (!account || !device)
return;
/* remove device from devices list */
if (account->last_device == device)
account->last_device = device->prev_device;
if (device->prev_device)
{
(device->prev_device)->next_device = device->next_device;
new_devices = account->devices;
}
else
new_devices = device->next_device;
if (device->next_device)
(device->next_device)->prev_device = device->prev_device;
/* free device data */
if (device->name)
free(device->name);
free(device);
account->devices = new_devices;
}
void account__free_device_all(struct t_account *account)
{
while (account->devices)
account__free_device(account, account->devices);
}
void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t level, void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t level,
const char *const area, const char *const msg) const char *const area, const char *const msg)
{ {
@ -204,6 +280,10 @@ struct t_account *account__alloc(const char *name)
new_account->is_connected = 0; new_account->is_connected = 0;
new_account->disconnected = 0; new_account->disconnected = 0;
new_account->current_retry = 0;
new_account->reconnect_delay = 0;
new_account->reconnect_start = 0;
new_account->logger.handler = &account__log_emit_weechat; new_account->logger.handler = &account__log_emit_weechat;
new_account->logger.userdata = new_account; new_account->logger.userdata = new_account;
new_account->context = xmpp_ctx_new(NULL, &new_account->logger); new_account->context = xmpp_ctx_new(NULL, &new_account->logger);
@ -211,6 +291,11 @@ struct t_account *account__alloc(const char *name)
new_account->buffer = NULL; new_account->buffer = NULL;
new_account->buffer_as_string = NULL; new_account->buffer_as_string = NULL;
new_account->omemo = NULL;
new_account->devices = NULL;
new_account->last_device = NULL;
new_account->users = NULL; new_account->users = NULL;
new_account->last_user = NULL; new_account->last_user = NULL;
new_account->channels = NULL; new_account->channels = NULL;
@ -300,6 +385,9 @@ void account__free_data(struct t_account *account)
if (account->buffer_as_string) if (account->buffer_as_string)
free(account->buffer_as_string); free(account->buffer_as_string);
if (account->omemo)
omemo__free(account->omemo);
//channel__free_all(account); //channel__free_all(account);
//user__free_all(account); //user__free_all(account);
} }
@ -384,26 +472,23 @@ void account__disconnect(struct t_account *account, int reconnect)
weechat_prefix ("network"), WEECHAT_XMPP_PLUGIN_NAME); weechat_prefix ("network"), WEECHAT_XMPP_PLUGIN_NAME);
} }
/* if (reconnect)
account->current_retry = 0; {
if (account->current_retry++ == 0)
if (switch_address) {
account__switch_address(account, 0); account->reconnect_delay = 5;
account->reconnect_start = time(NULL) + account->reconnect_delay;
}
account->current_retry %= 5;
}
else else
account__set_index_current_address(account, 0);
if (account->nick_modes)
{ {
free (account->nick_modes); account->current_retry = 0;
account->nick_modes = NULL; account->reconnect_delay = 0;
weechat_bar_item_update ("input_prompt"); account->reconnect_start = 0;
weechat_bar_item_update ("xmpp_nick_modes");
} }
account->cap_away_notify = 0;
account->cap_account_notify = 0; /*
account->cap_extended_join = 0;
account->is_away = 0;
account->away_time = 0;
account->lag = 0; account->lag = 0;
account->lag_displayed = -1; account->lag_displayed = -1;
account->lag_check_time.tv_sec = 0; account->lag_check_time.tv_sec = 0;
@ -412,30 +497,9 @@ void account__disconnect(struct t_account *account, int reconnect)
weechat_config_integer(xmpp_config_network_lag_check); weechat_config_integer(xmpp_config_network_lag_check);
account->lag_last_refresh = 0; account->lag_last_refresh = 0;
account__set_lag(account); account__set_lag(account);
account->monitor = 0; */ // lag based on xmpp ping
account->monitor_time = 0;
*/
/*
if (reconnect
&& IRC_SERVER_OPTION_BOOLEAN(account, IRC_SERVER_OPTION_AUTORECONNECT))
account__reconnect_schedule(account);
else
{
account->reconnect_delay = 0;
account->reconnect_start = 0;
}
*/
/* discard current nick if no reconnection asked */
/*
if (!reconnect && account->nick)
account__set_nick(account, NULL);
account__set_buffer_title(account);
account->disconnected = 1; account->disconnected = 1;
*/
/* send signal "account_disconnected" with account name */ /* send signal "account_disconnected" with account name */
(void) weechat_hook_signal_send("xmpp_account_disconnected", (void) weechat_hook_signal_send("xmpp_account_disconnected",
@ -536,6 +600,11 @@ int account__timer_cb(const void *pointer, void *data, int remaining_calls)
&& (xmpp_conn_is_connecting(ptr_account->connection) && (xmpp_conn_is_connecting(ptr_account->connection)
|| xmpp_conn_is_connected(ptr_account->connection))) || xmpp_conn_is_connected(ptr_account->connection)))
connection__process(ptr_account->context, ptr_account->connection, 10); connection__process(ptr_account->context, ptr_account->connection, 10);
else if (ptr_account->reconnect_start > 0
&& ptr_account->reconnect_start < time(NULL))
{
account__connect(ptr_account);
}
} }
return WEECHAT_RC_OK; return WEECHAT_RC_OK;

@ -58,6 +58,15 @@ enum t_account_option
#define account_autojoin(account) \ #define account_autojoin(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_AUTOJOIN]) weechat_config_string(account->options[ACCOUNT_OPTION_AUTOJOIN])
struct t_device
{
int id;
char *name;
struct t_device *prev_device;
struct t_device *next_device;
};
struct t_account struct t_account
{ {
char *name; char *name;
@ -68,18 +77,26 @@ struct t_account
int is_connected; int is_connected;
int disconnected; int disconnected;
int current_retry;
int reconnect_delay;
int reconnect_start;
xmpp_log_t logger; xmpp_log_t logger;
xmpp_ctx_t *context; xmpp_ctx_t *context;
xmpp_conn_t *connection; xmpp_conn_t *connection;
struct t_gui_buffer *buffer; struct t_gui_buffer *buffer;
char *buffer_as_string; char *buffer_as_string;
//struct t_device *devices;
//struct t_device *last_device; struct t_omemo *omemo;
struct t_device *devices;
struct t_device *last_device;
struct t_user *users; struct t_user *users;
struct t_user *last_user; struct t_user *last_user;
struct t_channel *channels; struct t_channel *channels;
struct t_channel *last_channel; struct t_channel *last_channel;
struct t_account *prev_account; struct t_account *prev_account;
struct t_account *next_account; struct t_account *next_account;
}; };
@ -89,6 +106,10 @@ 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_device *account__search_device(struct t_account *account, int id);
void account__add_device(struct t_account *account, struct t_device *device);
void account__free_device(struct t_account *account, struct t_device *device);
void account__free_device_all(struct t_account *account);
struct t_account *account__alloc(const char *name); struct t_account *account__alloc(const char *name);
void account__free_data(struct t_account *account); void account__free_data(struct t_account *account);
void account__free(struct t_account *account); void account__free(struct t_account *account);

@ -2,8 +2,8 @@
// 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 <strophe.h>
#include <string.h> #include <string.h>
#include <strophe.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"

@ -10,6 +10,7 @@
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"
#include "omemo.h"
#include "account.h" #include "account.h"
#include "user.h" #include "user.h"
#include "channel.h" #include "channel.h"
@ -489,6 +490,10 @@ void channel__member_free(struct t_channel *channel,
/* free member data */ /* free member data */
if (member->id) if (member->id)
free(member->id); free(member->id);
if (member->role)
free(member->role);
if (member->affiliation)
free(member->affiliation);
free(member); free(member);
@ -589,6 +594,9 @@ struct t_channel_member *channel__add_member(struct t_account *account,
member = malloc(sizeof(struct t_channel_member)); member = malloc(sizeof(struct t_channel_member));
member->id = strdup(id); member->id = strdup(id);
member->role = NULL;
member->affiliation = NULL;
member->prev_member = channel->last_member; member->prev_member = channel->last_member;
member->next_member = NULL; member->next_member = NULL;
if (channel->last_member) if (channel->last_member)
@ -607,12 +615,13 @@ struct t_channel_member *channel__add_member(struct t_account *account,
&& channel->type == CHANNEL_TYPE_MUC) && channel->type == CHANNEL_TYPE_MUC)
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s entered", weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s entered",
weechat_prefix("join"), weechat_prefix("join"),
jid_resource); user__as_prefix_raw(account, jid_resource));
else else
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s (%s) entered", weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s (%s) entered",
weechat_prefix("join"), weechat_prefix("join"),
xmpp_jid_bare(account->context, user->id), xmpp_jid_bare(account->context, user->id),
xmpp_jid_resource(account->context, user->id)); user__as_prefix_raw(account,
xmpp_jid_resource(account->context, user->id)));
return member; return member;
} }
@ -635,6 +644,46 @@ struct t_channel_member *channel__member_search(struct t_channel *channel,
return NULL; return NULL;
} }
int channel__set_member_role(struct t_account *account,
struct t_channel *channel,
const char *id, const char *role)
{
struct t_channel_member *member;
struct t_user *user;
user = user__search(account, id);
if (!user)
return 0;
member = channel__member_search(channel, id);
if (!member)
return 0;
member->role = strdup(role);
return 1;
}
int channel__set_member_affiliation(struct t_account *account,
struct t_channel *channel,
const char *id, const char *affiliation)
{
struct t_channel_member *member;
struct t_user *user;
user = user__search(account, id);
if (!user)
return 0;
member = channel__member_search(channel, id);
if (!member)
return 0;
member->affiliation = strdup(affiliation);
return 1;
}
struct t_channel_member *channel__remove_member(struct t_account *account, struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id) const char *id)
@ -643,8 +692,8 @@ struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_user *user; struct t_user *user;
user = user__search(account, id); user = user__search(account, id);
if (user) //if (user)
user__nicklist_remove(account, channel, user); // user__nicklist_remove(account, channel, user);
member = channel__member_search(channel, id); member = channel__member_search(channel, id);
if (member) if (member)

@ -27,6 +27,9 @@ struct t_channel_member
{ {
char *id; char *id;
char *role;
char *affiliation;
struct t_channel_member *prev_member; struct t_channel_member *prev_member;
struct t_channel_member *next_member; struct t_channel_member *next_member;
}; };
@ -120,6 +123,14 @@ struct t_channel_member *channel__add_member(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id); const char *id);
int channel__set_member_role(struct t_account *account,
struct t_channel *channel,
const char *id, const char *role);
int channel__set_member_affiliation(struct t_account *account,
struct t_channel *channel,
const char *id, const char *affiliation);
struct t_channel_member *channel__remove_member(struct t_account *account, struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id); const char *id);

@ -111,6 +111,8 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
} }
else if (channel) else if (channel)
{ {
channel__set_member_role(account, channel, from, role);
channel__set_member_affiliation(account, channel, from, affiliation);
if (weechat_strcasecmp(role, "none") == 0) if (weechat_strcasecmp(role, "none") == 0)
channel__remove_member(account, channel, from); channel__remove_member(account, channel, from);
else else
@ -127,7 +129,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 *body, *delay, *topic, *replace; xmpp_stanza_t *body, *delay, *topic, *replace;
const char *type, *from, *from_bare, *to, *id, *replace_id, *timestamp; const char *type, *from, *nick, *from_bare, *to, *id, *replace_id, *timestamp;
char *intext; char *intext;
struct tm time = {0}; struct tm time = {0};
time_t date = 0; time_t date = 0;
@ -170,9 +172,10 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
if (!channel) if (!channel)
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare); channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
nick = NULL;
if (weechat_strcasecmp(type, "groupchat") == 0) if (weechat_strcasecmp(type, "groupchat") == 0)
{ {
from = weechat_strcasecmp(channel->name, nick = weechat_strcasecmp(channel->name,
xmpp_jid_bare(account->context, xmpp_jid_bare(account->context,
from)) == 0 from)) == 0
? xmpp_jid_resource(account->context, from) ? xmpp_jid_resource(account->context, from)
@ -188,6 +191,14 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
char **dyn_tags = weechat_string_dyn_alloc(1); char **dyn_tags = weechat_string_dyn_alloc(1);
weechat_string_dyn_concat(dyn_tags, "xmpp_message,message", -1); weechat_string_dyn_concat(dyn_tags, "xmpp_message,message", -1);
{
weechat_string_dyn_concat(dyn_tags, ",nick_", -1);
weechat_string_dyn_concat(dyn_tags, nick, -1);
}
{
weechat_string_dyn_concat(dyn_tags, ",host_", -1);
weechat_string_dyn_concat(dyn_tags, from, -1);
}
if (id) if (id)
{ {
weechat_string_dyn_concat(dyn_tags, ",id_", -1); weechat_string_dyn_concat(dyn_tags, ",id_", -1);
@ -213,15 +224,15 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
const char *edit = replace ? "* " : ""; // Losing which message was edited, sadly const char *edit = replace ? "* " : ""; // Losing which message was edited, sadly
if (strcmp(to, channel->id) == 0) if (strcmp(to, channel->id) == 0)
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s[to %s]: %s", weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s[to %s]: %s",
edit, user__as_prefix_raw(account, from), edit, user__as_prefix_raw(account, nick),
to, intext ? intext : ""); to, intext ? intext : "");
else if (weechat_string_match(intext, "/me *", 0)) else if (weechat_string_match(intext, "/me *", 0))
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s%s %s", weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s%s %s",
edit, weechat_prefix("action"), from, edit, weechat_prefix("action"), nick,
intext ? intext+4 : ""); intext ? intext+4 : "");
else else
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s%s", weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s%s",
edit, user__as_prefix_raw(account, from), edit, user__as_prefix_raw(account, nick),
intext ? intext : ""); intext ? intext : "");
weechat_string_dyn_free(dyn_tags, 1); weechat_string_dyn_free(dyn_tags, 1);
@ -238,19 +249,20 @@ 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; xmpp_stanza_t *reply, *query, *identity, *feature, *x, *field, *value, *text;
const char *node; xmpp_stanza_t *pubsub, *items, *item, *list, *device, *children[2];
static struct utsname osinfo; static struct utsname osinfo;
char *client_name = weechat_string_eval_expression("weechat ${info:version}", query = xmpp_stanza_get_child_by_name_and_ns(
NULL, NULL, NULL); stanza, "query", "http://jabber.org/protocol/disco#info");
if (query)
{
char *client_name;
reply = xmpp_stanza_reply(stanza); reply = xmpp_stanza_reply(stanza);
xmpp_stanza_set_type(reply, "result"); xmpp_stanza_set_type(reply, "result");
query = xmpp_stanza_get_child_by_name_and_ns( client_name = weechat_string_eval_expression("weechat ${info:version}",
stanza, "query", "http://jabber.org/protocol/disco#info"); NULL, NULL, NULL);
node = xmpp_stanza_get_attribute(query, "node");
xmpp_stanza_set_attribute(reply, "id", node);
identity = xmpp_stanza_new(account->context); identity = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(identity, "identity"); xmpp_stanza_set_name(identity, "identity");
@ -273,6 +285,7 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
FEATURE("http://jabber.org/protocol/muc"); FEATURE("http://jabber.org/protocol/muc");
FEATURE("eu.siacs.conversations.axolotl.devicelist"); FEATURE("eu.siacs.conversations.axolotl.devicelist");
FEATURE("eu.siacs.conversations.axolotl.devicelist+notify"); FEATURE("eu.siacs.conversations.axolotl.devicelist+notify");
FEATURE("storage:bookmarks+notify");
#undef FEATURE #undef FEATURE
x = xmpp_stanza_new(account->context); x = xmpp_stanza_new(account->context);
@ -286,6 +299,7 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
*osinfo.release = 0; *osinfo.release = 0;
} }
// This is utter bullshit, TODO: not this.
{ {
field = xmpp_stanza_new(account->context); field = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(field, "field"); xmpp_stanza_set_name(field, "field");
@ -428,6 +442,83 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
xmpp_stanza_release(reply); xmpp_stanza_release(reply);
free(client_name); free(client_name);
}
pubsub = xmpp_stanza_get_child_by_name_and_ns(
stanza, "pubsub", "http://jabber.org/protocol/pubsub");
if (pubsub)
{
const char *items_node, *item_id, *device_id, *ns, *node;
items = xmpp_stanza_get_child_by_name(pubsub, "items");
if (items)
items_node = xmpp_stanza_get_attribute(items, "node");
if (items && items_node
&& weechat_strcasecmp(items_node,
"eu.siacs.conversations.axolotl.devicelist") == 0)
{
item = xmpp_stanza_get_child_by_name(items, "item");
if (item)
item_id = xmpp_stanza_get_id(item);
if (item && item_id && weechat_strcasecmp(item_id, "current") == 0)
{
list = xmpp_stanza_get_child_by_name_and_ns(
item, "list", "eu.siacs.conversations.axolotl");
if (list)
{
account__free_device_all(account);
struct t_device *dev = malloc(sizeof(dev));
char id[64] = {0};
dev->id = account->omemo->device_id;
snprintf(id, sizeof(id), "%d", dev->id);
dev->name = strdup(id);
account__add_device(account, dev);
free(dev->name);
free(dev);
for (device = xmpp_stanza_get_children(list);
device; device = xmpp_stanza_get_next(device))
{
device_id = xmpp_stanza_get_id(device);
dev = malloc(sizeof(dev));
dev->id = atoi(device_id);
dev->name = strdup(device_id);
account__add_device(account, dev);
free(dev->name);
free(dev);
}
reply = xmpp_stanza_reply(stanza);
xmpp_stanza_set_type(reply, "result");
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(id));
ns = "http://jabber.org/protocol/pubsub";
children[0] = stanza__iq_pubsub_publish_item_list(
account->context, NULL, children, with_noop(ns));
node = "eu.siacs.conversations.axolotl.devicelist";
children[0] = stanza__iq_pubsub_publish_item(
account->context, NULL, children, with_noop(node));
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, reply, children, NULL,
NULL, NULL, NULL, NULL);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
}
}
}
}
return 1; return 1;
} }
@ -441,18 +532,21 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
(void)error; (void)error;
(void)stream_error; (void)stream_error;
if (status == XMPP_CONN_CONNECT) { 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, **children;
char cap_hash[28+1] = {0}; char cap_hash[28+1] = {0};
xmpp_handler_add(conn, connection__version_handler, xmpp_handler_add(conn, &connection__version_handler,
"jabber:iq:version", "iq", NULL, account); "jabber:iq:version", "iq", NULL, account);
xmpp_handler_add(conn, connection__presence_handler, xmpp_handler_add(conn, &connection__presence_handler,
NULL, "presence", NULL, account); NULL, "presence", NULL, account);
xmpp_handler_add(conn, connection__message_handler, xmpp_handler_add(conn, &connection__message_handler,
NULL, "message", /*type*/ NULL, account); NULL, "message", /*type*/ NULL, account);
xmpp_handler_add(conn, connection__iq_handler, //xmpp_handler_add(conn, &connection__iq_handler,
NULL, "iq", "get", account); // NULL, "iq", "get", account);
xmpp_handler_add(conn, &connection__iq_handler,
NULL, "iq", NULL, account);
/* Send initial <presence/> so that we appear online to contacts */ /* Send initial <presence/> so that we appear online to contacts */
children = malloc(sizeof(*children) * (2 + 1)); children = malloc(sizeof(*children) * (2 + 1));
@ -495,7 +589,7 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
strdup("eu.siacs.conversations.axolotl.devicelist")); strdup("eu.siacs.conversations.axolotl.devicelist"));
children[0] = children[0] =
stanza__iq_pubsub(account->context, NULL, children, stanza__iq_pubsub(account->context, NULL, children,
strdup("http://jabber.org/protocol/pubsub")); with_noop("http://jabber.org/protocol/pubsub"));
children[0] = children[0] =
stanza__iq(account->context, NULL, children, NULL, strdup("fetch1"), stanza__iq(account->context, NULL, children, NULL, strdup("fetch1"),
strdup(account_jid(account)), strdup(account_jid(account)), strdup(account_jid(account)), strdup(account_jid(account)),
@ -504,8 +598,10 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
xmpp_send(conn, children[0]); xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]); xmpp_stanza_release(children[0]);
omemo__init(account); omemo__init(&account->omemo, 0, NULL);
} else { }
else
{
account__disconnect(account, 1); account__disconnect(account, 1);
//xmpp_stop(account->context); //keep context? //xmpp_stop(account->context); //keep context?
} }

@ -4,13 +4,58 @@
#include <stdlib.h> #include <stdlib.h>
#include "omemo/src/libomemo.h"
#include "axc/src/axc.h"
#include "omemo.h" #include "omemo.h"
void omemo__init() void omemo__init(struct t_omemo **omemo, uint32_t device,
struct t_identity *identity)
{ {
const char* ns_devicelist = "eu.siacs.conversations.axolotl.devicelist"; const char* ns_devicelist = "eu.siacs.conversations.axolotl.devicelist";
const char* ft_devicelist = "eu.siacs.conversations.axolotl.devicelist+notify"; const char* ft_devicelist = "eu.siacs.conversations.axolotl.devicelist+notify";
int rc;
srandom(time(NULL));
omemo_bundle* bundle;
rc = omemo_bundle_create(&bundle);
if (rc)
return;
if (!device)
device = random();
omemo_bundle_set_device_id(bundle, device);
if (identity)
omemo_bundle_set_identity_key(bundle, identity->key, identity->length);
else
{
identity = malloc(sizeof(*identity));
identity->length = 4;
identity->key = malloc(sizeof(*identity->key) * identity->length);
identity->key[0] = random();
identity->key[1] = random();
identity->key[2] = random();
identity->key[3] = random();
omemo_bundle_set_identity_key(bundle, identity->key, identity->length);
free(identity->key);
free(identity);
}
*omemo = malloc(sizeof(**omemo));
(*omemo)->provider.random_bytes_func = omemo_default_crypto_random_bytes;
(*omemo)->provider.aes_gcm_encrypt_func = omemo_default_crypto_aes_gcm_encrypt;
(*omemo)->provider.aes_gcm_decrypt_func = omemo_default_crypto_aes_gcm_decrypt;
(*omemo)->provider.user_data_p = (void *)(*omemo);
(*omemo)->bundle = bundle;
(*omemo)->device_id = omemo_bundle_get_device_id(bundle);
omemo_bundle_get_identity_key(bundle, &(*omemo)->identity.key, &(*omemo)->identity.length);
omemo_devicelist *devicelist;
}
void omemo__free(struct t_omemo *omemo)
{
free(omemo);
} }

@ -5,6 +5,32 @@
#ifndef _WEECHAT_XMPP_OMEMO_H_ #ifndef _WEECHAT_XMPP_OMEMO_H_
#define _WEECHAT_XMPP_OMEMO_H_ #define _WEECHAT_XMPP_OMEMO_H_
void omemo__init(); #include "axc/src/axc.h"
#include "omemo/src/libomemo.h"
#include "omemo/src/libomemo_crypto.h"
struct t_identity
{
uint8_t *key;
size_t length;
};
struct t_omemo
{
omemo_crypto_provider provider;
omemo_devicelist *devicelist;
omemo_bundle *bundle;
struct t_identity identity;
uint32_t device_id;
};
void omemo__init(struct t_omemo **omemo, uint32_t device,
struct t_identity *identity);
void omemo__free(struct t_omemo *omemo);
#endif /*WEECHAT_XMPP_OMEMO_H*/ #endif /*WEECHAT_XMPP_OMEMO_H*/

@ -5,6 +5,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <strophe.h> #include <strophe.h>
#include "stanza.h"
xmpp_stanza_t *stanza__iq(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, char *ns, char *id, xmpp_stanza_t **children, char *ns, char *id,
char *from, char *to, char *type) char *from, char *to, char *type)
@ -54,7 +56,7 @@ xmpp_stanza_t *stanza__iq(xmpp_ctx_t *context, xmpp_stanza_t *base,
} }
xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, char *ns) xmpp_stanza_t **children, struct t_string *ns)
{ {
xmpp_stanza_t *parent = base; xmpp_stanza_t *parent = base;
xmpp_stanza_t **child = children; xmpp_stanza_t **child = children;
@ -67,7 +69,8 @@ xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base,
if (ns) if (ns)
{ {
xmpp_stanza_set_ns(parent, ns); xmpp_stanza_set_ns(parent, ns->value);
ns->finalize(ns);
free(ns); free(ns);
} }
@ -100,3 +103,135 @@ xmpp_stanza_t *stanza__iq_pubsub_items(xmpp_ctx_t *context, xmpp_stanza_t *base,
return parent; return parent;
} }
xmpp_stanza_t *stanza__iq_pubsub_publish(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *node)
{
xmpp_stanza_t *parent = base;
xmpp_stanza_t **child = children;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "publish");
}
if (node)
{
xmpp_stanza_set_attribute(parent, "node", node->value);
node->finalize(node);
free(node);
}
while (*child)
{
xmpp_stanza_add_child(parent, *child);
xmpp_stanza_release(*child);
++child;
}
return parent;
}
xmpp_stanza_t *stanza__iq_pubsub_publish_item(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *id)
{
xmpp_stanza_t *parent = base;
xmpp_stanza_t **child = children;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "item");
}
if (id)
{
xmpp_stanza_set_id(parent, id->value);
id->finalize(id);
free(id);
}
while (*child)
{
xmpp_stanza_add_child(parent, *child);
xmpp_stanza_release(*child);
++child;
}
return parent;
}
xmpp_stanza_t *stanza__iq_pubsub_publish_item_list(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *ns)
{
xmpp_stanza_t *parent = base;
xmpp_stanza_t **child = children;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "list");
}
if (ns)
{
xmpp_stanza_set_ns(parent, ns->value);
ns->finalize(ns);
free(ns);
}
while (*child)
{
xmpp_stanza_add_child(parent, *child);
xmpp_stanza_release(*child);
++child;
}
return parent;
}
xmpp_stanza_t *stanza__iq_pubsub_publish_item_list_device(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *id)
{
xmpp_stanza_t *parent = base;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "device");
}
if (id)
{
xmpp_stanza_set_id(parent, id->value);
id->finalize(id);
free(id);
}
return parent;
}
xmpp_stanza_t *stanza__iq_ping(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *ns)
{
xmpp_stanza_t *parent = base;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "ping");
}
if (ns)
{
xmpp_stanza_set_ns(parent, ns->value);
ns->finalize(ns);
free(ns);
}
return parent;
}

@ -5,6 +5,50 @@
#ifndef _WEECHAT_XMPP_STANZA_H_ #ifndef _WEECHAT_XMPP_STANZA_H_
#define _WEECHAT_XMPP_STANZA_H_ #define _WEECHAT_XMPP_STANZA_H_
struct t_string
{
char *value;
void (*finalize)(struct t_string *);
void *pointer;
};
static void t_string_noop(struct t_string *string)
{ (void)string; }
static void t_string_free(struct t_string *string)
{ free(string->value); }
static void t_string_xmpp_free(struct t_string *string)
{ xmpp_free(string->pointer, string->value); }
static inline struct t_string *with_noop(const char *const value)
{
struct t_string *string = malloc(sizeof(struct t_string));
string->value = (char*)value;
string->finalize = &t_string_noop;
string->pointer = NULL;
return string;
}
static inline struct t_string *with_free(char *value)
{
struct t_string *string = malloc(sizeof(struct t_string));
string->value = value;
string->finalize = &t_string_free;
string->pointer = NULL;
return string;
}
static inline struct t_string *with_xmpp_free(char *value, xmpp_ctx_t *pointer)
{
struct t_string *string = malloc(sizeof(struct t_string));
string->value = value;
string->finalize = &t_string_xmpp_free;
string->pointer = pointer;
return string;
}
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);
@ -14,8 +58,23 @@ xmpp_stanza_t *stanza__iq(xmpp_ctx_t *context, xmpp_stanza_t *base,
char *from, char *to, char *type); char *from, char *to, char *type);
xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, char *ns); xmpp_stanza_t **children, struct t_string *ns);
xmpp_stanza_t *stanza__iq_pubsub_items(xmpp_ctx_t *context, xmpp_stanza_t *base, char *node); xmpp_stanza_t *stanza__iq_pubsub_items(xmpp_ctx_t *context, xmpp_stanza_t *base, char *node);
xmpp_stanza_t *stanza__iq_pubsub_publish(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *node);
xmpp_stanza_t *stanza__iq_pubsub_publish_item(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t **children, struct t_string *id);
xmpp_stanza_t *stanza__iq_pubsub_publish_item_list(xmpp_ctx_t *context, xmpp_stanza_t *base,
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,
struct t_string *id);
xmpp_stanza_t *stanza__iq_ping(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *ns);
#endif /*WEECHAT_XMPP_STANZA_H*/ #endif /*WEECHAT_XMPP_STANZA_H*/

Loading…
Cancel
Save