/soc/2012/sanket/statscollector-2.x.y: f55e642f3e88: [FEATURE] S...

Sanket Agarwal sanket at soc.pidgin.im
Sat Aug 18 11:32:26 EDT 2012


Changeset: f55e642f3e88feb05da0a72ec615f8d9eff7fc0c
Author:	 Sanket Agarwal <sanket at soc.pidgin.im>
Date:	 2012-08-18 08:30 +0530
Branch:	 soc.2012.statscollector
URL: http://hg.pidgin.im/soc/2012/sanket/statscollector-2.x.y/rev/f55e642f3e88

Description:

[FEATURE] Send *server* info from prpl-jabber/irc ONLY if public

Sending servers without knowing if they are public, for prpl-jabber/irc
breakdown can be considered breach of secrecy. In order to solve this
problem, the server provides a service on "/trusted" which replies back with
trusted md5's. These can be used to send only the public/trusted bits of
information.

Read on: http://developer.pidgin.im/wiki/GSoC2012/Statscollector#Ensuringservernamesinprpl-jabberircarepublic

diffstat:

 libpurple/plugins/statscollector.c |  121 +++++++++++++++++++++++++++++++++---
 1 files changed, 111 insertions(+), 10 deletions(-)

diffs (182 lines):

diff --git a/libpurple/plugins/statscollector.c b/libpurple/plugins/statscollector.c
--- a/libpurple/plugins/statscollector.c
+++ b/libpurple/plugins/statscollector.c
@@ -40,9 +40,11 @@ enum
 
 /* Timeout */
 #define RESEND_SEC (24*3600)
+#define TRUSTED_CACHE_REFRESH (24*3600)
 
 /* Sending URL */
-#define SEND_URL "http://stats.pidgin.im:8000/collect/"
+#define SEND_URL "http://stats.pidgin.im/collect/"
+#define TRUSTED_URL "http://stats.pidgin.im/trusted/"
 
 /* Version of XML this plugin supports writing */
 
@@ -65,6 +67,8 @@ enum
 PurplePlugin *plugin_g;
 xmlnode *root_stats, *cpuinfo_xml, *ui_info;
 GHashTable *stats_acc_ht, *stats_plugins_ht, *stats_uis_ht;
+GHashTable *trusted_server_cache_ht=NULL;
+
 int save_timer = 0, send_handle = 0, pref_cb_id = -1;
 
 /* Types of Operating Systems */
@@ -75,6 +79,8 @@ static void schedule_send(void);
 static gboolean send_stats();
 static gboolean plugin_load(PurplePlugin *);
 static gboolean plugin_unload(PurplePlugin *plugin);
+static gboolean refresh_trusted_cache(gpointer data);
+static xmlnode *init_stats();
 
 static char *
 epoch_to_str(time_t epoch){
@@ -198,6 +204,86 @@ schedule_stats_save(void){
     save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
 }
 
+static void
+refresh_trusted_cache_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message){
+
+  /*
+   * Check if the header has HTTP/1.1 200 ...
+   * I am assuming that the first few characters will always follow
+   * the following format:
+   * HTTP/1.x xyz reason
+   */
+
+  int code = -1;
+  char *header = g_strdup_printf("%s", url_text);
+  char *data_loc=NULL;
+  const char *hash_id;
+  xmlnode *trusted_hash_root, *start;
+
+  if(!trusted_server_cache_ht){
+    trusted_server_cache_ht = g_hash_table_new(g_str_hash, g_str_equal);
+  }
+
+  if(header && strlen(header) >= 14) {
+    header += 9;
+    header[3] = '\0';
+    code = atoi(header);
+  }
+
+  purple_debug_info("STATS", "Code returned: %d\n", code);
+  if(code == 200){
+    /* Extract the data to be converted to XML => GList */
+    data_loc = strstr(url_text, "\r\n\r\n");
+    trusted_hash_root = xmlnode_from_str(data_loc, -1);
+    if(trusted_hash_root != NULL){
+      /* Now load a Hash Table of accepted Hashes, currently they won't
+       * contain any data, but this is to keep space for any extra info
+       * that the server might give away!
+       */
+      start = xmlnode_get_child(trusted_hash_root, "hash");
+      for(;start;start = xmlnode_get_next_twin(start)){
+        hash_id = xmlnode_get_attrib(start, "id");
+        g_hash_table_insert(trusted_server_cache_ht, (void *)hash_id, NULL);
+      }
+      purple_timeout_add_seconds(TRUSTED_CACHE_REFRESH, refresh_trusted_cache, NULL);
+      /* Load the stats file into a global variable for any updations */
+      root_stats = init_stats();
+    }
+  } else {
+     purple_timeout_add_seconds(10, refresh_trusted_cache, NULL);
+  }
+}
+
+static gboolean
+refresh_trusted_cache(gpointer data){
+
+  /* Refresh the stored cache of information about IRC/Jabber
+   * servers which are in-effect public using md5 hashes!
+   */
+
+  /* Obtain the list through a webservice */
+  gchar *host, *path, *request, *url= TRUSTED_URL;
+  gboolean *send_success;
+  int port;
+
+  purple_debug_info("STATS", "requesting trusted ...");
+  purple_url_parse(url, &host, &port, &path, NULL, NULL);
+  send_success = g_new0(gboolean, 1);
+  request = g_strdup_printf(\
+          "GET /%s HTTP/1.0\r\n"
+          "Connection: keep-alive\r\n"
+          "Host: %s:%d\r\n\r\n",
+          path, host, port);
+  purple_debug_info("STATS", "%s", request);
+  purple_util_fetch_url_request(url, TRUE, NULL, FALSE, request, TRUE, refresh_trusted_cache_cb, send_success);
+
+  g_free(host);
+  g_free(path);
+  g_free(request);
+  return FALSE;
+
+}
+
 static xmlnode *
 get_app_32_64(){
 
@@ -708,9 +794,9 @@ acc_sign_on_event(PurpleAccount *account
       for (l = g_list_last(user_splits);l != NULL;l = l->prev) {
 
           PurpleAccountUserSplit *split = l->data;
-          const char *value = NULL;
+          const char *value = NULL, *value_md5=NULL;
           char *c;
-          xmlnode *user_split_node;
+          xmlnode *user_split_node, *user_split_node_hash;
 
           if(purple_account_user_split_get_reverse(split))
               c = strrchr(username_dup,
@@ -725,17 +811,29 @@ acc_sign_on_event(PurpleAccount *account
               value = c;
           }
 
-          if (value == NULL)
+          if (value == NULL){
               value = "";
+              value_md5 = NULL;
+          } else {
+            value_md5 = md5((const guchar *)value);
+          }
 
-          user_split_node = xmlnode_new(split->text);
-          xmlnode_insert_data(user_split_node, value, -1);
+
+          /* Check if the Hash is in the trusted_hash_table */
+          user_split_node = xmlnode_new(g_strdup_printf("%s", split->text));
+          if(g_hash_table_lookup_extended(trusted_server_cache_ht, value_md5, NULL, NULL)){
+            xmlnode_insert_data(user_split_node, value, -1);
+          }
           xmlnode_insert_child(acc, user_split_node);
+
+          /* Normal MD5 node */
+          user_split_node_hash = xmlnode_new(g_strdup_printf("%s_hash", split->text));
+          xmlnode_insert_data(user_split_node_hash, value_md5, -1);
+          xmlnode_insert_child(acc, user_split_node_hash);
+
       }
-
     }
 
-
     /* Server information if Jabber */
     if(!g_strcmp0(protocol,"prpl-jabber")){
 
@@ -1161,8 +1259,11 @@ plugin_load(PurplePlugin *plugin) {
 
   else if(check_ask == ALLOW){
 
-    /* Load the stats file into a global variable for any updations */
-    root_stats = init_stats();
+
+    /* Refresh the trusted cache first! */
+    refresh_trusted_cache(NULL);
+
+
 
     /* Register the account signals for sign-on */
     purple_signal_connect(purple_accounts_get_handle(), "account-signed-on",



More information about the Commits mailing list