Fixed compatibility for HTTPClient Library. (HTTPClient by Donatien Garnier)
Dependents: FlashAir_Twitter CyaSSL-Twitter-OAuth4Tw TweetTest NetworkThermometer ... more
Fork of OAuth4Tw by
oauth.cpp
00001 /* 00002 * OAuth string functions in POSIX-C. 00003 * 00004 * Copyright 2007-2010 Robin Gareus <robin@gareus.org> 00005 * 00006 * The base64 functions are by Jan-Henrik Haukeland, <hauk@tildeslash.com> 00007 * and un/escape_url() was inspired by libcurl's curl_escape under ISC-license 00008 * many thanks to Daniel Stenberg <daniel@haxx.se>. 00009 * 00010 * Permission is hereby granted, free of charge, to any person obtaining a copy 00011 * of this software and associated documentation files (the "Software"), to deal 00012 * in the Software without restriction, including without limitation the rights 00013 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00014 * copies of the Software, and to permit persons to whom the Software is 00015 * furnished to do so, subject to the following conditions: 00016 * 00017 * The above copyright notice and this permission notice shall be included in 00018 * all copies or substantial portions of the Software. 00019 * 00020 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00021 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00022 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00023 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00024 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00025 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00026 * THE SOFTWARE. 00027 * 00028 */ 00029 #if HAVE_CONFIG_H 00030 # include <config.h> 00031 #endif 00032 00033 #define WIPE_MEMORY ///< overwrite sensitve data before free()ing it. 00034 00035 #include <stdio.h> 00036 #include <stdarg.h> 00037 #include <stdlib.h> 00038 #include <string.h> 00039 #include <time.h> 00040 #include <math.h> 00041 #include <ctype.h> // isxdigit 00042 00043 #include "oauth.h" 00044 00045 #ifndef WIN32 // getpid() on POSIX systems 00046 //#include <sys/types.h> 00047 //#include <unistd.h> 00048 #else 00049 #define snprintf _snprintf 00050 #define strncasecmp strnicmp 00051 #pragma warning(disable:4996) 00052 #endif 00053 00054 #include <vector> 00055 #include <algorithm> 00056 #include <sstream> 00057 00058 /** 00059 * Base64 encode one byte 00060 */ 00061 char oauth_b64_encode(unsigned char u) 00062 { 00063 if (u < 26) return 'A' + u; 00064 if (u < 52) return 'a' + (u - 26); 00065 if (u < 62) return '0' + (u - 52); 00066 if (u == 62) return '+'; 00067 return '/'; 00068 } 00069 00070 /** 00071 * Decode a single base64 character. 00072 */ 00073 unsigned char oauth_b64_decode(char c) 00074 { 00075 if (c >= 'A' && c <= 'Z') return(c - 'A'); 00076 if (c >= 'a' && c <= 'z') return(c - 'a' + 26); 00077 if (c >= '0' && c <= '9') return(c - '0' + 52); 00078 if (c == '+') return 62; 00079 return 63; 00080 } 00081 00082 /** 00083 * Return TRUE if 'c' is a valid base64 character, otherwise FALSE 00084 */ 00085 bool oauth_b64_is_base64(char c) 00086 { 00087 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/') || (c == '=')); 00088 } 00089 00090 /** 00091 * Base64 encode and return size data in 'src'. The caller must free the 00092 * returned string. 00093 * 00094 * @param size The size of the data in src 00095 * @param src The data to be base64 encode 00096 * @return encoded string otherwise NULL 00097 */ 00098 std::string oauth_encode_base64(const unsigned char *src, int size) 00099 { 00100 int i; 00101 std::stringbuf sb; 00102 00103 if (!src) return NULL; 00104 if (!size) size= strlen((char *)src); 00105 00106 for (i = 0; i < size; i += 3) { 00107 unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0; 00108 b1= src[i]; 00109 if (i + 1 < size) b2 = src[i + 1]; 00110 if (i + 2 < size) b3 = src[i + 2]; 00111 00112 b4= b1 >> 2; 00113 b5= ((b1 & 0x3) << 4) | (b2 >> 4); 00114 b6= ((b2 & 0xf) << 2) | (b3 >> 6); 00115 b7= b3 & 0x3f; 00116 00117 sb.sputc(oauth_b64_encode(b4)); 00118 sb.sputc(oauth_b64_encode(b5)); 00119 00120 if (i + 1 < size) { 00121 sb.sputc(oauth_b64_encode(b6)); 00122 } else { 00123 sb.sputc('='); 00124 } 00125 00126 if (i + 2 < size) { 00127 sb.sputc(oauth_b64_encode(b7)); 00128 } else { 00129 sb.sputc('='); 00130 } 00131 } 00132 return sb.str(); 00133 } 00134 00135 /** 00136 * Decode the base64 encoded string 'src' into the memory pointed to by 00137 * 'dest'. 00138 * 00139 * @param dest Pointer to memory for holding the decoded string. 00140 * Must be large enough to receive the decoded string. 00141 * @param src A base64 encoded string. 00142 * @return the length of the decoded string if decode 00143 * succeeded otherwise 0. 00144 */ 00145 std::string oauth_decode_base64(const char *src) 00146 { 00147 if (src && *src) { 00148 std::stringbuf sb; 00149 //unsigned char *p= dest; 00150 int k, l= strlen(src)+1; 00151 std::vector<unsigned char> buf(l); 00152 00153 /* Ignore non base64 chars as per the POSIX standard */ 00154 for (k = 0, l = 0; src[k]; k++) { 00155 if (oauth_b64_is_base64(src[k])) { 00156 buf[l++]= src[k]; 00157 } 00158 } 00159 00160 for (k = 0; k < l; k += 4) { 00161 char c1='A', c2='A', c3='A', c4='A'; 00162 unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0; 00163 c1= buf[k]; 00164 00165 if (k + 1 < l) c2 = buf[k + 1]; 00166 if (k + 2 < l) c3 = buf[k + 2]; 00167 if (k + 3 < l) c4 = buf[k + 3]; 00168 00169 b1 = oauth_b64_decode(c1); 00170 b2 = oauth_b64_decode(c2); 00171 b3 = oauth_b64_decode(c3); 00172 b4 = oauth_b64_decode(c4); 00173 00174 sb.sputc((b1 << 2) | (b2 >> 4)); 00175 00176 if (c3 != '=') sb.sputc(((b2 & 0xf) << 4) | (b3 >> 2)); 00177 if (c4 != '=') sb.sputc(((b3 & 0x3) << 6) | b4); 00178 } 00179 00180 return sb.str(); 00181 } 00182 return 0; 00183 } 00184 00185 /** 00186 * Escape 'string' according to RFC3986 and 00187 * http://oauth.net/core/1.0/#encoding_parameters. 00188 * 00189 * @param string The data to be encoded 00190 * @return encoded string otherwise NULL 00191 * The caller must free the returned string. 00192 */ 00193 std::string oauth_url_escape(const char *string) 00194 { 00195 unsigned char in; 00196 size_t length; 00197 00198 if (!string) { 00199 return std::string(); 00200 } 00201 00202 length = strlen(string); 00203 00204 std::stringbuf sb; 00205 00206 while (length--) { 00207 in = *string; 00208 if (strchr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_~.-", in)) { 00209 sb.sputc(in); 00210 } else { 00211 char tmp[10]; 00212 snprintf(tmp, 4, "%%%02X", in); 00213 sb.sputc(tmp[0]); 00214 sb.sputc(tmp[1]); 00215 sb.sputc(tmp[2]); 00216 } 00217 string++; 00218 } 00219 return sb.str(); 00220 } 00221 00222 #ifndef ISXDIGIT 00223 # define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) 00224 #endif 00225 00226 /** 00227 * Parse RFC3986 encoded 'string' back to unescaped version. 00228 * 00229 * @param string The data to be unescaped 00230 * @param olen unless NULL the length of the returned string is stored there. 00231 * @return decoded string or NULL 00232 * The caller must free the returned string. 00233 */ 00234 std::string oauth_url_unescape(const char *string) 00235 { 00236 size_t alloc, strindex=0; 00237 unsigned char in; 00238 long hex; 00239 00240 if (!string) return NULL; 00241 00242 alloc = strlen(string)+1; 00243 std::vector<char> ns(alloc); 00244 00245 while(--alloc > 0) { 00246 in = *string; 00247 if (('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { 00248 char hexstr[3]; // '%XX' 00249 hexstr[0] = string[1]; 00250 hexstr[1] = string[2]; 00251 hexstr[2] = 0; 00252 hex = strtol(hexstr, NULL, 16); 00253 in = (unsigned char)hex; /* hex is always < 256 */ 00254 string += 2; 00255 alloc -= 2; 00256 } 00257 ns[strindex++] = in; 00258 string++; 00259 } 00260 ns[strindex]=0; 00261 return &ns[0]; 00262 } 00263 00264 /** 00265 * returns plaintext signature for the given key. 00266 * 00267 * the returned string needs to be freed by the caller 00268 * 00269 * @param m message to be signed 00270 * @param k key used for signing 00271 * @return signature string 00272 */ 00273 std::string oauth_sign_plaintext (const char *m, const char *k) 00274 { 00275 return oauth_url_escape(k); 00276 } 00277 00278 /** 00279 * encode strings and concatenate with '&' separator. 00280 * The number of strings to be concatenated must be 00281 * given as first argument. 00282 * all arguments thereafter must be of type (char *) 00283 * 00284 * @param len the number of arguments to follow this parameter 00285 * @param ... string to escape and added (may be NULL) 00286 * 00287 * @return pointer to memory holding the concatenated 00288 * strings - needs to be free(d) by the caller. or NULL 00289 * in case we ran out of memory. 00290 */ 00291 std::string oauth_catenc(int len, ...) 00292 { 00293 va_list va; 00294 std::string str; 00295 va_start(va, len); 00296 for (int i = 0; i < len; i++) { 00297 char *arg = va_arg(va, char *); 00298 std::string enc = oauth_url_escape(arg); 00299 if (i > 0) str += "&"; 00300 str += enc; 00301 } 00302 va_end(va); 00303 return str; 00304 } 00305 00306 /** 00307 * splits the given url into a parameter array. 00308 * (see \ref oauth_serialize_url and \ref oauth_serialize_url_parameters for the reverse) 00309 * 00310 * NOTE: Request-parameters-values may include an ampersand character. 00311 * However if unescaped this function will use them as parameter delimiter. 00312 * If you need to make such a request, this function since version 0.3.5 allows 00313 * to use the ASCII SOH (0x01) character as alias for '&' (0x26). 00314 * (the motivation is convenience: SOH is /untypeable/ and much more 00315 * unlikely to appear than '&' - If you plan to sign fancy URLs you 00316 * should not split a query-string, but rather provide the parameter array 00317 * directly to \ref oauth_serialize_url) 00318 * 00319 * @param url the url or query-string to parse. 00320 * @param argv pointer to a (char *) array where the results are stored. 00321 * The array is re-allocated to match the number of parameters and each 00322 * parameter-string is allocated with strdup. - The memory needs to be freed 00323 * by the caller. 00324 * @param qesc use query parameter escape (vs post-param-escape) - if set 00325 * to 1 all '+' are treated as spaces ' ' 00326 * 00327 * @return number of parameter(s) in array. 00328 */ 00329 void oauth_split_post_paramters(const char *url, std::vector<std::string> *argv, short qesc) 00330 { 00331 int argc=0; 00332 char *token, *tmp; 00333 if (!argv) return; 00334 if (!url) return; 00335 std::vector<char> t1(strlen(url) + 1); 00336 strcpy(&t1[0], url); 00337 00338 // '+' represents a space, in a URL query string 00339 while ((qesc&1) && (tmp=strchr(&t1[0],'+'))) *tmp = ' '; 00340 00341 tmp = &t1[0]; 00342 while ((token = strtok(tmp,"&?"))) { 00343 if (!strncasecmp("oauth_signature=", token, 16)) continue; 00344 while (!(qesc & 2) && (tmp = strchr(token, '\001'))) *tmp = '&'; 00345 argv->push_back(oauth_url_unescape(token)); 00346 if (argc == 0 && strstr(token, ":/")) { 00347 // HTTP does not allow empty absolute paths, so the URL 00348 // 'http://example.com' is equivalent to 'http://example.com/' and should 00349 // be treated as such for the purposes of OAuth signing (rfc2616, section 3.2.1) 00350 // see http://groups.google.com/group/oauth/browse_thread/thread/c44b6f061bfd98c?hl=en 00351 char *slash = strstr(token, ":/"); 00352 while (slash && *(++slash) == '/') ; // skip slashes eg /xxx:[\/]*/ 00353 #if 0 00354 // skip possibly unescaped slashes in the userinfo - they're not allowed by RFC2396 but have been seen. 00355 // the hostname/IP may only contain alphanumeric characters - so we're safe there. 00356 if (slash && strchr(slash,'@')) slash=strchr(slash, '@'); 00357 #endif 00358 if (slash && !strchr(slash,'/')) { 00359 #ifdef DEBUG_OAUTH 00360 fprintf(stderr, "\nliboauth: added trailing slash to URL: '%s'\n\n", token); 00361 #endif 00362 argv->push_back(std::string(token) + "/"); 00363 } 00364 } 00365 if (argc == 0 && (tmp = strstr((char *)argv->at(argc).c_str(), ":80/"))) { 00366 memmove(tmp, tmp + 3, strlen(tmp + 2)); 00367 } 00368 tmp = NULL; 00369 argc++; 00370 } 00371 } 00372 00373 void oauth_split_url_parameters(const char *url, std::vector<std::string> *argv) 00374 { 00375 oauth_split_post_paramters(url, argv, 1); 00376 } 00377 00378 /** 00379 * build a url query string from an array. 00380 * 00381 * @param argc the total number of elements in the array 00382 * @param start element in the array at which to start concatenating. 00383 * @param argv parameter-array to concatenate. 00384 * @return url string needs to be freed by the caller. 00385 * 00386 */ 00387 std::string oauth_serialize_url (std::vector<std::string> const &argv, int start) 00388 { 00389 return oauth_serialize_url_sep(argv, start, "&", 0); 00390 } 00391 00392 /** 00393 * encode query parameters from an array. 00394 * 00395 * @param argc the total number of elements in the array 00396 * @param start element in the array at which to start concatenating. 00397 * @param argv parameter-array to concatenate. 00398 * @param sep separator for parameters (usually "&") 00399 * @param mod - bitwise modifiers: 00400 * 1: skip all values that start with "oauth_" 00401 * 2: skip all values that don't start with "oauth_" 00402 * 4: add double quotation marks around values (use with sep=", " to generate HTTP Authorization header). 00403 * @return url string needs to be freed by the caller. 00404 */ 00405 std::string oauth_serialize_url_sep(std::vector<std::string> const &argv, int start, char const *sep, int mod) 00406 { 00407 int i; 00408 int first = 0; 00409 int seplen = strlen(sep); 00410 std::string query; 00411 for (i = start; i < (int)argv.size(); i++) { 00412 std::string tmp; 00413 00414 if ((mod & 1) == 1 && (strncmp(argv[i].c_str(), "oauth_", 6) == 0 || strncmp(argv[i].c_str(), "x_oauth_", 8) == 0)) continue; 00415 if ((mod & 2) == 2 && (strncmp(argv[i].c_str(), "oauth_", 6) != 0 && strncmp(argv[i].c_str(), "x_oauth_", 8) != 0) && i != 0) continue; 00416 00417 if (i == start && i == 0 && strstr(argv[i].c_str(), ":/")) { 00418 tmp = argv[i]; 00419 } else { 00420 char *p = strchr((char *)argv[i].c_str(), '='); 00421 if (p) { 00422 tmp = oauth_url_escape(std::string(argv[i].c_str(), (char const *)p).c_str()); 00423 std::string t2 = oauth_url_escape(p + 1); 00424 tmp += "="; 00425 if (mod & 4) tmp += "\""; 00426 tmp += t2; 00427 if (mod & 4) tmp += "\""; 00428 } else { 00429 // see http://oauth.net/core/1.0/#anchor14 00430 // escape parameter names and arguments but not the '=' 00431 tmp=argv[i]; 00432 tmp += "="; 00433 } 00434 } 00435 query += ((i == start || first) ? "" : sep); 00436 query += tmp; 00437 first = 0; 00438 if (i == start && i == 0 && strstr((char *)tmp.c_str(), ":/")) { 00439 query += "?"; 00440 first = 1; 00441 } 00442 } 00443 return (query); 00444 } 00445 00446 /** 00447 * build a query parameter string from an array. 00448 * 00449 * This function is a shortcut for \ref oauth_serialize_url (argc, 1, argv). 00450 * It strips the leading host/path, which is usually the first 00451 * element when using oauth_split_url_parameters on an URL. 00452 * 00453 * @param argc the total number of elements in the array 00454 * @param argv parameter-array to concatenate. 00455 * @return url string needs to be freed by the caller. 00456 */ 00457 std::string oauth_serialize_url_parameters (std::vector<std::string> const &argv) 00458 { 00459 return oauth_serialize_url(argv, 1); 00460 } 00461 00462 /** 00463 * generate a random string between 15 and 32 chars length 00464 * and return a pointer to it. The value needs to be freed by the 00465 * caller 00466 * 00467 * @return zero terminated random string. 00468 */ 00469 std::string oauth_gen_nonce() 00470 { 00471 static const char *chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 00472 const unsigned int max = 26 + 26 + 10 + 1; //strlen(chars); 00473 char tmp[50]; 00474 int i, len; 00475 00476 srand((unsigned int)time(0)); 00477 len = 15 + rand() % 16; 00478 for (i = 0; i < len; i++) { 00479 tmp[i] = chars[rand() % max]; 00480 } 00481 tmp[i]='\0'; 00482 return &tmp[0]; 00483 } 00484 00485 /** 00486 * string compare function for oauth parameters. 00487 * 00488 * used with qsort. needed to normalize request parameters. 00489 * see http://oauth.net/core/1.0/#anchor14 00490 */ 00491 int oauth_cmpstringp(const void *p1, const void *p2) 00492 { 00493 char const *e1; 00494 char const *e2; 00495 e1 = strchr((char *)p1, '='); 00496 e2 = strchr((char *)p2, '='); 00497 if (e1 && e2) { 00498 std::string left((char const *)p1, e1); 00499 std::string right((char const *)p2, e2); 00500 return strcmp(left.c_str(), right.c_str()); 00501 } 00502 00503 std::string left = oauth_url_escape((char const *)p1); 00504 std::string right = oauth_url_escape((char const *)p2); 00505 return strcmp(left.c_str(), right.c_str()); 00506 } 00507 00508 bool oauth_cmpstringp_ex(std::string const &left, std::string const &right) 00509 { 00510 return oauth_cmpstringp(left.c_str(), right.c_str()) < 0; 00511 } 00512 00513 /** 00514 * search array for parameter key. 00515 * @param argv length of array to search 00516 * @param argc parameter array to search 00517 * @param key key of parameter to check. 00518 * 00519 * @return FALSE (0) if array does not contain a parameter with given key, TRUE (1) otherwise. 00520 */ 00521 bool oauth_param_exists(std::vector<std::string> const &argv, char const *key) 00522 { 00523 int i; 00524 size_t l = strlen(key); 00525 for (i = 0; i < (int)argv.size(); i++) { 00526 if (!strncmp(argv[i].c_str(), key, l) && argv[i][l] == '=') { 00527 return true; 00528 } 00529 } 00530 return false; 00531 } 00532 00533 /** 00534 * 00535 */ 00536 void oauth_add_protocol( 00537 std::vector<std::string> *argvp, 00538 OAuthMethod method, 00539 const char *c_key, //< consumer key - posted plain text 00540 const char *t_key //< token key - posted plain text in URL 00541 ) 00542 { 00543 char oarg[1024]; 00544 00545 // add OAuth specific arguments 00546 if (!oauth_param_exists(*argvp,"oauth_nonce")) { 00547 std::string tmp = oauth_gen_nonce(); 00548 snprintf(oarg, 1024, "oauth_nonce=%s", tmp.c_str()); 00549 argvp->push_back(oarg); 00550 } 00551 00552 if (!oauth_param_exists(*argvp,"oauth_timestamp")) { 00553 snprintf(oarg, 1024, "oauth_timestamp=%li", (long int) time(NULL)); 00554 argvp->push_back(oarg); 00555 } 00556 00557 if (t_key) { 00558 snprintf(oarg, 1024, "oauth_token=%s", t_key); 00559 argvp->push_back(oarg); 00560 } 00561 00562 snprintf(oarg, 1024, "oauth_consumer_key=%s", c_key); 00563 argvp->push_back(oarg); 00564 00565 snprintf(oarg, 1024, "oauth_signature_method=%s", method==0?"HMAC-SHA1":method==1?"RSA-SHA1":"PLAINTEXT"); 00566 argvp->push_back(oarg); 00567 00568 if (!oauth_param_exists(*argvp,"oauth_version")) { 00569 snprintf(oarg, 1024, "oauth_version=1.0"); 00570 argvp->push_back(oarg); 00571 } 00572 00573 #if 0 // oauth_version 1.0 Rev A 00574 if (!oauth_param_exists(argv,argc,"oauth_callback")) { 00575 snprintf(oarg, 1024, "oauth_callback=oob"); 00576 argvp->push_back(oarg); 00577 } 00578 #endif 00579 00580 } 00581 00582 std::string oauth_sign_url( 00583 const char *url, 00584 std::string *postargs, 00585 OAuthMethod method, 00586 const char *c_key, //< consumer key - posted plain text 00587 const char *c_sec, //< consumer secret - used as 1st part of secret-key 00588 const char *t_key, //< token key - posted plain text in URL 00589 const char *t_sec //< token secret - used as 2st part of secret-key 00590 ) 00591 { 00592 return oauth_sign_url2(url, postargs, method, NULL, c_key, c_sec, t_key, t_sec); 00593 } 00594 00595 std::string oauth_sign_url2( 00596 const char *url, 00597 std::string *postargs, 00598 OAuthMethod method, 00599 const char *http_method, //< HTTP request method 00600 const char *c_key, //< consumer key - posted plain text 00601 const char *c_sec, //< consumer secret - used as 1st part of secret-key 00602 const char *t_key, //< token key - posted plain text in URL 00603 const char *t_sec //< token secret - used as 2st part of secret-key 00604 ) 00605 { 00606 //char **argv = NULL; 00607 std::vector<std::string> argv; 00608 std::string rv; 00609 00610 if (postargs) { 00611 oauth_split_post_paramters(url, &argv, 0); 00612 } else { 00613 oauth_split_url_parameters(url, &argv); 00614 } 00615 00616 rv = oauth_sign_array2(&argv, postargs, method, http_method, c_key, c_sec, t_key, t_sec); 00617 00618 return(rv); 00619 } 00620 00621 std::string oauth_sign_array ( 00622 std::vector<std::string> *argvp, 00623 std::string *postargs, 00624 OAuthMethod method, 00625 const char *c_key, //< consumer key - posted plain text 00626 const char *c_sec, //< consumer secret - used as 1st part of secret-key 00627 const char *t_key, //< token key - posted plain text in URL 00628 const char *t_sec //< token secret - used as 2st part of secret-key 00629 ) 00630 { 00631 return oauth_sign_array2( 00632 argvp, 00633 postargs, method, 00634 NULL, 00635 c_key, c_sec, 00636 t_key, t_sec 00637 ); 00638 } 00639 00640 void oauth_sign_array2_process( 00641 std::vector<std::string> *argvp, 00642 std::string *postargs, 00643 OAuthMethod method, 00644 const char *http_method, //< HTTP request method 00645 const char *c_key, //< consumer key - posted plain text 00646 const char *c_sec, //< consumer secret - used as 1st part of secret-key 00647 const char *t_key, //< token key - posted plain text in URL 00648 const char *t_sec //< token secret - used as 2st part of secret-key 00649 ) 00650 { 00651 char oarg[1024]; 00652 std::string query; 00653 std::string sign; 00654 std::string http_request_method; 00655 00656 if (!http_method) { 00657 http_request_method = postargs ? "POST" : "GET"; 00658 } else { 00659 std::vector<char> tmp(strlen(http_method) + 1); 00660 int i; 00661 for (i = 0; http_method[i]; i++) { 00662 tmp[i] = toupper(http_method[i]); 00663 } 00664 tmp[i] = 0; 00665 http_request_method = &tmp[0]; 00666 } 00667 00668 // add required OAuth protocol parameters 00669 oauth_add_protocol(argvp, method, c_key, t_key); 00670 00671 // sort parameters 00672 //qsort(&(*argvp)[1], (*argcp)-1, sizeof(char *), oauth_cmpstringp); 00673 std::sort(argvp->begin() + 1, argvp->end(), oauth_cmpstringp_ex); 00674 00675 // serialize URL - base-url 00676 query= oauth_serialize_url_parameters(*argvp); 00677 00678 // generate signature 00679 std::string okey = oauth_catenc(2, c_sec, t_sec); 00680 std::string odat = oauth_catenc(3, http_request_method.c_str(), (*argvp)[0].c_str(), query.c_str()); // base-string 00681 #ifdef DEBUG_OAUTH 00682 fprintf (stderr, "\nliboauth: data to sign='%s'\n\n", odat.c_str()); 00683 fprintf (stderr, "\nliboauth: key='%s'\n\n", okey.c_str()); 00684 #endif 00685 switch(method) { 00686 //case OA_RSA: 00687 // sign = oauth_sign_rsa_sha1(odat.c_str(), okey.c_str()); // XXX okey needs to be RSA key! 00688 // break; 00689 case OA_PLAINTEXT: 00690 sign = oauth_sign_plaintext(odat.c_str(), okey.c_str()).c_str(); 00691 break; 00692 default: 00693 sign = oauth_sign_hmac_sha1(odat.c_str(), okey.c_str()); 00694 break; 00695 } 00696 00697 // append signature to query args. 00698 snprintf(oarg, 1024, "oauth_signature=%s",sign.c_str()); 00699 argvp->push_back(oarg); 00700 } 00701 00702 std::string oauth_sign_array2( 00703 std::vector<std::string> *argvp, 00704 std::string *postargs, 00705 OAuthMethod method, 00706 const char *http_method, //< HTTP request method 00707 const char *c_key, //< consumer key - posted plain text 00708 const char *c_sec, //< consumer secret - used as 1st part of secret-key 00709 const char *t_key, //< token key - posted plain text in URL 00710 const char *t_sec //< token secret - used as 2st part of secret-key 00711 ) 00712 { 00713 00714 std::string result; 00715 oauth_sign_array2_process(argvp, postargs, method, http_method, c_key, c_sec, t_key, t_sec); 00716 00717 // build URL params 00718 result = oauth_serialize_url(*argvp, (postargs?1:0)); 00719 00720 if (postargs) { 00721 *postargs = result; 00722 result = argvp->at(0); 00723 } 00724 00725 return result; 00726 } 00727
Generated on Thu Jul 14 2022 04:27:06 by
![doxygen](doxygen.png)