Changeset da2efd4 for lib/oauth.c


Ignore:
Timestamp:
2010-04-25T18:57:06Z (10 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
346dfd9
Parents:
e9eaee6
Message:

Some HTTP stuff. Via gdb I can make this request a token.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/oauth.c

    re9eaee6 rda2efd4  
    2626#include <stdlib.h>
    2727#include <string.h>
     28#include "http_client.h"
    2829#include "base64.h"
    2930#include "misc.h"
    3031#include "sha1.h"
     32#include "url.h"
    3133
    3234#define CONSUMER_KEY "xsDNKJuNZYkZyMcu914uEA"
     
    3638#define HMAC_BLOCK_SIZE 64
    3739
    38 struct oauth_state
    39 {
     40struct oauth_info;
     41typedef void (*oauth_cb)( struct oauth_info * );
     42
     43struct oauth_info
     44{
     45        oauth_cb func;
     46        void *data;
     47       
     48        struct http_request *http;
     49       
     50        char *auth_params;
     51        char *token;
    4052};
    4153
     
    5264           otherwise just pad. */
    5365        memset( key, 0, HMAC_BLOCK_SIZE );
    54         i = strlen( CONSUMER_SECRET ) + 1 + token_secret ? strlen( token_secret ) : 0;
     66        i = strlen( CONSUMER_SECRET ) + 1 + ( token_secret ? strlen( token_secret ) : 0 );
    5567        if( i > HMAC_BLOCK_SIZE )
    5668        {
    5769                sha1_init( &sha1 );
    58                 sha1_append( &sha1, CONSUMER_SECRET, strlen( CONSUMER_SECRET ) );
    59                 sha1_append( &sha1, "&", 1 );
     70                sha1_append( &sha1, (uint8_t*) CONSUMER_SECRET, strlen( CONSUMER_SECRET ) );
     71                sha1_append( &sha1, (uint8_t*) "&", 1 );
    6072                if( token_secret )
    61                         sha1_append( &sha1, token_secret, strlen( token_secret ) );
     73                        sha1_append( &sha1, (uint8_t*) token_secret, strlen( token_secret ) );
    6274                sha1_finish( &sha1, key );
    6375        }
    6476        else
    6577        {
    66                 g_snprintf( key, HMAC_BLOCK_SIZE + 1, "%s&%s",
     78                g_snprintf( (gchar*) key, HMAC_BLOCK_SIZE + 1, "%s&%s",
    6779                            CONSUMER_SECRET, token_secret ? : "" );
    6880        }
     
    105117        return base64_encode( hash, sha1_hash_size );
    106118}
     119
     120static char *oauth_nonce()
     121{
     122        unsigned char bytes[9];
     123       
     124        random_bytes( bytes, sizeof( bytes ) );
     125        return base64_encode( bytes, sizeof( bytes ) );
     126}
     127
     128void oauth_params_add( GSList **params, const char *key, const char *value )
     129{
     130        char *item;
     131       
     132        item = g_strdup_printf( "%s=%s", key, value );
     133        *params = g_slist_insert_sorted( *params, item, (GCompareFunc) strcmp );
     134}
     135
     136void oauth_params_del( GSList **params, const char *key )
     137{
     138        int key_len = strlen( key );
     139        GSList *l, *n;
     140       
     141        for( l = *params; l; l = n )
     142        {
     143                n = l->next;
     144               
     145                if( strncmp( (char*) l->data, key, key_len ) == 0 &&
     146                    ((char*)l->data)[key_len] == '=' )
     147                {
     148                        g_free( l->data );
     149                        *params = g_slist_remove( *params, l );
     150                }
     151        }
     152}
     153
     154void oauth_params_set( GSList **params, const char *key, const char *value )
     155{
     156        oauth_params_del( params, key );
     157        oauth_params_add( params, key, value );
     158}
     159
     160const char *oauth_params_get( GSList **params, const char *key )
     161{
     162        int key_len = strlen( key );
     163        GSList *l;
     164       
     165        for( l = *params; l; l = l->next )
     166        {
     167                if( strncmp( (char*) l->data, key, key_len ) == 0 &&
     168                    ((char*)l->data)[key_len] == '=' )
     169                        return (const char*) l->data + key_len + 1;
     170        }
     171       
     172        return NULL;
     173}
     174
     175GSList *oauth_params_parse( char *in )
     176{
     177        GSList *ret = NULL;
     178        char *amp, *eq;
     179       
     180        while( in && *in )
     181        {
     182                eq = strchr( in, '=' );
     183                if( !eq )
     184                        break;
     185               
     186                *eq = '\0';
     187                if( ( amp = strchr( eq + 1, '&' ) ) )
     188                        *amp = '\0';
     189               
     190                oauth_params_add( &ret, in, eq + 1 );
     191               
     192                *eq = '=';
     193                if( amp == NULL )
     194                        break;
     195               
     196                *amp = '&';
     197                in = amp + 1;
     198        }
     199       
     200        return ret;
     201}
     202
     203void oauth_params_free( GSList **params )
     204{
     205        while( params && *params )
     206        {
     207                g_free( (*params)->data );
     208                *params = g_slist_remove( *params, (*params)->data );
     209        }
     210}
     211
     212char *oauth_params_string( GSList *params )
     213{
     214        GSList *l;
     215        GString *str = g_string_new( "" );
     216       
     217        for( l = params; l; l = l->next )
     218        {
     219                g_string_append( str, l->data );
     220                if( l->next )
     221                        g_string_append_c( str, '&' );
     222        }
     223       
     224        return g_string_free( str, FALSE );
     225}
     226
     227static void *oauth_post_request( const char *url, GSList **params_, http_input_function func, void *data )
     228{
     229        GSList *params = NULL;
     230        char *s, *params_s, *post;
     231        void *req;
     232        url_t url_p;
     233       
     234        if( !url_set( &url_p, url ) )
     235        {
     236                oauth_params_free( params_ );
     237                return NULL;
     238        }
     239       
     240        if( params_ )
     241                params = *params_;
     242       
     243        oauth_params_set( &params, "oauth_consumer_key", CONSUMER_KEY );
     244        oauth_params_set( &params, "oauth_signature_method", "HMAC-SHA1" );
     245       
     246        s = g_strdup_printf( "%d", (int) time( NULL ) );
     247        oauth_params_set( &params, "oauth_timestamp", s );
     248        g_free( s );
     249       
     250        s = oauth_nonce();
     251        oauth_params_set( &params, "oauth_nonce", s );
     252        g_free( s );
     253       
     254        oauth_params_set( &params, "oauth_version", "1.0" );
     255        oauth_params_set( &params, "oauth_callback", "oob" );
     256       
     257        params_s = oauth_params_string( params );
     258        oauth_params_free( params_ );
     259       
     260        s = oauth_sign( "POST", url, params_s, NULL );
     261        s = g_realloc( s, strlen( s ) * 3 + 1 );
     262        http_encode( s );
     263       
     264        post = g_strdup_printf( "%s&oauth_signature=%s", params_s, s );
     265        g_free( params_s );
     266        g_free( s );
     267       
     268        s = g_strdup_printf( "POST %s HTTP/1.0\r\n"
     269                             "Host: %s\r\n"
     270                             "Content-Type: application/x-www-form-urlencoded\r\n"
     271                             "Content-Length: %zd\r\n"
     272                             "\r\n"
     273                             "%s", url_p.file, url_p.host, strlen( post ), post );
     274        g_free( post );
     275       
     276        req = http_dorequest( url_p.host, url_p.port, url_p.proto == PROTO_HTTPS,
     277                              s, func, data );
     278        g_free( s );
     279       
     280        return req;
     281}
     282
     283void oauth_request_token_done( struct http_request *req );
     284
     285void *oauth_request_token( const char *url, oauth_cb func, void *data )
     286{
     287        struct oauth_info *st = g_new0( struct oauth_info, 1 );
     288       
     289        st->func = func;
     290        st->data = data;
     291       
     292        return oauth_post_request( url, NULL, oauth_request_token_done, st );
     293}
     294
     295void oauth_request_token_done( struct http_request *req )
     296{
     297        struct oauth_info *st = req->data;
     298       
     299        st->http = req;
     300       
     301        if( req->status_code == 200 )
     302        {
     303                GSList *params;
     304               
     305                st->auth_params = g_strdup( req->reply_body );
     306                params = oauth_params_parse( st->auth_params );
     307                st->token = g_strdup( oauth_params_get( &params, "oauth_token" ) );
     308                oauth_params_free( &params );
     309        }
     310       
     311        st->func( st );
     312}
Note: See TracChangeset for help on using the changeset viewer.