Index: lib/Makefile
===================================================================
--- lib/Makefile	(revision a01049810d7101b8c0014aa7b36826fc95f944a5)
+++ lib/Makefile	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
@@ -13,5 +13,5 @@
 
 # [SH] Program variables
-objects = arc.o base64.o $(DES) $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
+objects = arc.o base64.o $(DES) $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o oauth2.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
 
 LFLAGS += -r
Index: lib/oauth2.c
===================================================================
--- lib/oauth2.c	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
+++ lib/oauth2.c	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
@@ -0,0 +1,42 @@
+/***************************************************************************\
+*                                                                           *
+*  BitlBee - An IRC to IM gateway                                           *
+*  Simple OAuth client (consumer) implementation.                           *
+*                                                                           *
+*  Copyright 2010-2011 Wilmer van der Gaast <wilmer@gaast.net>              *
+*                                                                           *
+*  This program is free software; you can redistribute it and/or modify     *
+*  it under the terms of the GNU General Public License as published by     *
+*  the Free Software Foundation; either version 2 of the License, or        *
+*  (at your option) any later version.                                      *
+*                                                                           *
+*  This program is distributed in the hope that it will be useful,          *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
+*  GNU General Public License for more details.                             *
+*                                                                           *
+*  You should have received a copy of the GNU General Public License along  *
+*  with this program; if not, write to the Free Software Foundation, Inc.,  *
+*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
+*                                                                           *
+\***************************************************************************/
+
+#include <glib.h>
+#include "oauth2.h"
+
+struct oauth2_service oauth2_service_google =
+{
+	"https://accounts.google.com/o/oauth2/",
+	"783993391592.apps.googleusercontent.com",
+	"k5_EV4EQ7jEVCEk3WBwEFfuW",
+};
+
+char *oauth2_url( const struct oauth2_service *sp, const char *scope )
+{
+	return g_strconcat( sp->base_url, "auth"
+	                    "?scope=", scope,
+	                    "&response_type=code"
+	                    "&redirect_uri=urn:ietf:wg:oauth:2.0:oob",
+	                    "&client_id=", sp->consumer_key,
+	                    NULL );
+}
Index: lib/oauth2.h
===================================================================
--- lib/oauth2.h	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
+++ lib/oauth2.h	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
@@ -0,0 +1,69 @@
+/***************************************************************************\
+*                                                                           *
+*  BitlBee - An IRC to IM gateway                                           *
+*  Simple OAuth client (consumer) implementation.                           *
+*                                                                           *
+*  Copyright 2010-2011 Wilmer van der Gaast <wilmer@gaast.net>              *
+*                                                                           *
+*  This program is free software; you can redistribute it and/or modify     *
+*  it under the terms of the GNU General Public License as published by     *
+*  the Free Software Foundation; either version 2 of the License, or        *
+*  (at your option) any later version.                                      *
+*                                                                           *
+*  This program is distributed in the hope that it will be useful,          *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
+*  GNU General Public License for more details.                             *
+*                                                                           *
+*  You should have received a copy of the GNU General Public License along  *
+*  with this program; if not, write to the Free Software Foundation, Inc.,  *
+*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
+*                                                                           *
+\***************************************************************************/
+
+struct oauth2_info;
+
+/* Callback function called twice during the access token request process.
+   Return FALSE if something broke and the process must be aborted. */
+typedef gboolean (*oauth_cb)( struct oauth2_info * );
+
+struct oauth2_info
+{
+	const struct oauth_service *sp;
+	
+	oauth_cb func;
+	void *data;
+	
+	struct http_request *http;
+	
+//	char *auth_url;
+//	char *request_token;
+	
+//	char *token;
+//	char *token_secret;
+//	GSList *params;
+};
+
+struct oauth2_service
+{
+	char *base_url;
+	char *consumer_key;
+	char *consumer_secret;
+};
+
+extern struct oauth2_service oauth2_service_google;
+
+/* http://oauth.net/core/1.0a/#auth_step1 (section 6.1) 
+   Request an initial anonymous token which can be used to construct an
+   authorization URL for the user. This is passed to the callback function
+   in a struct oauth2_info. */
+char *oauth2_url( const struct oauth2_service *sp, const char *scope );
+
+/* http://oauth.net/core/1.0a/#auth_step3 (section 6.3)
+   The user gets a PIN or so which we now exchange for the final access
+   token. This is passed to the callback function in the same
+   struct oauth2_info. */
+gboolean oauth2_access_token( const char *pin, struct oauth2_info *st );
+
+/* Shouldn't normally be required unless the process is aborted by the user. */
+void oauth2_info_free( struct oauth2_info *info );
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision a01049810d7101b8c0014aa7b36826fc95f944a5)
+++ protocols/jabber/jabber.c	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
@@ -60,4 +60,6 @@
 	s = set_add( &acc->set, "activity_timeout", "600", set_eval_int, acc );
 	
+	s = set_add( &acc->set, "oauth", "false", set_eval_bool, acc );
+
 	g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] );
 	s = set_add( &acc->set, "port", str, set_eval_int, acc );
Index: protocols/jabber/sasl.c
===================================================================
--- protocols/jabber/sasl.c	(revision a01049810d7101b8c0014aa7b36826fc95f944a5)
+++ protocols/jabber/sasl.c	(revision 57b4525653972dc23c8c5ca5ffaa7e44fad64ee9)
@@ -26,4 +26,5 @@
 #include "jabber.h"
 #include "base64.h"
+#include "oauth2.h"
 
 xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
@@ -33,5 +34,5 @@
 	struct xt_node *c, *reply;
 	char *s;
-	int sup_plain = 0, sup_digest = 0;
+	int sup_plain = 0, sup_digest = 0, sup_oauth2 = 0;
 	
 	if( !sasl_supported( ic ) )
@@ -59,4 +60,6 @@
 		if( c->text && g_strcasecmp( c->text, "DIGEST-MD5" ) == 0 )
 			sup_digest = 1;
+		if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
+			sup_oauth2 = 1;
 		
 		c = c->next;
@@ -73,5 +76,13 @@
 	xt_add_attr( reply, "xmlns", XMLNS_SASL );
 	
-	if( sup_digest )
+	if( sup_oauth2 && set_getbool( &ic->acc->set, "oauth" ) )
+	{
+		imcb_log( ic, "Open this URL in your browser to authenticate: %s",
+		          oauth2_url( &oauth2_service_google,
+		                      "https://www.googleapis.com/auth/googletalk" ) );
+		xt_free_node( reply );
+		reply = NULL;
+	}
+	else if( sup_digest )
 	{
 		xt_add_attr( reply, "mechanism", "DIGEST-MD5" );
@@ -96,5 +107,5 @@
 	}
 	
-	if( !jabber_write_packet( ic, reply ) )
+	if( reply && !jabber_write_packet( ic, reply ) )
 	{
 		xt_free_node( reply );
