Changeset c153808


Ignore:
Timestamp:
2013-05-25T10:36:34Z (12 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
420ddc00
Parents:
be9f3f1
Message:

Fix OAuth2 error reporting.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • lib/oauth2.c

    rbe9f3f1 rc153808  
    22*                                                                           *
    33*  BitlBee - An IRC to IM gateway                                           *
    4 *  Simple OAuth client (consumer) implementation.                           *
     4*  Simple OAuth2 client (consumer) implementation.                          *
    55*                                                                           *
    6 *  Copyright 2010-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
     6*  Copyright 2010-2013 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    2222\***************************************************************************/
    2323
     24/* Out of protest, I should rename this file. OAuth2 is a pathetic joke, and
     25   of all things, DEFINITELY NOT A STANDARD. The only thing various OAuth2
     26   implementations have in common is that name, wrongfully stolen from
     27   a pretty nice standard called OAuth 1.0a. That, and the fact that they
     28   use JSON. Wait, no, Facebook's version doesn't use JSON. For some of its
     29   responses.
     30   
     31   Apparently too many people were too retarded to comprehend the elementary
     32   bits of crypto in OAuth 1.0a (took me one afternoon to implement) so
     33   the standard was replaced with what comes down to a complicated scheme
     34   around what's really just application-specific passwords.
     35   
     36   And then a bunch of mostly incompatible implementations. Great work, guys.
     37   
     38   http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ */
     39
    2440#include <glib.h>
    2541#include "http_client.h"
     
    2743#include "oauth.h"
    2844#include "json.h"
     45#include "json_util.h"
    2946#include "url.h"
    3047
     
    99116}
    100117
     118static char* oauth2_parse_error( json_value *e )
     119{
     120        /* This does a reasonable job with some of the flavours of error
     121           responses I've seen. Because apparently it's not standardised. */
     122       
     123        if( e->type == json_object )
     124        {
     125                /* Facebook style */
     126                const char *msg = json_o_str( e, "message" );
     127                const char *type = json_o_str( e, "type" );
     128                json_value *code_o = json_o_get( e, "code" );
     129                int code = 0;
     130               
     131                if( code_o && code_o->type == json_integer )
     132                        code = code_o->u.integer;
     133               
     134                return g_strdup_printf( "Error %d: %s", code, msg ? msg : type ? type : "Unknown error" );
     135        }
     136        else if( e->type == json_string )
     137        {
     138                return g_strdup( e->u.string.ptr );
     139        }
     140        return NULL;
     141}
     142
    101143static void oauth2_access_token_done( struct http_request *req )
    102144{
    103145        struct oauth2_access_token_data *cb_data = req->data;
    104         char *atoken = NULL, *rtoken = NULL;
     146        char *atoken = NULL, *rtoken = NULL, *error = NULL;
    105147        char *content_type;
    106148       
     
    110152        content_type = get_rfc822_header( req->reply_headers, "Content-Type", 0 );
    111153       
    112         if( req->status_code != 200 )
    113         {
    114         }
    115         else if( content_type && strstr( content_type, "application/json" ) )
     154        if( content_type && ( strstr( content_type, "application/json" ) ||
     155                              strstr( content_type, "text/javascript" ) ) )
    116156        {
    117157                json_value *js = json_parse( req->reply_body );
    118158                if( js && js->type == json_object )
    119159                {
    120                         int i;
    121                        
    122                         for( i = 0; i < js->u.object.length; i ++ )
     160                        JSON_O_FOREACH( js, k, v )
    123161                        {
    124                                 if( js->u.object.values[i].value->type != json_string )
     162                                if( strcmp( k, "error" ) == 0 )
     163                                        error = oauth2_parse_error( v );
     164                                if( v->type != json_string )
    125165                                        continue;
    126                                 if( strcmp( js->u.object.values[i].name, "access_token" ) == 0 )
    127                                         atoken = g_strdup( js->u.object.values[i].value->u.string.ptr );
    128                                 if( strcmp( js->u.object.values[i].name, "refresh_token" ) == 0 )
    129                                         rtoken = g_strdup( js->u.object.values[i].value->u.string.ptr );
     166                                if( strcmp( k, "access_token" ) == 0 )
     167                                        atoken = g_strdup( v->u.string.ptr );
     168                                if( strcmp( k, "refresh_token" ) == 0 )
     169                                        rtoken = g_strdup( v->u.string.ptr );
    130170                        }
    131171                }
     
    144184        if( getenv( "BITLBEE_DEBUG" ) )
    145185                printf( "Extracted atoken=%s rtoken=%s\n", atoken, rtoken );
     186        if( !atoken && !rtoken && !error )
     187                error = g_strdup( "Unusuable response" );
    146188       
    147         cb_data->func( cb_data->data, atoken, rtoken );
     189        cb_data->func( cb_data->data, atoken, rtoken, error );
    148190        g_free( content_type );
    149191        g_free( atoken );
    150192        g_free( rtoken );
     193        g_free( error );
    151194        g_free( cb_data );
    152195}
  • lib/oauth2.h

    rbe9f3f1 rc153808  
    44*  Simple OAuth2 client (consumer) implementation.                          *
    55*                                                                           *
    6 *  Copyright 2010-2011 Wilmer van der Gaast <wilmer@gaast.net>              *
     6*  Copyright 2010-2013 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    2525   module, and from http://code.google.com/apis/accounts/docs/OAuth2.html . */
    2626
    27 typedef void (*oauth2_token_callback)( gpointer data, const char *atoken, const char *rtoken );
     27typedef void (*oauth2_token_callback)( gpointer data, const char *atoken,
     28                                       const char *rtoken, const char *error );
    2829
    2930struct oauth2_service
  • protocols/jabber/sasl.c

    rbe9f3f1 rc153808  
    483483}
    484484
    485 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token );
     485static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error );
    486486
    487487int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg )
     
    514514}
    515515
    516 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token )
     516static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error )
    517517{
    518518        struct im_connection *ic = data;
     
    527527        if( access_token == NULL )
    528528        {
    529                 imcb_error( ic, "OAuth failure (missing access token)" );
     529                imcb_error( ic, "OAuth failure (%s)", error );
    530530                imc_logout( ic, TRUE );
    531531                return;
Note: See TracChangeset for help on using the changeset viewer.