/cpw/tomkiewicz/gg11: 169db6aa5e08: Gadu-Gadu: very initial GGDr...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Thu Sep 27 19:21:11 EDT 2012
Changeset: 169db6aa5e0821ccdf47f325e297eef5730a8f8a
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-09-28 01:21 +0200
Branch: default
URL: http://hg.pidgin.im/cpw/tomkiewicz/gg11/rev/169db6aa5e08
Description:
Gadu-Gadu: very initial GGDrive authentication support
diffstat:
libpurple/protocols/gg/Makefile.am | 2 +
libpurple/protocols/gg/gg.c | 46 +++++++++---
libpurple/protocols/gg/gg.h | 7 ++
libpurple/protocols/gg/ggdrive.c | 127 +++++++++++++++++++++++++++++++++++++
libpurple/protocols/gg/ggdrive.h | 8 ++
libpurple/protocols/gg/libgaduw.c | 11 +++
libpurple/protocols/gg/libgaduw.h | 2 +
7 files changed, 190 insertions(+), 13 deletions(-)
diffs (truncated from 317 to 300 lines):
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -64,6 +64,8 @@ GGSOURCES = \
deprecated.h \
gg.c \
gg.h \
+ ggdrive.c \
+ ggdrive.h \
html.c \
html.h \
image.c \
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -54,6 +54,7 @@
#include "pubdir-prpl.h"
#include "message-prpl.h"
#include "html.h"
+#include "ggdrive.h"
/* ---------------------------------------------------------------------- */
@@ -79,6 +80,30 @@ static void ggp_buddy_free(PurpleBuddy *
purple_buddy_set_protocol_data(buddy, NULL);
}
+const gchar * ggp_get_imtoken(PurpleConnection *gc)
+{
+ GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+
+ if (accdata->imtoken)
+ return accdata->imtoken;
+
+ if (accdata->imtoken_warned)
+ return NULL;
+ accdata->imtoken_warned = TRUE;
+
+ purple_notify_error(gc, _("Authentication failed"),
+ _("IMToken value has not been received."),
+ _("Some features will be disabled. "
+ "You may try again after a while."));
+ return NULL;
+}
+
+uin_t ggp_own_uin(PurpleConnection *gc)
+{
+ return ggp_str_to_uin(purple_account_get_username(
+ purple_connection_get_account(gc)));
+}
+
/* ---------------------------------------------------------------------- */
// buddy list import/export from/to file
@@ -350,7 +375,10 @@ static void ggp_callback_recv(gpointer _
ggp_multilogon_info(gc, &ev->event.multilogon_info);
break;
case GG_EVENT_IMTOKEN:
- purple_debug_info("gg", "gg11: got IMTOKEN %s\n", ev->event.imtoken.imtoken);
+ purple_debug_info("gg", "gg11: got IMTOKEN\n");
+ g_free(info->imtoken);
+ info->imtoken = g_strdup(ev->event.imtoken.imtoken);
+ ggp_ggdrive_test(gc);
break;
case GG_EVENT_PONG110:
purple_debug_info("gg", "gg11: got PONG110 %lu\n", ev->event.pong110.time);
@@ -621,9 +649,6 @@ static void ggp_login(PurpleAccount *acc
glp = g_new0(struct gg_login_params, 1);
info = g_new0(GGPInfo, 1);
- /* Probably this should be moved to *_new() function. */
- info->session = NULL;
-
purple_connection_set_protocol_data(gc, info);
ggp_image_setup(gc);
@@ -716,14 +741,13 @@ static void ggp_close(PurpleConnection *
PurpleAccount *account;
GGPInfo *info;;
- if (gc == NULL) {
- purple_debug_info("gg", "gc == NULL\n");
- return;
- }
+ g_return_if_fail(gc != NULL);
account = purple_connection_get_account(gc);
info = purple_connection_get_protocol_data(gc);
+ purple_notify_close_with_handle(gc);
+
if (info) {
if (info->session != NULL)
{
@@ -732,11 +756,6 @@ static void ggp_close(PurpleConnection *
gg_free_session(info->session);
}
- /* Immediately close any notifications on this handle since that process depends
- * upon the contents of info->searches, which we are about to destroy.
- */
- purple_notify_close_with_handle(gc);
-
ggp_image_cleanup(gc);
ggp_avatar_cleanup(gc);
ggp_roster_cleanup(gc);
@@ -747,6 +766,7 @@ static void ggp_close(PurpleConnection *
if (info->inpa > 0)
purple_input_remove(info->inpa);
+ g_free(info->imtoken);
purple_connection_set_protocol_data(gc, NULL);
g_free(info);
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
--- a/libpurple/protocols/gg/gg.h
+++ b/libpurple/protocols/gg/gg.h
@@ -44,6 +44,9 @@ typedef struct {
struct gg_session *session;
guint inpa;
+ gchar *imtoken;
+ gboolean imtoken_warned;
+
ggp_image_session_data *image_data;
ggp_avatar_session_data avatar_data;
ggp_roster_session_data roster_data;
@@ -60,4 +63,8 @@ typedef struct
ggp_buddy_data * ggp_buddy_get_data(PurpleBuddy *buddy);
+const gchar * ggp_get_imtoken(PurpleConnection *gc);
+
+uin_t ggp_own_uin(PurpleConnection *gc);
+
#endif /* _PURPLE_GG_H */
diff --git a/libpurple/protocols/gg/ggdrive.c b/libpurple/protocols/gg/ggdrive.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/ggdrive.c
@@ -0,0 +1,127 @@
+#include "ggdrive.h"
+
+#include <debug.h>
+
+#include "gg.h"
+#include "libgaduw.h"
+
+#define GGP_GGDRIVE_HOSTNAME "MyComputer"
+#define GGP_GGDRIVE_OS "WINNT x86-msvc"
+#define GGP_GGDRIVE_TYPE "desktop"
+
+#define GGP_GGDRIVE_RESPONSE_MAX 1024
+
+/*******************************************************************************
+ * Authentication
+ ******************************************************************************/
+
+typedef void (*ggp_ggdrive_authentication_cb)(const gchar *security_token,
+ gpointer user_data);
+
+static void ggp_ggdrive_authenticate(PurpleConnection *gc,
+ ggp_ggdrive_authentication_cb cb, gpointer user_data);
+
+static void ggp_ggdrive_authenticate_done(PurpleUtilFetchUrlData *url_data,
+ gpointer _user_data, const gchar *url_text, gsize len,
+ const gchar *error_message);
+
+typedef struct
+{
+ PurpleConnection *gc;
+ ggp_ggdrive_authentication_cb cb;
+ gpointer user_data;
+} ggp_ggdrive_authenticate_data;
+
+/******************************************************************************/
+
+static void ggp_ggdrive_authenticate(PurpleConnection *gc,
+ ggp_ggdrive_authentication_cb cb, gpointer user_data)
+{
+ PurpleAccount *account = purple_connection_get_account(gc);
+ const gchar *imtoken;
+ gchar *request, *metadata;
+ ggp_ggdrive_authenticate_data *req_data;
+
+ imtoken = ggp_get_imtoken(gc);
+ if (!imtoken)
+ {
+ cb(NULL, user_data);
+ return;
+ }
+
+ metadata = g_strdup_printf("{"
+ "\"id\": \"%032x\", "
+ "\"name\": \"" GGP_GGDRIVE_HOSTNAME "\", "
+ "\"os_version\": \"" GGP_GGDRIVE_OS "\", "
+ "\"client_version\": \"%s\", "
+ "\"type\": \"" GGP_GGDRIVE_TYPE "\"}",
+ g_random_int_range(1, 1 << 16),
+ ggp_libgaduw_version(gc));
+
+ request = g_strdup_printf(
+ "PUT /signin HTTP/1.1\r\n"
+ "Host: drive.mpa.gg.pl\r\n"
+ "Authorization: IMToken %s\r\n"
+ "X-gged-user: gg/pl:%u\r\n"
+ "X-gged-client-metadata: %s\r\n"
+ "X-gged-api-version: 6\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n",
+ imtoken, ggp_own_uin(gc), metadata);
+
+ req_data = g_new0(ggp_ggdrive_authenticate_data, 1);
+ req_data->gc = gc;
+ req_data->cb = cb;
+ req_data->user_data = user_data;
+
+ purple_util_fetch_url_request(account, "https://drive.mpa.gg.pl/signin",
+ FALSE, NULL, TRUE, request, TRUE, GGP_GGDRIVE_RESPONSE_MAX,
+ ggp_ggdrive_authenticate_done, req_data);
+
+ g_free(metadata);
+ g_free(request);
+}
+
+static void ggp_ggdrive_authenticate_done(PurpleUtilFetchUrlData *url_data,
+ gpointer _user_data, const gchar *url_text, gsize len,
+ const gchar *error_message)
+{
+ ggp_ggdrive_authenticate_data *req_data = _user_data;
+ PurpleConnection *gc = req_data->gc;
+ ggp_ggdrive_authentication_cb cb = req_data->cb;
+ gpointer user_data = req_data->user_data;
+
+ g_free(req_data);
+
+ if (!PURPLE_CONNECTION_IS_VALID(gc))
+ {
+ cb(NULL, user_data);
+ return;
+ }
+
+ if (len == 0)
+ {
+ purple_debug_error("gg", "ggp_ggdrive_authenticate_done: failed\n");
+ cb(NULL, user_data);
+ return;
+ }
+
+ purple_debug_info("gg", "ggp_ggdrive_authenticate_done: [%s]\n", url_text);
+}
+
+/***/
+
+static void ggp_ggdrive_test_cb(const gchar *security_token,
+ gpointer user_data)
+{
+ if (!security_token)
+ purple_debug_error("gg", "ggp_ggdrive_test_cb: didn't got security token\n");
+ else
+ purple_debug_info("gg", "ggp_ggdrive_test_cb: got security token [%s]\n", security_token);
+}
+
+void ggp_ggdrive_test(PurpleConnection *gc)
+{
+ ggp_ggdrive_authenticate(gc, ggp_ggdrive_test_cb, NULL);
+}
diff --git a/libpurple/protocols/gg/ggdrive.h b/libpurple/protocols/gg/ggdrive.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/ggdrive.h
@@ -0,0 +1,8 @@
+#ifndef _GGP_GGDRIVE_H
+#define _GGP_GGDRIVE_H
+
+#include <internal.h>
+
+void ggp_ggdrive_test(PurpleConnection *gc);
+
+#endif /* _GGP_GGDRIVE_H */
diff --git a/libpurple/protocols/gg/libgaduw.c b/libpurple/protocols/gg/libgaduw.c
--- a/libpurple/protocols/gg/libgaduw.c
+++ b/libpurple/protocols/gg/libgaduw.c
@@ -32,6 +32,7 @@
#include <debug.h>
#include "purplew.h"
+#include "gg.h"
/*******************************************************************************
* HTTP requests.
@@ -138,3 +139,13 @@ static void ggp_libgaduw_http_finish(ggp
req->h->destroy(req->h);
g_free(req);
}
+
+const gchar * ggp_libgaduw_version(PurpleConnection *gc)
+{
+ GGPInfo *accdata = purple_connection_get_protocol_data(gc);
More information about the Commits
mailing list