OAuth library for twitter. Original: http://mbed.org/users/soramimi/programs/Twitter/

Dependents:   OAuth4Tw

Committer:
takahashim
Date:
Mon Dec 12 18:47:10 2011 +0000
Revision:
0:0048b264a3ad
publish library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
takahashim 0:0048b264a3ad 1 /*
takahashim 0:0048b264a3ad 2 * OAuth string functions in POSIX-C.
takahashim 0:0048b264a3ad 3 *
takahashim 0:0048b264a3ad 4 * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
takahashim 0:0048b264a3ad 5 *
takahashim 0:0048b264a3ad 6 * The base64 functions are by Jan-Henrik Haukeland, <hauk@tildeslash.com>
takahashim 0:0048b264a3ad 7 * and un/escape_url() was inspired by libcurl's curl_escape under ISC-license
takahashim 0:0048b264a3ad 8 * many thanks to Daniel Stenberg <daniel@haxx.se>.
takahashim 0:0048b264a3ad 9 *
takahashim 0:0048b264a3ad 10 * Permission is hereby granted, free of charge, to any person obtaining a copy
takahashim 0:0048b264a3ad 11 * of this software and associated documentation files (the "Software"), to deal
takahashim 0:0048b264a3ad 12 * in the Software without restriction, including without limitation the rights
takahashim 0:0048b264a3ad 13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
takahashim 0:0048b264a3ad 14 * copies of the Software, and to permit persons to whom the Software is
takahashim 0:0048b264a3ad 15 * furnished to do so, subject to the following conditions:
takahashim 0:0048b264a3ad 16 *
takahashim 0:0048b264a3ad 17 * The above copyright notice and this permission notice shall be included in
takahashim 0:0048b264a3ad 18 * all copies or substantial portions of the Software.
takahashim 0:0048b264a3ad 19 *
takahashim 0:0048b264a3ad 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
takahashim 0:0048b264a3ad 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
takahashim 0:0048b264a3ad 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
takahashim 0:0048b264a3ad 23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
takahashim 0:0048b264a3ad 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
takahashim 0:0048b264a3ad 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
takahashim 0:0048b264a3ad 26 * THE SOFTWARE.
takahashim 0:0048b264a3ad 27 *
takahashim 0:0048b264a3ad 28 */
takahashim 0:0048b264a3ad 29 #if HAVE_CONFIG_H
takahashim 0:0048b264a3ad 30 # include <config.h>
takahashim 0:0048b264a3ad 31 #endif
takahashim 0:0048b264a3ad 32
takahashim 0:0048b264a3ad 33 #define WIPE_MEMORY ///< overwrite sensitve data before free()ing it.
takahashim 0:0048b264a3ad 34
takahashim 0:0048b264a3ad 35 #include <stdio.h>
takahashim 0:0048b264a3ad 36 #include <stdarg.h>
takahashim 0:0048b264a3ad 37 #include <stdlib.h>
takahashim 0:0048b264a3ad 38 #include <string.h>
takahashim 0:0048b264a3ad 39 #include <time.h>
takahashim 0:0048b264a3ad 40 #include <math.h>
takahashim 0:0048b264a3ad 41 #include <ctype.h> // isxdigit
takahashim 0:0048b264a3ad 42
takahashim 0:0048b264a3ad 43 #include "oauth.h"
takahashim 0:0048b264a3ad 44
takahashim 0:0048b264a3ad 45 #include <vector>
takahashim 0:0048b264a3ad 46 #include <algorithm>
takahashim 0:0048b264a3ad 47 #include <sstream>
takahashim 0:0048b264a3ad 48
takahashim 0:0048b264a3ad 49 /**
takahashim 0:0048b264a3ad 50 * Base64 encode one byte
takahashim 0:0048b264a3ad 51 */
takahashim 0:0048b264a3ad 52 char oauth_b64_encode(unsigned char u)
takahashim 0:0048b264a3ad 53 {
takahashim 0:0048b264a3ad 54 if (u < 26) return 'A' + u;
takahashim 0:0048b264a3ad 55 if (u < 52) return 'a' + (u - 26);
takahashim 0:0048b264a3ad 56 if (u < 62) return '0' + (u - 52);
takahashim 0:0048b264a3ad 57 if (u == 62) return '+';
takahashim 0:0048b264a3ad 58 return '/';
takahashim 0:0048b264a3ad 59 }
takahashim 0:0048b264a3ad 60
takahashim 0:0048b264a3ad 61 /**
takahashim 0:0048b264a3ad 62 * Decode a single base64 character.
takahashim 0:0048b264a3ad 63 */
takahashim 0:0048b264a3ad 64 unsigned char oauth_b64_decode(char c)
takahashim 0:0048b264a3ad 65 {
takahashim 0:0048b264a3ad 66 if (c >= 'A' && c <= 'Z') return(c - 'A');
takahashim 0:0048b264a3ad 67 if (c >= 'a' && c <= 'z') return(c - 'a' + 26);
takahashim 0:0048b264a3ad 68 if (c >= '0' && c <= '9') return(c - '0' + 52);
takahashim 0:0048b264a3ad 69 if (c == '+') return 62;
takahashim 0:0048b264a3ad 70 return 63;
takahashim 0:0048b264a3ad 71 }
takahashim 0:0048b264a3ad 72
takahashim 0:0048b264a3ad 73 /**
takahashim 0:0048b264a3ad 74 * Return TRUE if 'c' is a valid base64 character, otherwise FALSE
takahashim 0:0048b264a3ad 75 */
takahashim 0:0048b264a3ad 76 bool oauth_b64_is_base64(char c)
takahashim 0:0048b264a3ad 77 {
takahashim 0:0048b264a3ad 78 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/') || (c == '='));
takahashim 0:0048b264a3ad 79 }
takahashim 0:0048b264a3ad 80
takahashim 0:0048b264a3ad 81 /**
takahashim 0:0048b264a3ad 82 * Base64 encode and return size data in 'src'. The caller must free the
takahashim 0:0048b264a3ad 83 * returned string.
takahashim 0:0048b264a3ad 84 *
takahashim 0:0048b264a3ad 85 * @param size The size of the data in src
takahashim 0:0048b264a3ad 86 * @param src The data to be base64 encode
takahashim 0:0048b264a3ad 87 * @return encoded string otherwise NULL
takahashim 0:0048b264a3ad 88 */
takahashim 0:0048b264a3ad 89 std::string oauth_encode_base64(const unsigned char *src, int size)
takahashim 0:0048b264a3ad 90 {
takahashim 0:0048b264a3ad 91 int i;
takahashim 0:0048b264a3ad 92 std::stringbuf sb;
takahashim 0:0048b264a3ad 93
takahashim 0:0048b264a3ad 94 if (!src) return NULL;
takahashim 0:0048b264a3ad 95 if (!size) size= strlen((char *)src);
takahashim 0:0048b264a3ad 96
takahashim 0:0048b264a3ad 97 for (i = 0; i < size; i += 3) {
takahashim 0:0048b264a3ad 98 unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0;
takahashim 0:0048b264a3ad 99 b1= src[i];
takahashim 0:0048b264a3ad 100 if (i + 1 < size) b2 = src[i + 1];
takahashim 0:0048b264a3ad 101 if (i + 2 < size) b3 = src[i + 2];
takahashim 0:0048b264a3ad 102
takahashim 0:0048b264a3ad 103 b4= b1 >> 2;
takahashim 0:0048b264a3ad 104 b5= ((b1 & 0x3) << 4) | (b2 >> 4);
takahashim 0:0048b264a3ad 105 b6= ((b2 & 0xf) << 2) | (b3 >> 6);
takahashim 0:0048b264a3ad 106 b7= b3 & 0x3f;
takahashim 0:0048b264a3ad 107
takahashim 0:0048b264a3ad 108 sb.sputc(oauth_b64_encode(b4));
takahashim 0:0048b264a3ad 109 sb.sputc(oauth_b64_encode(b5));
takahashim 0:0048b264a3ad 110
takahashim 0:0048b264a3ad 111 if (i + 1 < size) {
takahashim 0:0048b264a3ad 112 sb.sputc(oauth_b64_encode(b6));
takahashim 0:0048b264a3ad 113 } else {
takahashim 0:0048b264a3ad 114 sb.sputc('=');
takahashim 0:0048b264a3ad 115 }
takahashim 0:0048b264a3ad 116
takahashim 0:0048b264a3ad 117 if (i + 2 < size) {
takahashim 0:0048b264a3ad 118 sb.sputc(oauth_b64_encode(b7));
takahashim 0:0048b264a3ad 119 } else {
takahashim 0:0048b264a3ad 120 sb.sputc('=');
takahashim 0:0048b264a3ad 121 }
takahashim 0:0048b264a3ad 122 }
takahashim 0:0048b264a3ad 123 return sb.str();
takahashim 0:0048b264a3ad 124 }
takahashim 0:0048b264a3ad 125
takahashim 0:0048b264a3ad 126 /**
takahashim 0:0048b264a3ad 127 * Decode the base64 encoded string 'src' into the memory pointed to by
takahashim 0:0048b264a3ad 128 * 'dest'.
takahashim 0:0048b264a3ad 129 *
takahashim 0:0048b264a3ad 130 * @param dest Pointer to memory for holding the decoded string.
takahashim 0:0048b264a3ad 131 * Must be large enough to receive the decoded string.
takahashim 0:0048b264a3ad 132 * @param src A base64 encoded string.
takahashim 0:0048b264a3ad 133 * @return the length of the decoded string if decode
takahashim 0:0048b264a3ad 134 * succeeded otherwise 0.
takahashim 0:0048b264a3ad 135 */
takahashim 0:0048b264a3ad 136 std::string oauth_decode_base64(const char *src)
takahashim 0:0048b264a3ad 137 {
takahashim 0:0048b264a3ad 138 if (src && *src) {
takahashim 0:0048b264a3ad 139 std::stringbuf sb;
takahashim 0:0048b264a3ad 140 //unsigned char *p= dest;
takahashim 0:0048b264a3ad 141 int k, l= strlen(src)+1;
takahashim 0:0048b264a3ad 142 std::vector<unsigned char> buf(l);
takahashim 0:0048b264a3ad 143
takahashim 0:0048b264a3ad 144 /* Ignore non base64 chars as per the POSIX standard */
takahashim 0:0048b264a3ad 145 for (k = 0, l = 0; src[k]; k++) {
takahashim 0:0048b264a3ad 146 if (oauth_b64_is_base64(src[k])) {
takahashim 0:0048b264a3ad 147 buf[l++]= src[k];
takahashim 0:0048b264a3ad 148 }
takahashim 0:0048b264a3ad 149 }
takahashim 0:0048b264a3ad 150
takahashim 0:0048b264a3ad 151 for (k = 0; k < l; k += 4) {
takahashim 0:0048b264a3ad 152 char c1='A', c2='A', c3='A', c4='A';
takahashim 0:0048b264a3ad 153 unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0;
takahashim 0:0048b264a3ad 154 c1= buf[k];
takahashim 0:0048b264a3ad 155
takahashim 0:0048b264a3ad 156 if (k + 1 < l) c2 = buf[k + 1];
takahashim 0:0048b264a3ad 157 if (k + 2 < l) c3 = buf[k + 2];
takahashim 0:0048b264a3ad 158 if (k + 3 < l) c4 = buf[k + 3];
takahashim 0:0048b264a3ad 159
takahashim 0:0048b264a3ad 160 b1 = oauth_b64_decode(c1);
takahashim 0:0048b264a3ad 161 b2 = oauth_b64_decode(c2);
takahashim 0:0048b264a3ad 162 b3 = oauth_b64_decode(c3);
takahashim 0:0048b264a3ad 163 b4 = oauth_b64_decode(c4);
takahashim 0:0048b264a3ad 164
takahashim 0:0048b264a3ad 165 sb.sputc((b1 << 2) | (b2 >> 4));
takahashim 0:0048b264a3ad 166
takahashim 0:0048b264a3ad 167 if (c3 != '=') sb.sputc(((b2 & 0xf) << 4) | (b3 >> 2));
takahashim 0:0048b264a3ad 168 if (c4 != '=') sb.sputc(((b3 & 0x3) << 6) | b4);
takahashim 0:0048b264a3ad 169 }
takahashim 0:0048b264a3ad 170
takahashim 0:0048b264a3ad 171 return sb.str();
takahashim 0:0048b264a3ad 172 }
takahashim 0:0048b264a3ad 173 return 0;
takahashim 0:0048b264a3ad 174 }
takahashim 0:0048b264a3ad 175
takahashim 0:0048b264a3ad 176 /**
takahashim 0:0048b264a3ad 177 * Escape 'string' according to RFC3986 and
takahashim 0:0048b264a3ad 178 * http://oauth.net/core/1.0/#encoding_parameters.
takahashim 0:0048b264a3ad 179 *
takahashim 0:0048b264a3ad 180 * @param string The data to be encoded
takahashim 0:0048b264a3ad 181 * @return encoded string otherwise NULL
takahashim 0:0048b264a3ad 182 * The caller must free the returned string.
takahashim 0:0048b264a3ad 183 */
takahashim 0:0048b264a3ad 184 std::string oauth_url_escape(const char *string)
takahashim 0:0048b264a3ad 185 {
takahashim 0:0048b264a3ad 186 unsigned char in;
takahashim 0:0048b264a3ad 187 size_t length;
takahashim 0:0048b264a3ad 188
takahashim 0:0048b264a3ad 189 if (!string) {
takahashim 0:0048b264a3ad 190 return std::string();
takahashim 0:0048b264a3ad 191 }
takahashim 0:0048b264a3ad 192
takahashim 0:0048b264a3ad 193 length = strlen(string);
takahashim 0:0048b264a3ad 194
takahashim 0:0048b264a3ad 195 std::stringbuf sb;
takahashim 0:0048b264a3ad 196
takahashim 0:0048b264a3ad 197 while (length--) {
takahashim 0:0048b264a3ad 198 in = *string;
takahashim 0:0048b264a3ad 199 if (strchr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_~.-", in)) {
takahashim 0:0048b264a3ad 200 sb.sputc(in);
takahashim 0:0048b264a3ad 201 } else {
takahashim 0:0048b264a3ad 202 char tmp[10];
takahashim 0:0048b264a3ad 203 snprintf(tmp, 4, "%%%02X", in);
takahashim 0:0048b264a3ad 204 sb.sputc(tmp[0]);
takahashim 0:0048b264a3ad 205 sb.sputc(tmp[1]);
takahashim 0:0048b264a3ad 206 sb.sputc(tmp[2]);
takahashim 0:0048b264a3ad 207 }
takahashim 0:0048b264a3ad 208 string++;
takahashim 0:0048b264a3ad 209 }
takahashim 0:0048b264a3ad 210 return sb.str();
takahashim 0:0048b264a3ad 211 }
takahashim 0:0048b264a3ad 212
takahashim 0:0048b264a3ad 213 #ifndef ISXDIGIT
takahashim 0:0048b264a3ad 214 # define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
takahashim 0:0048b264a3ad 215 #endif
takahashim 0:0048b264a3ad 216
takahashim 0:0048b264a3ad 217 /**
takahashim 0:0048b264a3ad 218 * Parse RFC3986 encoded 'string' back to unescaped version.
takahashim 0:0048b264a3ad 219 *
takahashim 0:0048b264a3ad 220 * @param string The data to be unescaped
takahashim 0:0048b264a3ad 221 * @param olen unless NULL the length of the returned string is stored there.
takahashim 0:0048b264a3ad 222 * @return decoded string or NULL
takahashim 0:0048b264a3ad 223 * The caller must free the returned string.
takahashim 0:0048b264a3ad 224 */
takahashim 0:0048b264a3ad 225 std::string oauth_url_unescape(const char *string)
takahashim 0:0048b264a3ad 226 {
takahashim 0:0048b264a3ad 227 size_t alloc, strindex=0;
takahashim 0:0048b264a3ad 228 unsigned char in;
takahashim 0:0048b264a3ad 229 long hex;
takahashim 0:0048b264a3ad 230
takahashim 0:0048b264a3ad 231 if (!string) return NULL;
takahashim 0:0048b264a3ad 232
takahashim 0:0048b264a3ad 233 alloc = strlen(string)+1;
takahashim 0:0048b264a3ad 234 std::vector<char> ns(alloc);
takahashim 0:0048b264a3ad 235
takahashim 0:0048b264a3ad 236 while(--alloc > 0) {
takahashim 0:0048b264a3ad 237 in = *string;
takahashim 0:0048b264a3ad 238 if (('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
takahashim 0:0048b264a3ad 239 char hexstr[3]; // '%XX'
takahashim 0:0048b264a3ad 240 hexstr[0] = string[1];
takahashim 0:0048b264a3ad 241 hexstr[1] = string[2];
takahashim 0:0048b264a3ad 242 hexstr[2] = 0;
takahashim 0:0048b264a3ad 243 hex = strtol(hexstr, NULL, 16);
takahashim 0:0048b264a3ad 244 in = (unsigned char)hex; /* hex is always < 256 */
takahashim 0:0048b264a3ad 245 string += 2;
takahashim 0:0048b264a3ad 246 alloc -= 2;
takahashim 0:0048b264a3ad 247 }
takahashim 0:0048b264a3ad 248 ns[strindex++] = in;
takahashim 0:0048b264a3ad 249 string++;
takahashim 0:0048b264a3ad 250 }
takahashim 0:0048b264a3ad 251 ns[strindex]=0;
takahashim 0:0048b264a3ad 252 return &ns[0];
takahashim 0:0048b264a3ad 253 }
takahashim 0:0048b264a3ad 254
takahashim 0:0048b264a3ad 255 /**
takahashim 0:0048b264a3ad 256 * returns plaintext signature for the given key.
takahashim 0:0048b264a3ad 257 *
takahashim 0:0048b264a3ad 258 * the returned string needs to be freed by the caller
takahashim 0:0048b264a3ad 259 *
takahashim 0:0048b264a3ad 260 * @param m message to be signed
takahashim 0:0048b264a3ad 261 * @param k key used for signing
takahashim 0:0048b264a3ad 262 * @return signature string
takahashim 0:0048b264a3ad 263 */
takahashim 0:0048b264a3ad 264 std::string oauth_sign_plaintext (const char *m, const char *k)
takahashim 0:0048b264a3ad 265 {
takahashim 0:0048b264a3ad 266 return oauth_url_escape(k);
takahashim 0:0048b264a3ad 267 }
takahashim 0:0048b264a3ad 268
takahashim 0:0048b264a3ad 269 /**
takahashim 0:0048b264a3ad 270 * encode strings and concatenate with '&' separator.
takahashim 0:0048b264a3ad 271 * The number of strings to be concatenated must be
takahashim 0:0048b264a3ad 272 * given as first argument.
takahashim 0:0048b264a3ad 273 * all arguments thereafter must be of type (char *)
takahashim 0:0048b264a3ad 274 *
takahashim 0:0048b264a3ad 275 * @param len the number of arguments to follow this parameter
takahashim 0:0048b264a3ad 276 * @param ... string to escape and added (may be NULL)
takahashim 0:0048b264a3ad 277 *
takahashim 0:0048b264a3ad 278 * @return pointer to memory holding the concatenated
takahashim 0:0048b264a3ad 279 * strings - needs to be free(d) by the caller. or NULL
takahashim 0:0048b264a3ad 280 * in case we ran out of memory.
takahashim 0:0048b264a3ad 281 */
takahashim 0:0048b264a3ad 282 std::string oauth_catenc(int len, ...)
takahashim 0:0048b264a3ad 283 {
takahashim 0:0048b264a3ad 284 va_list va;
takahashim 0:0048b264a3ad 285 std::string str;
takahashim 0:0048b264a3ad 286 va_start(va, len);
takahashim 0:0048b264a3ad 287 for (int i = 0; i < len; i++) {
takahashim 0:0048b264a3ad 288 char *arg = va_arg(va, char *);
takahashim 0:0048b264a3ad 289 std::string enc = oauth_url_escape(arg);
takahashim 0:0048b264a3ad 290 if (i > 0) str += "&";
takahashim 0:0048b264a3ad 291 str += enc;
takahashim 0:0048b264a3ad 292 }
takahashim 0:0048b264a3ad 293 va_end(va);
takahashim 0:0048b264a3ad 294 return str;
takahashim 0:0048b264a3ad 295 }
takahashim 0:0048b264a3ad 296
takahashim 0:0048b264a3ad 297 /**
takahashim 0:0048b264a3ad 298 * splits the given url into a parameter array.
takahashim 0:0048b264a3ad 299 * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse)
takahashim 0:0048b264a3ad 300 *
takahashim 0:0048b264a3ad 301 * NOTE: Request-parameters-values may include an ampersand character.
takahashim 0:0048b264a3ad 302 * However if unescaped this function will use them as parameter delimiter.
takahashim 0:0048b264a3ad 303 * If you need to make such a request, this function since version 0.3.5 allows
takahashim 0:0048b264a3ad 304 * to use the ASCII SOH (0x01) character as alias for '&' (0x26).
takahashim 0:0048b264a3ad 305 * (the motivation is convenience: SOH is /untypeable/ and much more
takahashim 0:0048b264a3ad 306 * unlikely to appear than '&' - If you plan to sign fancy URLs you
takahashim 0:0048b264a3ad 307 * should not split a query-string, but rather provide the parameter array
takahashim 0:0048b264a3ad 308 * directly to \ref oauth_serialize_url)
takahashim 0:0048b264a3ad 309 *
takahashim 0:0048b264a3ad 310 * @param url the url or query-string to parse.
takahashim 0:0048b264a3ad 311 * @param argv pointer to a (char *) array where the results are stored.
takahashim 0:0048b264a3ad 312 * The array is re-allocated to match the number of parameters and each
takahashim 0:0048b264a3ad 313 * parameter-string is allocated with strdup. - The memory needs to be freed
takahashim 0:0048b264a3ad 314 * by the caller.
takahashim 0:0048b264a3ad 315 * @param qesc use query parameter escape (vs post-param-escape) - if set
takahashim 0:0048b264a3ad 316 * to 1 all '+' are treated as spaces ' '
takahashim 0:0048b264a3ad 317 *
takahashim 0:0048b264a3ad 318 * @return number of parameter(s) in array.
takahashim 0:0048b264a3ad 319 */
takahashim 0:0048b264a3ad 320 void oauth_split_post_paramters(const char *url, std::vector<std::string> *argv, short qesc)
takahashim 0:0048b264a3ad 321 {
takahashim 0:0048b264a3ad 322 int argc=0;
takahashim 0:0048b264a3ad 323 char *token, *tmp;
takahashim 0:0048b264a3ad 324 if (!argv) return;
takahashim 0:0048b264a3ad 325 if (!url) return;
takahashim 0:0048b264a3ad 326 std::vector<char> t1(strlen(url) + 1);
takahashim 0:0048b264a3ad 327 strcpy(&t1[0], url);
takahashim 0:0048b264a3ad 328
takahashim 0:0048b264a3ad 329 // '+' represents a space, in a URL query string
takahashim 0:0048b264a3ad 330 while ((qesc&1) && (tmp = strchr(&t1[0],'+'))) *tmp = ' ';
takahashim 0:0048b264a3ad 331
takahashim 0:0048b264a3ad 332 tmp = &t1[0];
takahashim 0:0048b264a3ad 333 while ((token = strtok(tmp,"&?"))) {
takahashim 0:0048b264a3ad 334 if (!strncasecmp("oauth_signature=", token, 16)) continue;
takahashim 0:0048b264a3ad 335 while (!(qesc & 2) && (tmp = strchr(token, '\001'))) *tmp = '&';
takahashim 0:0048b264a3ad 336 argv->push_back(oauth_url_unescape(token));
takahashim 0:0048b264a3ad 337 if (argc == 0 && strstr(token, ":/")) {
takahashim 0:0048b264a3ad 338 // HTTP does not allow empty absolute paths, so the URL
takahashim 0:0048b264a3ad 339 // 'http://example.com' is equivalent to 'http://example.com/' and should
takahashim 0:0048b264a3ad 340 // be treated as such for the purposes of OAuth signing (rfc2616, section 3.2.1)
takahashim 0:0048b264a3ad 341 // see http://groups.google.com/group/oauth/browse_thread/thread/c44b6f061bfd98c?hl=en
takahashim 0:0048b264a3ad 342 char *slash = strstr(token, ":/");
takahashim 0:0048b264a3ad 343 while (slash && *(++slash) == '/') ; // skip slashes eg /xxx:[\/]*/
takahashim 0:0048b264a3ad 344 #if 0
takahashim 0:0048b264a3ad 345 // skip possibly unescaped slashes in the userinfo - they're not allowed by RFC2396 but have been seen.
takahashim 0:0048b264a3ad 346 // the hostname/IP may only contain alphanumeric characters - so we're safe there.
takahashim 0:0048b264a3ad 347 if (slash && strchr(slash,'@')) slash=strchr(slash, '@');
takahashim 0:0048b264a3ad 348 #endif
takahashim 0:0048b264a3ad 349 if (slash && !strchr(slash,'/')) {
takahashim 0:0048b264a3ad 350 #ifdef DEBUG_OAUTH
takahashim 0:0048b264a3ad 351 fprintf(stderr, "\nliboauth: added trailing slash to URL: '%s'\n\n", token);
takahashim 0:0048b264a3ad 352 #endif
takahashim 0:0048b264a3ad 353 argv->push_back(std::string(token) + "/");
takahashim 0:0048b264a3ad 354 }
takahashim 0:0048b264a3ad 355 }
takahashim 0:0048b264a3ad 356 if (argc == 0 && (tmp = strstr((char *)argv->at(argc).c_str(), ":80/"))) {
takahashim 0:0048b264a3ad 357 memmove(tmp, tmp + 3, strlen(tmp + 2));
takahashim 0:0048b264a3ad 358 }
takahashim 0:0048b264a3ad 359 tmp = NULL;
takahashim 0:0048b264a3ad 360 argc++;
takahashim 0:0048b264a3ad 361 }
takahashim 0:0048b264a3ad 362 }
takahashim 0:0048b264a3ad 363
takahashim 0:0048b264a3ad 364 void oauth_split_url_parameters(const char *url, std::vector<std::string> *argv)
takahashim 0:0048b264a3ad 365 {
takahashim 0:0048b264a3ad 366 oauth_split_post_paramters(url, argv, 1);
takahashim 0:0048b264a3ad 367 }
takahashim 0:0048b264a3ad 368
takahashim 0:0048b264a3ad 369 /**
takahashim 0:0048b264a3ad 370 * build a url query string from an array.
takahashim 0:0048b264a3ad 371 *
takahashim 0:0048b264a3ad 372 * @param argc the total number of elements in the array
takahashim 0:0048b264a3ad 373 * @param start element in the array at which to start concatenating.
takahashim 0:0048b264a3ad 374 * @param argv parameter-array to concatenate.
takahashim 0:0048b264a3ad 375 * @return url string needs to be freed by the caller.
takahashim 0:0048b264a3ad 376 *
takahashim 0:0048b264a3ad 377 */
takahashim 0:0048b264a3ad 378 std::string oauth_serialize_url (std::vector<std::string> const &argv, int start)
takahashim 0:0048b264a3ad 379 {
takahashim 0:0048b264a3ad 380 return oauth_serialize_url_sep(argv, start, "&", 0);
takahashim 0:0048b264a3ad 381 }
takahashim 0:0048b264a3ad 382
takahashim 0:0048b264a3ad 383 /**
takahashim 0:0048b264a3ad 384 * encode query parameters from an array.
takahashim 0:0048b264a3ad 385 *
takahashim 0:0048b264a3ad 386 * @param argc the total number of elements in the array
takahashim 0:0048b264a3ad 387 * @param start element in the array at which to start concatenating.
takahashim 0:0048b264a3ad 388 * @param argv parameter-array to concatenate.
takahashim 0:0048b264a3ad 389 * @param sep separator for parameters (usually "&")
takahashim 0:0048b264a3ad 390 * @param mod - bitwise modifiers:
takahashim 0:0048b264a3ad 391 * 1: skip all values that start with "oauth_"
takahashim 0:0048b264a3ad 392 * 2: skip all values that don't start with "oauth_"
takahashim 0:0048b264a3ad 393 * 4: add double quotation marks around values (use with sep=", " to generate HTTP Authorization header).
takahashim 0:0048b264a3ad 394 * @return url string needs to be freed by the caller.
takahashim 0:0048b264a3ad 395 */
takahashim 0:0048b264a3ad 396 std::string oauth_serialize_url_sep(std::vector<std::string> const &argv, int start, char const *sep, int mod)
takahashim 0:0048b264a3ad 397 {
takahashim 0:0048b264a3ad 398 int i;
takahashim 0:0048b264a3ad 399 int first = 0;
takahashim 0:0048b264a3ad 400 int seplen = strlen(sep);
takahashim 0:0048b264a3ad 401 std::string query;
takahashim 0:0048b264a3ad 402 for (i = start; i < (int)argv.size(); i++) {
takahashim 0:0048b264a3ad 403 std::string tmp;
takahashim 0:0048b264a3ad 404
takahashim 0:0048b264a3ad 405 if ((mod & 1) == 1 && (strncmp(argv[i].c_str(), "oauth_", 6) == 0 || strncmp(argv[i].c_str(), "x_oauth_", 8) == 0)) continue;
takahashim 0:0048b264a3ad 406 if ((mod & 2) == 2 && (strncmp(argv[i].c_str(), "oauth_", 6) != 0 && strncmp(argv[i].c_str(), "x_oauth_", 8) != 0) && i != 0) continue;
takahashim 0:0048b264a3ad 407
takahashim 0:0048b264a3ad 408 if (i == start && i == 0 && strstr(argv[i].c_str(), ":/")) {
takahashim 0:0048b264a3ad 409 tmp = argv[i];
takahashim 0:0048b264a3ad 410 } else {
takahashim 0:0048b264a3ad 411 char *p = strchr((char *)argv[i].c_str(), '=');
takahashim 0:0048b264a3ad 412 if (p) {
takahashim 0:0048b264a3ad 413 tmp = oauth_url_escape(std::string(argv[i].c_str(), (char const *)p).c_str());
takahashim 0:0048b264a3ad 414 std::string t2 = oauth_url_escape(p + 1);
takahashim 0:0048b264a3ad 415 tmp += "=";
takahashim 0:0048b264a3ad 416 if (mod & 4) tmp += "\"";
takahashim 0:0048b264a3ad 417 tmp += t2;
takahashim 0:0048b264a3ad 418 if (mod & 4) tmp += "\"";
takahashim 0:0048b264a3ad 419 } else {
takahashim 0:0048b264a3ad 420 // see http://oauth.net/core/1.0/#anchor14
takahashim 0:0048b264a3ad 421 // escape parameter names and arguments but not the '='
takahashim 0:0048b264a3ad 422 tmp=argv[i];
takahashim 0:0048b264a3ad 423 tmp += "=";
takahashim 0:0048b264a3ad 424 }
takahashim 0:0048b264a3ad 425 }
takahashim 0:0048b264a3ad 426 query += ((i == start || first) ? "" : sep);
takahashim 0:0048b264a3ad 427 query += tmp;
takahashim 0:0048b264a3ad 428 first = 0;
takahashim 0:0048b264a3ad 429 if (i == start && i == 0 && strstr((char *)tmp.c_str(), ":/")) {
takahashim 0:0048b264a3ad 430 query += "?";
takahashim 0:0048b264a3ad 431 first = 1;
takahashim 0:0048b264a3ad 432 }
takahashim 0:0048b264a3ad 433 }
takahashim 0:0048b264a3ad 434 return (query);
takahashim 0:0048b264a3ad 435 }
takahashim 0:0048b264a3ad 436
takahashim 0:0048b264a3ad 437 /**
takahashim 0:0048b264a3ad 438 * build a query parameter string from an array.
takahashim 0:0048b264a3ad 439 *
takahashim 0:0048b264a3ad 440 * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv).
takahashim 0:0048b264a3ad 441 * It strips the leading host/path, which is usually the first
takahashim 0:0048b264a3ad 442 * element when using oauth_split_url_parameters on an URL.
takahashim 0:0048b264a3ad 443 *
takahashim 0:0048b264a3ad 444 * @param argc the total number of elements in the array
takahashim 0:0048b264a3ad 445 * @param argv parameter-array to concatenate.
takahashim 0:0048b264a3ad 446 * @return url string needs to be freed by the caller.
takahashim 0:0048b264a3ad 447 */
takahashim 0:0048b264a3ad 448 std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv)
takahashim 0:0048b264a3ad 449 {
takahashim 0:0048b264a3ad 450 return oauth_serialize_url(argv, 1);
takahashim 0:0048b264a3ad 451 }
takahashim 0:0048b264a3ad 452
takahashim 0:0048b264a3ad 453 /**
takahashim 0:0048b264a3ad 454 * generate a random string between 15 and 32 chars length
takahashim 0:0048b264a3ad 455 * and return a pointer to it. The value needs to be freed by the
takahashim 0:0048b264a3ad 456 * caller
takahashim 0:0048b264a3ad 457 *
takahashim 0:0048b264a3ad 458 * @return zero terminated random string.
takahashim 0:0048b264a3ad 459 */
takahashim 0:0048b264a3ad 460 std::string oauth_gen_nonce()
takahashim 0:0048b264a3ad 461 {
takahashim 0:0048b264a3ad 462 static const char *chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
takahashim 0:0048b264a3ad 463 const unsigned int max = 26 + 26 + 10 + 1; //strlen(chars);
takahashim 0:0048b264a3ad 464 char tmp[50];
takahashim 0:0048b264a3ad 465 int i, len;
takahashim 0:0048b264a3ad 466
takahashim 0:0048b264a3ad 467 srand((unsigned int)time(0));
takahashim 0:0048b264a3ad 468 len = 15 + rand() % 16;
takahashim 0:0048b264a3ad 469 for (i = 0; i < len; i++) {
takahashim 0:0048b264a3ad 470 tmp[i] = chars[rand() % max];
takahashim 0:0048b264a3ad 471 }
takahashim 0:0048b264a3ad 472 tmp[i]='\0';
takahashim 0:0048b264a3ad 473 return &tmp[0];
takahashim 0:0048b264a3ad 474 }
takahashim 0:0048b264a3ad 475
takahashim 0:0048b264a3ad 476 /**
takahashim 0:0048b264a3ad 477 * string compare function for oauth parameters.
takahashim 0:0048b264a3ad 478 *
takahashim 0:0048b264a3ad 479 * used with qsort. needed to normalize request parameters.
takahashim 0:0048b264a3ad 480 * see http://oauth.net/core/1.0/#anchor14
takahashim 0:0048b264a3ad 481 */
takahashim 0:0048b264a3ad 482 int oauth_cmpstringp(const void *p1, const void *p2)
takahashim 0:0048b264a3ad 483 {
takahashim 0:0048b264a3ad 484 char const *e1;
takahashim 0:0048b264a3ad 485 char const *e2;
takahashim 0:0048b264a3ad 486 e1 = strchr((char *)p1, '=');
takahashim 0:0048b264a3ad 487 e2 = strchr((char *)p2, '=');
takahashim 0:0048b264a3ad 488 if (e1 && e2) {
takahashim 0:0048b264a3ad 489 std::string left((char const *)p1, e1);
takahashim 0:0048b264a3ad 490 std::string right((char const *)p2, e2);
takahashim 0:0048b264a3ad 491 return strcmp(left.c_str(), right.c_str());
takahashim 0:0048b264a3ad 492 }
takahashim 0:0048b264a3ad 493
takahashim 0:0048b264a3ad 494 std::string left = oauth_url_escape((char const *)p1);
takahashim 0:0048b264a3ad 495 std::string right = oauth_url_escape((char const *)p2);
takahashim 0:0048b264a3ad 496 return strcmp(left.c_str(), right.c_str());
takahashim 0:0048b264a3ad 497 }
takahashim 0:0048b264a3ad 498
takahashim 0:0048b264a3ad 499 bool oauth_cmpstringp_ex(std::string const &left, std::string const &right)
takahashim 0:0048b264a3ad 500 {
takahashim 0:0048b264a3ad 501 return oauth_cmpstringp(left.c_str(), right.c_str()) < 0;
takahashim 0:0048b264a3ad 502 }
takahashim 0:0048b264a3ad 503
takahashim 0:0048b264a3ad 504 /**
takahashim 0:0048b264a3ad 505 * search array for parameter key.
takahashim 0:0048b264a3ad 506 * @param argv length of array to search
takahashim 0:0048b264a3ad 507 * @param argc parameter array to search
takahashim 0:0048b264a3ad 508 * @param key key of parameter to check.
takahashim 0:0048b264a3ad 509 *
takahashim 0:0048b264a3ad 510 * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise.
takahashim 0:0048b264a3ad 511 */
takahashim 0:0048b264a3ad 512 bool oauth_param_exists(std::vector<std::string> const &argv, char const *key)
takahashim 0:0048b264a3ad 513 {
takahashim 0:0048b264a3ad 514 int i;
takahashim 0:0048b264a3ad 515 size_t l = strlen(key);
takahashim 0:0048b264a3ad 516 for (i = 0; i < (int)argv.size(); i++) {
takahashim 0:0048b264a3ad 517 if (!strncmp(argv[i].c_str(), key, l) && argv[i][l] == '=') {
takahashim 0:0048b264a3ad 518 return true;
takahashim 0:0048b264a3ad 519 }
takahashim 0:0048b264a3ad 520 }
takahashim 0:0048b264a3ad 521 return false;
takahashim 0:0048b264a3ad 522 }
takahashim 0:0048b264a3ad 523
takahashim 0:0048b264a3ad 524 /**
takahashim 0:0048b264a3ad 525 *
takahashim 0:0048b264a3ad 526 */
takahashim 0:0048b264a3ad 527 void oauth_add_protocol(
takahashim 0:0048b264a3ad 528 std::vector<std::string> *argvp,
takahashim 0:0048b264a3ad 529 OAuthMethod method,
takahashim 0:0048b264a3ad 530 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 531 const char *t_key //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 532 )
takahashim 0:0048b264a3ad 533 {
takahashim 0:0048b264a3ad 534 char oarg[1024];
takahashim 0:0048b264a3ad 535
takahashim 0:0048b264a3ad 536 // add OAuth specific arguments
takahashim 0:0048b264a3ad 537 if (!oauth_param_exists(*argvp,"oauth_nonce")) {
takahashim 0:0048b264a3ad 538 std::string tmp = oauth_gen_nonce();
takahashim 0:0048b264a3ad 539 snprintf(oarg, 1024, "oauth_nonce=%s", tmp.c_str());
takahashim 0:0048b264a3ad 540 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 541 }
takahashim 0:0048b264a3ad 542
takahashim 0:0048b264a3ad 543 if (!oauth_param_exists(*argvp,"oauth_timestamp")) {
takahashim 0:0048b264a3ad 544 long t = time(0);
takahashim 0:0048b264a3ad 545 snprintf(oarg, 1024, "oauth_timestamp=%u", t);
takahashim 0:0048b264a3ad 546 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 547 }
takahashim 0:0048b264a3ad 548
takahashim 0:0048b264a3ad 549 if (t_key) {
takahashim 0:0048b264a3ad 550 snprintf(oarg, 1024, "oauth_token=%s", t_key);
takahashim 0:0048b264a3ad 551 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 552 }
takahashim 0:0048b264a3ad 553
takahashim 0:0048b264a3ad 554 snprintf(oarg, 1024, "oauth_consumer_key=%s", c_key);
takahashim 0:0048b264a3ad 555 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 556
takahashim 0:0048b264a3ad 557 snprintf(oarg, 1024, "oauth_signature_method=%s", method==0?"HMAC-SHA1":method==1?"RSA-SHA1":"PLAINTEXT");
takahashim 0:0048b264a3ad 558 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 559
takahashim 0:0048b264a3ad 560 if (!oauth_param_exists(*argvp,"oauth_version")) {
takahashim 0:0048b264a3ad 561 snprintf(oarg, 1024, "oauth_version=1.0");
takahashim 0:0048b264a3ad 562 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 563 }
takahashim 0:0048b264a3ad 564
takahashim 0:0048b264a3ad 565 #if 0 // oauth_version 1.0 Rev A
takahashim 0:0048b264a3ad 566 if (!oauth_param_exists(argv,argc,"oauth_callback")) {
takahashim 0:0048b264a3ad 567 snprintf(oarg, 1024, "oauth_callback=oob");
takahashim 0:0048b264a3ad 568 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 569 }
takahashim 0:0048b264a3ad 570 #endif
takahashim 0:0048b264a3ad 571
takahashim 0:0048b264a3ad 572 }
takahashim 0:0048b264a3ad 573
takahashim 0:0048b264a3ad 574 std::string oauth_sign_url(
takahashim 0:0048b264a3ad 575 const char *url,
takahashim 0:0048b264a3ad 576 std::string *postargs,
takahashim 0:0048b264a3ad 577 OAuthMethod method,
takahashim 0:0048b264a3ad 578 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 579 const char *c_secret, //< consumer secret - used as 1st part of secret-key
takahashim 0:0048b264a3ad 580 const char *t_key, //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 581 const char *t_secret //< token secret - used as 2st part of secret-key
takahashim 0:0048b264a3ad 582 )
takahashim 0:0048b264a3ad 583 {
takahashim 0:0048b264a3ad 584 return oauth_sign_url2(url, postargs, method, NULL, c_key, c_secret, t_key, t_secret);
takahashim 0:0048b264a3ad 585 }
takahashim 0:0048b264a3ad 586
takahashim 0:0048b264a3ad 587 std::string oauth_sign_url2(
takahashim 0:0048b264a3ad 588 const char *url,
takahashim 0:0048b264a3ad 589 std::string *postargs,
takahashim 0:0048b264a3ad 590 OAuthMethod method,
takahashim 0:0048b264a3ad 591 const char *http_method, //< HTTP request method
takahashim 0:0048b264a3ad 592 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 593 const char *c_secret, //< consumer secret - used as 1st part of secret-key
takahashim 0:0048b264a3ad 594 const char *t_key, //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 595 const char *t_secret //< token secret - used as 2st part of secret-key
takahashim 0:0048b264a3ad 596 )
takahashim 0:0048b264a3ad 597 {
takahashim 0:0048b264a3ad 598 //char **argv = NULL;
takahashim 0:0048b264a3ad 599 std::vector<std::string> argv;
takahashim 0:0048b264a3ad 600 std::string rv;
takahashim 0:0048b264a3ad 601
takahashim 0:0048b264a3ad 602 if (postargs) {
takahashim 0:0048b264a3ad 603 oauth_split_post_paramters(url, &argv, 0);
takahashim 0:0048b264a3ad 604 } else {
takahashim 0:0048b264a3ad 605 oauth_split_url_parameters(url, &argv);
takahashim 0:0048b264a3ad 606 }
takahashim 0:0048b264a3ad 607
takahashim 0:0048b264a3ad 608 rv = oauth_sign_array2(&argv, postargs, method, http_method, c_key, c_secret, t_key, t_secret);
takahashim 0:0048b264a3ad 609
takahashim 0:0048b264a3ad 610 return(rv);
takahashim 0:0048b264a3ad 611 }
takahashim 0:0048b264a3ad 612
takahashim 0:0048b264a3ad 613 std::string oauth_sign_array(
takahashim 0:0048b264a3ad 614 std::vector<std::string> *argvp,
takahashim 0:0048b264a3ad 615 std::string *postargs,
takahashim 0:0048b264a3ad 616 OAuthMethod method,
takahashim 0:0048b264a3ad 617 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 618 const char *c_secret, //< consumer secret - used as 1st part of secret-key
takahashim 0:0048b264a3ad 619 const char *t_key, //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 620 const char *t_secret //< token secret - used as 2st part of secret-key
takahashim 0:0048b264a3ad 621 )
takahashim 0:0048b264a3ad 622 {
takahashim 0:0048b264a3ad 623 return oauth_sign_array2(
takahashim 0:0048b264a3ad 624 argvp,
takahashim 0:0048b264a3ad 625 postargs, method,
takahashim 0:0048b264a3ad 626 NULL,
takahashim 0:0048b264a3ad 627 c_key, c_secret,
takahashim 0:0048b264a3ad 628 t_key, t_secret
takahashim 0:0048b264a3ad 629 );
takahashim 0:0048b264a3ad 630 }
takahashim 0:0048b264a3ad 631
takahashim 0:0048b264a3ad 632 void oauth_sign_array2_process(
takahashim 0:0048b264a3ad 633 std::vector<std::string> *argvp,
takahashim 0:0048b264a3ad 634 std::string *postargs,
takahashim 0:0048b264a3ad 635 OAuthMethod method,
takahashim 0:0048b264a3ad 636 const char *http_method, //< HTTP request method
takahashim 0:0048b264a3ad 637 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 638 const char *c_secret, //< consumer secret - used as 1st part of secret-key
takahashim 0:0048b264a3ad 639 const char *t_key, //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 640 const char *t_secret //< token secret - used as 2st part of secret-key
takahashim 0:0048b264a3ad 641 )
takahashim 0:0048b264a3ad 642 {
takahashim 0:0048b264a3ad 643 char oarg[1024];
takahashim 0:0048b264a3ad 644 std::string query;
takahashim 0:0048b264a3ad 645 std::string sign;
takahashim 0:0048b264a3ad 646 std::string http_request_method;
takahashim 0:0048b264a3ad 647
takahashim 0:0048b264a3ad 648 if (!http_method) {
takahashim 0:0048b264a3ad 649 http_request_method = postargs ? "POST" : "GET";
takahashim 0:0048b264a3ad 650 } else {
takahashim 0:0048b264a3ad 651 std::vector<char> tmp(strlen(http_method) + 1);
takahashim 0:0048b264a3ad 652 int i;
takahashim 0:0048b264a3ad 653 for (i = 0; http_method[i]; i++) {
takahashim 0:0048b264a3ad 654 tmp[i] = toupper(http_method[i]);
takahashim 0:0048b264a3ad 655 }
takahashim 0:0048b264a3ad 656 tmp[i] = 0;
takahashim 0:0048b264a3ad 657 http_request_method = &tmp[0];
takahashim 0:0048b264a3ad 658 }
takahashim 0:0048b264a3ad 659
takahashim 0:0048b264a3ad 660 // add required OAuth protocol parameters
takahashim 0:0048b264a3ad 661 oauth_add_protocol(argvp, method, c_key, t_key);
takahashim 0:0048b264a3ad 662
takahashim 0:0048b264a3ad 663 // sort parameters
takahashim 0:0048b264a3ad 664 //qsort(&(*argvp)[1], (*argcp)-1, sizeof(char *), oauth_cmpstringp);
takahashim 0:0048b264a3ad 665 std::sort(argvp->begin() + 1, argvp->end(), oauth_cmpstringp_ex);
takahashim 0:0048b264a3ad 666
takahashim 0:0048b264a3ad 667 // serialize URL - base-url
takahashim 0:0048b264a3ad 668 query= oauth_serialize_url_parameters(*argvp);
takahashim 0:0048b264a3ad 669
takahashim 0:0048b264a3ad 670 // generate signature
takahashim 0:0048b264a3ad 671 std::string okey = oauth_catenc(2, c_secret, t_secret);
takahashim 0:0048b264a3ad 672 std::string odat = oauth_catenc(3, http_request_method.c_str(), (*argvp)[0].c_str(), query.c_str()); // base-string
takahashim 0:0048b264a3ad 673 #ifdef DEBUG_OAUTH
takahashim 0:0048b264a3ad 674 fprintf (stderr, "\nliboauth: data to sign='%s'\n\n", odat.c_str());
takahashim 0:0048b264a3ad 675 fprintf (stderr, "\nliboauth: key='%s'\n\n", okey.c_str());
takahashim 0:0048b264a3ad 676 #endif
takahashim 0:0048b264a3ad 677 switch(method) {
takahashim 0:0048b264a3ad 678 //case OA_RSA:
takahashim 0:0048b264a3ad 679 // sign = oauth_sign_rsa_sha1(odat.c_str(), okey.c_str()); // XXX okey needs to be RSA key!
takahashim 0:0048b264a3ad 680 // break;
takahashim 0:0048b264a3ad 681 case OA_PLAINTEXT:
takahashim 0:0048b264a3ad 682 sign = oauth_sign_plaintext(odat.c_str(), okey.c_str()).c_str();
takahashim 0:0048b264a3ad 683 break;
takahashim 0:0048b264a3ad 684 default:
takahashim 0:0048b264a3ad 685 sign = oauth_sign_hmac_sha1(odat.c_str(), okey.c_str());
takahashim 0:0048b264a3ad 686 break;
takahashim 0:0048b264a3ad 687 }
takahashim 0:0048b264a3ad 688
takahashim 0:0048b264a3ad 689 // append signature to query args.
takahashim 0:0048b264a3ad 690 snprintf(oarg, 1024, "oauth_signature=%s",sign.c_str());
takahashim 0:0048b264a3ad 691 argvp->push_back(oarg);
takahashim 0:0048b264a3ad 692 }
takahashim 0:0048b264a3ad 693
takahashim 0:0048b264a3ad 694 std::string oauth_sign_array2(
takahashim 0:0048b264a3ad 695 std::vector<std::string> *argvp,
takahashim 0:0048b264a3ad 696 std::string *postargs,
takahashim 0:0048b264a3ad 697 OAuthMethod method,
takahashim 0:0048b264a3ad 698 const char *http_method, //< HTTP request method
takahashim 0:0048b264a3ad 699 const char *c_key, //< consumer key - posted plain text
takahashim 0:0048b264a3ad 700 const char *c_secret, //< consumer secret - used as 1st part of secret-key
takahashim 0:0048b264a3ad 701 const char *t_key, //< token key - posted plain text in URL
takahashim 0:0048b264a3ad 702 const char *t_secret //< token secret - used as 2st part of secret-key
takahashim 0:0048b264a3ad 703 )
takahashim 0:0048b264a3ad 704 {
takahashim 0:0048b264a3ad 705
takahashim 0:0048b264a3ad 706 std::string result;
takahashim 0:0048b264a3ad 707 oauth_sign_array2_process(argvp, postargs, method, http_method, c_key, c_secret, t_key, t_secret);
takahashim 0:0048b264a3ad 708
takahashim 0:0048b264a3ad 709 // build URL params
takahashim 0:0048b264a3ad 710 result = oauth_serialize_url(*argvp, (postargs?1:0));
takahashim 0:0048b264a3ad 711
takahashim 0:0048b264a3ad 712 if (postargs) {
takahashim 0:0048b264a3ad 713 *postargs = result;
takahashim 0:0048b264a3ad 714 result = argvp->at(0);
takahashim 0:0048b264a3ad 715 }
takahashim 0:0048b264a3ad 716
takahashim 0:0048b264a3ad 717 return result;
takahashim 0:0048b264a3ad 718 }
takahashim 0:0048b264a3ad 719