diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/jabber/jabber.c | 23 | ||||
| -rw-r--r-- | protocols/jabber/jabber.h | 1 | ||||
| -rw-r--r-- | protocols/jabber/sasl.c | 47 | 
3 files changed, 39 insertions, 32 deletions
| diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index bf849e2a..50ee6f2d 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -151,16 +151,27 @@ static void jabber_login( account_t *acc )  		else  			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  		jabber_connect( ic ); diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 0a46633e..57f01695 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -326,6 +326,7 @@ gboolean sasl_supported( struct im_connection *ic );  void sasl_oauth2_init( struct im_connection *ic );  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;  extern const struct oauth2_service oauth2_service_facebook; diff --git a/protocols/jabber/sasl.c b/protocols/jabber/sasl.c index 89ab1337..622bff74 100644 --- a/protocols/jabber/sasl.c +++ b/protocols/jabber/sasl.c @@ -51,7 +51,7 @@ const struct oauth2_service oauth2_service_mslive =  	"https://oauth.live.com/authorize",  	"https://oauth.live.com/token",  	"http://www.bitlbee.org/main.php/Messenger/oauth2.html", -	"wl.messenger", +	"wl.offline_access%20wl.messenger",  	"000000004C06FCD1",  	"IRKlBPzJJAWcY-TbZjiTEJu9tn7XCFaV",  }; @@ -87,13 +87,13 @@ xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )  	{  		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;  		c = c->next; @@ -134,7 +134,7 @@ xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )  		reply->text = g_strdup( jd->oauth2_access_token );  		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" );  		jd->flags |= JFLAG_SASL_FB; @@ -291,40 +291,23 @@ xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data )  		   Mechanism is described on http://developers.facebook.com/docs/chat/  		   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 );  		oauth_params_add( &p_out, "nonce", oauth_params_get( &p_in, "nonce" ) );  		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 ) );  		oauth_params_add( &p_out, "call_id", time );  		oauth_params_add( &p_out, "api_key", oauth2_service_facebook.consumer_key );  		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" ) ) )  	{ @@ -520,6 +503,18 @@ int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token )  	                            refresh_token, sasl_oauth2_got_token, ic );  } +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 )  {  	struct im_connection *ic = data; | 
