mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-25 19:26:21 +00:00
Added _handle_presence_caps
This commit is contained in:
122
src/jabber.c
122
src/jabber.c
@@ -39,8 +39,6 @@
|
|||||||
#include "muc.h"
|
#include "muc.h"
|
||||||
#include "stanza.h"
|
#include "stanza.h"
|
||||||
|
|
||||||
#include "ui.h"
|
|
||||||
|
|
||||||
static struct _jabber_conn_t {
|
static struct _jabber_conn_t {
|
||||||
xmpp_log_t *log;
|
xmpp_log_t *log;
|
||||||
xmpp_ctx_t *ctx;
|
xmpp_ctx_t *ctx;
|
||||||
@@ -93,6 +91,7 @@ static int _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza
|
|||||||
static int _presence_handler(xmpp_conn_t * const conn,
|
static int _presence_handler(xmpp_conn_t * const conn,
|
||||||
xmpp_stanza_t * const stanza, void * const userdata);
|
xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
static int _ping_timed_handler(xmpp_conn_t * const conn, void * const userdata);
|
static int _ping_timed_handler(xmpp_conn_t * const conn, void * const userdata);
|
||||||
|
static char * _handle_presence_caps(xmpp_stanza_t * const stanza);
|
||||||
|
|
||||||
void
|
void
|
||||||
jabber_init(const int disable_tls)
|
jabber_init(const int disable_tls)
|
||||||
@@ -1063,34 +1062,37 @@ _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
|||||||
void * const userdata)
|
void * const userdata)
|
||||||
{
|
{
|
||||||
char *type = xmpp_stanza_get_type(stanza);
|
char *type = xmpp_stanza_get_type(stanza);
|
||||||
|
char *id = xmpp_stanza_get_id(stanza);
|
||||||
|
|
||||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||||
log_error("Roster query failed");
|
log_error("Roster query failed");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||||
const char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate sha1
|
char *caps_key = NULL;
|
||||||
gchar **split = g_strsplit(node, "#", -1);
|
if (g_strcmp0(id, "disco") == 0) {
|
||||||
char *given_sha1 = split[1];
|
caps_key = node;
|
||||||
char *generated_sha1 = sha1_caps_str(query);
|
|
||||||
cons_show("GIVEN: %s", given_sha1);
|
|
||||||
cons_show("GEN : %s", generated_sha1);
|
|
||||||
win_current_page_off();
|
|
||||||
ui_refresh();
|
|
||||||
|
|
||||||
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
// validate sha1
|
||||||
log_info("Invalid SHA1 recieved for caps.");
|
gchar **split = g_strsplit(node, "#", -1);
|
||||||
return 1;
|
char *given_sha1 = split[1];
|
||||||
|
char *generated_sha1 = sha1_caps_str(query);
|
||||||
|
|
||||||
|
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
||||||
|
log_info("Invalid SHA1 recieved for caps.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
caps_key = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// already cached
|
// already cached
|
||||||
if (caps_contains(node)) {
|
if (caps_contains(caps_key)) {
|
||||||
log_info("Client info already cached.");
|
log_info("Client info already cached.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1115,7 +1117,7 @@ _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
caps_add(node, name);
|
caps_add(caps_key, name);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1175,19 +1177,7 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza)
|
|||||||
} else {
|
} else {
|
||||||
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
|
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
|
||||||
char *show_str, *status_str;
|
char *show_str, *status_str;
|
||||||
char *caps_str = NULL;
|
char *caps_key = _handle_presence_caps(stanza);
|
||||||
|
|
||||||
if (stanza_contains_caps(stanza)) {
|
|
||||||
caps_str = stanza_get_caps_str(stanza);
|
|
||||||
|
|
||||||
if (caps_str != NULL) {
|
|
||||||
if (!caps_contains(caps_str)) {
|
|
||||||
xmpp_stanza_t *iq = stanza_create_disco_iq(jabber_conn.ctx, jid, caps_str);
|
|
||||||
xmpp_send(jabber_conn.conn, iq);
|
|
||||||
xmpp_stanza_release(iq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
|
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
|
||||||
if (status != NULL) {
|
if (status != NULL) {
|
||||||
@@ -1213,18 +1203,18 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza)
|
|||||||
show_str = "online";
|
show_str = "online";
|
||||||
}
|
}
|
||||||
if (!muc_get_roster_received(room)) {
|
if (!muc_get_roster_received(room)) {
|
||||||
muc_add_to_roster(room, nick, show_str, status_str, caps_str);
|
muc_add_to_roster(room, nick, show_str, status_str, caps_key);
|
||||||
} else {
|
} else {
|
||||||
char *old_nick = muc_complete_roster_nick_change(room, nick);
|
char *old_nick = muc_complete_roster_nick_change(room, nick);
|
||||||
|
|
||||||
if (old_nick != NULL) {
|
if (old_nick != NULL) {
|
||||||
muc_add_to_roster(room, nick, show_str, status_str, caps_str);
|
muc_add_to_roster(room, nick, show_str, status_str, caps_key);
|
||||||
prof_handle_room_member_nick_change(room, old_nick, nick);
|
prof_handle_room_member_nick_change(room, old_nick, nick);
|
||||||
} else {
|
} else {
|
||||||
if (!muc_nick_in_roster(room, nick)) {
|
if (!muc_nick_in_roster(room, nick)) {
|
||||||
prof_handle_room_member_online(room, nick, show_str, status_str, caps_str);
|
prof_handle_room_member_online(room, nick, show_str, status_str, caps_key);
|
||||||
} else {
|
} else {
|
||||||
prof_handle_room_member_presence(room, nick, show_str, status_str, caps_str);
|
prof_handle_room_member_presence(room, nick, show_str, status_str, caps_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1237,6 +1227,55 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_handle_presence_caps(xmpp_stanza_t * const stanza)
|
||||||
|
{
|
||||||
|
char *caps_key = NULL;
|
||||||
|
char *node = NULL;
|
||||||
|
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||||
|
if (stanza_contains_caps(stanza)) {
|
||||||
|
char *hash_type = stanza_caps_get_hash(stanza);
|
||||||
|
|
||||||
|
// xep-0115
|
||||||
|
if (hash_type != NULL) {
|
||||||
|
|
||||||
|
// supported hash
|
||||||
|
if (strcmp(hash_type, "sha-1") == 0) {
|
||||||
|
node = stanza_get_caps_str(stanza);
|
||||||
|
caps_key = node;
|
||||||
|
|
||||||
|
if (node != NULL) {
|
||||||
|
if (!caps_contains(caps_key)) {
|
||||||
|
xmpp_stanza_t *iq = stanza_create_disco_iq(jabber_conn.ctx, "disco", from, node);
|
||||||
|
xmpp_send(jabber_conn.conn, iq);
|
||||||
|
xmpp_stanza_release(iq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsupported hash
|
||||||
|
} else {
|
||||||
|
node = stanza_get_caps_str(stanza);
|
||||||
|
caps_key = from;
|
||||||
|
|
||||||
|
if (node != NULL) {
|
||||||
|
if (!caps_contains(caps_key)) {
|
||||||
|
xmpp_stanza_t *iq = stanza_create_disco_iq(jabber_conn.ctx, from, from, node);
|
||||||
|
xmpp_send(jabber_conn.conn, iq);
|
||||||
|
xmpp_stanza_release(iq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strdup(caps_key);
|
||||||
|
|
||||||
|
//ignore or handle legacy caps
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_presence_handler(xmpp_conn_t * const conn,
|
_presence_handler(xmpp_conn_t * const conn,
|
||||||
xmpp_stanza_t * const stanza, void * const userdata)
|
xmpp_stanza_t * const stanza, void * const userdata)
|
||||||
@@ -1269,18 +1308,7 @@ _presence_handler(xmpp_conn_t * const conn,
|
|||||||
g_date_time_unref(now);
|
g_date_time_unref(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *caps_str = NULL;
|
char *caps_key = _handle_presence_caps(stanza);
|
||||||
if (stanza_contains_caps(stanza)) {
|
|
||||||
caps_str = stanza_get_caps_str(stanza);
|
|
||||||
|
|
||||||
if (caps_str != NULL) {
|
|
||||||
if (!caps_contains(caps_str)) {
|
|
||||||
xmpp_stanza_t *iq = stanza_create_disco_iq(jabber_conn.ctx, from, caps_str);
|
|
||||||
xmpp_send(jabber_conn.conn, iq);
|
|
||||||
xmpp_stanza_release(iq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
|
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
|
||||||
if (status != NULL)
|
if (status != NULL)
|
||||||
@@ -1296,7 +1324,7 @@ _presence_handler(xmpp_conn_t * const conn,
|
|||||||
show_str = "online";
|
show_str = "online";
|
||||||
|
|
||||||
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
||||||
prof_handle_contact_online(from_jid->barejid, show_str, status_str, last_activity, caps_str);
|
prof_handle_contact_online(from_jid->barejid, show_str, status_str, last_activity, caps_key);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0) {
|
} else if (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0) {
|
||||||
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
||||||
|
|||||||
23
src/stanza.c
23
src/stanza.c
@@ -181,14 +181,14 @@ stanza_create_roster_iq(xmpp_ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_t *
|
xmpp_stanza_t *
|
||||||
stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const to,
|
stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id, const char * const to,
|
||||||
const char * const node)
|
const char * const node)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
|
xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
|
xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
|
||||||
xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
|
xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
|
||||||
xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, to);
|
xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, to);
|
||||||
xmpp_stanza_set_id(iq, "disco");
|
xmpp_stanza_set_id(iq, id);
|
||||||
|
|
||||||
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
|
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
||||||
@@ -431,6 +431,25 @@ stanza_contains_caps(xmpp_stanza_t * const stanza)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
stanza_caps_get_hash(xmpp_stanza_t * const stanza)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
|
||||||
|
|
||||||
|
if (caps == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(xmpp_stanza_get_ns(caps), STANZA_NS_CAPS) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *result = xmpp_stanza_get_attribute(caps, STANZA_ATTR_HASH);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
stanza_get_caps_str(xmpp_stanza_t * const stanza)
|
stanza_get_caps_str(xmpp_stanza_t * const stanza)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
#define STANZA_ATTR_SECONDS "seconds"
|
#define STANZA_ATTR_SECONDS "seconds"
|
||||||
#define STANZA_ATTR_NODE "node"
|
#define STANZA_ATTR_NODE "node"
|
||||||
#define STANZA_ATTR_VER "ver"
|
#define STANZA_ATTR_VER "ver"
|
||||||
|
#define STANZA_ATTR_HASH "hash"
|
||||||
|
|
||||||
#define STANZA_TEXT_AWAY "away"
|
#define STANZA_TEXT_AWAY "away"
|
||||||
#define STANZA_TEXT_DND "dnd"
|
#define STANZA_TEXT_DND "dnd"
|
||||||
@@ -123,8 +124,8 @@ xmpp_stanza_t* stanza_create_presence(xmpp_ctx_t *ctx, const char * const show,
|
|||||||
|
|
||||||
xmpp_stanza_t* stanza_create_roster_iq(xmpp_ctx_t *ctx);
|
xmpp_stanza_t* stanza_create_roster_iq(xmpp_ctx_t *ctx);
|
||||||
xmpp_stanza_t* stanza_create_ping_iq(xmpp_ctx_t *ctx);
|
xmpp_stanza_t* stanza_create_ping_iq(xmpp_ctx_t *ctx);
|
||||||
xmpp_stanza_t* stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const to,
|
xmpp_stanza_t* stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id,
|
||||||
const char * const node);
|
const char * const to, const char * const node);
|
||||||
|
|
||||||
gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza);
|
gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza);
|
||||||
|
|
||||||
@@ -139,6 +140,7 @@ char * stanza_get_new_nick(xmpp_stanza_t * const stanza);
|
|||||||
int stanza_get_idle_time(xmpp_stanza_t * const stanza);
|
int stanza_get_idle_time(xmpp_stanza_t * const stanza);
|
||||||
char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
|
char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
|
||||||
gboolean stanza_contains_caps(xmpp_stanza_t * const stanza);
|
gboolean stanza_contains_caps(xmpp_stanza_t * const stanza);
|
||||||
|
char * stanza_caps_get_hash(xmpp_stanza_t * const stanza);
|
||||||
|
|
||||||
DataForm * stanza_get_form(xmpp_stanza_t * const stanza);
|
DataForm * stanza_get_form(xmpp_stanza_t * const stanza);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user