Changeset 18c6d36


Ignore:
Timestamp:
2011-12-18T19:25:44Z (13 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
64b6635
Parents:
6e9ae72
Message:

More generic OAuth support now. Should work well for all GTalk accounts now
and somewhat for MS Messenger. The fb part needs different parsing of the
authorize request, and possibly some other work.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • lib/oauth2.c

    r6e9ae72 r18c6d36  
    2828#include "url.h"
    2929
    30 struct oauth2_service oauth2_service_google =
    31 {
    32         "https://accounts.google.com/o/oauth2/auth",
    33         "https://accounts.google.com/o/oauth2/token",
    34         "urn:ietf:wg:oauth:2.0:oob",
    35         "783993391592.apps.googleusercontent.com",
    36         "6C-Zgf7Tr7gEQTPlBhMUgo7R",
    37 };
    38 struct oauth2_service oauth2_service_facebook =
    39 {
    40         "https://www.facebook.com/dialog/oauth",
    41         "https://graph.facebook.com/oauth/access_token",
    42         "http://www.bitlbee.org/main.php/fb.html",
    43         "126828914005625",
    44         "4b100f0f244d620bf3f15f8b217d4c32",
    45 };
    46 
    47 char *oauth2_url( const struct oauth2_service *sp, const char *scope )
     30char *oauth2_url( const struct oauth2_service *sp )
    4831{
    4932        return g_strconcat( sp->auth_url,
    50                             "?scope=", scope,
     33                            "?scope=", sp->scope,
    5134                            "&response_type=code"
    5235                            "&redirect_uri=", sp->redirect_url,
     
    121104        char *atoken = NULL, *rtoken = NULL;
    122105       
     106        if( getenv( "BITLBEE_DEBUG" ) && req->reply_body )
     107                printf( "%s\n", req->reply_body );
     108       
    123109        if( req->status_code == 200 )
    124110        {
    125111                atoken = oauth2_json_dumb_get( req->reply_body, "access_token" );
    126112                rtoken = oauth2_json_dumb_get( req->reply_body, "refresh_token" );
     113                if( getenv( "BITLBEE_DEBUG" ) )
     114                        printf( "Extracted atoken=%s rtoken=%s\n", atoken, rtoken );
    127115        }
    128116        cb_data->func( cb_data->data, atoken, rtoken );
  • lib/oauth2.h

    r6e9ae72 r18c6d36  
    3232        char *token_url;
    3333        char *redirect_url;
     34        char *scope;
    3435        char *consumer_key;
    3536        char *consumer_secret;
    3637};
    37 
    38 /* Currently suitable for authenticating to Google Talk only, and only for
    39    accounts that have 2-factor authorization enabled. */
    40 extern struct oauth2_service oauth2_service_google;
    41 
    42 extern struct oauth2_service oauth2_service_facebook;
    4338
    4439#define OAUTH2_AUTH_CODE "authorization_code"
     
    4742/* Generate a URL the user should open in his/her browser to get an
    4843   authorization code. */
    49 char *oauth2_url( const struct oauth2_service *sp, const char *scope );
     44char *oauth2_url( const struct oauth2_service *sp );
    5045
    5146/* Exchanges an auth code or refresh token for an access token.
  • protocols/jabber/jabber.c

    r6e9ae72 r18c6d36  
    144144        {
    145145                jd->fd = jd->r_inpa = jd->w_inpa = -1;
     146               
     147                if( strstr( jd->server, ".live.com" ) )
     148                        jd->oauth2_service = &oauth2_service_mslive;
     149                else if( strstr( jd->server, ".facebook.com" ) )
     150                        jd->oauth2_service = &oauth2_service_facebook;
     151                else
     152                        jd->oauth2_service = &oauth2_service_google;
    146153               
    147154                /* For the first login with OAuth, we have to authenticate via the browser.
  • protocols/jabber/jabber.h

    r6e9ae72 r18c6d36  
    9595        char *server;           /* username@SERVER -=> server/domain, not hostname */
    9696       
     97        const struct oauth2_service *oauth2_service;
    9798        char *oauth2_access_token;
    9899       
     
    327328int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token );
    328329
     330extern const struct oauth2_service oauth2_service_google;
     331extern const struct oauth2_service oauth2_service_facebook;
     332extern const struct oauth2_service oauth2_service_mslive;
     333
    329334/* conference.c */
    330335struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password );
  • protocols/jabber/sasl.c

    r6e9ae72 r18c6d36  
    2929#include "oauth.h"
    3030
     31const struct oauth2_service oauth2_service_google =
     32{
     33        "https://accounts.google.com/o/oauth2/auth",
     34        "https://accounts.google.com/o/oauth2/token",
     35        "urn:ietf:wg:oauth:2.0:oob",
     36        "https://www.googleapis.com/auth/googletalk",
     37        "783993391592.apps.googleusercontent.com",
     38        "6C-Zgf7Tr7gEQTPlBhMUgo7R",
     39};
     40const struct oauth2_service oauth2_service_facebook =
     41{
     42        "https://www.facebook.com/dialog/oauth",
     43        "https://graph.facebook.com/oauth/access_token",
     44        "http://www.bitlbee.org/main.php/Facebook/oauth2.html",
     45        "offline_access,xmpp_login",
     46        "126828914005625",
     47        "4b100f0f244d620bf3f15f8b217d4c32",
     48};
     49const struct oauth2_service oauth2_service_mslive =
     50{
     51        "https://oauth.live.com/authorize",
     52        "https://oauth.live.com/token",
     53        "http://www.bitlbee.org/main.php/Messenger/oauth2.html",
     54        "wl.messenger",
     55        "000000004C06FCD1",
     56        "IRKlBPzJJAWcY-TbZjiTEJu9tn7XCFaV",
     57};
     58
    3159xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
    3260{
     
    3563        struct xt_node *c, *reply;
    3664        char *s;
    37         int sup_plain = 0, sup_digest = 0, sup_oauth2 = 0, sup_fb = 0;
     65        int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0, sup_ms = 0;
     66        int want_oauth = FALSE;
    3867       
    3968        if( !sasl_supported( ic ) )
     
    6291                        sup_digest = 1;
    6392                if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
    64                         sup_oauth2 = 1;
     93                        sup_gtalk = 1;
    6594                if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
    6695                        sup_fb = 1;
     96                if( c->text && g_strcasecmp( c->text, "X-MESSENGER-OAUTH2" ) == 0 )
     97                        sup_ms = 1;
    6798               
    6899                c = c->next;
    69100        }
    70101       
    71         if( !sup_plain && !sup_digest )
     102        if( !sup_plain && !sup_digest && !sup_gtalk && !sup_fb && !sup_ms )
    72103        {
    73104                imcb_error( ic, "No known SASL authentication schemes supported" );
     
    78109        reply = xt_new_node( "auth", NULL, NULL );
    79110        xt_add_attr( reply, "xmlns", XMLNS_SASL );
    80        
    81         if( set_getbool( &ic->acc->set, "oauth" ) )
     111        want_oauth = set_getbool( &ic->acc->set, "oauth" );
     112       
     113        if( sup_gtalk && want_oauth )
    82114        {
    83115                int len;
    84                
    85                 if( !sup_oauth2 )
    86                 {
    87                         imcb_error( ic, "OAuth requested, but not supported by server" );
    88                         imc_logout( ic, FALSE );
    89                         xt_free_node( reply );
    90                         return XT_ABORT;
    91                 }
    92116               
    93117                /* X-OAUTH2 is, not *the* standard OAuth2 SASL/XMPP implementation.
     
    105129                g_free( s );
    106130        }
    107         else if( sup_fb && strstr( ic->acc->pass, "session_key=" ) )
     131        else if( sup_ms && want_oauth )
     132        {
     133                xt_add_attr( reply, "mechanism", "X-MESSENGER-OAUTH2" );
     134                reply->text = g_strdup( jd->oauth2_access_token );
     135                reply->text_len = strlen( jd->oauth2_access_token );
     136        }
     137        else if( sup_fb && want_oauth && strstr( ic->acc->pass, "session_key=" ) )
    108138        {
    109139                xt_add_attr( reply, "mechanism", "X-FACEBOOK-PLATFORM" );
    110140                jd->flags |= JFLAG_SASL_FB;
     141        }
     142        else if( want_oauth )
     143        {
     144                imcb_error( ic, "OAuth requested, but not supported by server" );
     145                imc_logout( ic, FALSE );
     146                xt_free_node( reply );
     147                return XT_ABORT;
    111148        }
    112149        else if( sup_digest )
     
    428465void sasl_oauth2_init( struct im_connection *ic )
    429466{
     467        struct jabber_data *jd = ic->proto_data;
    430468        char *msg, *url;
    431469       
     
    434472        /* Temporary contact, just used to receive the OAuth response. */
    435473        imcb_add_buddy( ic, "jabber_oauth", NULL );
    436         url = oauth2_url( &oauth2_service_google,
    437                           "https://www.googleapis.com/auth/googletalk" );
     474        url = oauth2_url( jd->oauth2_service );
    438475        msg = g_strdup_printf( "Open this URL in your browser to authenticate: %s", url );
    439476        imcb_buddy_msg( ic, "jabber_oauth", msg, 0, 0 );
     
    457494int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg )
    458495{
     496        struct jabber_data *jd = ic->proto_data;
    459497        char *code;
    460498        int ret;
     
    468506        code = g_strdup( msg );
    469507        g_strstrip( code );
    470         ret = oauth2_access_token( &oauth2_service_google, OAUTH2_AUTH_CODE,
     508        ret = oauth2_access_token( jd->oauth2_service, OAUTH2_AUTH_CODE,
    471509                                   code, sasl_oauth2_got_token, ic );
    472510       
     
    477515int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token )
    478516{
    479         return oauth2_access_token( &oauth2_service_google, OAUTH2_AUTH_REFRESH,
     517        struct jabber_data *jd = ic->proto_data;
     518       
     519        return oauth2_access_token( jd->oauth2_service, OAUTH2_AUTH_REFRESH,
    480520                                    refresh_token, sasl_oauth2_got_token, ic );
    481521}
Note: See TracChangeset for help on using the changeset viewer.