Fixed compatibility for HTTPClient Library. (HTTPClient by Donatien Garnier)
Dependents: FlashAir_Twitter CyaSSL-Twitter-OAuth4Tw TweetTest NetworkThermometer ... more
Fork of OAuth4Tw by
twicpps/oauth.cpp@5:5146becb651f, 2015-07-14 (annotated)
- 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?
User | Revision | Line number | New 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 |