/*! * \brief Perform an OAuth GET or POST request for a Dropbox client. * \param cli authenticated dropbox client * \param url request base url * \param data where the request answer is readed (e.g. FILE*) * \param readFct called function to read data content (e.g. fwrite) * \param[out] answer server answer (must be freed by caller) * \param timeout request timeout limit (0 is infinite) * \return error code (DRBERR_XXX or http error returned by the Dropbox server) */ int drbOAuthPostFile(drbClient* cli, const char *url, void* data, ssize_t (*readFct)(void *, size_t , size_t , void *), char** answer, int timeout) { int err; memStream fileData; memStreamInit(&fileData); if (memStreamLoad(&fileData, data, (void*)readFct)) { // Build request url char *reqUrl = NULL; char* key = oauth_catenc(2, cli->c.secret, cli->t.secret); char* sign = oauth_sign_hmac_sha1_raw(fileData.data, fileData.size, key, strlen(key)); asprintf(&reqUrl,"%s&xoauth_body_signature=%s¶m=val" "&xoauth_body_signature_method=HMAC_SHA1", url, sign); free(key), free(sign); CURL *curl; if(reqUrl && (curl = curl_easy_init())) { memStream answerData; memStreamInit(&answerData); char* header; asprintf(&header, "Content-Type: application/octet-stream\r\n " "Content-Length: %lu\r\n" "accept-ranges: bytes", fileData.size); struct curl_slist *slist = curl_slist_append(NULL, header); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); curl_easy_setopt(curl, CURLOPT_READDATA, &fileData); curl_easy_setopt(curl, CURLOPT_READFUNCTION, memStreamRead); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, fileData.size); err = drbOAuthCurlPerform(cli, curl, reqUrl, DRB_HTTP_POST2, &answerData, answer ? memStreamWrite:NULL, NULL, timeout); free(header); curl_slist_free_all(slist); curl_easy_cleanup(curl); free(fileData.data); if (answer) *answer = answerData.data; } else err = DRBERR_MALLOC; free(reqUrl); } else err = DRBERR_MALLOC; return err; }
/* * creates base string and returns signature. * @param mode * * @return encoded string otherwise NULL * The caller must free the returned string. */ char *process_array(int argc, char **argv, char *method, int mode, oauthparam *op) { char *base_url; char *okey, *odat, *sign; // sort parameters qsort(&argv[1], argc-1, sizeof(char *), oauth_cmpstringp); // serialize URL base_url= oauth_serialize_url_parameters(argc, argv); if (mode&16) fprintf(stdout, "%s\n",base_url); else if (want_verbose) fprintf(stderr, "base-url=%s\n",base_url); if (mode&16) exit(0); // generate signature okey = oauth_catenc(2, op->c_secret, op->t_secret); odat = oauth_catenc(3, method, argv[0], base_url); if (mode&8) fprintf(stdout, "%s\n",odat); else if (want_verbose) fprintf(stderr, "base-string=%s\n",odat); if (mode&32) fprintf(stdout, "%s\n",okey); else if (want_verbose) fprintf(stderr, "secret-string=%s\n",okey); if (mode&40) exit(0); switch(op->signature_method) { case OA_RSA: sign = oauth_sign_rsa_sha1(odat,op->c_secret); // TODO don't re-use consumer-key; allow to read from file. break; case OA_PLAINTEXT: sign = oauth_sign_plaintext(odat,okey); break; default: sign = oauth_sign_hmac_sha1(odat,okey); } free(odat); free(okey); if (mode&64 && !want_verbose) fprintf(stdout, "%s\n",sign); //if (mode&64) exit(0); // TODO return sign; // needs to be free()d }
/* * test hmac-sha1 checksum */ int test_sha1(char *c_secret, char *t_secret, char *base, char *expected) { int rv=0; char *okey = oauth_catenc(2, c_secret, t_secret); char *b64d = oauth_sign_hmac_sha1(base, okey); if (strcmp(b64d,expected)) { printf("HMAC-SHA1 invalid. base:'%s' secrets:'%s'\n" " got: '%s' expected: '%s'\n", base, okey, b64d, expected); rv=1; } else if (loglevel) printf("HMAC-SHA1 test sucessful.\n"); free(b64d); free(okey); return (rv); }
/* * test request concatenation */ int test_request(char *http_method, char *request, char *expected) { int rv=2; int i, argc; char **argv = NULL; char *query, *testcase; argc = oauth_split_url_parameters(request, &argv); qsort(&argv[1], argc-1, sizeof(char *), oauth_cmpstringp); query= oauth_serialize_url(argc,1, argv); testcase = oauth_catenc(3, http_method, argv[0], query); rv=strcmp(testcase,expected); if (rv) { printf("request concatenation test failed for: '%s'.\n" " got: '%s'\n expected: '%s'\n", request, testcase, expected); } else if (loglevel) printf("request concatenation ok.\n"); for (i=0;i<argc;i++) free(argv[i]); if (argv) free(argv); if (query) free(query); if (testcase) free(testcase); return (rv); }