about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2013-01-20 22:39:52 +0000
committerJames Booth <boothj5@gmail.com>2013-01-20 22:39:52 +0000
commit3d5f04ee80238fa4dac415afbf6cb6f68b7fa668 (patch)
treeb17e7b8a02c65cb80ad41291a38e267f6a6ba7b0
parentdfeb884e9b6114b765adae9104e68d60ef5444ab (diff)
downloadprofani-tty-3d5f04ee80238fa4dac415afbf6cb6f68b7fa668.tar.gz
Added _handle_presence_caps
-rw-r--r--src/jabber.c124
-rw-r--r--src/stanza.c23
-rw-r--r--src/stanza.h6
3 files changed, 101 insertions, 52 deletions
diff --git a/src/jabber.c b/src/jabber.c
index a9dc5709..8d71c51d 100644
--- a/src/jabber.c
+++ b/src/jabber.c
@@ -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();
-
-        if (g_strcmp0(given_sha1, generated_sha1) != 0) {
-            log_info("Invalid SHA1 recieved for caps.");
-            return 1;
+        char *caps_key = NULL;
+        if (g_strcmp0(id, "disco") == 0) {
+            caps_key = node;
+
+            // 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) {
diff --git a/src/stanza.c b/src/stanza.c
index 3abc0abd..4274ed22 100644
--- a/src/stanza.c
+++ b/src/stanza.c
@@ -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);
@@ -432,6 +432,25 @@ stanza_contains_caps(xmpp_stanza_t * const stanza)
 }
 
 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)
 {
     xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C);
diff --git a/src/stanza.h b/src/stanza.h
index 4e8d52be..a61f4639 100644
--- a/src/stanza.h
+++ b/src/stanza.h
@@ -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);