~ubuntu-branches/debian/sid/flickcurl/sid

« back to all changes in this revision

Viewing changes to src/oauth.c

  • Committer: Package Import Robot
  • Author(s): Kumar Appaiah
  • Date: 2013-05-20 21:15:09 UTC
  • mfrom: (1.4.1) (15.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130520211509-e701o5dlwa04aqiw
Tags: 1.24-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 * oauth.c - OAuth 1.0 for Flickr
4
4
 *
5
 
 * Copyright (C) 2011, David Beckett http://www.dajobe.org/
 
5
 * Copyright (C) 2011-2012, David Beckett http://www.dajobe.org/
6
6
 * 
7
7
 * This file is licensed under the following three licenses as alternatives:
8
8
 *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
169
169
  
170
170
  if(od->data)
171
171
    free(od->data);
 
172
 
 
173
  if(od->username)
 
174
    free(od->username);
 
175
  
 
176
  if(od->user_nsid)
 
177
    free(od->user_nsid);
 
178
 
172
179
}
173
180
 
174
181
 
200
207
  else
201
208
    od->key_len += od->token_secret_len;
202
209
 
203
 
  od->key = malloc(od->key_len + 1); /* for NUL */
 
210
  od->key = (unsigned char*)malloc(od->key_len + 1); /* for NUL */
204
211
  if(!od->key)
205
212
    return 1;
206
213
  
258
265
 
259
266
 
260
267
static void
261
 
flickcurl_sort_args(flickcurl *fc, const char *parameters[][2], int count)
 
268
flickcurl_sort_args(flickcurl *fc)
262
269
{
263
 
  qsort((void*)parameters, count, sizeof(char*[2]), compare_args);
 
270
  qsort((void*)fc->parameters, fc->count, sizeof(char*[2]), compare_args);
264
271
}
265
272
 
266
273
 
276
283
                               const char* method,
277
284
                               const char* upload_field,
278
285
                               const char* upload_value,
279
 
                               const char* parameters[][2], int count,
280
286
                               int parameters_in_url, int need_auth)
281
287
{
282
288
  flickcurl_oauth_data* od = &fc->od;
284
290
  char *signature_string = NULL;
285
291
  size_t* values_len = NULL;
286
292
  unsigned int fc_uri_len = 0;
 
293
  unsigned int full_uri_len = 0;
287
294
  char* nonce = NULL;
288
295
  int free_nonce = 0;
289
296
  char* timestamp = NULL;
290
297
  int rc = 0;
291
298
  int need_to_add_query = 0;
292
 
  const char* http_method = "GET";
293
299
  int is_oauth_method = 0;
 
300
  char *p;
294
301
 
295
 
  if(!url || !parameters)
 
302
  if(!url)
296
303
    return 1;
297
304
  
298
305
  /* If one is given, both are required */
337
344
  
338
345
  if(fc->method)
339
346
    free(fc->method);
340
 
  if(method) {
341
 
    fc->method = strdup(method);
 
347
  if(method) { 
 
348
    size_t len = strlen(method);
 
349
    fc->method = (char*)malloc(len + 1);
 
350
    memcpy(fc->method, method, len + 1);
342
351
    is_oauth_method = !strncmp(method, "flickr.oauth.", 13);
343
352
  } else
344
353
    fc->method = NULL;
357
366
   * oauth_token            access token or request token
358
367
   */
359
368
 
360
 
  if(fc->method && !is_oauth_method) {
361
 
    parameters[count][0]  = "method";
362
 
    parameters[count++][1]= fc->method;
363
 
  }
 
369
  if(fc->method && !is_oauth_method)
 
370
    flickcurl_add_param(fc, "method", fc->method);
364
371
 
365
 
  if(od->callback) {
366
 
    parameters[count][0]  = "oauth_callback";
367
 
    parameters[count++][1]= od->callback;
368
 
  }
 
372
  if(od->callback)
 
373
    flickcurl_add_param(fc, "oauth_callback", od->callback);
369
374
  
370
 
  parameters[count][0]  = "oauth_consumer_key";
371
 
  parameters[count++][1]= od->client_key;
 
375
  flickcurl_add_param(fc, "oauth_consumer_key", od->client_key);
372
376
 
373
377
  nonce = (char*)od->nonce;
374
378
  if(!nonce) {
376
380
    free_nonce = 1;
377
381
    sprintf(nonce, "%ld", mtwist_u32rand(fc->mt));
378
382
  }
379
 
  parameters[count][0]  = "oauth_nonce";
380
 
  parameters[count++][1]= nonce;
 
383
  flickcurl_add_param(fc, "oauth_nonce", nonce);
381
384
 
382
385
  /* oauth_signature - computed over these fields */
383
 
  parameters[count][0]  = "oauth_signature_method";
384
 
  parameters[count++][1]= "HMAC-SHA1";
 
386
  flickcurl_add_param(fc, "oauth_signature_method", "HMAC-SHA1");
385
387
 
386
388
  timestamp = (char*)malloc(20);
387
389
  if(od->timestamp)
391
393
    (void)gettimeofday(&tp, NULL);
392
394
    sprintf(timestamp, "%ld", (long)tp.tv_sec);
393
395
  }
394
 
  parameters[count][0]  = "oauth_timestamp";
395
 
  parameters[count++][1]= timestamp;
396
 
 
397
 
  parameters[count][0]  = "oauth_version";
398
 
  parameters[count++][1]= "1.0";
399
 
 
400
 
  if(od->token) {
401
 
    parameters[count][0]  = "oauth_token";
402
 
    parameters[count++][1]= od->token;
403
 
  } else if(od->request_token) {
404
 
    parameters[count][0]  = "oauth_token";
405
 
    parameters[count++][1]= od->request_token;
406
 
  }
407
 
  if(od->verifier) {
408
 
    parameters[count][0]  = "oauth_verifier";
409
 
    parameters[count++][1]= od->verifier;
410
 
  }
411
 
 
412
 
  parameters[count][0]  = NULL;
 
396
  flickcurl_add_param(fc, "oauth_timestamp", timestamp);
 
397
 
 
398
  flickcurl_add_param(fc, "oauth_version", "1.0");
 
399
 
 
400
  if(od->token)
 
401
    flickcurl_add_param(fc, "oauth_token", od->token);
 
402
  else if(od->request_token) 
 
403
    flickcurl_add_param(fc, "oauth_token", od->request_token);
 
404
 
 
405
  if(od->verifier)
 
406
    flickcurl_add_param(fc, "oauth_verifier", od->verifier);
 
407
 
 
408
  flickcurl_end_params(fc);
413
409
 
414
410
  /* +FLICKCURL_FLICKCURL_MAX_OAUTH_PARAM_COUNT for oauth fields +1 for NULL terminating pointer */
415
 
  fc->param_fields = (char**)calloc(count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(char*));
416
 
  fc->param_values = (char**)calloc(count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(char*));
417
 
  values_len       = (size_t*)calloc(count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(size_t));
 
411
  fc->param_fields = (char**)calloc(fc->count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(char*));
 
412
  fc->param_values = (char**)calloc(fc->count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(char*));
 
413
  values_len       = (size_t*)calloc(fc->count + FLICKCURL_MAX_OAUTH_PARAM_COUNT + 1, sizeof(size_t));
418
414
 
419
415
  if((need_auth && (od->client_secret || od->token_secret)) || fc->sign)
420
 
    flickcurl_sort_args(fc, parameters, count);
 
416
    flickcurl_sort_args(fc);
421
417
 
422
418
 
423
419
  fc_uri_len = strlen(url);
424
 
  if(url[fc_uri_len -1] != '?')
 
420
  full_uri_len = fc_uri_len;
 
421
 
 
422
  if(url[fc_uri_len - 1] != '?')
425
423
    need_to_add_query++;
426
424
  
427
425
  /* Save away the parameters and calculate the value lengths */
428
 
  for(i = 0; parameters[i][0]; i++) {
429
 
    size_t param_len = strlen(parameters[i][0]);
 
426
  for(i = 0; fc->parameters[i][0]; i++) {
 
427
    size_t param_len = strlen(fc->parameters[i][0]);
430
428
 
431
 
    if(parameters[i][1])
432
 
      values_len[i] = strlen(parameters[i][1]);
 
429
    if(fc->parameters[i][1])
 
430
      values_len[i] = strlen(fc->parameters[i][1]);
433
431
    else {
434
432
      values_len[i] = 0;
435
 
      parameters[i][1] = "";
 
433
      fc->parameters[i][1] = "";
436
434
    }
437
435
    fc->param_fields[i] = (char*)malloc(param_len + 1);
438
 
    strcpy(fc->param_fields[i], parameters[i][0]);
 
436
    memcpy(fc->param_fields[i], fc->parameters[i][0], param_len + 1);
 
437
 
439
438
    fc->param_values[i] = (char*)malloc(values_len[i] + 1);
440
 
    strcpy(fc->param_values[i], parameters[i][1]);
 
439
    memcpy(fc->param_values[i], fc->parameters[i][1], values_len[i] + 1);
441
440
 
442
441
    /* 3x value len is conservative URI %XX escaping on every char */
443
 
    fc_uri_len += param_len + 1 /* = */ + 3 * values_len[i];
 
442
    full_uri_len += param_len + 1 /* = */ + 3 * values_len[i];
444
443
  }
445
444
 
446
445
  if(upload_field) {
447
 
    fc->upload_field = (char*)malloc(strlen(upload_field) + 1);
448
 
    strcpy(fc->upload_field, upload_field);
 
446
    size_t len = strlen(upload_field);
 
447
    fc->upload_field = (char*)malloc(len + 1);
 
448
    memcpy(fc->upload_field, upload_field, len + 1);
449
449
 
450
 
    fc->upload_value = (char*)malloc(strlen(upload_value) + 1);
451
 
    strcpy(fc->upload_value, upload_value);
 
450
    len = strlen(upload_value);
 
451
    fc->upload_value = (char*)malloc(len + 1);
 
452
    memcpy(fc->upload_value, upload_value, len + 1);
452
453
  }
453
454
 
454
455
 
460
461
    size_t param_buf_len = 0;
461
462
    size_t vlen = 0;
462
463
    char *escaped_value = NULL;
 
464
    const char* http_method;
 
465
    size_t http_method_len;
 
466
    size_t escaped_value_len;
463
467
    
464
 
    for(i = 0; parameters[i][0]; i++)
465
 
      param_buf_len += strlen(parameters[i][0]) + 3 + (3 * values_len[i]) + 3;
 
468
    for(i = 0; fc->parameters[i][0]; i++)
 
469
      param_buf_len += strlen(fc->parameters[i][0]) + 3 + (3 * values_len[i]) + 3;
466
470
    param_buf = (char*)malloc(param_buf_len + 1);
467
471
    *param_buf = '\0';
468
472
    
469
 
    for(i = 0; parameters[i][0]; i++) {
 
473
    p = param_buf;
 
474
 
 
475
    for(i = 0; fc->parameters[i][0]; i++) {
 
476
      size_t len = strlen(fc->parameters[i][0]);
470
477
      if(i > 0)
471
 
        strcat(param_buf, "&");
472
 
      strcat(param_buf, parameters[i][0]);
473
 
      strcat(param_buf, "=");
474
 
      escaped_value = curl_escape(parameters[i][1], 0);
475
 
      strcat(param_buf, escaped_value);
 
478
        *p++ = '&';
 
479
      memcpy(p, fc->parameters[i][0], len);
 
480
      p += len;
 
481
 
 
482
      *p++ = '=';
 
483
 
 
484
      escaped_value = curl_escape(fc->parameters[i][1], 0);
 
485
      escaped_value_len = strlen(escaped_value);
 
486
      memcpy(p, escaped_value, escaped_value_len);
 
487
      p += escaped_value_len;
476
488
      curl_free(escaped_value);
477
489
    }
478
 
 
479
 
    buf_len = strlen(http_method);
 
490
    *p = '\0';
 
491
 
 
492
    http_method = (upload_field || fc->is_write) ? "POST" : "GET";
 
493
    http_method_len = (upload_field || fc->is_write) ? 4  : 3;
 
494
 
 
495
    buf_len = http_method_len;
480
496
    buf_len += 1; /* & */
481
497
    buf_len += (3 * strlen(url));
482
498
    buf_len += 1; /* & */
483
499
    buf_len += param_buf_len * 3;
484
500
 
485
501
    buf = (char*)malloc(buf_len + 1);
486
 
    strcpy(buf, http_method);
487
 
    strcat(buf, "&");
 
502
 
 
503
    p = buf;
 
504
    memcpy(p, http_method, http_method_len);
 
505
    p += http_method_len;
 
506
 
 
507
    *p++ = '&';
 
508
 
488
509
    escaped_value = curl_escape(url, 0);
489
 
    strcat(buf, escaped_value);
 
510
    escaped_value_len = strlen(escaped_value);
 
511
    memcpy(p, escaped_value, escaped_value_len);
 
512
    p += escaped_value_len;
490
513
    curl_free(escaped_value);
491
 
    strcat(buf, "&");
 
514
 
 
515
    *p++ = '&';
 
516
 
492
517
    escaped_value = curl_escape(param_buf, 0);
493
 
    strcat(buf, escaped_value);
 
518
    escaped_value_len = strlen(escaped_value);
 
519
    memcpy(p, escaped_value, escaped_value_len);
 
520
    p += escaped_value_len;
494
521
    curl_free(escaped_value);
495
 
 
 
522
    *p = '\0';
 
523
    
496
524
    free(param_buf);
497
525
 
498
526
    if(flickcurl_oauth_build_key(od)) {
517
545
    free(od->key);
518
546
    od->key = NULL;
519
547
 
520
 
    parameters[count][0]  = "oauth_signature";
521
 
    parameters[count][1]  = signature_string;
522
 
 
 
548
    flickcurl_add_param(fc, "oauth_signature", signature_string);
 
549
    fc->count--;
 
550
    
523
551
    /* Add a new parameter pair */
524
 
    values_len[count] = vlen;
 
552
    values_len[fc->count] = vlen;
525
553
    /* 15 = strlen(oauth_signature) */
526
 
    fc->param_fields[count] = (char*)malloc(15 + 1);
527
 
    strcpy(fc->param_fields[count], parameters[count][0]);
528
 
    fc->param_values[count] = (char*)malloc(vlen + 1);
529
 
    strcpy(fc->param_values[count], parameters[count][1]);
530
 
 
531
 
    fc_uri_len += 15 /* "oauth_signature" */ + 1 /* = */ + vlen;
532
 
 
533
 
    count++;
 
554
    fc->param_fields[fc->count] = (char*)malloc(15 + 1);
 
555
    memcpy(fc->param_fields[fc->count], fc->parameters[fc->count][0], 15 + 1);
 
556
 
 
557
    fc->param_values[fc->count] = (char*)malloc(vlen + 1);
 
558
    memcpy(fc->param_values[fc->count], fc->parameters[fc->count][1], vlen + 1);
 
559
 
 
560
    full_uri_len += 15 /* "oauth_signature" */ + 1 /* = */ + vlen;
 
561
    
 
562
    fc->count++;
534
563
    
535
564
#ifdef FLICKCURL_DEBUG
536
565
    fprintf(stderr, "HMAC-SHA1 signature:\n  %s\n", signature_string);
540
569
    od->data = NULL;
541
570
    od->data_len = 0;
542
571
    
543
 
    parameters[count][0] = NULL;
 
572
    flickcurl_end_params(fc);
544
573
  }
545
574
 
546
 
  /* add &s between parameters */
547
 
  fc_uri_len += count-1;
 
575
  /* add &s between fc->parameters */
 
576
  full_uri_len += fc->count - 1;
548
577
 
549
578
  /* reuse or grow uri buffer */
550
 
  if(fc->uri_len < fc_uri_len) {
 
579
  if(fc->uri_len < full_uri_len) {
551
580
    free(fc->uri);
552
 
    fc->uri = (char*)malloc(fc_uri_len+1);
553
 
    fc->uri_len = fc_uri_len;
 
581
    fc->uri = (char*)malloc(full_uri_len + 1);
 
582
    fc->uri_len = full_uri_len;
554
583
  }
555
 
  strcpy(fc->uri, url);
 
584
  memcpy(fc->uri, url, fc_uri_len);
 
585
 
 
586
  p = fc->uri + fc_uri_len;
 
587
  *p = '\0';
556
588
 
557
589
  if(need_to_add_query)
558
 
    strcat(fc->uri, "?");
 
590
    *p++ = '?';
559
591
 
560
592
  if(parameters_in_url) {
561
 
    for(i = 0; parameters[i][0]; i++) {
562
 
      char *value = (char*)parameters[i][1];
563
 
      char *escaped_value = NULL;
 
593
    for(i = 0; fc->parameters[i][0]; i++) {
 
594
      char *value = (char*)fc->parameters[i][1];
 
595
      size_t len;
564
596
 
565
 
      if(!parameters[i][1])
 
597
      if(!fc->parameters[i][1])
566
598
        continue;
567
599
 
568
 
      strcat(fc->uri, parameters[i][0]);
569
 
      strcat(fc->uri, "=");
570
 
      escaped_value = curl_escape(value, values_len[i]);
571
 
      strcat(fc->uri, escaped_value);
572
 
      curl_free(escaped_value);
573
 
      strcat(fc->uri, "&");
 
600
      len = strlen(fc->parameters[i][0]);
 
601
      memcpy(p, fc->parameters[i][0], len);
 
602
      p += len;
 
603
      *p++ = '=';
 
604
 
 
605
      value = curl_escape(value, values_len[i]);
 
606
      len = strlen(value);
 
607
      memcpy(p, value, len);
 
608
      p += len;
 
609
      curl_free(value);
 
610
 
 
611
      *p++ = '&';
574
612
    }
575
613
 
576
 
    /* zap last & */
577
 
    fc->uri[strlen(fc->uri)-1] = '\0';
 
614
    /* zap last & and terminate fc->url */
 
615
    *--p = '\0';
578
616
  }
579
617
 
580
618
#ifdef FLICKCURL_DEBUG
602
640
 
603
641
 
604
642
 
605
 
/*
606
 
 * flickcurl_oauth_request_token:
 
643
/**
 
644
 * flickcurl_oauth_create_request_token:
607
645
 * @fc: flickcurl object
608
 
 *
609
 
 * INTERNAL - get a Flickr OAuth request token
610
 
 *
611
 
 * Calls the Flickr OAuth endpoint to get a request token.
612
 
 *
613
 
 * Stores the request token in @od fields 'request_token' and
614
 
 * 'request_token_secret' on success.
 
646
 * @callback: callback URL or NULL for out of band
 
647
 *
 
648
 * Request an OAuth request token from Flickr for the application API Key/secret
 
649
 *
 
650
 * Requires the OAuth Client key (API key) and Client secret to have
 
651
 * been set with flickcurl_set_oauth_client_key() and
 
652
 * flickcurl_set_oauth_client_secret() respectively.
 
653
 * 
 
654
 * Calls the Flickr OAuth endpoint to get a request token for the
 
655
 * given callback or uses out-of-band if @callback is NULL.
 
656
 *
 
657
 * On success, stores the request token in the @fc structure.
615
658
 *
616
659
 * Return value: non-0 on failure
617
660
 */
618
661
int
619
 
flickcurl_oauth_request_token(flickcurl* fc)
 
662
flickcurl_oauth_create_request_token(flickcurl* fc, const char* callback)
620
663
{
621
664
  flickcurl_oauth_data* od = &fc->od;
622
 
  const char * parameters[2 + FLICKCURL_MAX_OAUTH_PARAM_COUNT][2];
623
 
  int count = 0;
624
665
  char* request_token = NULL;
625
666
  char* request_token_secret = NULL;
626
667
  char** form = NULL;
627
668
  int rc = 0;
628
669
  const char* uri = fc->oauth_request_token_uri;
629
670
  int i;
 
671
  int count;
630
672
 
631
 
  parameters[count][0]  = NULL;
 
673
  flickcurl_end_params(fc);
632
674
 
633
675
  /* Require signature */
634
676
  flickcurl_set_sign(fc);
635
677
 
636
 
  od->callback = "oob";
 
678
  if(!callback || !*callback)
 
679
    callback = "oob";
 
680
  od->callback = callback;
 
681
 
637
682
  rc = flickcurl_oauth_prepare_common(fc,
638
683
                                      uri,
639
684
                                      /* method */ "flickr.oauth.request_token",
640
685
                                      /* upload_field */ NULL,
641
686
                                      /* upload_value */ NULL,
642
 
                                      parameters, count,
643
687
                                      /* parameters_in_url */ 1,
644
688
                                      /* need_auth */ 1);
645
689
  od->callback = NULL;
668
712
 
669
713
  if(request_token && request_token_secret) {
670
714
    /* Take copies that are owned by od */
671
 
    od->request_token = strdup(request_token);
672
 
    od->request_token_len = strlen(od->request_token);
673
 
    od->request_token_secret = strdup(request_token_secret);
674
 
    od->request_token_secret_len = strlen(od->request_token_secret);
 
715
    size_t len = strlen(request_token);
 
716
    od->request_token = (char*)malloc(len + 1);
 
717
    memcpy(od->request_token, request_token, len + 1);
 
718
    od->request_token_len = len;
 
719
 
 
720
    len = strlen(request_token_secret);
 
721
    od->request_token_secret = (char*)malloc(len + 1);
 
722
    memcpy(od->request_token_secret, request_token_secret, len + 1);
 
723
    od->request_token_secret_len = len;
675
724
 
676
725
#ifdef FLICKCURL_DEBUG
677
726
    fprintf(stderr,
689
738
}
690
739
 
691
740
 
692
 
/*
 
741
/**
693
742
 * flickcurl_oauth_get_authorize_uri:
694
743
 * @fc: flickcurl object
695
744
 *
696
 
 * INTERNAL - get the URL for the user to authorize an application
 
745
 * Get the URL for the user to authorize Flickr OAuth of an application
697
746
 *
698
747
 * Forms the URL the user needs to start at to authorize the
699
 
 * application.  The application should pass the verifier to
700
 
 * flickcurl_oauth_access_token() for the final step in OAuth.
 
748
 * application.
 
749
 *
 
750
 * This function requires flickcurl_oauth_create_request_token() to have
 
751
 * been called to build a request token / secret pair.
 
752
 *
 
753
 * After this function, the application should pass the verifier to
 
754
 * flickcurl_oauth_create_access_token() for the final step in OAuth along
 
755
 * with the request token and request token secret.
701
756
 *
702
757
 * Return value: authorize URI or NULL on failure
703
758
 */
732
787
}
733
788
 
734
789
 
735
 
/*
736
 
 * flickcurl_oauth_access_token:
 
790
/**
 
791
 * flickcurl_oauth_create_access_token:
737
792
 * @fc: flickcurl object
738
793
 * @verifier: verifier from OOB authentication
739
794
 *
740
 
 * INTERNAL - get a Flickr OAuth access token from a verifier
 
795
 * Get a Flickr OAuth access token from request token credentials and verifier
741
796
 *
742
797
 * Calls the Flickr OAuth access token endpoint using the verifier
743
 
 * from out of band authentication to get an access token.
744
 
 *
745
 
 * Uses the @verifier and the @od fields 'request_token' and
746
 
 * 'request_token_secret' to get an access token stored which on
747
 
 * success is stored in the @od fields 'access_token' and
748
 
 * 'access_token_secret'.  The request token fields are deleted on
749
 
 * success.
 
798
 * from out of band authentication to get an access token to enable
 
799
 * authenticated calls to the Flickr API.
750
800
 *
751
801
 * Return value: non-0 on failure
752
802
 */
753
803
int
754
 
flickcurl_oauth_access_token(flickcurl* fc, const char* verifier)
 
804
flickcurl_oauth_create_access_token(flickcurl* fc, const char* verifier)
755
805
{
756
806
  flickcurl_oauth_data* od = &fc->od;
757
 
  const char * parameters[2 + FLICKCURL_MAX_OAUTH_PARAM_COUNT][2];
758
 
  int count = 0;
759
807
  char* access_token = NULL;
760
808
  char* access_token_secret = NULL;
 
809
  char* username = NULL;
 
810
  char* user_nsid = NULL;
761
811
  char** form = NULL;
762
812
  int rc = 0;
763
813
  const char* uri = fc->oauth_access_token_uri;
764
814
  int i;
 
815
  int count;
765
816
  
766
 
  parameters[count][0]  = NULL;
 
817
  if(!verifier)
 
818
    return 1;
 
819
 
 
820
  flickcurl_end_params(fc);
767
821
 
768
822
  /* Require signature */
769
823
  flickcurl_set_sign(fc);
776
830
                                      /* method */ "flickr.oauth.access_token",
777
831
                                      /* upload_field */ NULL,
778
832
                                      /* upload_value */ NULL,
779
 
                                      parameters, count,
780
833
                                      /* parameters_in_url */ 1,
781
834
                                      /* need_auth */ 1);
782
835
 
801
854
      access_token = form[i+1];
802
855
    } else if(!strcmp(form[i], "oauth_token_secret")) {
803
856
      access_token_secret = form[i+1];
 
857
    } else if(!strcmp(form[i], "username")) {
 
858
      username = form[i+1];
 
859
    } else if(!strcmp(form[i], "user_nsid")) {
 
860
      user_nsid = form[i+1];
804
861
    }
805
 
    /* ignoring: fullname, user_nsid, username */
 
862
    /* ignoring: fullname */
806
863
  }
807
864
 
808
865
  if(access_token && access_token_secret) {
809
866
    /* Take copies that are owned by od */
810
 
    od->token = strdup(access_token);
811
 
    od->token_len = strlen(od->token);
812
 
    od->token_secret = strdup(access_token_secret);
813
 
    od->token_secret_len = strlen(od->token_secret);
814
 
 
 
867
    size_t len = strlen(access_token);
 
868
    od->token = (char*)malloc(len + 1);
 
869
    memcpy(od->token, access_token, len + 1);
 
870
    od->token_len = len;
 
871
 
 
872
    len = strlen(access_token_secret);
 
873
    od->token_secret = (char*)malloc(len + 1);
 
874
    memcpy(od->token_secret, access_token_secret, len + 1);
 
875
    od->token_secret_len = len;
 
876
 
 
877
    if(username) {
 
878
      len = strlen(username);
 
879
      od->username = (char*)malloc(len + 1);
 
880
      memcpy(od->username, username, len + 1);
 
881
      od->username_len = len;
 
882
    } else {
 
883
      od->username = NULL;
 
884
      od->username_len = 0;
 
885
    }
 
886
 
 
887
    if(user_nsid) {
 
888
      len = strlen(user_nsid);
 
889
      od->user_nsid = (char*)malloc(len + 1);
 
890
      memcpy(od->user_nsid, user_nsid, len + 1);
 
891
      od->user_nsid_len = len;
 
892
    } else {
 
893
      od->user_nsid = NULL;
 
894
      od->user_nsid_len = 0;
 
895
    }
 
896
    
815
897
    /* Delete temporary request token and secret */
816
898
    free(od->request_token);
817
899
    od->request_token = NULL;
835
917
  
836
918
  return rc;
837
919
}
 
920
 
 
921
 
 
922
 
 
923
/**
 
924
 * flickcurl_get_oauth_client_key:
 
925
 * @fc: flickcurl object
 
926
 *
 
927
 * Get OAuth Client Key (aka Consumer key, API Key)
 
928
 *
 
929
 * See also flickcurl_get_oauth_client_secret()
 
930
 *
 
931
 * Return value: client key or NULL if none set
 
932
 */
 
933
const char*
 
934
flickcurl_get_oauth_client_key(flickcurl *fc)
 
935
{
 
936
  return fc->od.client_key;
 
937
}
 
938
 
 
939
 
 
940
/**
 
941
 * flickcurl_get_oauth_client_secret:
 
942
 * @fc: flickcurl object
 
943
 *
 
944
 * Get OAuth Client secret
 
945
 *
 
946
 * See also flickcurl_get_oauth_client_key()
 
947
 *
 
948
 * Return value: client secret or NULL if none set
 
949
 */
 
950
const char*
 
951
flickcurl_get_oauth_client_secret(flickcurl *fc)
 
952
{
 
953
  return fc->od.client_secret;
 
954
}
 
955
 
 
956
 
 
957
/**
 
958
 * flickcurl_set_oauth_client_key:
 
959
 * @fc: flickcurl object
 
960
 * @client_key: client key (API key)
 
961
 *
 
962
 * Set OAuth client key (aka API key)
 
963
 *
 
964
 * See also flickcurl_get_oauth_client_key()
 
965
 */
 
966
void
 
967
flickcurl_set_oauth_client_key(flickcurl *fc, const char* client_key)
 
968
{
 
969
  if(fc->od.client_key) {
 
970
    free(fc->od.client_key);
 
971
    fc->od.client_key = NULL;
 
972
    fc->od.client_key_len = 0;
 
973
  }
 
974
 
 
975
  if(client_key) {
 
976
    size_t len = strlen(client_key);
 
977
    fc->od.client_key = (char*)malloc(len + 1);
 
978
    memcpy(fc->od.client_key, client_key, len + 1);
 
979
    fc->od.client_key_len = len;
 
980
  }
 
981
}
 
982
 
 
983
 
 
984
/**
 
985
 * flickcurl_set_oauth_client_secret:
 
986
 * @fc: flickcurl object
 
987
 * @client_secret: client key (shared key)
 
988
 *
 
989
 * Set OAuth client key (aka shared secret)
 
990
 *
 
991
 * See also flickcurl_set_oauth_client_secret()
 
992
 */
 
993
void
 
994
flickcurl_set_oauth_client_secret(flickcurl *fc, const char* client_secret)
 
995
{
 
996
  if(fc->od.client_secret) {
 
997
    free(fc->od.client_secret);
 
998
    fc->od.client_secret = NULL;
 
999
    fc->od.client_secret_len = 0;
 
1000
  }
 
1001
  
 
1002
  if(client_secret) {
 
1003
    size_t len = strlen(client_secret);
 
1004
    fc->od.client_secret = (char*)malloc(len + 1);
 
1005
    memcpy(fc->od.client_secret, client_secret, len + 1);
 
1006
    fc->od.client_secret_len = len;
 
1007
  }
 
1008
}
 
1009
 
 
1010
 
 
1011
/**
 
1012
 * flickcurl_get_oauth_token:
 
1013
 * @fc: flickcurl object
 
1014
 *
 
1015
 * Get OAuth Token
 
1016
 *
 
1017
 * Return value: auth token or NULL if none set
 
1018
 */
 
1019
const char*
 
1020
flickcurl_get_oauth_token(flickcurl *fc)
 
1021
{
 
1022
  return fc->od.token;
 
1023
}
 
1024
 
 
1025
 
 
1026
/**
 
1027
 * flickcurl_set_oauth_token:
 
1028
 * @fc: flickcurl object
 
1029
 * @token: auth token
 
1030
 *
 
1031
 * Set OAuth Token
 
1032
 */
 
1033
void
 
1034
flickcurl_set_oauth_token(flickcurl *fc, const char* token)
 
1035
{
 
1036
#if FLICKCURL_DEBUG > 1
 
1037
  fprintf(stderr, "OAuth token: '%s'\n", token);
 
1038
#endif
 
1039
  if(fc->od.token) {
 
1040
    free(fc->od.token);
 
1041
    fc->od.token = NULL;
 
1042
    fc->od.token_len = 0;
 
1043
  }
 
1044
  if(token) {
 
1045
    size_t len = strlen(token);
 
1046
    fc->od.token = (char*)malloc(len + 1);
 
1047
    memcpy(fc->od.token, token, len + 1);
 
1048
    fc->od.token_len = len;
 
1049
  }
 
1050
}
 
1051
 
 
1052
 
 
1053
/**
 
1054
 * flickcurl_get_oauth_token_secret:
 
1055
 * @fc: flickcurl object
 
1056
 *
 
1057
 * Get OAuth token secret
 
1058
 *
 
1059
 * Return value: secret or NULL if none set
 
1060
 */
 
1061
const char*
 
1062
flickcurl_get_oauth_token_secret(flickcurl* fc)
 
1063
{
 
1064
  return fc->od.token_secret;
 
1065
}
 
1066
 
 
1067
/**
 
1068
 * flickcurl_get_oauth_username:
 
1069
 * @fc: flickcurl object
 
1070
 *
 
1071
 * Get the username for the authenticated user
 
1072
 *
 
1073
 * Return value: username or NULL if none set
 
1074
 */
 
1075
const char*
 
1076
flickcurl_get_oauth_username(flickcurl* fc)
 
1077
{
 
1078
  return fc->od.username;
 
1079
}
 
1080
 
 
1081
/**
 
1082
 * flickcurl_get_oauth_user_nsid:
 
1083
 * @fc: flickcurl object
 
1084
 *
 
1085
 * Get the user_nsid for the authenticated user
 
1086
 *
 
1087
 * Return value: user_nsid or NULL if none set
 
1088
 */
 
1089
const char*
 
1090
flickcurl_get_oauth_user_nsid(flickcurl* fc)
 
1091
{
 
1092
  return fc->od.user_nsid;
 
1093
}
 
1094
 
 
1095
/**
 
1096
 * flickcurl_set_oauth_token_secret:
 
1097
 * @fc: flickcurl object
 
1098
 * @secret: shared secret
 
1099
 *
 
1100
 * Set OAuth token Secret
 
1101
 */
 
1102
void
 
1103
flickcurl_set_oauth_token_secret(flickcurl* fc, const char *secret)
 
1104
{
 
1105
#if FLICKCURL_DEBUG > 1
 
1106
  fprintf(stderr, "OAuth token secret: '%s'\n", secret);
 
1107
#endif
 
1108
  if(fc->od.token_secret) {
 
1109
    free(fc->od.token_secret);
 
1110
    fc->od.token_secret = NULL;
 
1111
    fc->od.token_secret_len = 0;
 
1112
  }
 
1113
  
 
1114
  if(secret) {
 
1115
    size_t len = strlen(secret);
 
1116
    fc->od.token_secret = (char*)malloc(len + 1);
 
1117
    memcpy(fc->od.token_secret, secret, len + 1);
 
1118
    fc->od.token_secret_len = len;
 
1119
  }
 
1120
}
 
1121
 
 
1122
 
 
1123
/**
 
1124
 * flickcurl_get_oauth_request_token:
 
1125
 * @fc: flickcurl object
 
1126
 *
 
1127
 * Get OAuth request token
 
1128
 *
 
1129
 * Return value: request token or NULL if none set
 
1130
 */
 
1131
const char*
 
1132
flickcurl_get_oauth_request_token(flickcurl* fc)
 
1133
{
 
1134
  return fc->od.request_token;
 
1135
}
 
1136
 
 
1137
 
 
1138
/**
 
1139
 * flickcurl_get_oauth_request_token_secret:
 
1140
 * @fc: flickcurl object
 
1141
 *
 
1142
 * Get OAuth request token secret
 
1143
 *
 
1144
 * Return value: request token secret or NULL if none set
 
1145
 */
 
1146
const char*
 
1147
flickcurl_get_oauth_request_token_secret(flickcurl* fc)
 
1148
{
 
1149
  return fc->od.request_token_secret;
 
1150
}
 
1151
 
 
1152
 
 
1153
/**
 
1154
 * flickcurl_set_oauth_request_token:
 
1155
 * @fc: flickcurl object
 
1156
 * @token: request token
 
1157
 *
 
1158
 * Set OAuth request token
 
1159
 *
 
1160
 * See also flickcurl_get_oauth_request_token()
 
1161
 */
 
1162
void
 
1163
flickcurl_set_oauth_request_token(flickcurl *fc, const char* token)
 
1164
{
 
1165
#if FLICKCURL_DEBUG > 1
 
1166
  fprintf(stderr, "OAuth request token: '%s'\n", token);
 
1167
#endif
 
1168
  if(fc->od.request_token) {
 
1169
    free(fc->od.request_token);
 
1170
    fc->od.request_token = NULL;
 
1171
    fc->od.request_token_len = 0;
 
1172
  }
 
1173
 
 
1174
  if(token) {
 
1175
    size_t len = strlen(token);
 
1176
    fc->od.request_token = (char*)malloc(len + 1);
 
1177
    memcpy(fc->od.request_token, token, len + 1);
 
1178
    fc->od.request_token_len = len;
 
1179
  }
 
1180
}
 
1181
 
 
1182
 
 
1183
/**
 
1184
 * flickcurl_set_oauth_request_token_secret:
 
1185
 * @fc: flickcurl object
 
1186
 * @secret: request token secret
 
1187
 *
 
1188
 * Set OAuth request token secret credentials
 
1189
 *
 
1190
 * See also flickcurl_get_oauth_request_token_secret()
 
1191
 */
 
1192
void
 
1193
flickcurl_set_oauth_request_token_secret(flickcurl *fc, const char* secret)
 
1194
{
 
1195
#if FLICKCURL_DEBUG > 1
 
1196
  fprintf(stderr, "OAuth request token secret: '%s'\n", secret);
 
1197
#endif
 
1198
  if(fc->od.request_token_secret) {
 
1199
    free(fc->od.request_token_secret);
 
1200
    fc->od.request_token_secret = NULL;
 
1201
    fc->od.request_token_secret = 0;
 
1202
  }
 
1203
  if(secret) {
 
1204
    size_t len = strlen(secret);
 
1205
    fc->od.request_token_secret = (char*)malloc(len + 1);
 
1206
    memcpy(fc->od.request_token_secret, secret, len + 1);
 
1207
    fc->od.request_token_secret_len = len;
 
1208
  }
 
1209
}
 
1210
 
 
1211
 
 
1212
 
 
1213
 
838
1214
#endif
839
1215
 
840
1216
 
902
1278
 
903
1279
  oauth_init_test_secrets(od);
904
1280
 
905
 
  rc = flickcurl_oauth_request_token(fc);
 
1281
  rc = flickcurl_oauth_create_request_token(fc, NULL);
906
1282
 
907
1283
  memset(od, '\0', sizeof(*od));
908
1284
 
927
1303
  
928
1304
  oauth_init_test_secrets(od);
929
1305
 
930
 
  rc = flickcurl_oauth_access_token(fc, verifier);
 
1306
  rc = flickcurl_oauth_create_access_token(fc, verifier);
931
1307
 
932
1308
  memset(od, '\0', sizeof(*od));
933
1309
 
1006
1382
                                 test_uri_base_string, 
1007
1383
                                 test_request_parameters);
1008
1384
  
1009
 
  fprintf(stderr, "%s: key is (%d bytes)\n  %s\n", program, (int)od->key_len, od->key);
1010
 
  fprintf(stderr, "%s: expected key is\n  %s\n", program, expected_key);
1011
 
  
1012
 
  fprintf(stderr, "%s: data is (%d bytes)\n  %s\n", program, (int)od->data_len, od->data);
1013
 
  fprintf(stderr, "%s: expected data is\n  %s\n", program, expected_data);
 
1385
  if(strcmp((const char*)od->key, expected_key)) {
 
1386
    fprintf(stderr, "%s: FAIL\n" 
 
1387
                    "  key is (%d bytes)\n    %s\n"
 
1388
                    "  expected key is\n    %s\n",
 
1389
            program, (int)od->key_len, od->key, expected_key);
 
1390
    rc++;
 
1391
  }
 
1392
 
 
1393
  if(strcmp((const char*)od->data, expected_data)) {
 
1394
    fprintf(stderr, "%s: FAIL\n"
 
1395
            "  data is (%d bytes)\n    %s\n"
 
1396
            "  expected data is\n    %s\n",
 
1397
            program, (int)od->data_len, od->data, expected_data);
 
1398
    rc++;
 
1399
  }
1014
1400
  
1015
1401
  signature = flickcurl_oauth_compute_signature(od, &escaped_s_len);
1016
1402
  
1018
1404
  free(signature);
1019
1405
  escaped_s_len = strlen(escaped_s);
1020
1406
  
1021
 
  fprintf(stdout, "URI Escaped result (%d bytes):\n   %s\n",
1022
 
          (int)escaped_s_len, escaped_s);
1023
 
  
1024
 
  fprintf(stdout, "Expected URI escaped result\n   %s\n", 
1025
 
          expected_signature);
 
1407
  if(strcmp(escaped_s, expected_signature)) {
 
1408
    fprintf(stdout, "%s: FAIL\n"
 
1409
            "  URI Escaped result (%d bytes):\n    %s\n"
 
1410
            "  Expected URI escaped result\n    %s\n", 
 
1411
            program, (int)escaped_s_len, escaped_s, expected_signature);
 
1412
    rc++;
 
1413
  }
1026
1414
  
1027
1415
  curl_free(escaped_s);
1028
1416