Changes in / [839189b:3b878a1]
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/oauth.c
r839189b r3b878a1 33 33 #include "oauth.h" 34 34 35 #define CONSUMER_KEY "xsDNKJuNZYkZyMcu914uEA"36 #define CONSUMER_SECRET "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo"37 /* How can it be a secret if it's right here in the source code? No clue... */38 39 35 #define HMAC_BLOCK_SIZE 64 40 36 41 37 static char *oauth_sign( const char *method, const char *url, 42 const char *params, const char *token_secret)38 const char *params, struct oauth_info *oi ) 43 39 { 44 40 sha1_state_t sha1; … … 51 47 otherwise just pad. */ 52 48 memset( key, 0, HMAC_BLOCK_SIZE ); 53 i = strlen( CONSUMER_SECRET ) + 1 + ( token_secret ? strlen(token_secret ) : 0 );49 i = strlen( oi->sp->consumer_secret ) + 1 + ( oi->token_secret ? strlen( oi->token_secret ) : 0 ); 54 50 if( i > HMAC_BLOCK_SIZE ) 55 51 { 56 52 sha1_init( &sha1 ); 57 sha1_append( &sha1, (uint8_t*) CONSUMER_SECRET, strlen( CONSUMER_SECRET) );53 sha1_append( &sha1, (uint8_t*) oi->sp->consumer_secret, strlen( oi->sp->consumer_secret ) ); 58 54 sha1_append( &sha1, (uint8_t*) "&", 1 ); 59 if( token_secret )60 sha1_append( &sha1, (uint8_t*) token_secret, strlen(token_secret ) );55 if( oi->token_secret ) 56 sha1_append( &sha1, (uint8_t*) oi->token_secret, strlen( oi->token_secret ) ); 61 57 sha1_finish( &sha1, key ); 62 58 } … … 64 60 { 65 61 g_snprintf( (gchar*) key, HMAC_BLOCK_SIZE + 1, "%s&%s", 66 CONSUMER_SECRET,token_secret ? : "" );62 oi->sp->consumer_secret, oi->token_secret ? : "" ); 67 63 } 68 64 … … 229 225 if( info ) 230 226 { 231 g_free( info->auth_ params);227 g_free( info->auth_url ); 232 228 g_free( info->request_token ); 233 g_free( info->access_token ); 229 g_free( info->token ); 230 g_free( info->token_secret ); 234 231 g_free( info ); 235 232 } 236 233 } 237 234 238 static void oauth_add_default_params( GSList **params )235 static void oauth_add_default_params( GSList **params, const struct oauth_service *sp ) 239 236 { 240 237 char *s; 241 238 242 oauth_params_set( params, "oauth_consumer_key", CONSUMER_KEY);239 oauth_params_set( params, "oauth_consumer_key", sp->consumer_key ); 243 240 oauth_params_set( params, "oauth_signature_method", "HMAC-SHA1" ); 244 241 … … 254 251 } 255 252 256 static void *oauth_post_request( const char *url, GSList **params_, http_input_function func, void *data)253 static void *oauth_post_request( const char *url, GSList **params_, http_input_function func, struct oauth_info *oi ) 257 254 { 258 255 GSList *params = NULL; … … 270 267 params = *params_; 271 268 272 oauth_add_default_params( ¶ms );269 oauth_add_default_params( ¶ms, oi->sp ); 273 270 274 271 params_s = oauth_params_string( params ); 275 272 oauth_params_free( ¶ms ); 276 273 277 s = oauth_sign( "POST", url, params_s, NULL);274 s = oauth_sign( "POST", url, params_s, oi ); 278 275 post = g_strdup_printf( "%s&oauth_signature=%s", params_s, s ); 279 276 g_free( params_s ); … … 289 286 290 287 req = http_dorequest( url_p.host, url_p.port, url_p.proto == PROTO_HTTPS, 291 s, func, data);288 s, func, oi ); 292 289 g_free( s ); 293 290 … … 297 294 static void oauth_request_token_done( struct http_request *req ); 298 295 299 struct oauth_info *oauth_request_token( const char *url, oauth_cb func, void *data )296 struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data ) 300 297 { 301 298 struct oauth_info *st = g_new0( struct oauth_info, 1 ); … … 304 301 st->func = func; 305 302 st->data = data; 303 st->sp = sp; 306 304 307 305 oauth_params_add( ¶ms, "oauth_callback", "oob" ); 308 306 309 if( !oauth_post_request( url, ¶ms, oauth_request_token_done, st ) )307 if( !oauth_post_request( sp->url_request_token, ¶ms, oauth_request_token_done, st ) ) 310 308 { 311 309 oauth_info_free( st ); … … 326 324 GSList *params = NULL; 327 325 328 st->auth_ params = g_strdup(req->reply_body );329 oauth_params_parse( ¶ms, st->auth_params);326 st->auth_url = g_strdup_printf( "%s?%s", st->sp->url_authorize, req->reply_body ); 327 oauth_params_parse( ¶ms, req->reply_body ); 330 328 st->request_token = g_strdup( oauth_params_get( ¶ms, "oauth_token" ) ); 331 329 oauth_params_free( ¶ms ); … … 333 331 334 332 st->stage = OAUTH_REQUEST_TOKEN; 335 if( !st->func( st ) ) 336 oauth_info_free( st ); 333 st->func( st ); 337 334 } 338 335 339 336 static void oauth_access_token_done( struct http_request *req ); 340 337 341 void oauth_access_token( const char *url,const char *pin, struct oauth_info *st )338 gboolean oauth_access_token( const char *pin, struct oauth_info *st ) 342 339 { 343 340 GSList *params = NULL; … … 346 343 oauth_params_add( ¶ms, "oauth_verifier", pin ); 347 344 348 if( !oauth_post_request( url, ¶ms, oauth_access_token_done, st ) ) 349 oauth_info_free( st ); 345 return oauth_post_request( st->sp->url_access_token, ¶ms, oauth_access_token_done, st ) != NULL; 350 346 } 351 347 … … 359 355 { 360 356 GSList *params = NULL; 361 const char *token, *token_secret;362 357 363 358 oauth_params_parse( ¶ms, req->reply_body ); 364 token = oauth_params_get( ¶ms, "oauth_token" ); 365 token_secret = oauth_params_get( ¶ms, "oauth_token_secret" ); 366 st->access_token = g_strdup_printf( 367 "oauth_token=%s&oauth_token_secret=%s", token, token_secret ); 359 st->token = g_strdup( oauth_params_get( ¶ms, "oauth_token" ) ); 360 st->token_secret = g_strdup( oauth_params_get( ¶ms, "oauth_token_secret" ) ); 368 361 oauth_params_free( ¶ms ); 369 362 } 370 363 371 364 st->stage = OAUTH_ACCESS_TOKEN; 372 st->func( st ); 373 oauth_info_free( st ); 374 } 375 376 char *oauth_http_header( char *access_token, const char *method, const char *url, char *args ) 365 if( st->func( st ) ) 366 { 367 /* Don't need these anymore, but keep the rest. */ 368 g_free( st->auth_url ); 369 st->auth_url = NULL; 370 g_free( st->request_token ); 371 st->request_token = NULL; 372 } 373 } 374 375 char *oauth_http_header( struct oauth_info *oi, const char *method, const char *url, char *args ) 377 376 { 378 377 GSList *params = NULL, *l; 379 char * token_secret = NULL, *sig = NULL, *params_s, *s;378 char *sig = NULL, *params_s, *s; 380 379 GString *ret = NULL; 381 380 382 /* First, get the two pieces of info from the access token that we need. */ 383 oauth_params_parse( ¶ms, access_token ); 384 if( params == NULL ) 385 goto err; 386 387 /* Pick out the token secret, we shouldn't include it but use it for signing. */ 388 token_secret = g_strdup( oauth_params_get( ¶ms, "oauth_token_secret" ) ); 389 if( token_secret == NULL ) 390 goto err; 391 oauth_params_del( ¶ms, "oauth_token_secret" ); 392 393 oauth_add_default_params( ¶ms ); 381 oauth_params_add( ¶ms, "oauth_token", oi->token ); 382 oauth_add_default_params( ¶ms, oi->sp ); 394 383 395 384 /* Start building the OAuth header. 'key="value", '... */ … … 421 410 { 422 411 s = g_strdup( s + 1 ); 423 oauth_params_parse( ¶ms, s + 1);412 oauth_params_parse( ¶ms, s ); 424 413 g_free( s ); 425 414 } … … 427 416 /* Append the signature and we're done! */ 428 417 params_s = oauth_params_string( params ); 429 sig = oauth_sign( method, url, params_s, token_secret);418 sig = oauth_sign( method, url, params_s, oi ); 430 419 g_string_append_printf( ret, "oauth_signature=\"%s\"", sig ); 431 420 g_free( params_s ); 432 421 433 err:434 422 oauth_params_free( ¶ms ); 435 423 g_free( sig ); 436 g_free( token_secret );437 424 438 425 return ret ? g_string_free( ret, FALSE ) : NULL; 439 426 } 427 428 char *oauth_to_string( struct oauth_info *oi ) 429 { 430 GSList *params = NULL; 431 char *ret; 432 433 oauth_params_add( ¶ms, "oauth_token", oi->token ); 434 oauth_params_add( ¶ms, "oauth_token_secret", oi->token_secret ); 435 ret = oauth_params_string( params ); 436 oauth_params_free( ¶ms ); 437 438 return ret; 439 } 440 441 struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp ) 442 { 443 struct oauth_info *oi = g_new0( struct oauth_info, 1 ); 444 GSList *params = NULL; 445 446 oauth_params_parse( ¶ms, in ); 447 oi->token = g_strdup( oauth_params_get( ¶ms, "oauth_token" ) ); 448 oi->token_secret = g_strdup( oauth_params_get( ¶ms, "oauth_token_secret" ) ); 449 oauth_params_free( ¶ms ); 450 oi->sp = sp; 451 452 return oi; 453 } -
lib/oauth.h
r839189b r3b878a1 40 40 { 41 41 oauth_stage_t stage; 42 const struct oauth_service *sp; 42 43 43 44 oauth_cb func; … … 46 47 struct http_request *http; 47 48 48 char *auth_ params;49 char *auth_url; 49 50 char *request_token; 50 51 51 char *access_token; 52 char *token; 53 char *token_secret; 54 }; 55 56 struct oauth_service 57 { 58 char *url_request_token; 59 char *url_access_token; 60 char *url_authorize; 61 62 char *consumer_key; 63 char *consumer_secret; 52 64 }; 53 65 … … 56 68 authorization URL for the user. This is passed to the callback function 57 69 in a struct oauth_info. */ 58 struct oauth_info *oauth_request_token( const char *url, oauth_cb func, void *data );70 struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data ); 59 71 60 72 /* http://oauth.net/core/1.0a/#auth_step3 (section 6.3) … … 62 74 token. This is passed to the callback function in the same 63 75 struct oauth_info. */ 64 void oauth_access_token( const char *url,const char *pin, struct oauth_info *st );76 gboolean oauth_access_token( const char *pin, struct oauth_info *st ); 65 77 66 78 /* http://oauth.net/core/1.0a/#anchor12 (section 7) … … 69 81 whatever's going to be in the POST body of the request. GET args will 70 82 automatically be grabbed from url. */ 71 char *oauth_http_header( char *access_token, const char *method, const char *url, char *args );83 char *oauth_http_header( struct oauth_info *oi, const char *method, const char *url, char *args ); 72 84 73 85 /* Shouldn't normally be required unless the process is aborted by the user. */ 74 86 void oauth_info_free( struct oauth_info *info ); 87 88 /* Convert to and back from strings, for easier saving. */ 89 char *oauth_to_string( struct oauth_info *oi ); 90 struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp ); -
protocols/twitter/twitter.c
r839189b r3b878a1 28 28 #include "twitter_lib.h" 29 29 30 31 30 /** 32 31 * Main loop function … … 66 65 } 67 66 67 68 static const struct oauth_service twitter_oauth = 69 { 70 "http://api.twitter.com/oauth/request_token", 71 "http://api.twitter.com/oauth/access_token", 72 "http://api.twitter.com/oauth/authorize", 73 .consumer_key = "xsDNKJuNZYkZyMcu914uEA", 74 .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo", 75 }; 76 68 77 static gboolean twitter_oauth_callback( struct oauth_info *info ); 69 78 … … 74 83 imcb_log( ic, "Requesting OAuth request token" ); 75 84 76 td->oauth_info = oauth_request_token( 77 TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); 85 td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic ); 78 86 } 79 87 … … 100 108 sprintf( name, "twitter_%s", ic->acc->user ); 101 109 msg = g_strdup_printf( "To finish OAuth authentication, please visit " 102 "%s ?%sand respond with the resulting PIN code.",103 TWITTER_OAUTH_AUTHORIZE, info->auth_params);110 "%s and respond with the resulting PIN code.", 111 info->auth_url ); 104 112 imcb_buddy_msg( ic, name, msg, 0, 0 ); 105 113 g_free( msg ); … … 107 115 else if( info->stage == OAUTH_ACCESS_TOKEN ) 108 116 { 109 if( info-> access_token== NULL )117 if( info->token == NULL || info->token_secret == NULL ) 110 118 { 111 119 imcb_error( ic, "OAuth error: %s", info->http->status_string ); … … 114 122 } 115 123 116 td->oauth = g_strdup( info->access_token );117 118 124 /* IM mods didn't do this so far and it's ugly but I should 119 125 be able to get away with it... */ 120 126 g_free( ic->acc->pass ); 121 ic->acc->pass = g_strdup( info->access_token);127 ic->acc->pass = oauth_to_string( info ); 122 128 123 129 twitter_main_loop_start( ic ); … … 126 132 return TRUE; 127 133 } 134 128 135 129 136 static char *set_eval_mode( set_t *set, char *value ) … … 165 172 td->pass = g_strdup( acc->pass ); 166 173 else if( strstr( acc->pass, "oauth_token=" ) ) 167 td->oauth = g_strdup( acc->pass);174 td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth ); 168 175 td->home_timeline_id = 0; 169 176 … … 172 179 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 173 180 174 if( td->pass || td->oauth )181 if( td->pass || td->oauth_info ) 175 182 twitter_main_loop_start( ic ); 176 183 else … … 197 204 { 198 205 oauth_info_free( td->oauth_info ); 199 200 206 g_free( td->pass ); 201 g_free( td->oauth );202 207 g_free( td ); 203 208 } … … 216 221 g_strcasecmp(who + 8, ic->acc->user) == 0) 217 222 { 218 if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth_info ) 223 if( set_getbool( &ic->acc->set, "oauth" ) && 224 td->oauth_info && td->oauth_info->token == NULL ) 219 225 { 220 oauth_access_token( TWITTER_OAUTH_ACCESS_TOKEN, message, td->oauth_info ); 221 td->oauth_info = NULL; 226 if( !oauth_access_token( message, td->oauth_info ) ) 227 { 228 imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); 229 imc_logout( ic, TRUE ); 230 return FALSE; 231 } 222 232 } 223 233 else -
protocols/twitter/twitter.h
r839189b r3b878a1 37 37 char* user; 38 38 char* pass; 39 char* oauth;40 39 struct oauth_info *oauth_info; 41 40 guint64 home_timeline_id; … … 52 51 GSList *twitter_connections; 53 52 54 #define TWITTER_OAUTH_REQUEST_TOKEN "http://api.twitter.com/oauth/request_token"55 #define TWITTER_OAUTH_ACCESS_TOKEN "http://api.twitter.com/oauth/access_token"56 #define TWITTER_OAUTH_AUTHORIZE "http://api.twitter.com/oauth/authorize"57 58 53 #endif //_TWITTER_H -
protocols/twitter/twitter_http.c
r839189b r3b878a1 29 29 ****************************************************************************/ 30 30 31 #include "twitter_http.h"32 31 #include "twitter.h" 33 32 #include "bitlbee.h" … … 39 38 #include <errno.h> 40 39 40 #include "twitter_http.h" 41 41 42 42 43 char *twitter_url_append(char *url, char *key, char* value); … … 46 47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c 47 48 */ 48 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* oauth_token, char** arguments, int arguments_len)49 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, struct oauth_info* oi, char** arguments, int arguments_len) 49 50 { 50 51 url_t *url = g_new0( url_t, 1 ); … … 111 112 112 113 // If a pass and user are given we append them to the request. 113 if (o auth_token)114 if (oi) 114 115 { 115 116 char *full_header; 116 117 117 full_header = oauth_http_header(oauth_token, 118 is_post ? "POST" : "GET", 118 full_header = oauth_http_header(oi, is_post ? "POST" : "GET", 119 119 url_string, url_arguments); 120 120 -
protocols/twitter/twitter_http.h
r839189b r3b878a1 28 28 #include "http_client.h" 29 29 30 struct oauth_info; 31 30 32 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, 31 char* user, char* pass, char *oauth_token, char** arguments, int arguments_len);33 char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len); 32 34 33 35 #endif //_TWITTER_HTTP_H -
protocols/twitter/twitter_lib.c
r839189b r3b878a1 130 130 args[0] = "cursor"; 131 131 args[1] = g_strdup_printf ("%d", next_cursor); 132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth , args, 2);132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 133 133 134 134 g_free(args[1]); … … 396 396 } 397 397 398 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth , args, td->home_timeline_id ? 4 : 2);398 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth_info, args, td->home_timeline_id ? 4 : 2); 399 399 400 400 g_free(args[1]); … … 510 510 { 511 511 td->http_fails = 0; 512 if (! ic->flags & OPT_LOGGED_IN)512 if (!(ic->flags & OPT_LOGGED_IN)) 513 513 imcb_connected(ic); 514 514 } … … 620 620 args[1] = g_strdup_printf ("%d", next_cursor); 621 621 622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth , args, 2);622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 623 623 624 624 g_free(args[1]); … … 654 654 args[0] = "status"; 655 655 args[1] = msg; 656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth , args, 2);656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2); 657 657 // g_free(args[1]); 658 658 } … … 672 672 args[3] = msg; 673 673 // Use the same callback as for twitter_post_status, since it does basically the same. 674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth , args, 4);674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4); 675 675 // g_free(args[1]); 676 676 // g_free(args[3]);
Note: See TracChangeset
for help on using the changeset viewer.