Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 18c6d369d777a1d38ef450f868c22de1d0ebba2d)
+++ protocols/jabber/jabber.c	(revision 64b663524a465efb7707a2c634be97b9fb6f963b)
@@ -152,14 +152,25 @@
 			jd->oauth2_service = &oauth2_service_google;
 		
-		/* For the first login with OAuth, we have to authenticate via the browser.
-		   For subsequent logins, exchange the refresh token for a valid access
-		   token (even though the last one maybe didn't expire yet). */
-		if( strncmp( acc->pass, "refresh_token=", 14 ) != 0 )
+		/* First see if we have a refresh token, in which case any
+		   access token we *might* have has probably expired already
+		   anyway. */
+		if( strstr( acc->pass, "refresh_token=" ) )
+		{
+			sasl_oauth2_refresh( ic, acc->pass + 14 );
+		}
+		/* If we don't have a refresh token, let's hope the access
+		   token is still usable. */
+		else if( strstr( acc->pass, "access_token=" ) )
+		{
+			sasl_oauth2_load_access_token( ic );
+			jabber_connect( ic );
+		}
+		/* If we don't have any, start the OAuth process now. Don't
+		   even open an XMPP connection yet. */
+		else
 		{
 			sasl_oauth2_init( ic );
 			ic->flags |= OPT_SLOW_LOGIN;
 		}
-		else
-			sasl_oauth2_refresh( ic, acc->pass + 14 );
 	}
 	else
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 18c6d369d777a1d38ef450f868c22de1d0ebba2d)
+++ protocols/jabber/jabber.h	(revision 64b663524a465efb7707a2c634be97b9fb6f963b)
@@ -327,4 +327,5 @@
 int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg );
 int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token );
+int sasl_oauth2_load_access_token( struct im_connection *ic );
 
 extern const struct oauth2_service oauth2_service_google;
Index: protocols/jabber/sasl.c
===================================================================
--- protocols/jabber/sasl.c	(revision 18c6d369d777a1d38ef450f868c22de1d0ebba2d)
+++ protocols/jabber/sasl.c	(revision 64b663524a465efb7707a2c634be97b9fb6f963b)
@@ -52,5 +52,5 @@
 	"https://oauth.live.com/token",
 	"http://www.bitlbee.org/main.php/Messenger/oauth2.html",
-	"wl.messenger",
+	"wl.offline_access%20wl.messenger",
 	"000000004C06FCD1",
 	"IRKlBPzJJAWcY-TbZjiTEJu9tn7XCFaV",
@@ -88,11 +88,11 @@
 		if( c->text && g_strcasecmp( c->text, "PLAIN" ) == 0 )
 			sup_plain = 1;
-		if( c->text && g_strcasecmp( c->text, "DIGEST-MD5" ) == 0 )
+		else if( c->text && g_strcasecmp( c->text, "DIGEST-MD5" ) == 0 )
 			sup_digest = 1;
-		if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
+		else if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
 			sup_gtalk = 1;
-		if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
+		else if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
 			sup_fb = 1;
-		if( c->text && g_strcasecmp( c->text, "X-MESSENGER-OAUTH2" ) == 0 )
+		else if( c->text && g_strcasecmp( c->text, "X-MESSENGER-OAUTH2" ) == 0 )
 			sup_ms = 1;
 		
@@ -135,5 +135,5 @@
 		reply->text_len = strlen( jd->oauth2_access_token );
 	}
-	else if( sup_fb && want_oauth && strstr( ic->acc->pass, "session_key=" ) )
+	else if( sup_fb && want_oauth )
 	{
 		xt_add_attr( reply, "mechanism", "X-FACEBOOK-PLATFORM" );
@@ -292,8 +292,6 @@
 		   and in their Python module. It's all mostly useless because the tokens
 		   expire after 24h. */
-		GSList *p_in = NULL, *p_out = NULL, *p;
-		md5_state_t md5;
-		char time[33], *token;
-		const char *secret;
+		GSList *p_in = NULL, *p_out = NULL;
+		char time[33];
 		
 		oauth_params_parse( &p_in, dec );
@@ -301,9 +299,4 @@
 		oauth_params_add( &p_out, "method", oauth_params_get( &p_in, "method" ) );
 		oauth_params_free( &p_in );
-		
-		token = g_strdup( ic->acc->pass );
-		oauth_params_parse( &p_in, token );
-		g_free( token );
-		oauth_params_add( &p_out, "session_key", oauth_params_get( &p_in, "session_key" ) );
 		
 		g_snprintf( time, sizeof( time ), "%lld", (long long) ( gettime() * 1000 ) );
@@ -312,18 +305,8 @@
 		oauth_params_add( &p_out, "v", "1.0" );
 		oauth_params_add( &p_out, "format", "XML" );
-		
-		md5_init( &md5 );
-		for( p = p_out; p; p = p->next )
-			md5_append( &md5, p->data, strlen( p->data ) );
-		
-		secret = oauth_params_get( &p_in, "secret" );
-		if( secret )
-			md5_append( &md5, (unsigned char*) secret, strlen( secret ) );
-		md5_finish_ascii( &md5, time );
-		oauth_params_add( &p_out, "sig", time );
+		oauth_params_add( &p_out, "access_token", jd->oauth2_access_token );
 		
 		reply = oauth_params_string( p_out );
 		oauth_params_free( &p_out );
-		oauth_params_free( &p_in );
 	}
 	else if( !( s = sasl_get_part( dec, "rspauth" ) ) )
@@ -521,4 +504,16 @@
 }
 
+int sasl_oauth2_load_access_token( struct im_connection *ic )
+{
+	struct jabber_data *jd = ic->proto_data;
+	GSList *p_in = NULL;
+	
+	oauth_params_parse( &p_in, ic->acc->pass );
+	jd->oauth2_access_token = g_strdup( oauth_params_get( &p_in, "access_token" ) );
+	oauth_params_free( &p_in );
+	
+	return jd->oauth2_access_token != NULL;
+}
+
 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token )
 {
