char *http_post_lastpass(const char *page, const struct session *session, size_t *final_len, ...) { va_list args; struct http_param_set params = { .argv = NULL, .n_alloced = 0 }; va_start(args, final_len); vhttp_post_add_params(¶ms, args); char *result = http_post_lastpass_param_set(page, session, final_len, ¶ms); free(params.argv); return result; } int file_exist (const char *fname) { FILE *file; if ((file = fopen(fname, "r"))) { fclose(file); return 1; } return 0; }
char *http_post_lastpass(const char *page, const struct session *session, size_t *final_len, ...) { va_list args; struct http_param_set params = { .argv = NULL, .n_alloced = 0 }; va_start(args, final_len); vhttp_post_add_params(¶ms, args); char *result = http_post_lastpass_param_set(page, session, final_len, ¶ms); free(params.argv); return result; } #ifndef TEST_BUILD char *http_post_lastpass_v_noexit(const char *server, const char *page, const struct session *session, size_t *final_len, char **argv, int *curl_ret, long *http_code) { _cleanup_free_ char *url = NULL; _cleanup_free_ char *postdata = NULL; _cleanup_free_ char *cookie = NULL; _cleanup_fclose_ FILE *logstream = NULL; char *param, *encoded_param; CURL *curl = NULL; char separator; size_t len, new_len; int ret; struct mem_chunk result; const char *login_server; /* if we have a session, use that server, otherwise use whatever was passed */ login_server = session ? session->server : server; /* if nothing passed, use lastpass */ if (!login_server) login_server = LASTPASS_SERVER; xasprintf(&url, "https://%s/%s", login_server, page); lpass_log(LOG_DEBUG, "Making request to %s\n", url); curl = curl_easy_init(); if (!curl) die("Could not init curl"); len = 0; for (separator = '=', param = *argv; param; separator = (separator == '=') ? '&' : '=', param = *(++argv)) { encoded_param = curl_easy_escape(curl, param, 0); if (!encoded_param) die("Could not escape %s with curl", param); new_len = strlen(encoded_param) + 1 /* separator */; postdata = xrealloc(postdata, len + new_len + 1 /* null */); snprintf(postdata + len, new_len + 1, "%s%c", encoded_param, separator); len += new_len; curl_free(encoded_param); } if (len && postdata) postdata[len - 1] = '\0'; memset(&result, 0, sizeof(result)); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_USERAGENT, LASTPASS_CLI_USERAGENT); /* TODO: Make this optional via either env vars and/or an option for * lpass -4 or lpass -6 */ curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); if (lpass_log_level() >= LOG_VERBOSE) { logstream = lpass_log_open(); if (logstream) { curl_easy_setopt(curl, CURLOPT_STDERR, logstream); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); } } #if defined(DO_NOT_ENABLE_ME_MITM_PROXY_FOR_DEBUGGING_ONLY) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); #else curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, pin_keys); #endif curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, check_interruption); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); if (postdata) curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); if (session) { xasprintf(&cookie, "PHPSESSID=%s", session->sessionid); curl_easy_setopt(curl, CURLOPT_COOKIE, cookie); } set_interrupt_detect(); ret = curl_easy_perform(curl); unset_interrupt_detect(); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, http_code); curl_easy_cleanup(curl); *curl_ret = ret; if (ret != CURLE_OK) { result.len = 0; free(result.ptr); result.ptr = NULL; } else if (!result.ptr) result.ptr = xstrdup(""); if (final_len) *final_len = result.len; return result.ptr; }