Tony Olagbaiye 2 years ago
commit 5c50107bb9
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -5,10 +5,12 @@ export CC=gcc CXX="g++ -fdiagnostics-color=always"
# Miscellaneous packages. # Miscellaneous packages.
ENVIRONMENTS=( ENVIRONMENTS=(
weechat # Debug runs weechat # Debug runs
profanity # Test
) )
# Environment packages. # Environment packages.
PACKAGES=( PACKAGES=(
profanity # Test
autoconf # Deps with autoreconf autoconf # Deps with autoreconf
autoconf-archive # Deps with m4 tooling autoconf-archive # Deps with m4 tooling
automake # Deps with automake automake # Deps with automake
@ -25,7 +27,7 @@ PACKAGES=(
libxml2 # Dep (libxml2) libxml2 # Dep (libxml2)
libstrophe # Dep (strophe) libstrophe # Dep (strophe)
libgcrypt # Dep (gcrypt) libgcrypt # Dep (gcrypt)
libsignal-protocol-c # Dep (libsignal) libsignal-protocol-c -l libomemo.scm # Dep (libsignal)
lmdb lmdbxx # Dep (lmdb) lmdb lmdbxx # Dep (lmdb)
rnp # Dep (rnpgp) rnp # Dep (rnpgp)
) )
@ -34,11 +36,17 @@ echo direnv: fetching source - weechat
mkdir -p /tmp/guix-build-weechat-3.2.drv-0 mkdir -p /tmp/guix-build-weechat-3.2.drv-0
tar -C /tmp/guix-build-weechat-3.2.drv-0 -xJf $(guix build --source weechat) tar -C /tmp/guix-build-weechat-3.2.drv-0 -xJf $(guix build --source weechat)
echo direnv: fetching source - libomemo-c
mkdir -p /tmp/guix-build-libomemo-c-2.3.3.drv-0
ln -sf $(guix build --source -f libomemo.scm) /tmp/guix-build-libomemo-c-2.3.3.drv-0
use guix \ use guix \
${ENVIRONMENTS[@]} --ad-hoc ${PACKAGES[@]} \ ${ENVIRONMENTS[@]} --ad-hoc ${PACKAGES[@]} \
--with-debug-info=profanity\
--with-debug-info=weechat \ --with-debug-info=weechat \
--with-debug-info=libstrophe \ --with-debug-info=libstrophe \
--with-debug-info=libsignal-protocol-c \ --with-debug-info=libsignal-protocol-c \
--with-debug-info=libomemo-c\
--with-debug-info=lmdb \ --with-debug-info=lmdb \
--with-debug-info=rnp \ --with-debug-info=rnp \
clang clang:extra ccls gdb clang clang:extra ccls gdb

@ -16,7 +16,7 @@
[[https://github.com/bqv/weechat-xmpp/issues?q=is:issue+is:closed][file:https://img.shields.io/github/issues-closed/bqv/weechat-xmpp.svg]] [[https://github.com/bqv/weechat-xmpp/issues?q=is:issue+is:closed][file:https://img.shields.io/github/issues-closed/bqv/weechat-xmpp.svg]]
[[https://github.com/bqv/weechat-xmpp/blob/master/LICENSE][file:https://img.shields.io/github/license/bqv/weechat-xmpp.svg]] [[https://github.com/bqv/weechat-xmpp/blob/master/LICENSE][file:https://img.shields.io/github/license/bqv/weechat-xmpp.svg]]
[[https://github.com/bqv/weechat-extras/][file:https://img.shields.io/badge/weechat--extras-xmpp-blue.svg]] [[https://github.com/bqv/weechat-extras/][file:https://img.shields.io/badge/weechat--extras-xmpp-blue.svg]]
[[https://github.com/bqv/weechat-extras/][file:https://inverse.chat/badge.svg?room=weechat@muc.xa0.uk]] [[https://inverse.chat/#converse/room?jid=weechat@muc.xa0.uk][file:https://inverse.chat/badge.svg?room=weechat@muc.xa0.uk]]
| Status: | XMPP for power users and digital masochists | | Status: | XMPP for power users and digital masochists |
| Location: | [[http://github.com/bqv/weechat-xmpp]] | | Location: | [[http://github.com/bqv/weechat-xmpp]] |
@ -31,14 +31,14 @@
My priority here is to have an android-available XMPP client My priority here is to have an android-available XMPP client
that hides as little as possible from the user. To use this with that hides as little as possible from the user. To use this with
android, set up a relay (`/relay`) and see weechat-android. android, set up a relay (`/relay`) and see weechat-android.
I'm gonna rewrite this in C++ at some point when I have a feel I might rewrite this in C++ at some point when I feel like I
for the full behaviour of an average client. can do it without burning out.
* Usage * Usage
1. Start with =/xmpp add=, use =/help xmpp= for instructions. 1. Start with =/account add=, use =/help account= for instructions.
2. Use =/xmpp connect <account-name>= with the name set at 2. Use =/account connect <account-name>= with the name set at
add-time. add-time.
* Installing * Installing
@ -49,7 +49,8 @@
- libstrophe (dynamic, dependency) - libstrophe (dynamic, dependency)
- libxml2 (dynamic, dependency) - libxml2 (dynamic, dependency)
- libsignal-protocol-c (dynamic, dependency) - lmdb (dynamic, dependency)
- libomemo-c (libsignal-protocol-c) (dynamic, dependency)
- rnp (dynamic, dependency) - rnp (dynamic, dependency)
- weechat (>= v3.0) - weechat (>= v3.0)
@ -95,6 +96,7 @@
* [-] OOB messages * [-] OOB messages
* [X] Single media on a line * [X] Single media on a line
* [ ] Multiple media inline (protocol?) * [ ] Multiple media inline (protocol?)
* [ ] Encrypted (pgp/omemo)
* [X] Buffer autoswitch on enter/open * [X] Buffer autoswitch on enter/open
* [X] Handle open/enter jids with a resource without breaking * [X] Handle open/enter jids with a resource without breaking
* [X] Allow /close without crashing * [X] Allow /close without crashing
@ -119,18 +121,18 @@
* [X] [#B] Leaves * [X] [#B] Leaves
* [X] [#B] Tracking * [X] [#B] Tracking
* [X] [#B] Set/show topic * [X] [#B] Set/show topic
* [-] OMEMO (libsignal-protocol-c) * [X] OMEMO (libomemo-c)
* [-] Presence * [X] Presence
* [X] Disco * [X] Disco
* [X] Disco response * [X] Disco response
* [-] Key Generation / storage (lmdb) * [X] Key Generation / storage (lmdb)
* [X] Generation * [X] Generation
* [?] Storage * [X] Storage
* [-] Announce * [X] Announce
* [X] Device ID * [X] Device ID
* [ ] Bundles * [X] Bundles
* [ ] Messages * [X] Messages
* [ ] [#C] MUC PMs * [X] [#C] MUC PMs
* [X] [#A] Send typing notifications * [X] [#A] Send typing notifications
* [X] [#A] Recv typing notifications * [X] [#A] Recv typing notifications
* [X] [#C] Read receipts * [X] [#C] Read receipts
@ -156,7 +158,6 @@
* [X] Decryption * [X] Decryption
* [X] Encryption * [X] Encryption
* [X] Custom set/clear key (/pgp) * [X] Custom set/clear key (/pgp)
* [ ] OOB data and media
* [ ] Room Explorer (https://search.jabber.network/docs/api) * [ ] 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)
@ -167,7 +168,7 @@
Please submit a pull request or create an issue Please submit a pull request or create an issue
to add a new or missing feature. to add a new or missing feature.
* Testemonials * Testimonials
"Weechat-Strophe - for the discerning dual IRCer XMPPer" -- [[github.com/janicez][Ellenor et al Bjornsdottir]] "Weechat-Strophe - for the discerning dual IRCer XMPPer" -- [[github.com/janicez][Ellenor et al Bjornsdottir]]

@ -11,6 +11,7 @@
#include <libxml/xmlwriter.h> #include <libxml/xmlwriter.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"
@ -89,7 +90,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;
@ -117,6 +118,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;
@ -150,6 +152,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);
@ -164,6 +168,59 @@ 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), NULL);
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, with_noop("current"));
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,
@ -692,7 +749,7 @@ int account__timer_cb(const void *pointer, void *data, int remaining_calls)
struct t_account *ptr_account; struct t_account *ptr_account;
for (ptr_account = accounts; ptr_account; for (ptr_account = accounts; ptr_account;
ptr_account = ptr_account->next_account) ptr_account = ptr_account ? ptr_account->next_account : NULL)
{ {
if (ptr_account->is_connected if (ptr_account->is_connected
&& (xmpp_conn_is_connecting(ptr_account->connection) && (xmpp_conn_is_connecting(ptr_account->connection)

@ -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>

@ -10,29 +10,61 @@
#include <strophe.h> #include <strophe.h>
#include "plugin.h" #include "plugin.h"
#include "omemo.h"
#include "account.h" #include "account.h"
#include "omemo.h"
#include "user.h" #include "user.h"
#include "channel.h" #include "channel.h"
#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)
{ {
switch (transport) switch (transport)
{ {
case CHANNEL_TRANSPORT_PLAINTEXT: case CHANNEL_TRANSPORT_PLAIN:
return "PLAINTEXT"; return "PLAINTEXT";
case CHANNEL_TRANSPORT_OMEMO: case CHANNEL_TRANSPORT_OMEMO:
return "OMEMO"; return "OMEMO";
case CHANNEL_TRANSPORT_PGP: case CHANNEL_TRANSPORT_PGP:
return "PGP"; return "PGP";
case CHANNEL_TRANSPORT_OTR:
return "OTR";
default: default:
return NULL; return NULL;
} }
} }
void channel__set_transport(struct t_channel *channel, enum t_channel_transport transport, int force)
{
if (force)
switch (transport)
{
case CHANNEL_TRANSPORT_PLAIN:
channel->omemo.enabled = 0;
channel->pgp.enabled = 0;
break;
case CHANNEL_TRANSPORT_OMEMO:
channel->omemo.enabled = 1;
channel->pgp.enabled = 0;
break;
case CHANNEL_TRANSPORT_PGP:
channel->omemo.enabled = 0;
channel->pgp.enabled = 1;
break;
default:
break;
}
if (channel->transport != transport)
{
channel->transport = transport;
weechat_printf_date_tags(channel->buffer, 0, NULL, "%s%sTransport: %s",
weechat_prefix("network"), weechat_color("gray"),
channel__transport_name(channel->transport));
}
}
struct t_account *channel__account(struct t_channel *channel) struct t_account *channel__account(struct t_channel *channel)
{ {
struct t_account *ptr_account; struct t_account *ptr_account;
@ -80,7 +112,7 @@ struct t_gui_buffer *channel__search_buffer(struct t_account *account,
{ {
struct t_hdata *hdata_buffer; struct t_hdata *hdata_buffer;
struct t_gui_buffer *ptr_buffer; struct t_gui_buffer *ptr_buffer;
const char *ptr_type, *ptr_account_name, *ptr_channel_name; const char *ptr_type, *ptr_account_name, *ptr_remote_jid;
hdata_buffer = weechat_hdata_get("buffer"); hdata_buffer = weechat_hdata_get("buffer");
ptr_buffer = weechat_hdata_get_list(hdata_buffer, "gui_buffers"); ptr_buffer = weechat_hdata_get_list(hdata_buffer, "gui_buffers");
@ -91,18 +123,18 @@ struct t_gui_buffer *channel__search_buffer(struct t_account *account,
{ {
ptr_type = weechat_buffer_get_string(ptr_buffer, "localvar_type"); ptr_type = weechat_buffer_get_string(ptr_buffer, "localvar_type");
ptr_account_name = weechat_buffer_get_string(ptr_buffer, ptr_account_name = weechat_buffer_get_string(ptr_buffer,
"localvar_server"); "localvar_account");
ptr_channel_name = weechat_buffer_get_string(ptr_buffer, ptr_remote_jid = weechat_buffer_get_string(ptr_buffer,
"localvar_channel"); "localvar_remote_jid");
if (ptr_type && ptr_type[0] if (ptr_type && ptr_type[0]
&& ptr_account_name && ptr_account_name[0] && ptr_account_name && ptr_account_name[0]
&& ptr_channel_name && ptr_channel_name[0] && ptr_remote_jid && ptr_remote_jid[0]
&& ( (( (type == CHANNEL_TYPE_MUC)) && ( (( (type == CHANNEL_TYPE_MUC))
&& (strcmp(ptr_type, "channel") == 0)) && (strcmp(ptr_type, "room") == 0))
|| (( (type == CHANNEL_TYPE_PM)) || (( (type == CHANNEL_TYPE_PM))
&& (strcmp(ptr_type, "private") == 0))) && (strcmp(ptr_type, "private") == 0)))
&& (strcmp(ptr_account_name, account->name) == 0) && (strcmp(ptr_account_name, account->name) == 0)
&& (weechat_strcasecmp(ptr_channel_name, name) == 0)) && (weechat_strcasecmp(ptr_remote_jid, name) == 0))
{ {
return ptr_buffer; return ptr_buffer;
} }
@ -119,13 +151,13 @@ struct t_gui_buffer *channel__create_buffer(struct t_account *account,
{ {
struct t_gui_buffer *ptr_buffer; struct t_gui_buffer *ptr_buffer;
int buffer_created; int buffer_created;
const char *short_name, *localvar_channel; const char *short_name, *localvar_remote_jid;
char buffer_name[256]; char buffer_name[1024];
buffer_created = 0; buffer_created = 0;
snprintf(buffer_name, sizeof(buffer_name), snprintf(buffer_name, sizeof(buffer_name),
"xmpp.%s.%s", account->name, name); "%s.%s", account->name, name);
ptr_buffer = channel__search_buffer(account, type, name); ptr_buffer = channel__search_buffer(account, type, name);
if (ptr_buffer) if (ptr_buffer)
@ -145,17 +177,19 @@ struct t_gui_buffer *channel__create_buffer(struct t_account *account,
if (buffer_created) if (buffer_created)
{ {
char *res = strrchr(name, '/');
if (!weechat_buffer_get_integer(ptr_buffer, "short_name_is_set")) if (!weechat_buffer_get_integer(ptr_buffer, "short_name_is_set"))
weechat_buffer_set(ptr_buffer, "short_name", name); weechat_buffer_set(ptr_buffer, "short_name",
res ? res + 1 : name);
} }
else else
{ {
short_name = weechat_buffer_get_string (ptr_buffer, "short_name"); short_name = weechat_buffer_get_string(ptr_buffer, "short_name");
localvar_channel = weechat_buffer_get_string(ptr_buffer, localvar_remote_jid = weechat_buffer_get_string(ptr_buffer,
"localvar_channel"); "localvar_remote_jid");
if (!short_name || if (!short_name ||
(localvar_channel && (strcmp(localvar_channel, short_name) == 0))) (localvar_remote_jid && (strcmp(localvar_remote_jid, short_name) == 0)))
{ {
weechat_buffer_set(ptr_buffer, "short_name", weechat_buffer_set(ptr_buffer, "short_name",
xmpp_jid_node(account->context, name)); xmpp_jid_node(account->context, name));
@ -165,20 +199,21 @@ struct t_gui_buffer *channel__create_buffer(struct t_account *account,
account_option_set(account, ACCOUNT_OPTION_NICKNAME, account_option_set(account, ACCOUNT_OPTION_NICKNAME,
xmpp_jid_node(account->context, account_jid(account))); xmpp_jid_node(account->context, account_jid(account)));
weechat_buffer_set(ptr_buffer, "name", name); weechat_buffer_set(ptr_buffer, "notify",
(type == CHANNEL_TYPE_PM) ? "3" : "1");
weechat_buffer_set(ptr_buffer, "localvar_set_type", weechat_buffer_set(ptr_buffer, "localvar_set_type",
(type == CHANNEL_TYPE_PM) ? "private" : "channel"); (type == CHANNEL_TYPE_PM) ? "private" : "channel");
weechat_buffer_set(ptr_buffer, "localvar_set_nick", weechat_buffer_set(ptr_buffer, "localvar_set_nick",
account_nickname(account)); account_nickname(account));
weechat_buffer_set(ptr_buffer, "localvar_set_server", account->name); weechat_buffer_set(ptr_buffer, "localvar_set_account", account->name);
weechat_buffer_set(ptr_buffer, "localvar_set_channel", name); weechat_buffer_set(ptr_buffer, "localvar_set_remote_jid", name);
weechat_buffer_set(ptr_buffer, "input_multiline", "1"); weechat_buffer_set(ptr_buffer, "input_multiline", "1");
if (buffer_created) if (buffer_created)
{ {
(void) weechat_hook_signal_send ("logger_backlog", (void) weechat_hook_signal_send("logger_backlog",
WEECHAT_HOOK_SIGNAL_POINTER, WEECHAT_HOOK_SIGNAL_POINTER,
ptr_buffer); ptr_buffer);
weechat_buffer_set(ptr_buffer, "input_get_unknown_commands", "1"); weechat_buffer_set(ptr_buffer, "input_get_unknown_commands", "1");
if (type != CHANNEL_TYPE_PM) if (type != CHANNEL_TYPE_PM)
{ {
@ -271,8 +306,15 @@ struct t_channel *channel__new(struct t_account *account,
new_channel->type = type; new_channel->type = type;
new_channel->id = strdup(id); new_channel->id = strdup(id);
new_channel->name = strdup(name); new_channel->name = strdup(name);
new_channel->transport = CHANNEL_TRANSPORT_PLAINTEXT; new_channel->transport = CHANNEL_TRANSPORT_PLAIN;
new_channel->pgp_id = NULL; new_channel->omemo.enabled = type == CHANNEL_TYPE_PM ? 1 : 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->pgp.enabled = 1;
new_channel->pgp.id = NULL;
new_channel->otr.enabled = 0;
new_channel->topic.value = NULL; new_channel->topic.value = NULL;
new_channel->topic.creator = NULL; new_channel->topic.creator = NULL;
@ -788,8 +830,8 @@ void channel__free(struct t_account *account,
free(channel->id); free(channel->id);
if (channel->name) if (channel->name)
free(channel->name); free(channel->name);
if (channel->pgp_id) if (channel->pgp.id)
free(channel->pgp_id); free(channel->pgp.id);
if (channel->topic.value) if (channel->topic.value)
free(channel->topic.value); free(channel->topic.value);
if (channel->topic.creator) if (channel->topic.creator)
@ -914,10 +956,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;
} }
@ -983,8 +1028,8 @@ struct t_channel_member *channel__remove_member(struct t_account *account,
return member; return member;
} }
void channel__send_message(struct t_account *account, struct t_channel *channel, int channel__send_message(struct t_account *account, struct t_channel *channel,
const char *to, const char *body) const char *to, const char *body)
{ {
channel__send_reads(account, channel); channel__send_reads(account, channel);
@ -997,17 +1042,51 @@ 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.enabled)
if (channel->pgp_id) {
xmpp_stanza_t *encrypted = omemo__encode(account, to, body);
if (!encrypted)
{
weechat_printf_date_tags(channel->buffer, 0, "notify_none", "%s%s",
weechat_prefix("error"), "OMEMO Error");
channel__set_transport(channel, CHANNEL_TRANSPORT_PLAIN, 1);
xmpp_stanza_release(message);
return WEECHAT_RC_ERROR;
}
xmpp_stanza_add_child(message, encrypted);
xmpp_stanza_release(encrypted);
xmpp_stanza_t *message__encryption = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__encryption, "encryption");
xmpp_stanza_set_ns(message__encryption, "urn:xmpp:eme:0");
xmpp_stanza_set_attribute(message__encryption, "namespace",
"eu.siacs.conversations.axolotl");
xmpp_stanza_set_attribute(message__encryption, "name", "OMEMO");
xmpp_stanza_add_child(message, message__encryption);
xmpp_stanza_release(message__encryption);
xmpp_message_set_body(message, OMEMO_ADVICE);
channel__set_transport(channel, CHANNEL_TRANSPORT_OMEMO, 0);
}
else if (channel->pgp.enabled && 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");
xmpp_stanza_set_ns(message__x, "jabber:x:encrypted"); xmpp_stanza_set_ns(message__x, "jabber:x:encrypted");
xmpp_stanza_t *message__x__text = xmpp_stanza_new(account->context); xmpp_stanza_t *message__x__text = xmpp_stanza_new(account->context);
char *ciphertext = pgp__encrypt(channel->buffer, account->pgp, account_pgp_keyid(account), channel->pgp_id, body); char *ciphertext = pgp__encrypt(channel->buffer, account->pgp, account_pgp_keyid(account), channel->pgp.id, body);
if (ciphertext) if (ciphertext)
xmpp_stanza_set_text(message__x__text, ciphertext); xmpp_stanza_set_text(message__x__text, ciphertext);
else
{
weechat_printf_date_tags(channel->buffer, 0, "notify_none", "%s%s",
weechat_prefix("error"), "PGP Error");
channel__set_transport(channel, CHANNEL_TRANSPORT_PLAIN, 1);
xmpp_stanza_release(message);
return WEECHAT_RC_ERROR;
}
free(ciphertext); free(ciphertext);
xmpp_stanza_add_child(message__x, message__x__text); xmpp_stanza_add_child(message__x, message__x__text);
@ -1026,28 +1105,17 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
xmpp_message_set_body(message, PGP_ADVICE); xmpp_message_set_body(message, PGP_ADVICE);
if (ciphertext && channel->transport != CHANNEL_TRANSPORT_PGP) channel__set_transport(channel, CHANNEL_TRANSPORT_PGP, 0);
{
channel->transport = CHANNEL_TRANSPORT_PGP;
weechat_printf_date_tags(channel->buffer, 0, NULL, "%s%sTransport: %s",
weechat_prefix("network"), weechat_color("gray"),
channel__transport_name(channel->transport));
}
} }
else else
{ {
xmpp_message_set_body(message, body); xmpp_message_set_body(message, body);
if (channel->transport != CHANNEL_TRANSPORT_PLAINTEXT) channel__set_transport(channel, CHANNEL_TRANSPORT_PLAIN, 0);
{
channel->transport = CHANNEL_TRANSPORT_PLAINTEXT;
weechat_printf_date_tags(channel->buffer, 0, NULL, "%s%sTransport: %s",
weechat_prefix("network"), weechat_color("gray"),
channel__transport_name(channel->transport));
}
} }
if (url) char *url = strstr(body, "http");
if (url && channel->transport == CHANNEL_TRANSPORT_PLAIN)
{ {
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");
@ -1070,11 +1138,28 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
xmpp_stanza_t *message__active = xmpp_stanza_new(account->context); xmpp_stanza_t *message__active = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__active, "active"); xmpp_stanza_set_name(message__active, "active");
xmpp_stanza_set_ns(message__active, "http://jabber./org/protocol/chatstates"); xmpp_stanza_set_ns(message__active, "http://jabber.org/protocol/chatstates");
xmpp_stanza_add_child(message, message__active); xmpp_stanza_add_child(message, message__active);
xmpp_stanza_release(message__active); xmpp_stanza_release(message__active);
xmpp_stanza_t *message__request = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__request, "request");
xmpp_stanza_set_ns(message__request, "urn:xmpp:receipts");
xmpp_stanza_add_child(message, message__request);
xmpp_stanza_release(message__request);
xmpp_stanza_t *message__markable = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__markable, "markable");
xmpp_stanza_set_ns(message__markable, "urn:xmpp:chat-markers:0");
xmpp_stanza_add_child(message, message__markable);
xmpp_stanza_release(message__markable);
xmpp_stanza_t *message__store = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(message__store, "store");
xmpp_stanza_set_ns(message__store, "urn:xmpp:hints");
xmpp_stanza_add_child(message, message__store);
xmpp_stanza_release(message__store);
xmpp_send(account->connection, message); xmpp_send(account->connection, message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
if (channel->type != CHANNEL_TYPE_MUC) if (channel->type != CHANNEL_TYPE_MUC)
@ -1083,6 +1168,8 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
"%s\t%s", "%s\t%s",
user__as_prefix_raw(account, account_jid(account)), user__as_prefix_raw(account, account_jid(account)),
body); body);
return WEECHAT_RC_OK;
} }
void channel__send_reads(struct t_account *account, struct t_channel *channel) void channel__send_reads(struct t_account *account, struct t_channel *channel)

@ -15,9 +15,11 @@ enum t_channel_type
enum t_channel_transport enum t_channel_transport
{ {
CHANNEL_TRANSPORT_PLAINTEXT, CHANNEL_TRANSPORT_PLAIN,
CHANNEL_TRANSPORT_OMEMO, CHANNEL_TRANSPORT_OMEMO,
CHANNEL_TRANSPORT_PGP, CHANNEL_TRANSPORT_PGP,
CHANNEL_TRANSPORT_OTR,
CHANNEL_TRANSPORT_OX,
}; };
struct t_channel_typing struct t_channel_typing
@ -63,7 +65,18 @@ struct t_channel
char *id; char *id;
char *name; char *name;
enum t_channel_transport transport; enum t_channel_transport transport;
char *pgp_id; struct {
int enabled;
struct t_hashtable *devicelist_requests;
struct t_hashtable *bundle_requests;
} omemo;
struct {
int enabled;
char *id;
} pgp;
struct {
int enabled;
} otr;
struct t_channel_topic topic; struct t_channel_topic topic;
@ -92,6 +105,9 @@ struct t_channel
const char *channel__transport_name(enum t_channel_transport transport); const char *channel__transport_name(enum t_channel_transport transport);
void channel__set_transport(struct t_channel *channel,
enum t_channel_transport transport, int force);
struct t_account *channel__account(struct t_channel *channel); struct t_account *channel__account(struct t_channel *channel);
struct t_channel *channel__search(struct t_account *account, struct t_channel *channel__search(struct t_account *account,
@ -179,8 +195,8 @@ struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel, struct t_channel *channel,
const char *id, const char *reason); const char *id, const char *reason);
void channel__send_message(struct t_account *account, struct t_channel *channel, int channel__send_message(struct t_account *account, struct t_channel *channel,
const char *to, const char *body); const char *to, const char *body);
void channel__send_reads(struct t_account *account, struct t_channel *channel); void channel__send_reads(struct t_account *account, struct t_channel *channel);

@ -4,12 +4,12 @@
#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 "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"
@ -501,7 +501,7 @@ int command__enter(const void *pointer, void *data,
} }
else else
{ {
const char *buffer_jid = weechat_buffer_get_string(buffer, "localvar_channel"); const char *buffer_jid = weechat_buffer_get_string(buffer, "localvar_remote_jid");
pres_jid = xmpp_jid_new( pres_jid = xmpp_jid_new(
ptr_account->context, ptr_account->context,
@ -756,6 +756,41 @@ int command__mam(const void *pointer, void *data,
return WEECHAT_RC_OK; return WEECHAT_RC_OK;
} }
int command__omemo(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
(void) pointer;
(void) data;
(void) argc;
(void) argv;
(void) argv_eol;
buffer__get_account_and_channel(buffer, &ptr_account, &ptr_channel);
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_channel)
{
weechat_printf(
ptr_account->buffer,
_("%s%s: \"%s\" command can not be executed on a account buffer"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME, "omemo");
return WEECHAT_RC_OK;
}
ptr_channel->omemo.enabled = 1;
ptr_channel->pgp.enabled = 0;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_OMEMO, 0);
return WEECHAT_RC_OK;
}
int command__pgp(const void *pointer, void *data, int command__pgp(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol) char **argv, char **argv_eol)
@ -786,13 +821,48 @@ int command__pgp(const void *pointer, void *data,
{ {
keyid = argv_eol[1]; keyid = argv_eol[1];
ptr_channel->pgp_id = strdup(keyid); ptr_channel->pgp.id = strdup(keyid);
} }
else ptr_channel->omemo.enabled = 0;
ptr_channel->pgp.enabled = 1;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_PGP, 0);
return WEECHAT_RC_OK;
}
int command__plain(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
(void) pointer;
(void) data;
(void) argc;
(void) argv;
(void) argv_eol;
buffer__get_account_and_channel(buffer, &ptr_account, &ptr_channel);
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_channel)
{ {
ptr_channel->pgp_id = NULL; weechat_printf(
ptr_account->buffer,
_("%s%s: \"%s\" command can not be executed on a account buffer"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME, "plain");
return WEECHAT_RC_OK;
} }
ptr_channel->omemo.enabled = 0;
ptr_channel->pgp.enabled = 0;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_PLAIN, 0);
return WEECHAT_RC_OK; return WEECHAT_RC_OK;
} }
@ -810,6 +880,9 @@ int command__xml(const void *pointer, void *data,
buffer__get_account_and_channel(buffer, &ptr_account, &ptr_channel); buffer__get_account_and_channel(buffer, &ptr_account, &ptr_channel);
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_account->is_connected) if (!ptr_account->is_connected)
{ {
weechat_printf(buffer, weechat_printf(buffer,
@ -821,7 +894,7 @@ int command__xml(const void *pointer, void *data,
if (argc > 1) if (argc > 1)
{ {
stanza = xmpp_stanza_new_from_string(ptr_account->context, stanza = xmpp_stanza_new_from_string(ptr_account->context,
argv_eol[0]); argv_eol[1]);
if (!stanza) if (!stanza)
return WEECHAT_RC_ERROR; return WEECHAT_RC_ERROR;
@ -906,15 +979,33 @@ void command__init()
if (!hook) if (!hook)
weechat_printf(NULL, "Failed to setup command /mam"); weechat_printf(NULL, "Failed to setup command /mam");
hook = weechat_hook_command(
"omemo",
N_("set the current buffer to use omemo encryption"),
N_(""),
N_(""),
NULL, &command__omemo, NULL, NULL);
if (!hook)
weechat_printf(NULL, "Failed to setup command /omemo");
hook = weechat_hook_command( hook = weechat_hook_command(
"pgp", "pgp",
N_("set the target pgp key for the current channel"), N_("set the current buffer to use pgp encryption (with a given target pgp key)"),
N_("<keyid>"), N_("<keyid>"),
N_("keyid: recipient keyid"), N_("keyid: recipient keyid"),
NULL, &command__pgp, NULL, NULL); NULL, &command__pgp, NULL, NULL);
if (!hook) if (!hook)
weechat_printf(NULL, "Failed to setup command /pgp"); weechat_printf(NULL, "Failed to setup command /pgp");
hook = weechat_hook_command(
"plain",
N_("set the current buffer to use no encryption"),
N_(""),
N_(""),
NULL, &command__plain, NULL, NULL);
if (!hook)
weechat_printf(NULL, "Failed to setup command /plain");
hook = weechat_hook_command( hook = weechat_hook_command(
"xml", "xml",
N_("send a raw xml stanza"), N_("send a raw xml stanza"),

@ -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>

File diff suppressed because it is too large Load Diff

@ -4,6 +4,8 @@
#include <strophe.h> #include <strophe.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <weechat/weechat-plugin.h>
#include "plugin.h" #include "plugin.h"
#include "account.h" #include "account.h"
@ -32,16 +34,20 @@ int input__data(struct t_gui_buffer *buffer, const char *text)
return WEECHAT_RC_OK; return WEECHAT_RC_OK;
} }
channel__send_message(account, channel, channel->id, text); if (channel__send_message(account, channel, channel->id, text) == WEECHAT_RC_OK)
return WEECHAT_RC_OK;
else
{
return WEECHAT_RC_OK_EAT;
}
} }
else else
{ {
weechat_printf(buffer, weechat_printf(buffer,
_("%s%s: this buffer is not a channel!"), _("%s%s: this buffer is not a channel!"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME); weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME);
return WEECHAT_RC_OK;
} }
return WEECHAT_RC_OK;
} }
int input__data_cb(const void *pointer, void *data, int input__data_cb(const void *pointer, void *data,

@ -0,0 +1,126 @@
(define-module (libomemo)
#: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

@ -9,7 +9,7 @@ FIND=find
INCLUDES=-Ilibstrophe \ INCLUDES=-Ilibstrophe \
$(shell xml2-config --cflags) \ $(shell xml2-config --cflags) \
$(shell pkg-config --cflags librnp-0) \ $(shell pkg-config --cflags librnp-0) \
$(shell pkg-config --cflags libsignal-protocol-c) $(shell pkg-config --cflags libomemo-c)
CFLAGS+=$(DBGCFLAGS) \ CFLAGS+=$(DBGCFLAGS) \
-fno-omit-frame-pointer -fPIC \ -fno-omit-frame-pointer -fPIC \
-std=gnu99 -gdwarf-4 \ -std=gnu99 -gdwarf-4 \
@ -32,7 +32,7 @@ LDLIBS=-lstrophe \
-lpthread \ -lpthread \
$(shell xml2-config --libs) \ $(shell xml2-config --libs) \
$(shell pkg-config --libs librnp-0) \ $(shell pkg-config --libs librnp-0) \
$(shell pkg-config --libs libsignal-protocol-c) \ $(shell pkg-config --libs libomemo-c) \
-lgcrypt \ -lgcrypt \
-llmdb -llmdb

@ -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>

2002
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_account *account, const char *jid,
xmpp_stanza_t *encrypted);
void omemo__deserialize(struct t_omemo *omemo, const char *device, xmpp_stanza_t *omemo__encode(struct t_account *account, const char *jid,
const char *identity, size_t identity_len); const char *unencrypted);
void omemo__free(struct t_omemo *omemo); void omemo__free(struct t_omemo *omemo);

@ -5,15 +5,11 @@
#ifndef _WEECHAT_XMPP_PLUGIN_H_ #ifndef _WEECHAT_XMPP_PLUGIN_H_
#define _WEECHAT_XMPP_PLUGIN_H_ #define _WEECHAT_XMPP_PLUGIN_H_
#ifndef __cplusplus #define weechat_plugin weechat_xmpp_plugin
#include <weechat/weechat-plugin.h> #define WEECHAT_XMPP_PLUGIN_NAME "xmpp"
#define weechat_plugin weechat_xmpp_plugin() #define WEECHAT_XMPP_PLUGIN_VERSION "0.1.1"
#define WEECHAT_XMPP_PLUGIN_NAME weechat_xmpp_plugin_name() #define TIMER_INTERVAL_SEC 0.01
#define WEECHAT_XMPP_PLUGIN_VERSION weechat_xmpp_plugin_version()
#endif//__cplusplus
struct t_weechat_plugin *weechat_xmpp_plugin(); extern struct t_weechat_plugin *weechat_xmpp_plugin;
const char *weechat_xmpp_plugin_name();
const char *weechat_xmpp_plugin_version();
#endif /*WEECHAT_XMPP_PLUGIN_H*/ #endif /*WEECHAT_XMPP_PLUGIN_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>
@ -140,7 +141,7 @@ void user__nicklist_remove(struct t_account *account,
ptr_buffer = channel ? channel->buffer : account->buffer; ptr_buffer = channel ? channel->buffer : account->buffer;
if ((ptr_nick = weechat_nicklist_search_nick(ptr_buffer, NULL, name))) if (name && (ptr_nick = weechat_nicklist_search_nick(ptr_buffer, NULL, name)))
weechat_nicklist_remove_nick(ptr_buffer, ptr_nick); weechat_nicklist_remove_nick(ptr_buffer, ptr_nick);
} }
@ -190,6 +191,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

@ -98,9 +98,36 @@ xmpp_stanza_t *stanza__iq_pubsub_items(xmpp_ctx_t *context, xmpp_stanza_t *base,
if (node) if (node)
{ {
xmpp_stanza_set_attribute(parent, "node", node); xmpp_stanza_set_attribute(parent, "node", node);
}
return parent;
}
xmpp_stanza_t *stanza__iq_pubsub_subscribe(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *node, struct t_string *jid)
{
xmpp_stanza_t *parent = base;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "subscribe");
}
if (node)
{
xmpp_stanza_set_attribute(parent, "node", node->value);
node->finalize(node);
free(node); free(node);
} }
if (jid)
{
xmpp_stanza_set_attribute(parent, "jid", jid->value);
jid->finalize(jid);
free(jid);
}
return parent; return parent;
} }
@ -193,7 +220,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 +237,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;
} }
@ -401,3 +435,31 @@ xmpp_stanza_t *stanza__iq_ping(xmpp_ctx_t *context, xmpp_stanza_t *base,
return parent; return parent;
} }
xmpp_stanza_t *stanza__iq_query(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *ns, struct t_string *node)
{
xmpp_stanza_t *parent = base;
if (!parent)
{
parent = xmpp_stanza_new(context);
xmpp_stanza_set_name(parent, "query");
}
if (ns)
{
xmpp_stanza_set_ns(parent, ns->value);
ns->finalize(ns);
free(ns);
}
if (node)
{
xmpp_stanza_set_attribute(parent, "node", node->value);
node->finalize(node);
free(node);
}
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);
@ -62,6 +78,9 @@ xmpp_stanza_t *stanza__iq_pubsub(xmpp_ctx_t *context, xmpp_stanza_t *base,
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_subscribe(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *node, struct t_string *jid);
xmpp_stanza_t *stanza__iq_pubsub_publish(xmpp_ctx_t *context, xmpp_stanza_t *base, 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 **children, struct t_string *node);
@ -72,7 +91,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);
@ -98,4 +117,7 @@ xmpp_stanza_t *stanza__iq_enable(xmpp_ctx_t *context, xmpp_stanza_t *base,
xmpp_stanza_t *stanza__iq_ping(xmpp_ctx_t *context, xmpp_stanza_t *base, xmpp_stanza_t *stanza__iq_ping(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *ns); struct t_string *ns);
xmpp_stanza_t *stanza__iq_query(xmpp_ctx_t *context, xmpp_stanza_t *base,
struct t_string *ns, struct t_string *node);
#endif /*WEECHAT_XMPP_STANZA_H*/ #endif /*WEECHAT_XMPP_STANZA_H*/

Loading…
Cancel
Save