1.1 --- a/libpurple/plugins/statscollector.c
1.2 +++ b/libpurple/plugins/statscollector.c
1.3 @@ -40,9 +40,11 @@
1.4
1.5 /* Timeout */
1.6 #define RESEND_SEC (24*3600)
1.7 +#define TRUSTED_CACHE_REFRESH (24*3600)
1.8
1.9 /* Sending URL */
1.10 -#define SEND_URL "http://stats.pidgin.im:8000/collect/"
1.11 +#define SEND_URL "http://stats.pidgin.im/collect/"
1.12 +#define TRUSTED_URL "http://stats.pidgin.im/trusted/"
1.13
1.14 /* Version of XML this plugin supports writing */
1.15
1.16 @@ -65,6 +67,8 @@
1.17 PurplePlugin *plugin_g;
1.18 xmlnode *root_stats, *cpuinfo_xml, *ui_info;
1.19 GHashTable *stats_acc_ht, *stats_plugins_ht, *stats_uis_ht;
1.20 +GHashTable *trusted_server_cache_ht=NULL;
1.21 +
1.22 int save_timer = 0, send_handle = 0, pref_cb_id = -1;
1.23
1.24 /* Types of Operating Systems */
1.25 @@ -75,6 +79,8 @@
1.26 static gboolean send_stats();
1.27 static gboolean plugin_load(PurplePlugin *);
1.28 static gboolean plugin_unload(PurplePlugin *plugin);
1.29 +static gboolean refresh_trusted_cache(gpointer data);
1.30 +static xmlnode *init_stats();
1.31
1.32 static char *
1.33 epoch_to_str(time_t epoch){
1.34 @@ -198,6 +204,86 @@
1.35 save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
1.36 }
1.37
1.38 +static void
1.39 +refresh_trusted_cache_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message){
1.40 +
1.41 + /*
1.42 + * Check if the header has HTTP/1.1 200 ...
1.43 + * I am assuming that the first few characters will always follow
1.44 + * the following format:
1.45 + * HTTP/1.x xyz reason
1.46 + */
1.47 +
1.48 + int code = -1;
1.49 + char *header = g_strdup_printf("%s", url_text);
1.50 + char *data_loc=NULL;
1.51 + const char *hash_id;
1.52 + xmlnode *trusted_hash_root, *start;
1.53 +
1.54 + if(!trusted_server_cache_ht){
1.55 + trusted_server_cache_ht = g_hash_table_new(g_str_hash, g_str_equal);
1.56 + }
1.57 +
1.58 + if(header && strlen(header) >= 14) {
1.59 + header += 9;
1.60 + header[3] = '\0';
1.61 + code = atoi(header);
1.62 + }
1.63 +
1.64 + purple_debug_info("STATS", "Code returned: %d\n", code);
1.65 + if(code == 200){
1.66 + /* Extract the data to be converted to XML => GList */
1.67 + data_loc = strstr(url_text, "\r\n\r\n");
1.68 + trusted_hash_root = xmlnode_from_str(data_loc, -1);
1.69 + if(trusted_hash_root != NULL){
1.70 + /* Now load a Hash Table of accepted Hashes, currently they won't
1.71 + * contain any data, but this is to keep space for any extra info
1.72 + * that the server might give away!
1.73 + */
1.74 + start = xmlnode_get_child(trusted_hash_root, "hash");
1.75 + for(;start;start = xmlnode_get_next_twin(start)){
1.76 + hash_id = xmlnode_get_attrib(start, "id");
1.77 + g_hash_table_insert(trusted_server_cache_ht, (void *)hash_id, NULL);
1.78 + }
1.79 + purple_timeout_add_seconds(TRUSTED_CACHE_REFRESH, refresh_trusted_cache, NULL);
1.80 + /* Load the stats file into a global variable for any updations */
1.81 + root_stats = init_stats();
1.82 + }
1.83 + } else {
1.84 + purple_timeout_add_seconds(10, refresh_trusted_cache, NULL);
1.85 + }
1.86 +}
1.87 +
1.88 +static gboolean
1.89 +refresh_trusted_cache(gpointer data){
1.90 +
1.91 + /* Refresh the stored cache of information about IRC/Jabber
1.92 + * servers which are in-effect public using md5 hashes!
1.93 + */
1.94 +
1.95 + /* Obtain the list through a webservice */
1.96 + gchar *host, *path, *request, *url= TRUSTED_URL;
1.97 + gboolean *send_success;
1.98 + int port;
1.99 +
1.100 + purple_debug_info("STATS", "requesting trusted ...");
1.101 + purple_url_parse(url, &host, &port, &path, NULL, NULL);
1.102 + send_success = g_new0(gboolean, 1);
1.103 + request = g_strdup_printf(\
1.104 + "GET /%s HTTP/1.0\r\n"
1.105 + "Connection: keep-alive\r\n"
1.106 + "Host: %s:%d\r\n\r\n",
1.107 + path, host, port);
1.108 + purple_debug_info("STATS", "%s", request);
1.109 + purple_util_fetch_url_request(url, TRUE, NULL, FALSE, request, TRUE, refresh_trusted_cache_cb, send_success);
1.110 +
1.111 + g_free(host);
1.112 + g_free(path);
1.113 + g_free(request);
1.114 + return FALSE;
1.115 +
1.116 +}
1.117 +
1.118 static xmlnode *
1.119 get_app_32_64(){
1.120
1.121 @@ -708,9 +794,9 @@
1.122 for (l = g_list_last(user_splits);l != NULL;l = l->prev) {
1.123
1.124 PurpleAccountUserSplit *split = l->data;
1.125 - const char *value = NULL;
1.126 + const char *value = NULL, *value_md5=NULL;
1.127 char *c;
1.128 - xmlnode *user_split_node;
1.129 + xmlnode *user_split_node, *user_split_node_hash;
1.130
1.131 if(purple_account_user_split_get_reverse(split))
1.132 c = strrchr(username_dup,
1.133 @@ -725,17 +811,29 @@
1.134 value = c;
1.135 }
1.136
1.137 - if (value == NULL)
1.138 + if (value == NULL){
1.139 value = "";
1.140 + value_md5 = NULL;
1.141 + } else {
1.142 + value_md5 = md5((const guchar *)value);
1.143 + }
1.144
1.145 - user_split_node = xmlnode_new(split->text);
1.146 - xmlnode_insert_data(user_split_node, value, -1);
1.147 +
1.148 + /* Check if the Hash is in the trusted_hash_table */
1.149 + user_split_node = xmlnode_new(g_strdup_printf("%s", split->text));
1.150 + if(g_hash_table_lookup_extended(trusted_server_cache_ht, value_md5, NULL, NULL)){
1.151 + xmlnode_insert_data(user_split_node, value, -1);
1.152 + }
1.153 xmlnode_insert_child(acc, user_split_node);
1.154 +
1.155 + /* Normal MD5 node */
1.156 + user_split_node_hash = xmlnode_new(g_strdup_printf("%s_hash", split->text));
1.157 + xmlnode_insert_data(user_split_node_hash, value_md5, -1);
1.158 + xmlnode_insert_child(acc, user_split_node_hash);
1.159 +
1.160 }
1.161 -
1.162 }
1.163
1.164 -
1.165 /* Server information if Jabber */
1.166 if(!g_strcmp0(protocol,"prpl-jabber")){
1.167
1.168 @@ -1161,8 +1259,11 @@
1.169
1.170 else if(check_ask == ALLOW){
1.171
1.172 - /* Load the stats file into a global variable for any updations */
1.173 - root_stats = init_stats();
1.174 +
1.175 + /* Refresh the trusted cache first! */
1.176 + refresh_trusted_cache(NULL);
1.177 +
1.178 +
1.179
1.180 /* Register the account signals for sign-on */
1.181 purple_signal_connect(purple_accounts_get_handle(), "account-signed-on",