Skip to content

Commit

Permalink
Use TLS 1.2 as minimum TLS version.
Browse files Browse the repository at this point in the history
Bug: internal b/240476093
Test: test on device
Change-Id: Iea183b01a9c0d37e246c1c2ad0bed6e09d95e64c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3924397
Commit-Queue: Yuchen Liu <yucliu@chromium.org>
Auto-Submit: Mohit Hotwani <hmohit@google.com>
Reviewed-by: Ryan Chung <ryanchung@chromium.org>
Reviewed-by: Yuchen Liu <yucliu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1052181}
  • Loading branch information
Mohit Hotwani authored and Chromium LUCI CQ committed Sep 28, 2022
1 parent ed8b19d commit 568c546
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 18 deletions.
2 changes: 2 additions & 0 deletions chromecast/crash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ cast_source_set("crash") {
sources += [
"cast_crashdump_uploader.cc",
"cast_crashdump_uploader.h",
"libcurl_wrapper.cc",
"libcurl_wrapper.h",
]

if (is_linux || is_chromeos) {
Expand Down
8 changes: 3 additions & 5 deletions chromecast/crash/cast_crashdump_uploader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "base/logging.h"
// TODO(slan): Find a replacement for LibcurlWrapper in Chromium to remove the
// breakpad dependency.
#include "third_party/breakpad/breakpad/src/common/linux/libcurl_wrapper.h"
#include "chromecast/crash/libcurl_wrapper.h"

namespace chromecast {
namespace {
Expand All @@ -37,13 +37,11 @@ CastCrashdumpData::~CastCrashdumpData() {
}

CastCrashdumpUploader::CastCrashdumpUploader(const CastCrashdumpData& data)
: CastCrashdumpUploader(
data,
std::make_unique<google_breakpad::LibcurlWrapper>()) {}
: CastCrashdumpUploader(data, std::make_unique<LibcurlWrapper>()) {}

CastCrashdumpUploader::CastCrashdumpUploader(
const CastCrashdumpData& data,
std::unique_ptr<google_breakpad::LibcurlWrapper> http_layer)
std::unique_ptr<LibcurlWrapper> http_layer)
: http_layer_(std::move(http_layer)), data_(data) {
DCHECK(http_layer_);
}
Expand Down
12 changes: 4 additions & 8 deletions chromecast/crash/cast_crashdump_uploader.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
#include <memory>
#include <string>

namespace google_breakpad {
class LibcurlWrapper;
}

namespace chromecast {
class LibcurlWrapper;

struct CastCrashdumpData {
CastCrashdumpData();
Expand All @@ -36,9 +33,8 @@ struct CastCrashdumpData {

class CastCrashdumpUploader {
public:
CastCrashdumpUploader(
const CastCrashdumpData& data,
std::unique_ptr<google_breakpad::LibcurlWrapper> http_layer);
CastCrashdumpUploader(const CastCrashdumpData& data,
std::unique_ptr<LibcurlWrapper> http_layer);
explicit CastCrashdumpUploader(const CastCrashdumpData& data);

CastCrashdumpUploader(const CastCrashdumpUploader&) = delete;
Expand All @@ -54,7 +50,7 @@ class CastCrashdumpUploader {
private:
bool CheckRequiredParametersArePresent();

std::unique_ptr<google_breakpad::LibcurlWrapper> http_layer_;
std::unique_ptr<LibcurlWrapper> http_layer_;
CastCrashdumpData data_;

// Holds the following mapping for attachments: <label, filepath>
Expand Down
7 changes: 2 additions & 5 deletions chromecast/crash/cast_crashdump_uploader_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@
#include "base/files/file_util.h"
#include "chromecast/base/scoped_temp_file.h"
#include "chromecast/crash/cast_crashdump_uploader.h"
#include "chromecast/crash/libcurl_wrapper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/breakpad/breakpad/src/common/linux/libcurl_wrapper.h"

namespace chromecast {

class MockLibcurlWrapper : public google_breakpad::LibcurlWrapper {
class MockLibcurlWrapper : public LibcurlWrapper {
public:
MOCK_METHOD0(Init, bool());
MOCK_METHOD2(SetProxy,
bool(const std::string& proxy_host,
const std::string& proxy_userpwd));
MOCK_METHOD2(AddFile,
bool(const std::string& upload_file_path,
const std::string& basename));
Expand Down
227 changes: 227 additions & 0 deletions chromecast/crash/libcurl_wrapper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <dlfcn.h>

#include <iostream>
#include <string>

#include "chromecast/crash/libcurl_wrapper.h"

namespace chromecast {
LibcurlWrapper::LibcurlWrapper()
: init_ok_(false),
curl_lib_(nullptr),
last_curl_error_(""),
curl_(nullptr),
formpost_(nullptr),
lastptr_(nullptr),
headerlist_(nullptr) {}

LibcurlWrapper::~LibcurlWrapper() {
if (init_ok_) {
(*easy_cleanup_)(curl_);
dlclose(curl_lib_);
}
}

bool LibcurlWrapper::AddFile(const std::string& upload_file_path,
const std::string& basename) {
if (!CheckInit())
return false;

std::cout << "Adding " << upload_file_path << " to form upload.";
// Add form file.
(*formadd_)(&formpost_, &lastptr_, CURLFORM_COPYNAME, basename.c_str(),
CURLFORM_FILE, upload_file_path.c_str(), CURLFORM_END);

return true;
}

// Callback to get the response data from server.
static size_t WriteCallback(void* ptr, size_t size, size_t nmemb, void* userp) {
if (!userp)
return 0;

std::string* response = reinterpret_cast<std::string*>(userp);
size_t real_size = size * nmemb;
response->append(reinterpret_cast<char*>(ptr), real_size);
return real_size;
}

bool LibcurlWrapper::SendRequest(
const std::string& url,
const std::map<std::string, std::string>& parameters,
long* http_status_code,
std::string* http_header_data,
std::string* http_response_data) {
if (!CheckInit())
return false;

std::map<std::string, std::string>::const_iterator iter = parameters.begin();
for (; iter != parameters.end(); ++iter)
(*formadd_)(&formpost_, &lastptr_, CURLFORM_COPYNAME, iter->first.c_str(),
CURLFORM_COPYCONTENTS, iter->second.c_str(), CURLFORM_END);

(*easy_setopt_)(curl_, CURLOPT_HTTPPOST, formpost_);

return SendRequestInner(url, http_status_code, http_header_data,
http_response_data);
}

bool LibcurlWrapper::Init() {
// First check to see if libcurl was statically linked:
curl_lib_ = dlopen(nullptr, RTLD_NOW);
if (curl_lib_ && (!dlsym(curl_lib_, "curl_easy_init") ||
!dlsym(curl_lib_, "curl_easy_setopt"))) {
// Not statically linked, try again below.
dlerror(); // Clear dlerror before attempting to open libraries.
dlclose(curl_lib_);
curl_lib_ = nullptr;
}
if (!curl_lib_) {
curl_lib_ = dlopen("libcurl.so", RTLD_NOW);
}
if (!curl_lib_) {
curl_lib_ = dlopen("libcurl.so.4", RTLD_NOW);
}
if (!curl_lib_) {
curl_lib_ = dlopen("libcurl.so.3", RTLD_NOW);
}
if (!curl_lib_) {
std::cout << "Could not find libcurl via dlopen";
return false;
}

if (!SetFunctionPointers()) {
std::cout << "Could not find function pointers";
return false;
}

curl_ = (*easy_init_)();

last_curl_error_ = "No Error";

if (!curl_) {
dlclose(curl_lib_);
std::cout << "Curl initialization failed";
return false;
}

init_ok_ = true;
return true;
}

#define SET_AND_CHECK_FUNCTION_POINTER(var, function_name, type) \
var = reinterpret_cast<type>(dlsym(curl_lib_, function_name)); \
if (!var) { \
std::cout << "Could not find libcurl function " << function_name; \
init_ok_ = false; \
return false; \
}

bool LibcurlWrapper::SetFunctionPointers() {
SET_AND_CHECK_FUNCTION_POINTER(easy_init_, "curl_easy_init", CURL * (*)());

SET_AND_CHECK_FUNCTION_POINTER(easy_setopt_, "curl_easy_setopt",
CURLcode(*)(CURL*, CURLoption, ...));

SET_AND_CHECK_FUNCTION_POINTER(
formadd_, "curl_formadd",
CURLFORMcode(*)(curl_httppost**, curl_httppost**, ...));

SET_AND_CHECK_FUNCTION_POINTER(slist_append_, "curl_slist_append",
curl_slist * (*)(curl_slist*, const char*));

SET_AND_CHECK_FUNCTION_POINTER(easy_perform_, "curl_easy_perform",
CURLcode(*)(CURL*));

SET_AND_CHECK_FUNCTION_POINTER(easy_cleanup_, "curl_easy_cleanup",
void (*)(CURL*));

SET_AND_CHECK_FUNCTION_POINTER(easy_getinfo_, "curl_easy_getinfo",
CURLcode(*)(CURL*, CURLINFO info, ...));

SET_AND_CHECK_FUNCTION_POINTER(easy_reset_, "curl_easy_reset",
void (*)(CURL*));

SET_AND_CHECK_FUNCTION_POINTER(slist_free_all_, "curl_slist_free_all",
void (*)(curl_slist*));

SET_AND_CHECK_FUNCTION_POINTER(formfree_, "curl_formfree",
void (*)(curl_httppost*));
return true;
}

bool LibcurlWrapper::SendRequestInner(const std::string& url,
long* http_status_code,
std::string* http_header_data,
std::string* http_response_data) {
std::string url_copy(url);
(*easy_setopt_)(curl_, CURLOPT_URL, url_copy.c_str());
// Use the enum when available in the header file.
(*easy_setopt_)(curl_, CURLOPT_SSLVERSION, 6 /*CURL_SSLVERSION_TLSv1_2*/);

// Disable 100-continue header.
char buf[] = "Expect:";
headerlist_ = (*slist_append_)(headerlist_, buf);
(*easy_setopt_)(curl_, CURLOPT_HTTPHEADER, headerlist_);

if (http_response_data != nullptr) {
http_response_data->clear();
(*easy_setopt_)(curl_, CURLOPT_WRITEFUNCTION, WriteCallback);
(*easy_setopt_)(curl_, CURLOPT_WRITEDATA,
reinterpret_cast<void*>(http_response_data));
}
if (http_header_data != nullptr) {
http_header_data->clear();
(*easy_setopt_)(curl_, CURLOPT_HEADERFUNCTION, WriteCallback);
(*easy_setopt_)(curl_, CURLOPT_HEADERDATA,
reinterpret_cast<void*>(http_header_data));
}
CURLcode err_code = CURLE_OK;
err_code = (*easy_perform_)(curl_);
easy_strerror_ = reinterpret_cast<const char* (*)(CURLcode)>(
dlsym(curl_lib_, "curl_easy_strerror"));

if (http_status_code != nullptr) {
(*easy_getinfo_)(curl_, CURLINFO_RESPONSE_CODE, http_status_code);
}

#ifndef NDEBUG
if (err_code != CURLE_OK)
fprintf(stderr, "Failed to send http request to %s, error: %s\n",
url.c_str(), (*easy_strerror_)(err_code));
#endif

Reset();

return err_code == CURLE_OK;
}

void LibcurlWrapper::Reset() {
if (headerlist_ != nullptr) {
(*slist_free_all_)(headerlist_);
headerlist_ = nullptr;
}

if (formpost_ != nullptr) {
(*formfree_)(formpost_);
formpost_ = nullptr;
}

(*easy_reset_)(curl_);
}

bool LibcurlWrapper::CheckInit() {
if (!init_ok_) {
std::cout << "LibcurlWrapper: You must call Init(), and have it return "
"'true' before invoking any other methods.\n";
return false;
}

return true;
}

} // namespace chromecast
71 changes: 71 additions & 0 deletions chromecast/crash/libcurl_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_CRASH_LIBCURL_WRAPPER_H_
#define CHROMECAST_CRASH_LIBCURL_WRAPPER_H_

#include <map>
#include <string>

#include "third_party/breakpad/breakpad/src/third_party/curl/curl.h"

namespace chromecast {
class LibcurlWrapper {
public:
LibcurlWrapper();
virtual ~LibcurlWrapper();
virtual bool Init();
virtual bool AddFile(const std::string& upload_file_path,
const std::string& basename);
virtual bool SendRequest(const std::string& url,
const std::map<std::string, std::string>& parameters,
long* http_status_code,
std::string* http_header_data,
std::string* http_response_data);

private:
// This function initializes class state corresponding to function
// pointers into the CURL library.
bool SetFunctionPointers();

bool SendRequestInner(const std::string& url,
long* http_status_code,
std::string* http_header_data,
std::string* http_response_data);

void Reset();

bool CheckInit();

bool init_ok_; // Whether init succeeded
void* curl_lib_; // Pointer to result of dlopen() on
// curl library
std::string last_curl_error_; // The text of the last error when
// dealing
// with CURL.

CURL* curl_; // Pointer for handle for CURL calls.

CURL* (*easy_init_)(void);

// Stateful pointers for calling into curl_formadd()
struct curl_httppost* formpost_;
struct curl_httppost* lastptr_;
struct curl_slist* headerlist_;

// Function pointers into CURL library
CURLcode (*easy_setopt_)(CURL*, CURLoption, ...);
CURLFORMcode (*formadd_)(struct curl_httppost**, struct curl_httppost**, ...);
struct curl_slist* (*slist_append_)(struct curl_slist*, const char*);
void (*slist_free_all_)(struct curl_slist*);
CURLcode (*easy_perform_)(CURL*);
const char* (*easy_strerror_)(CURLcode);
void (*easy_cleanup_)(CURL*);
CURLcode (*easy_getinfo_)(CURL*, CURLINFO info, ...);
void (*easy_reset_)(CURL*);
void (*formfree_)(struct curl_httppost*);
};
} // namespace chromecast

#endif // CHROMECAST_CRASH_LIBCURL_WRAPPER_H_

0 comments on commit 568c546

Please sign in to comment.