[Telepathy-commits] [telepathy-gabble/master] Move hash functions in a new file caps-hash.[ch]
Alban Crequy
alban.crequy at collabora.co.uk
Tue Aug 19 10:52:32 PDT 2008
20080509171001-a41c0-717a00624ff62250c40a772840f88419b64df9dc.gz
---
src/Makefile.am | 2 +
src/caps-hash.c | 345 +++++++++++++++++++++++++++++++++++++++++++++++
src/caps-hash.h | 31 +++++
src/gabble-connection.c | 2 +
src/presence-cache.c | 1 +
src/presence.c | 299 ----------------------------------------
src/presence.h | 4 -
7 files changed, 381 insertions(+), 303 deletions(-)
create mode 100644 src/caps-hash.c
create mode 100644 src/caps-hash.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 84f689e..68b53a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,8 @@ libgabble_convenience_la_our_sources = \
base64.c \
capabilities.h \
capabilities.c \
+ caps-hash.h \
+ caps-hash.c \
bytestream-factory.h \
bytestream-factory.c \
bytestream-ibb.h \
diff --git a/src/caps-hash.c b/src/caps-hash.c
new file mode 100644
index 0000000..a8e0edf
--- /dev/null
+++ b/src/caps-hash.c
@@ -0,0 +1,345 @@
+/*
+ * caps-hash.c - Computing verification string hash (XEP-0115 v1.5)
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Computing verification string hash (XEP-0115 v1.5)
+ *
+ * Gabble does not do anything with dataforms (XEP-0128) included in
+ * capabilities. However, it needs to parse them in order to compute the hash
+ * according to XEP-0115.
+ */
+
+#include "caps-hash.h"
+
+#include <string.h>
+#include <glib.h>
+#include <time.h>
+
+#include "base64.h"
+#include "capabilities.h"
+#include "presence.h"
+#include "presence-cache.h"
+#include "namespaces.h"
+#include "sha1/sha1.h"
+#include "util.h"
+
+#include "config.h"
+#define DEBUG_FLAG GABBLE_DEBUG_PRESENCE
+#include "debug.h"
+
+struct _dataform_field {
+ gchar *fieldname;
+ GPtrArray *values;
+};
+
+struct _dataform {
+ gchar *form_type;
+ GPtrArray *fields;
+};
+
+
+static gint
+feature_strcmp (gconstpointer a, gconstpointer b)
+{
+ gchar *left = *(gchar **) a;
+ gchar *right = *(gchar **) b;
+
+ return strcmp (left, right);
+}
+
+static gint
+fields_cmp (gconstpointer a, gconstpointer b)
+{
+ struct _dataform_field *left = *(struct _dataform_field **) a;
+ struct _dataform_field *right = *(struct _dataform_field **) b;
+
+ return strcmp (left->fieldname, right->fieldname);
+}
+
+static gint
+dataforms_cmp (gconstpointer a, gconstpointer b)
+{
+ struct _dataform *left = *(struct _dataform **) a;
+ struct _dataform *right = *(struct _dataform **) b;
+
+ return strcmp (left->form_type, right->form_type);
+}
+
+static void
+_free_field (gpointer data, gpointer user_data)
+{
+ struct _dataform_field *field = data;
+
+ g_free (field->fieldname);
+ g_ptr_array_foreach (field->values, (GFunc) g_free, NULL);
+
+ g_slice_free1 (sizeof (struct _dataform_field), field);
+}
+
+static void
+_free_form (gpointer data, gpointer user_data)
+{
+ struct _dataform *form = data;
+
+ g_free (form->form_type);
+
+ g_ptr_array_foreach (form->fields, (GFunc) _free_field, NULL);
+
+ g_slice_free1 (sizeof (struct _dataform), form);
+}
+
+static void
+gabble_presence_free_xep0115_hash (
+ GPtrArray *features,
+ GPtrArray *identities,
+ GPtrArray *dataforms)
+{
+ g_ptr_array_foreach (features, (GFunc) g_free, NULL);
+ g_ptr_array_foreach (identities, (GFunc) g_free, NULL);
+ g_ptr_array_foreach (dataforms, (GFunc) _free_form, NULL);
+
+ g_ptr_array_free (features, TRUE);
+ g_ptr_array_free (identities, TRUE);
+ g_ptr_array_free (dataforms, TRUE);
+}
+
+static gchar *
+gabble_presence_compute_xep0115_hash (
+ GPtrArray *features,
+ GPtrArray *identities,
+ GPtrArray *dataforms)
+{
+ GString *s;
+ gchar *str;
+ gchar sha1[SHA1_HASH_SIZE];
+ unsigned int i, j, k;
+ gchar *encoded;
+
+ g_ptr_array_sort (identities, feature_strcmp);
+ g_ptr_array_sort (features, feature_strcmp);
+ g_ptr_array_sort (dataforms, dataforms_cmp);
+
+ s = g_string_new ("");
+
+ for (i = 0 ; i < identities->len ; i++)
+ {
+ s = g_string_append (s, g_ptr_array_index (identities, i));
+ s = g_string_append (s, "<");
+ }
+
+ for (i = 0 ; i < features->len ; i++)
+ {
+ s = g_string_append (s, g_ptr_array_index (features, i));
+ s = g_string_append (s, "<");
+ }
+
+ for (i = 0 ; i < dataforms->len ; i++)
+ {
+ struct _dataform *form = g_ptr_array_index (features, i);
+
+ s = g_string_append (s, form->form_type);
+ s = g_string_append (s, "<");
+
+ g_ptr_array_sort (form->fields, fields_cmp);
+
+ for (j = 0 ; j < form->fields->len ; j++)
+ {
+ struct _dataform_field *field = g_ptr_array_index (form->fields, j);
+
+ s = g_string_append (s, field->fieldname);
+ s = g_string_append (s, "<");
+
+ g_ptr_array_sort (field->values, fields_cmp);
+
+ for (k = 0 ; k < field->values->len ; k++)
+ {
+ s = g_string_append (s, g_ptr_array_index (field->values, k));
+ s = g_string_append (s, "<");
+ }
+ }
+ }
+
+ str = g_string_free (s, FALSE);
+ DEBUG ("caps string: '%s'\n", str);
+ sha1_bin (str, strlen (str), (guchar *) sha1);
+ encoded = base64_encode (SHA1_HASH_SIZE, sha1, FALSE);
+ DEBUG ("caps base64: '%s'\n", encoded);
+
+ return encoded;
+}
+
+/**
+ * Compute the hash as defined by the XEP-0115 from a received LmMessageNode
+ *
+ * Returns: the hash. The called must free the returned hash with g_free().
+ */
+gchar *
+gabble_presence_compute_xep0115_hash_from_lm_node (LmMessageNode *node)
+{
+ GPtrArray *features = g_ptr_array_new ();
+ GPtrArray *identities = g_ptr_array_new ();
+ GPtrArray *dataforms = g_ptr_array_new ();
+ LmMessageNode *child;
+ gchar *str;
+
+ for (child = node->children; NULL != child; child = child->next)
+ {
+ if (g_str_equal (child->name, "identity"))
+ {
+ const gchar *category;
+ const gchar *name;
+ const gchar *type;
+ const gchar *xmllang;
+
+ category = lm_message_node_get_attribute (child, "category");
+ name = lm_message_node_get_attribute (child, "name");
+ type = lm_message_node_get_attribute (child, "type");
+ xmllang = lm_message_node_get_attribute (child, "xml:lang");
+
+ if (NULL == category)
+ continue;
+ if (NULL == name)
+ name = "";
+ if (NULL == type)
+ type = "";
+ if (NULL == xmllang)
+ xmllang = "";
+
+ g_ptr_array_add (identities,
+ (gpointer) g_strdup_printf ("%s/%s/%s/%s",
+ category, type, xmllang, name));
+ }
+ else if (g_str_equal (child->name, "feature"))
+ {
+ const gchar *var;
+ var = lm_message_node_get_attribute (child, "var");
+
+ if (NULL == var)
+ continue;
+
+ g_ptr_array_add (features, (gpointer) g_strdup (var));
+ }
+ else if (g_str_equal (child->name, "x"))
+ {
+ const gchar *xmlns;
+ const gchar *type;
+ LmMessageNode *x_child;
+ struct _dataform *form;
+
+ xmlns = lm_message_node_get_attribute (child, "xmlns");
+ type = lm_message_node_get_attribute (child, "type");
+
+ if (! g_str_equal (xmlns, "jabber:x:data"))
+ continue;
+
+ if (! g_str_equal (type, "result"))
+ continue;
+
+ form = g_slice_new0 (struct _dataform);
+
+ for (x_child = child->children;
+ NULL != x_child;
+ x_child = x_child->next)
+ {
+ const gchar *var;
+ LmMessageNode *value_child;
+ struct _dataform_field *field;
+
+ if (! g_str_equal (x_child->name, "field"))
+ continue;
+
+ var = lm_message_node_get_attribute (x_child, "var");
+
+ if (NULL == var)
+ continue;
+
+ field = g_slice_new0 (struct _dataform_field);
+
+ for (value_child = x_child->children;
+ NULL != value_child;
+ value_child = value_child->next)
+ {
+ const gchar *content;
+
+ if (! g_str_equal (value_child->name, "value"))
+ continue;
+
+ if (g_str_equal (var, "FORM_TYPE"))
+ {
+ form->form_type = g_strdup (var);
+ }
+ else
+ {
+ content = lm_message_node_get_value (value_child);
+ g_ptr_array_add (field->values,
+ (gpointer) g_strdup (content));
+ }
+ }
+
+ g_ptr_array_add (form->fields, (gpointer) field);
+ }
+
+ g_ptr_array_add (dataforms, (gpointer) form);
+ }
+ }
+
+ str = gabble_presence_compute_xep0115_hash (features, identities, dataforms);
+
+ gabble_presence_free_xep0115_hash (features, identities, dataforms);
+
+ return str;
+}
+
+
+/**
+ * Compute our hash as defined by the XEP-0115.
+ *
+ * Returns: the hash. The called must free the returned hash with g_free().
+ */
+gchar *
+gabble_presence_compute_xep0115_hash_from_self_presence (GabbleConnection *self)
+{
+ GabblePresence *presence = self->self_presence;
+ GSList *features_list = capabilities_get_features (presence->caps);
+ GPtrArray *features = g_ptr_array_new ();
+ GPtrArray *identities = g_ptr_array_new ();
+ GPtrArray *dataforms = g_ptr_array_new ();
+ gchar *str;
+ GSList *i;
+
+ /* get our features list */
+ for (i = features_list; NULL != i; i = i->next)
+ {
+ const Feature *feat = (const Feature *) i->data;
+ g_ptr_array_add (features, (gpointer) g_strdup (feat->ns));
+ }
+
+ /* XEP-0030 requires at least 1 identity. We don't need more. */
+ g_ptr_array_add (identities,
+ (gpointer) g_strdup ("client/pc//" PACKAGE_STRING));
+
+ /* Gabble does not use dataforms, let 'dataforms' be empty */
+
+ str = gabble_presence_compute_xep0115_hash (features, identities, dataforms);
+
+ gabble_presence_free_xep0115_hash (features, identities, dataforms);
+ g_slist_free (features_list);
+
+ return str;
+}
+
diff --git a/src/caps-hash.h b/src/caps-hash.h
new file mode 100644
index 0000000..cc9c3c4
--- /dev/null
+++ b/src/caps-hash.h
@@ -0,0 +1,31 @@
+/*
+ * caps-hash.h - Headers for computing verification string hash (XEP-0115 v1.5)
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef __CAPS_HASH_H__
+#define __CAPS_HASH_H__
+
+#include <loudmouth/loudmouth.h>
+#include "gabble-connection.h"
+
+gchar *gabble_presence_compute_xep0115_hash_from_lm_node (LmMessageNode *node);
+gchar *gabble_presence_compute_xep0115_hash_from_self_presence (
+ GabbleConnection *self);
+
+#endif /* __CAPS_HASH_H__ */
diff --git a/src/gabble-connection.c b/src/gabble-connection.c
index e41eaa0..6eb718d 100644
--- a/src/gabble-connection.c
+++ b/src/gabble-connection.c
@@ -46,6 +46,7 @@
#include "bytestream-factory.h"
#include "capabilities.h"
+#include "caps-hash.h"
#include "conn-aliasing.h"
#include "conn-avatars.h"
#include "conn-presence.h"
@@ -1266,6 +1267,7 @@ connection_shut_down (TpBaseConnection *base)
}
}
+
/**
* _gabble_connection_signal_own_presence:
* @self: A #GabbleConnection
diff --git a/src/presence-cache.c b/src/presence-cache.c
index 898abf4..59759e5 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -30,6 +30,7 @@ be enough */
#include <telepathy-glib/intset.h>
+#include "caps-hash.h"
#include "debug.h"
#include "disco.h" /* \o\ \o/ /o/ */
#include "namespaces.h"
diff --git a/src/presence.c b/src/presence.c
index fb7c6bd..cb60622 100644
--- a/src/presence.c
+++ b/src/presence.c
@@ -24,11 +24,8 @@
#include <glib.h>
#include <time.h>
-#include "base64.h"
-#include "capabilities.h"
#include "presence-cache.h"
#include "namespaces.h"
-#include "sha1/sha1.h"
#include "util.h"
#include "config.h"
@@ -469,299 +466,3 @@ gabble_presence_dump (GabblePresence *presence)
return g_string_free (ret, FALSE);
}
-static gint
-feature_strcmp (gconstpointer a, gconstpointer b)
-{
- gchar *left = *(gchar **) a;
- gchar *right = *(gchar **) b;
-
- return strcmp (left, right);
-}
-
-struct _dataform_field {
- gchar *fieldname;
- GPtrArray *values;
-};
-
-struct _dataform {
- gchar *form_type;
- GPtrArray *fields;
-};
-
-static gint
-fields_cmp (gconstpointer a, gconstpointer b)
-{
- struct _dataform_field *left = *(struct _dataform_field **) a;
- struct _dataform_field *right = *(struct _dataform_field **) b;
-
- return strcmp (left->fieldname, right->fieldname);
-}
-
-static gint
-dataforms_cmp (gconstpointer a, gconstpointer b)
-{
- struct _dataform *left = *(struct _dataform **) a;
- struct _dataform *right = *(struct _dataform **) b;
-
- return strcmp (left->form_type, right->form_type);
-}
-
-static gchar *
-gabble_presence_compute_xep0115_hash (
- GPtrArray *features,
- GPtrArray *identities,
- GPtrArray *dataforms)
-{
- GString *s;
- gchar *str;
- gchar sha1[SHA1_HASH_SIZE];
- unsigned int i, j, k;
- gchar *encoded;
-
- g_ptr_array_sort (identities, feature_strcmp);
- g_ptr_array_sort (features, feature_strcmp);
- g_ptr_array_sort (dataforms, dataforms_cmp);
-
- s = g_string_new ("");
-
- for (i = 0 ; i < identities->len ; i++)
- {
- s = g_string_append (s, g_ptr_array_index (identities, i));
- s = g_string_append (s, "<");
- }
-
- for (i = 0 ; i < features->len ; i++)
- {
- s = g_string_append (s, g_ptr_array_index (features, i));
- s = g_string_append (s, "<");
- }
-
- for (i = 0 ; i < dataforms->len ; i++)
- {
- struct _dataform *form = g_ptr_array_index (features, i);
-
- s = g_string_append (s, form->form_type);
- s = g_string_append (s, "<");
-
- g_ptr_array_sort (form->fields, fields_cmp);
-
- for (j = 0 ; j < form->fields->len ; j++)
- {
- struct _dataform_field *field = g_ptr_array_index (form->fields, j);
-
- s = g_string_append (s, field->fieldname);
- s = g_string_append (s, "<");
-
- g_ptr_array_sort (field->values, fields_cmp);
-
- for (k = 0 ; k < field->values->len ; k++)
- {
- s = g_string_append (s, g_ptr_array_index (field->values, k));
- s = g_string_append (s, "<");
- }
- }
- }
-
- str = g_string_free (s, FALSE);
- DEBUG ("caps string: '%s'\n", str);
- sha1_bin (str, strlen (str), (guchar *) sha1);
- encoded = base64_encode (SHA1_HASH_SIZE, sha1, FALSE);
- DEBUG ("caps base64: '%s'\n", encoded);
-
- return encoded;
-}
-
-static void
-_free_field (gpointer data, gpointer user_data)
-{
- struct _dataform_field *field = data;
-
- g_free (field->fieldname);
- g_ptr_array_foreach (field->values, (GFunc) g_free, NULL);
-
- g_slice_free1 (sizeof (struct _dataform_field), field);
-}
-
-static void
-_free_form (gpointer data, gpointer user_data)
-{
- struct _dataform *form = data;
-
- g_free (form->form_type);
-
- g_ptr_array_foreach (form->fields, (GFunc) _free_field, NULL);
-
- g_slice_free1 (sizeof (struct _dataform), form);
-}
-
-static void
-gabble_presence_free_xep0115_hash (
- GPtrArray *features,
- GPtrArray *identities,
- GPtrArray *dataforms)
-{
- g_ptr_array_foreach (features, (GFunc) g_free, NULL);
- g_ptr_array_foreach (identities, (GFunc) g_free, NULL);
- g_ptr_array_foreach (dataforms, (GFunc) _free_form, NULL);
-
- g_ptr_array_free (features, TRUE);
- g_ptr_array_free (identities, TRUE);
- g_ptr_array_free (dataforms, TRUE);
-}
-
-/**
- *
- * Compute the hash as defined by the XEP-0115
- *
- * Returns: the hash. The called must free the returned hash.
- */
-gchar *
-gabble_presence_compute_xep0115_hash_from_lm_node (LmMessageNode *node)
-{
- GPtrArray *features = g_ptr_array_new ();
- GPtrArray *identities = g_ptr_array_new ();
- GPtrArray *dataforms = g_ptr_array_new ();
- LmMessageNode *child;
- gchar *str;
-
- for (child = node->children; NULL != child; child = child->next)
- {
- if (g_str_equal (child->name, "identity"))
- {
- const gchar *category;
- const gchar *name;
- const gchar *type;
- const gchar *xmllang;
-
- category = lm_message_node_get_attribute (child, "category");
- name = lm_message_node_get_attribute (child, "name");
- type = lm_message_node_get_attribute (child, "type");
- xmllang = lm_message_node_get_attribute (child, "xml:lang");
-
- if (NULL == category)
- continue;
- if (NULL == name)
- name = "";
- if (NULL == type)
- type = "";
- if (NULL == xmllang)
- xmllang = "";
-
- g_ptr_array_add (identities,
- (gpointer) g_strdup_printf ("%s/%s/%s/%s",
- category, type, xmllang, name));
- }
- else if (g_str_equal (child->name, "feature"))
- {
- const gchar *var;
- var = lm_message_node_get_attribute (child, "var");
-
- if (NULL == var)
- continue;
-
- g_ptr_array_add (features, (gpointer) g_strdup (var));
- }
- else if (g_str_equal (child->name, "x"))
- {
- const gchar *xmlns;
- const gchar *type;
- LmMessageNode *x_child;
- struct _dataform *form;
-
- xmlns = lm_message_node_get_attribute (child, "xmlns");
- type = lm_message_node_get_attribute (child, "type");
-
- if (! g_str_equal (xmlns, "jabber:x:data"))
- continue;
-
- if (! g_str_equal (type, "result"))
- continue;
-
- form = g_slice_new0 (struct _dataform);
-
- for (x_child = child->children;
- NULL != x_child;
- x_child = x_child->next)
- {
- const gchar *var;
- LmMessageNode *value_child;
- struct _dataform_field *field;
-
- if (! g_str_equal (x_child->name, "field"))
- continue;
-
- var = lm_message_node_get_attribute (x_child, "var");
-
- if (NULL == var)
- continue;
-
- field = g_slice_new0 (struct _dataform_field);
-
- for (value_child = x_child->children;
- NULL != value_child;
- value_child = value_child->next)
- {
- const gchar *content;
-
- if (! g_str_equal (value_child->name, "value"))
- continue;
-
- if (g_str_equal (var, "FORM_TYPE"))
- {
- form->form_type = g_strdup (var);
- }
- else
- {
- content = lm_message_node_get_value (value_child);
- g_ptr_array_add (field->values,
- (gpointer) g_strdup (content));
- }
- }
-
- g_ptr_array_add (form->fields, (gpointer) field);
- }
-
- g_ptr_array_add (dataforms, (gpointer) form);
- }
- }
-
- str = gabble_presence_compute_xep0115_hash (features, identities, dataforms);
-
- gabble_presence_free_xep0115_hash (features, identities, dataforms);
-
- return str;
-}
-
-
-gchar *
-gabble_presence_compute_xep0115_hash_from_self_presence (GabbleConnection *self)
-{
- GabblePresence *presence = self->self_presence;
- GSList *features_list = capabilities_get_features (presence->caps);
- GPtrArray *features = g_ptr_array_new ();
- GPtrArray *identities = g_ptr_array_new ();
- GPtrArray *dataforms = g_ptr_array_new ();
- gchar *str;
- GSList *i;
-
- /* get our features list */
- for (i = features_list; NULL != i; i = i->next)
- {
- const Feature *feat = (const Feature *) i->data;
- g_ptr_array_add (features, (gpointer) g_strdup (feat->ns));
- }
-
- /* XEP-0030 requires at least 1 identity. We don't need more. */
- g_ptr_array_add (identities,
- (gpointer) g_strdup ("client/pc//" PACKAGE_STRING));
-
- /* Gabble does not use dataforms, let 'dataforms' be empty */
-
- str = gabble_presence_compute_xep0115_hash (features, identities, dataforms);
-
- gabble_presence_free_xep0115_hash (features, identities, dataforms);
- g_slist_free (features_list);
-
- return str;
-}
-
diff --git a/src/presence.h b/src/presence.h
index d6f2327..a5a56bf 100644
--- a/src/presence.h
+++ b/src/presence.h
@@ -91,10 +91,6 @@ LmMessage *gabble_presence_as_message (GabblePresence *presence,
gchar *gabble_presence_dump (GabblePresence *presence);
-gchar *gabble_presence_compute_xep0115_hash_from_lm_node (LmMessageNode *node);
-gchar *gabble_presence_compute_xep0115_hash_from_self_presence (
- GabbleConnection *self);
-
G_END_DECLS
#endif /* __GABBLE_PRESENCE_H__ */
--
1.5.6.3
More information about the Telepathy-commits
mailing list