Fixed compatibility for HTTPClient Library. (HTTPClient by Donatien Garnier)

Dependents:   FlashAir_Twitter CyaSSL-Twitter-OAuth4Tw TweetTest NetworkThermometer ... more

Fork of OAuth4Tw by Masayoshi Takahashi

Committer:
ban4jp
Date:
Tue Jul 14 09:31:13 2015 +0000
Revision:
5:5146becb651f
Parent:
3:c28b796ef7ed
Fixed argument of post method.

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