/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