/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