static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error ) { struct im_connection *ic = data; struct jabber_data *jd; GSList *auth = NULL; if( g_slist_find( jabber_connections, ic ) == NULL ) return; jd = ic->proto_data; if( access_token == NULL ) { imcb_error( ic, "OAuth failure (%s)", error ); imc_logout( ic, TRUE ); return; } oauth_params_parse( &auth, ic->acc->pass ); if( refresh_token ) oauth_params_set( &auth, "refresh_token", refresh_token ); if( access_token ) oauth_params_set( &auth, "access_token", access_token ); g_free( ic->acc->pass ); ic->acc->pass = oauth_params_string( auth ); oauth_params_free( &auth ); g_free( jd->oauth2_access_token ); jd->oauth2_access_token = g_strdup( access_token ); jabber_connect( ic ); }
static void jabber_login( account_t *acc ) { struct im_connection *ic = imcb_new( acc ); struct jabber_data *jd = g_new0( struct jabber_data, 1 ); char *s; /* For now this is needed in the _connected() handlers if using GLib event handling, to make sure we're not handling events on dead connections. */ jabber_connections = g_slist_prepend( jabber_connections, ic ); jd->ic = ic; ic->proto_data = jd; jabber_set_me( ic, acc->user ); jd->fd = jd->r_inpa = jd->w_inpa = -1; if( jd->server == NULL ) { imcb_error( ic, "Incomplete account name (format it like <*****@*****.**>)" ); imc_logout( ic, FALSE ); return; } if( ( s = strchr( jd->server, '/' ) ) ) { *s = 0; set_setstr( &acc->set, "resource", s + 1 ); /* Also remove the /resource from the original variable so we won't have to do this again every time. */ s = strchr( acc->user, '/' ); *s = 0; } jd->node_cache = g_hash_table_new_full( g_str_hash, g_str_equal, NULL, jabber_cache_entry_free ); jd->buddies = g_hash_table_new( g_str_hash, g_str_equal ); if( set_getbool( &acc->set, "oauth" ) ) { GSList *p_in = NULL; const char *tok; jd->fd = jd->r_inpa = jd->w_inpa = -1; if( strstr( jd->server, ".live.com" ) ) jd->oauth2_service = &oauth2_service_mslive; else if( strstr( jd->server, ".facebook.com" ) ) jd->oauth2_service = &oauth2_service_facebook; else jd->oauth2_service = &oauth2_service_google; oauth_params_parse( &p_in, ic->acc->pass ); /* First see if we have a refresh token, in which case any access token we *might* have has probably expired already anyway. */ if( ( tok = oauth_params_get( &p_in, "refresh_token" ) ) ) { sasl_oauth2_refresh( ic, tok ); } /* If we don't have a refresh token, let's hope the access token is still usable. */ else if( ( tok = oauth_params_get( &p_in, "access_token" ) ) ) { jd->oauth2_access_token = g_strdup( tok ); 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; } oauth_params_free( &p_in ); } else jabber_connect( ic ); }