1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-09-22 19:45:54 -04:00

Added _handle_presence_caps

This commit is contained in:
James Booth 2013-01-20 22:39:52 +00:00
parent dfeb884e9b
commit 3d5f04ee80
3 changed files with 100 additions and 51 deletions

View File

@ -39,8 +39,6 @@
#include "muc.h"
#include "stanza.h"
#include "ui.h"
static struct _jabber_conn_t {
xmpp_log_t *log;
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,
xmpp_stanza_t * const stanza, 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
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)
{
char *type = xmpp_stanza_get_type(stanza);
char *id = xmpp_stanza_get_id(stanza);
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
log_error("Roster query failed");
return 1;
} else {
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) {
return 1;
}
// validate sha1
gchar **split = g_strsplit(node, "#", -1);
char *given_sha1 = split[1];
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();
char *caps_key = NULL;
if (g_strcmp0(id, "disco") == 0) {
caps_key = node;
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
log_info("Invalid SHA1 recieved for caps.");
return 1;
// validate sha1
gchar **split = g_strsplit(node, "#", -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
if (caps_contains(node)) {
if (caps_contains(caps_key)) {
log_info("Client info already cached.");
return 1;
}
@ -1115,7 +1117,7 @@ _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
return 1;
}
caps_add(node, name);
caps_add(caps_key, name);
return 1;
}
@ -1175,19 +1177,7 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza)
} else {
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
char *show_str, *status_str;
char *caps_str = NULL;
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);
}
}
}
char *caps_key = _handle_presence_caps(stanza);
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
if (status != NULL) {
@ -1213,18 +1203,18 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza)
show_str = "online";
}
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 {
char *old_nick = muc_complete_roster_nick_change(room, nick);
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);
} else {
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 {
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;
}
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
_presence_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata)
@ -1269,18 +1308,7 @@ _presence_handler(xmpp_conn_t * const conn,
g_date_time_unref(now);
}
char *caps_str = NULL;
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);
}
}
}
char *caps_key = _handle_presence_caps(stanza);
xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS);
if (status != NULL)
@ -1296,7 +1324,7 @@ _presence_handler(xmpp_conn_t * const conn,
show_str = "online";
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) {
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {

View File

@ -181,14 +181,14 @@ stanza_create_roster_iq(xmpp_ctx_t *ctx)
}
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)
{
xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
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_set_name(query, STANZA_NAME_QUERY);
@ -431,6 +431,25 @@ stanza_contains_caps(xmpp_stanza_t * const stanza)
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 *
stanza_get_caps_str(xmpp_stanza_t * const stanza)
{

View File

@ -77,6 +77,7 @@
#define STANZA_ATTR_SECONDS "seconds"
#define STANZA_ATTR_NODE "node"
#define STANZA_ATTR_VER "ver"
#define STANZA_ATTR_HASH "hash"
#define STANZA_TEXT_AWAY "away"
#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_ping_iq(xmpp_ctx_t *ctx);
xmpp_stanza_t* stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const to,
const char * const node);
xmpp_stanza_t* stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id,
const char * const to, const char * const node);
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);
char * stanza_get_caps_str(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);