Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/EionRobb/skype4pidgin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-11-07 00:06:20 +0300
committerdequis <dx@dxzone.com.ar>2015-11-07 00:16:36 +0300
commit88b452ac170c3de1bbfef3df424821a4542fae61 (patch)
treed9ac916ae1df72a59a244393098a907c7ee066aa
parent256e64d82aa27dca979ae09409552a6a1c3998ac (diff)
Keep track of PurpleUtilFetchUrlData and cancel them on logout
Fixes use-after-free bugs when the callback is called after the account is turned off. This creates a wrapper function skypeweb_fetch_url_request() which takes a SkypeWebAccount instead of a PurpleAccount, and stores each return value in a linked list, sa->url_datas. The callbacks must take care of removing this entry. The linked list idea is pretty much copy-pasted from built-in prpls, main difference is that others don't have a wrapper function. This diff is rather repetitive, but it's as good as it gets.
-rw-r--r--skypeweb/libskypeweb.c5
-rw-r--r--skypeweb/libskypeweb.h2
-rw-r--r--skypeweb/skypeweb_contacts.c26
-rw-r--r--skypeweb/skypeweb_login.c18
-rw-r--r--skypeweb/skypeweb_messages.c8
-rw-r--r--skypeweb/skypeweb_util.c21
-rw-r--r--skypeweb/skypeweb_util.h8
7 files changed, 74 insertions, 14 deletions
diff --git a/skypeweb/libskypeweb.c b/skypeweb/libskypeweb.c
index 01b3203..dd9d6cd 100644
--- a/skypeweb/libskypeweb.c
+++ b/skypeweb/libskypeweb.c
@@ -367,6 +367,11 @@ skypeweb_close(PurpleConnection *pc)
sa->dns_queries = g_slist_remove(sa->dns_queries, dns_query);
purple_dnsquery_destroy(dns_query);
}
+
+ while (sa->url_datas) {
+ purple_util_fetch_url_cancel(sa->url_datas->data);
+ sa->url_datas = g_slist_delete_link(sa->url_datas, sa->url_datas);
+ }
g_hash_table_destroy(sa->sent_messages_hash);
g_hash_table_destroy(sa->cookie_table);
diff --git a/skypeweb/libskypeweb.h b/skypeweb/libskypeweb.h
index ebc3471..d750212 100644
--- a/skypeweb/libskypeweb.h
+++ b/skypeweb/libskypeweb.h
@@ -272,6 +272,8 @@ struct _SkypeWebAccount {
gchar *registration_token;
gchar *endpoint;
gint registration_expiry;
+
+ GSList *url_datas; /**< PurpleUtilFetchUrlData to be cancelled on logout */
};
struct _SkypeWebBuddy {
diff --git a/skypeweb/skypeweb_contacts.c b/skypeweb/skypeweb_contacts.c
index 41d9220..c92af89 100644
--- a/skypeweb/skypeweb_contacts.c
+++ b/skypeweb/skypeweb_contacts.c
@@ -34,6 +34,10 @@ static void
skypeweb_get_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
{
PurpleBuddy *buddy = user_data;
+ SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
+ SkypeWebAccount *sa = sbuddy->sa;
+
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
active_icon_downloads--;
@@ -58,7 +62,7 @@ skypeweb_get_icon_now(PurpleBuddy *buddy)
url = g_strdup_printf("https://api.skype.com/users/%s/profile/avatar", purple_url_encode(purple_buddy_get_name(buddy)));
}
- purple_util_fetch_url_request(purple_buddy_get_account(buddy), url, TRUE, NULL, FALSE, NULL, FALSE, 524288, skypeweb_get_icon_cb, buddy);
+ skypeweb_fetch_url_request(sbuddy->sa, url, TRUE, NULL, FALSE, NULL, FALSE, 524288, skypeweb_get_icon_cb, buddy);
g_free(url);
@@ -91,15 +95,18 @@ static void
skypeweb_got_imagemessage(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
{
PurpleConversation *conv = user_data;
+ PurpleConnection *pc = purple_conversation_get_connection(conv);
+ SkypeWebAccount *sa = purple_connection_get_protocol_data(pc);
gint icon_id;
gchar *msg_tmp;
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
+
if (url_text == NULL && url_data->data_len) {
gchar *location;
location = skypeweb_string_get_chunk(url_data->webdata, url_data->data_len, "Location: https://", "/");
if (location && *location) {
- PurpleConnection *pc = purple_conversation_get_connection(conv);
- skypeweb_download_uri_to_conv(purple_connection_get_protocol_data(pc), location, conv);
+ skypeweb_download_uri_to_conv(sa, location, conv);
g_free(location);
}
return;
@@ -137,8 +144,10 @@ skypeweb_download_uri_to_conv(SkypeWebAccount *sa, const gchar *uri, PurpleConve
purple_http_url_get_path(httpurl), sa->skype_token,
purple_http_url_get_host(httpurl));
- requestdata = purple_util_fetch_url_request(sa->account, uri, TRUE, NULL, FALSE, headers, FALSE, -1, skypeweb_got_imagemessage, conv);
- requestdata->num_times_redirected = 10; /* Prevent following redirects */
+ requestdata = skypeweb_fetch_url_request(sa, uri, TRUE, NULL, FALSE, headers, FALSE, -1, skypeweb_got_imagemessage, conv);
+
+ if (requestdata != NULL)
+ requestdata->num_times_redirected = 10; /* Prevent following redirects */
g_free(headers);
purple_http_url_free(httpurl);
@@ -149,6 +158,9 @@ static void
skypeweb_got_vm_file(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
{
PurpleXfer *xfer = user_data;
+ SkypeWebAccount *sa = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
+
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
purple_xfer_write(xfer, (guchar *)url_text, len);
}
@@ -156,6 +168,7 @@ skypeweb_got_vm_file(PurpleUtilFetchUrlData *url_data, gpointer user_data, const
static void
skypeweb_init_vm_download(PurpleXfer *xfer)
{
+ SkypeWebAccount *sa;
JsonObject *file = xfer->data;
gint64 fileSize;
const gchar *url;
@@ -164,7 +177,8 @@ skypeweb_init_vm_download(PurpleXfer *xfer)
url = json_object_get_string_member(file, "url");
purple_xfer_set_completed(xfer, FALSE);
- purple_util_fetch_url_request(xfer->account, url, TRUE, NULL, FALSE, NULL, FALSE, fileSize, skypeweb_got_vm_file, xfer);
+ sa = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
+ skypeweb_fetch_url_request(sa, url, TRUE, NULL, FALSE, NULL, FALSE, fileSize, skypeweb_got_vm_file, xfer);
json_object_unref(file);
}
diff --git a/skypeweb/skypeweb_login.c b/skypeweb/skypeweb_login.c
index c923b79..84ed1a6 100644
--- a/skypeweb/skypeweb_login.c
+++ b/skypeweb/skypeweb_login.c
@@ -26,6 +26,8 @@ skypeweb_login_did_auth(PurpleUtilFetchUrlData *url_data, gpointer user_data, co
gchar *refresh_token;
SkypeWebAccount *sa = user_data;
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
+
if (url_text == NULL) {
url_text = url_data->webdata;
len = url_data->data_len;
@@ -68,6 +70,8 @@ skypeweb_login_got_pie(PurpleUtilFetchUrlData *url_data, gpointer user_data, con
struct timezone tz;
guint tzhours, tzminutes;
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
+
if (error_message && *error_message) {
purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
return;
@@ -112,7 +116,7 @@ skypeweb_login_got_pie(PurpleUtilFetchUrlData *url_data, gpointer user_data, con
"Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s",
strlen(postdata->str), postdata->str);
- purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa);
+ skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa);
g_string_free(postdata, TRUE);
g_free(request);
@@ -128,7 +132,7 @@ skypeweb_begin_web_login(SkypeWebAccount *sa)
{
const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST "/login?method=skype&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com";
- purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, NULL, FALSE, 524288, skypeweb_login_got_pie, sa);
+ skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, NULL, FALSE, 524288, skypeweb_login_got_pie, sa);
purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTING);
purple_connection_update_progress(sa->pc, _("Connecting"), 1, 4);
@@ -142,6 +146,8 @@ skypeweb_login_got_t(PurpleUtilFetchUrlData *url_data, gpointer user_data, const
gchar *request;
GString *postdata;
gchar *magic_t_value; // T is for tasty
+
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
// <input type="hidden" name="t" id="t" value="...">
magic_t_value = skypeweb_string_get_chunk(url_text, len, "=\"t\" value=\"", "\"");
@@ -167,7 +173,7 @@ skypeweb_login_got_t(PurpleUtilFetchUrlData *url_data, gpointer user_data, const
"Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s",
strlen(postdata->str), postdata->str);
- purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa);
+ skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa);
g_string_free(postdata, TRUE);
g_free(request);
@@ -187,6 +193,8 @@ skypeweb_login_got_ppft(PurpleUtilFetchUrlData *url_data, gpointer user_data, co
gchar *ppft;
GString *postdata;
gchar *request;
+
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
// grab PPFT and cookies (MSPRequ, MSPOK)
msprequ_cookie = skypeweb_string_get_chunk(url_text, len, "Set-Cookie: MSPRequ=", ";");
@@ -225,7 +233,7 @@ skypeweb_login_got_ppft(PurpleUtilFetchUrlData *url_data, gpointer user_data, co
"Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s",
msprequ_cookie, mspok_cookie, cktst_cookie, strlen(postdata->str), postdata->str);
- purple_util_fetch_url_request(sa->account, live_login_url, TRUE, NULL, FALSE, request, FALSE, 524288, skypeweb_login_got_t, sa);
+ skypeweb_fetch_url_request(sa, live_login_url, TRUE, NULL, FALSE, request, FALSE, 524288, skypeweb_login_got_t, sa);
g_string_free(postdata, TRUE);
g_free(request);
@@ -243,7 +251,7 @@ skypeweb_begin_oauth_login(SkypeWebAccount *sa)
{
const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST "/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com";
- purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, NULL, TRUE, 524288, skypeweb_login_got_ppft, sa);
+ skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, NULL, TRUE, 524288, skypeweb_login_got_ppft, sa);
purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTING);
purple_connection_update_progress(sa->pc, _("Connecting"), 1, 4);
diff --git a/skypeweb/skypeweb_messages.c b/skypeweb/skypeweb_messages.c
index 72ebee6..0610793 100644
--- a/skypeweb/skypeweb_messages.c
+++ b/skypeweb/skypeweb_messages.c
@@ -992,6 +992,8 @@ skypeweb_got_registration_token(PurpleUtilFetchUrlData *url_data, gpointer user_
gchar *expires;
SkypeWebAccount *sa = user_data;
gchar *new_messages_host;
+
+ sa->url_datas = g_slist_remove(sa->url_datas, url_data);
if (url_text == NULL) {
url_text = url_data->webdata;
@@ -1075,8 +1077,10 @@ skypeweb_get_registration_token(SkypeWebAccount *sa)
//purple_debug_info("skypeweb", "reg token request is %s\n", request);
- requestdata = purple_util_fetch_url_request(sa->account, messages_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_got_registration_token, sa);
- requestdata->num_times_redirected = 10; /* Prevent following redirects */
+ requestdata = skypeweb_fetch_url_request(sa, messages_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_got_registration_token, sa);
+
+ if (requestdata != NULL)
+ requestdata->num_times_redirected = 10; /* Prevent following redirects */
g_free(request);
g_free(curtime);
diff --git a/skypeweb/skypeweb_util.c b/skypeweb/skypeweb_util.c
index 81b303b..f6bfb73 100644
--- a/skypeweb/skypeweb_util.c
+++ b/skypeweb/skypeweb_util.c
@@ -247,3 +247,24 @@ find_acct(const char *prpl, const char *acct_id)
return acct;
}
+
+
+/* Wrapper of purple_util_fetch_url_request_len_with_account()
+ * that takes a SkypeWebAccount instead of a PurpleAccount,
+ * and keeps track of requests in sa->url_datas to cancel them on logout. */
+
+PurpleUtilFetchUrlData *
+skypeweb_fetch_url_request(SkypeWebAccount *sa,
+ const char *url, gboolean full, const char *user_agent, gboolean http11,
+ const char *request, gboolean include_headers, gssize max_len,
+ PurpleUtilFetchUrlCallback callback, void *user_data)
+{
+ PurpleUtilFetchUrlData *url_data;
+
+ url_data = purple_util_fetch_url_request(sa->account, url, full, user_agent, http11, request, include_headers, max_len, callback, user_data);
+
+ if (url_data != NULL)
+ sa->url_datas = g_slist_prepend(sa->url_datas, url_data);
+
+ return url_data;
+}
diff --git a/skypeweb/skypeweb_util.h b/skypeweb/skypeweb_util.h
index c0bbb12..f73a32f 100644
--- a/skypeweb/skypeweb_util.h
+++ b/skypeweb/skypeweb_util.h
@@ -29,4 +29,10 @@ gchar *skypeweb_hmac_sha256(gchar *input);
gint64 skypeweb_get_js_time();
-PurpleAccount *find_acct(const char *prpl, const char *acct_id); \ No newline at end of file
+PurpleAccount *find_acct(const char *prpl, const char *acct_id);
+
+PurpleUtilFetchUrlData *
+skypeweb_fetch_url_request(SkypeWebAccount *sa,
+ const char *url, gboolean full, const char *user_agent, gboolean http11,
+ const char *request, gboolean include_headers, gssize max_len,
+ PurpleUtilFetchUrlCallback callback, void *user_data);