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

« back to all changes in this revision

Viewing changes to src/legacy-auth.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:
 
1
/* -*- Mode: c; c-basic-offset: 2 -*-
 
2
 *
 
3
 * legacy-auth.c - Flickr Legacy authentication
 
4
 *
 
5
 * Copyright (C) 2007-2012, David Beckett http://www.dajobe.org/
 
6
 *
 
7
 * This file is licensed under the following three licenses as alternatives:
 
8
 *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
 
9
 *   2. GNU General Public License (GPL) V2 or any newer version
 
10
 *   3. Apache License, V2.0 or any newer version
 
11
 *
 
12
 * You may not use this file except in compliance with at least one of
 
13
 * the above three licenses.
 
14
 *
 
15
 * See LICENSE.html or LICENSE.txt at the top of this package for the
 
16
 * complete terms and further detail along with the license texts for
 
17
 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
 
18
 *
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <string.h>
 
23
#include <stdarg.h>
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#include <config.h>
 
27
#endif
 
28
 
 
29
#ifdef WIN32
 
30
#include <win32_flickcurl_config.h>
 
31
#endif
 
32
 
 
33
#include <flickcurl.h>
 
34
#include <flickcurl_internal.h>
 
35
 
 
36
 
 
37
 
 
38
static int
 
39
compare_args(const void *a, const void *b)
 
40
{
 
41
  return strcmp(*(char**)a, *(char**)b);
 
42
}
 
43
 
 
44
 
 
45
static void
 
46
flickcurl_sort_args(flickcurl *fc)
 
47
{
 
48
  qsort((void*)fc->parameters, fc->count, sizeof(char*[2]), compare_args);
 
49
}
 
50
 
 
51
 
 
52
int
 
53
flickcurl_legacy_prepare_common(flickcurl *fc,
 
54
                                const char* url,
 
55
                                const char* method,
 
56
                                const char* upload_field,
 
57
                                const char* upload_value,
 
58
                                int parameters_in_url, int need_auth)
 
59
{
 
60
  int i;
 
61
  char *md5_string = NULL;
 
62
  size_t* values_len = NULL;
 
63
  unsigned int fc_uri_len = 0;
 
64
  unsigned int full_uri_len = 0;
 
65
  
 
66
  if(!url)
 
67
    return 1;
 
68
 
 
69
  /* If one is given, both are required */
 
70
  if((upload_field || upload_value) && (!upload_field || !upload_value))
 
71
    return 1;
 
72
 
 
73
  fc->failed = 0;
 
74
  fc->error_code = 0;
 
75
  if(fc->error_msg) {
 
76
    free(fc->error_msg);
 
77
    fc->error_msg = NULL;
 
78
  }
 
79
  /* Default to read */
 
80
  fc->is_write = 0;
 
81
  /* Default to no data */
 
82
  if(fc->data) {
 
83
    if(fc->data_is_xml)
 
84
      xmlFree(fc->data);
 
85
    fc->data = NULL;
 
86
    fc->data_length = 0;
 
87
    fc->data_is_xml = 0;
 
88
  }
 
89
  if(fc->param_fields) {
 
90
    for(i = 0; fc->param_fields[i]; i++) {
 
91
      free(fc->param_fields[i]);
 
92
      free(fc->param_values[i]);
 
93
    }
 
94
    free(fc->param_fields);
 
95
    free(fc->param_values);
 
96
    fc->param_fields = NULL;
 
97
    fc->param_values = NULL;
 
98
    fc->parameter_count = 0;
 
99
  }
 
100
  if(fc->upload_field) {
 
101
    free(fc->upload_field);
 
102
    fc->upload_field = NULL;
 
103
  }
 
104
  if(fc->upload_value) {
 
105
    free(fc->upload_value);
 
106
    fc->upload_value = NULL;
 
107
  }
 
108
 
 
109
  if(!fc->secret) {
 
110
    flickcurl_error(fc, "No legacy Flickr auth secret");
 
111
    return 1;
 
112
  }
 
113
  if(!fc->api_key) {
 
114
    flickcurl_error(fc, "No API Key (OAuth Client Key)");
 
115
    return 1;
 
116
  }
 
117
 
 
118
 
 
119
  if(fc->method)
 
120
    free(fc->method);
 
121
  if(method) {
 
122
    size_t len = strlen(method);
 
123
    fc->method = (char*)malloc(len + 1);
 
124
    memcpy(fc->method, method, len + 1);
 
125
  } else
 
126
    fc->method = NULL;
 
127
 
 
128
  if(fc->method)
 
129
    flickcurl_add_param(fc, "method", fc->method);
 
130
 
 
131
  flickcurl_add_param(fc, "api_key", fc->api_key);
 
132
 
 
133
  if(need_auth && fc->auth_token)
 
134
    flickcurl_add_param(fc, "auth_token", fc->auth_token);
 
135
 
 
136
  flickcurl_end_params(fc);
 
137
 
 
138
  /* +1 for api_sig +1 for NULL terminating pointer */
 
139
  fc->param_fields = (char**)calloc(fc->count + 2, sizeof(char*));
 
140
  fc->param_values = (char**)calloc(fc->count + 2, sizeof(char*));
 
141
  values_len = (size_t*)calloc(fc->count + 2, sizeof(size_t));
 
142
 
 
143
  if((need_auth && fc->auth_token) || fc->sign)
 
144
    flickcurl_sort_args(fc);
 
145
 
 
146
  fc_uri_len = strlen(url);
 
147
  full_uri_len = fc_uri_len;
 
148
 
 
149
  /* Save away the parameters and calculate the value lengths */
 
150
  for(i = 0; fc->parameters[i][0]; i++) {
 
151
    size_t param_len = strlen(fc->parameters[i][0]);
 
152
 
 
153
    if(fc->parameters[i][1])
 
154
      values_len[i] = strlen(fc->parameters[i][1]);
 
155
    else {
 
156
      values_len[i] = 0;
 
157
      fc->parameters[i][1] = "";
 
158
    }
 
159
 
 
160
    fc->param_fields[i] = (char*)malloc(param_len + 1);
 
161
    memcpy(fc->param_fields[i], fc->parameters[i][0], param_len + 1);
 
162
 
 
163
    fc->param_values[i] = (char*)malloc(values_len[i] + 1);
 
164
    memcpy(fc->param_values[i], fc->parameters[i][1], values_len[i] + 1);
 
165
 
 
166
    /* 3x value len is conservative URI %XX escaping on every char */
 
167
    full_uri_len += param_len + 1 /* = */ + 3 * values_len[i];
 
168
  }
 
169
 
 
170
  if(upload_field) {
 
171
    size_t len = strlen(upload_field);
 
172
    fc->upload_field = (char*)malloc(len + 1);
 
173
    memcpy(fc->upload_field, upload_field, len + 1);
 
174
 
 
175
    len = strlen(upload_value);
 
176
    fc->upload_value = (char*)malloc(len + 1);
 
177
    memcpy(fc->upload_value, upload_value, len + 1);
 
178
  }
 
179
 
 
180
  if((need_auth && fc->auth_token) || fc->sign) {
 
181
    size_t secret_len;
 
182
    size_t buf_len = 0;
 
183
    char *buf;
 
184
    char *p;
 
185
   
 
186
    secret_len = strlen(fc->secret);
 
187
    buf_len = secret_len;
 
188
    for(i = 0; fc->parameters[i][0]; i++)
 
189
      buf_len += strlen(fc->parameters[i][0]) + values_len[i];
 
190
 
 
191
    buf = (char*)malloc(buf_len + 1);
 
192
 
 
193
    p = buf;
 
194
    memcpy(p, fc->secret, secret_len);
 
195
    p += secret_len;
 
196
    for(i = 0; fc->parameters[i][0]; i++) {
 
197
      size_t len = strlen(fc->parameters[i][0]);
 
198
      memcpy(p, fc->parameters[i][0], len);
 
199
      p += len;
 
200
      memcpy(p, fc->parameters[i][1], values_len[i]);
 
201
      p += values_len[i];
 
202
    }
 
203
    *p = '\0';
 
204
   
 
205
#ifdef FLICKCURL_DEBUG
 
206
    fprintf(stderr, "MD5 Buffer '%s'\n", buf);
 
207
#endif
 
208
    md5_string = MD5_string(buf);
 
209
   
 
210
    flickcurl_add_param(fc, "api_sig", md5_string);
 
211
    fc->count--;
 
212
 
 
213
    /* Add a new parameter pair */
 
214
    values_len[fc->count] = 32; /* MD5 is always 32 */
 
215
    fc->param_fields[fc->count] = (char*)malloc(7+1); /* 7 = strlen(api_sig) */
 
216
    memcpy(fc->param_fields[fc->count], fc->parameters[fc->count][0], 7 + 1);
 
217
 
 
218
    fc->param_values[fc->count] = (char*)malloc(32+1); /* 32 = MD5 */
 
219
    memcpy(fc->param_values[fc->count], fc->parameters[fc->count][1], 32 + 1);
 
220
 
 
221
    full_uri_len += 7 /* "api_sig" */ + 1 /* = */ + 32 /* MD5 value: never escaped */;
 
222
    
 
223
    fc->count++;
 
224
   
 
225
#ifdef FLICKCURL_DEBUG
 
226
    fprintf(stderr, "Signature: '%s'\n", fc->parameters[fc->count - 1][1]);
 
227
#endif
 
228
   
 
229
    free(buf);
 
230
   
 
231
    flickcurl_end_params(fc);
 
232
  }
 
233
 
 
234
  /* add &s between parameters */
 
235
  full_uri_len += fc->count - 1;
 
236
 
 
237
  /* reuse or grow uri buffer */
 
238
  if(fc->uri_len < full_uri_len) {
 
239
    free(fc->uri);
 
240
    fc->uri = (char*)malloc(full_uri_len + 1);
 
241
    fc->uri_len = full_uri_len;
 
242
  }
 
243
  memcpy(fc->uri, url, fc_uri_len);
 
244
  fc->uri[fc_uri_len] = '\0';
 
245
 
 
246
  if(parameters_in_url) {
 
247
    char* p = fc->uri + fc_uri_len;
 
248
 
 
249
    for(i = 0; fc->parameters[i][0]; i++) {
 
250
      char *value = (char*)fc->parameters[i][1];
 
251
      int value_is_escaped = 0;
 
252
      size_t len;
 
253
 
 
254
      if(!fc->parameters[i][1])
 
255
        continue;
 
256
 
 
257
      len = strlen(fc->parameters[i][0]);
 
258
      memcpy(p, fc->parameters[i][0], len);
 
259
      p += len;
 
260
      *p++ = '=';
 
261
 
 
262
      len = values_len[i];
 
263
      if(!strcmp(fc->parameters[i][0], "method")) {
 
264
        /* do not touch method name */
 
265
      } else {
 
266
        value = curl_escape(value, len);
 
267
        len = strlen(value);
 
268
        value_is_escaped = 1;
 
269
      }
 
270
 
 
271
      memcpy(p, value, len);
 
272
      p += len;
 
273
 
 
274
      if(value_is_escaped)
 
275
        curl_free(value);
 
276
 
 
277
      *p++ = '&';
 
278
    }
 
279
 
 
280
    /* zap last & and terminate fc->url */
 
281
    *--p = '\0';
 
282
  }
 
283
 
 
284
#ifdef FLICKCURL_DEBUG
 
285
  fprintf(stderr, "URI is '%s'\n", fc->uri);
 
286
 
 
287
  FLICKCURL_ASSERT((strlen(fc->uri) == full_uri_len),
 
288
                   "Final URI does not match expected length");
 
289
#endif
 
290
 
 
291
  if(md5_string)
 
292
    free(md5_string);
 
293
 
 
294
  if(values_len)
 
295
    free(values_len);
 
296
 
 
297
  return 0;
 
298
}
 
299
 
 
300