Improved error handling

This commit is contained in:
Federico Stazi 2020-08-21 16:08:10 +00:00
parent 6167cafbde
commit 9fed2ec097
9 changed files with 162 additions and 271 deletions

View File

@ -20,6 +20,9 @@
#include "../sandbox.h"
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
sapi::StatusOr<CURL*> status_or_curl;
sapi::StatusOr<int> status_or_int;
@ -27,59 +30,41 @@ int main(int argc, char* argv[]) {
// Initialize sandbox2 and sapi
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
std::cerr << "error in sandbox Init" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
CurlApi api(&sandbox);
// Initialize the curl session
status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_curl.ok())
LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the library to follow a redirection
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_FOLLOWLOCATION, 1l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_long" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
// Disable authentication of peer certificate
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 0l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_long" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
// Perform the request
status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_perform" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
// Cleanup curl
status = api.curl_easy_cleanup(&curl);
if (!status.ok()) {
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
return EXIT_SUCCESS;
}

View File

@ -25,7 +25,10 @@ struct MemoryStruct {
size_t size;
};
int main() {
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
sapi::StatusOr<CURL*> status_or_curl;
sapi::StatusOr<int> status_or_int;
@ -33,91 +36,66 @@ int main() {
// Initialize sandbox2 and sapi
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
std::cerr << "error in sandbox Init" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
CurlApi api(&sandbox);
// Generate pointer to WriteMemoryCallback function
sapi::RPCChannel rpcc(sandbox.comms());
size_t (*_function_ptr)(void*, size_t, size_t, void*);
status = rpcc.Symbol("WriteMemoryCallback", (void**)&_function_ptr);
if (!status.ok()) {
std::cerr << "error in RPCChannel Symbol" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "rpcc.Symbol failed: " << status;
sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr);
// Initialize the curl session
status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_curl.ok())
LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set WriteMemoryCallback as the write function
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION,
&remote_function_ptr);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Pass 'chunk' struct to the callback function
sapi::v::Struct<MemoryStruct> chunk;
status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA, chunk.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set a user agent
sapi::v::ConstCStr user_agent("libcurl-agent/1.0");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT,
user_agent.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Perform the request
status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_perform" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
// Retrieve memory size
sapi::v::Int size;
size.SetRemote(&((MemoryStruct*)chunk.GetRemote())->size);
status = sandbox.TransferFromSandboxee(&size);
if (!status.ok()) {
std::cerr << "error in sandbox TransferFromSandboxee" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "sandbox.TransferFromSandboxee failed: " << status;
std::cout << "memory size: " << size.GetValue() << " bytes" << std::endl;
// Cleanup curl
status = api.curl_easy_cleanup(&curl);
if (!status.ok()) {
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
return EXIT_SUCCESS;
}

View File

@ -33,8 +33,10 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
// Add the syscalls and files missing in CurlSandbox to a new PolicyBuilder
auto policy_builder = std::make_unique<sandbox2::PolicyBuilder>();
(*policy_builder)
.AllowFutexOp(FUTEX_WAIT_PRIVATE)
.AllowGetPIDs()
.AllowGetRandom()
.AllowHandleSignals()
.AllowSyscall(__NR_sysinfo)
.AddFile(ssl_certificate)
.AddFile(ssl_key)
@ -49,15 +51,15 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
};
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
sapi::StatusOr<int> status_or_int;
sapi::StatusOr<CURL*> status_or_curl;
// Get input parameters (should be absolute paths)
if (argc != 5) {
std::cerr << "wrong number of arguments (4 expected)" << std::endl;
return EXIT_FAILURE;
}
if (argc != 5) LOG(FATAL) << "wrong number of arguments (4 expected)";
std::string ssl_certificate = argv[1];
std::string ssl_key = argv[2];
std::string ssl_key_password = argv[3];
@ -66,111 +68,80 @@ int main(int argc, char* argv[]) {
// Initialize sandbox2 and sapi
CurlSapiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates);
status = sandbox.Init();
if (!status.ok()) {
std::cerr << "error in sandbox Init" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
CurlApi api(&sandbox);
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_global_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
// Initialize curl easy handle
status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_curl.ok())
LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
// Specify URL to get (using HTTPS)
sapi::v::ConstCStr url("https://example.com");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the SSL certificate type to "PEM"
sapi::v::ConstCStr ssl_cert_type("PEM");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE,
ssl_cert_type.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the certificate for client authentication
sapi::v::ConstCStr sapi_ssl_certificate(ssl_certificate.c_str());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT,
sapi_ssl_certificate.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the private key for client authentication
sapi::v::ConstCStr sapi_ssl_key(ssl_key.c_str());
status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY, sapi_ssl_key.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the password used to protect the private key
sapi::v::ConstCStr sapi_ssl_key_password(ssl_key_password.c_str());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD,
sapi_ssl_key_password.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Set the file with the certificates vaildating the server
sapi::v::ConstCStr sapi_ca_certificates(ca_certificates.c_str());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO,
sapi_ca_certificates.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Verify the authenticity of the server
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_long" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
// Perform the request
status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_perform" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
// Cleanup curl easy handle
status = api.curl_easy_cleanup(&curl);
if (!status.ok()) {
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
// Cleanup curl
status = api.curl_global_cleanup();
if (!status.ok()) {
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
return EXIT_SUCCESS;
}

View File

@ -21,7 +21,10 @@
#include "curl_sapi.sapi.h"
#include "sandboxed_api/util/flag.h"
int main() {
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
sapi::StatusOr<int> status_or_int;
sapi::StatusOr<CURL*> status_or_curl;
@ -30,10 +33,8 @@ int main() {
// Initialize sandbox2 and sapi
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
std::cerr << "error in sandbox Init" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
CurlApi api(&sandbox);
// Number of running handles
@ -41,50 +42,36 @@ int main() {
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_global_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
// Initialize http_handle
status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_curl.ok())
LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
sapi::v::RemotePtr http_handle(status_or_curl.value());
if (!http_handle.GetValue()) {
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
if (!http_handle.GetValue())
LOG(FATAL) << "curl_easy_init failed: http_handle is NULL";
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
status_or_int =
api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Initialize multi_handle
status_or_curlm = api.curl_multi_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_multi_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_curlm.ok())
LOG(FATAL) << "curl_multi_init failed: " << status_or_curlm.status();
sapi::v::RemotePtr multi_handle(status_or_curlm.value());
if (!multi_handle.GetValue()) {
std::cerr << "error in curl_multi_init" << std::endl;
return EXIT_FAILURE;
}
if (!multi_handle.GetValue())
LOG(FATAL) << "curl_multi_init failed: multi_handle is NULL";
// Add http_handle to the multi stack
status_or_int = api.curl_multi_add_handle(&multi_handle, &http_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_multi_add_handle" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_multi_add_handle failed: " << status_or_int.status();
while (still_running.GetValue()) {
sapi::v::Int numfds(0);
@ -92,50 +79,36 @@ int main() {
// Perform the request
status_or_int =
api.curl_multi_perform(&multi_handle, still_running.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_multi_perform" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_mutli_perform failed: " << status_or_int.status();
if (still_running.GetValue()) {
// Wait for an event or timeout
sapi::v::NullPtr null_ptr;
status_or_int = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0,
1000, numfds.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_multi_poll_sapi" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_multi_poll_sapi failed: " << status_or_int.status();
}
}
// Remove http_handle from the multi stack
status_or_int = api.curl_multi_remove_handle(&multi_handle, &http_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_multi_remove_handle" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_multi_remove_handle failed: " << status_or_int.status();
// Cleanup http_handle
status = api.curl_easy_cleanup(&http_handle);
if (!status.ok()) {
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
// Cleanup multi_handle
status_or_int = api.curl_multi_cleanup(&multi_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_multi_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_multi_cleanup failed: " << status_or_int.status();
// Cleanup curl
status = api.curl_global_cleanup();
if (!status.ok()) {
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
return EXIT_SUCCESS;
}

View File

@ -37,38 +37,26 @@ void* pull_one_url(void* args) {
// Initialize the curl session
status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) {
std::cerr << "error in curl_easy_init" << std::endl;
return NULL;
}
if (!status_or_curl.ok())
LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) {
std::cerr << "error in curl_easy_init" << std::endl;
return NULL;
}
if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
// Specify URL to get
sapi::v::ConstCStr sapi_url(((thread_args*)args)->url);
status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, sapi_url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_setopt_ptr" << std::endl;
return NULL;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
// Perform the request
status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_easy_perform" << std::endl;
return NULL;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
// Cleanup curl
status = api.curl_easy_cleanup(&curl);
if (!status.ok()) {
std::cerr << "error in curl_easy_cleanup" << std::endl;
return NULL;
}
if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
return NULL;
}
@ -77,7 +65,10 @@ const char* const urls[kThreadsnumber] = {
"http://example.com", "http://example.edu", "http://example.net",
"http://example.org"};
int main(int argc, char** argv) {
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
pthread_t tid[kThreadsnumber];
absl::Status status;
@ -86,42 +77,33 @@ int main(int argc, char** argv) {
// Initialize sandbox2 and sapi
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
std::cerr << "error in sandbox Init" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok())
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
CurlApi api(&sandbox);
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) {
std::cerr << "error in curl_global_init" << std::endl;
return EXIT_FAILURE;
}
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
// Create the threads
for (int i = 0; i < kThreadsnumber; ++i) {
thread_args args = {urls[i], &api};
int error = pthread_create(&tid[i], NULL, pull_one_url, (void*)&args);
if (error) {
std::cerr << "error in pthread_create" << std::endl;
return EXIT_FAILURE;
}
if (error) LOG(FATAL) << "pthread_create failed";
std::cout << "Thread " << i << " gets " << urls[i] << std::endl;
}
// Join the threads
for (int i = 0; i < kThreadsnumber; i++) {
pthread_join(tid[i], NULL);
for (int i = 0; i < kThreadsnumber; ++i) {
int error = pthread_join(tid[i], NULL);
if (error) LOG(FATAL) << "pthread_join failed";
std::cout << "Thread " << i << " terminated" << std::endl;
}
// Cleanup curl
status = api.curl_global_cleanup();
if (!status.ok()) {
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
return EXIT_SUCCESS;
}

View File

@ -39,26 +39,26 @@ absl::Status CurlTransaction::Main() {
CurlApi api(sandbox());
// Initialize the curl session
SAPI_ASSIGN_OR_RETURN(void* curl_remote, api.curl_easy_init())
SAPI_ASSIGN_OR_RETURN(void* curl_remote, api.curl_easy_init());
sapi::v::RemotePtr curl(curl_remote);
TRANSACTION_FAIL_IF_NOT(curl.GetValue(), "error in curl_easy_init");
TRANSACTION_FAIL_IF_NOT(curl.GetValue(), "curl_easy_init failed");
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
SAPI_ASSIGN_OR_RETURN(
int setopt_url_code,
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()))
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()));
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK,
"error in curl_easy_setopt_ptr");
"curl_easy_setopt_ptr failed");
// Perform the request
SAPI_ASSIGN_OR_RETURN(int perform_code, api.curl_easy_perform(&curl))
SAPI_ASSIGN_OR_RETURN(int perform_code, api.curl_easy_perform(&curl));
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK,
"error in curl_easy_perform");
"curl_easy_perform failed");
// Cleanup curl
TRANSACTION_FAIL_IF_NOT(api.curl_easy_cleanup(&curl).ok(),
"error in curl_easy_cleanup");
"curl_easy_cleanup failed");
return absl::OkStatus();
}
@ -66,7 +66,7 @@ absl::Status CurlTransaction::Main() {
int main(int argc, char* argv[]) {
CurlTransaction curl{std::make_unique<CurlSapiSandbox>()};
absl::Status status = curl.Run();
CHECK(status.ok());
CHECK(status.ok()) << "CurlTransaction failed";
return EXIT_SUCCESS;
}

View File

@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <linux/futex.h>
#include <sys/mman.h> // For mmap arguments
#include <syscall.h>
#include <cstdlib>
#include "curl_sapi.sapi.h"
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
#include "sandboxed_api/util/flag.h"
class CurlSapiSandbox : public CurlSandbox {
@ -28,7 +31,8 @@ class CurlSapiSandbox : public CurlSandbox {
.AllowDynamicStartup()
.AllowExit()
.AllowFork()
.AllowHandleSignals()
.AllowFutexOp(FUTEX_WAKE_PRIVATE)
.AllowMmap()
.AllowOpen()
.AllowRead()
.AllowSafeFcntl()
@ -38,14 +42,12 @@ class CurlSapiSandbox : public CurlSandbox {
__NR_access,
__NR_bind,
__NR_connect,
__NR_futex,
__NR_getpeername,
__NR_getsockname,
__NR_getsockopt,
__NR_ioctl,
__NR_listen,
__NR_madvise,
__NR_mmap,
__NR_poll,
__NR_recvfrom,
__NR_recvmsg,

View File

@ -24,7 +24,7 @@
void CurlTestUtils::curl_test_set_up() {
// Initialize sandbox2 and sapi
sandbox = std::make_unique<CurlSapiSandbox>();
sandbox->Init().IgnoreError();
ASSERT_THAT(sandbox->Init(), sapi::IsOk());
api = std::make_unique<CurlApi>(sandbox.get());
// Initialize curl
@ -36,18 +36,18 @@ void CurlTestUtils::curl_test_set_up() {
SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_url_code,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_URL, sapi_url.PtrBefore()));
EXPECT_EQ(setopt_url_code, CURLE_OK);
ASSERT_EQ(setopt_url_code, CURLE_OK);
// Set port
SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_port_code,
api->curl_easy_setopt_long(curl.get(), CURLOPT_PORT, port));
EXPECT_EQ(setopt_port_code, CURLE_OK);
ASSERT_EQ(setopt_port_code, CURLE_OK);
// Generate pointer to the write_to_memory callback
sapi::RPCChannel rpcc(sandbox->comms());
size_t (*_function_ptr)(char*, size_t, size_t, void*);
EXPECT_THAT(rpcc.Symbol("write_to_memory", (void**)&_function_ptr),
ASSERT_THAT(rpcc.Symbol("write_to_memory", (void**)&_function_ptr),
sapi::IsOk());
sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr);
@ -56,36 +56,36 @@ void CurlTestUtils::curl_test_set_up() {
int setopt_write_function,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEFUNCTION,
&remote_function_ptr));
EXPECT_EQ(setopt_write_function, CURLE_OK);
ASSERT_EQ(setopt_write_function, CURLE_OK);
// Pass memory chunk object to the callback
SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_write_data,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEDATA,
chunk.PtrBoth()));
EXPECT_EQ(setopt_write_data, CURLE_OK);
ASSERT_EQ(setopt_write_data, CURLE_OK);
}
void CurlTestUtils::curl_test_tear_down() {
// Cleanup curl
api->curl_easy_cleanup(curl.get()).IgnoreError();
ASSERT_THAT(api->curl_easy_cleanup(curl.get()), sapi::IsOk());
}
void CurlTestUtils::perform_request(std::string& response) {
// Perform the request
SAPI_ASSERT_OK_AND_ASSIGN(int perform_code,
api->curl_easy_perform(curl.get()));
EXPECT_EQ(perform_code, CURLE_OK);
ASSERT_EQ(perform_code, CURLE_OK);
// Get pointer to the memory chunk
sapi::v::GenericPtr remote_ptr;
remote_ptr.SetRemote(&((MemoryStruct*)chunk.GetRemote())->memory);
sandbox->TransferFromSandboxee(&remote_ptr).IgnoreError();
ASSERT_THAT(sandbox->TransferFromSandboxee(&remote_ptr), sapi::IsOk());
void* chunk_ptr = (void*)remote_ptr.GetValue();
// Get the string and store it in response
SAPI_ASSERT_OK_AND_ASSIGN(
response, sandbox->GetCString(sapi::v::RemotePtr(chunk_ptr)));
SAPI_ASSERT_OK_AND_ASSIGN(response,
sandbox->GetCString(sapi::v::RemotePtr(chunk_ptr)));
}
void CurlTestUtils::perform_request() {

View File

@ -19,7 +19,7 @@ class Curl_Test : public CurlTestUtils, public ::testing::Test {
void SetUp() override {
// Start mock server, also sets port number
start_mock_server();
EXPECT_TRUE(server_future.valid());
ASSERT_TRUE(server_future.valid());
curl_test_set_up();
}
@ -28,7 +28,7 @@ class Curl_Test : public CurlTestUtils, public ::testing::Test {
curl_test_tear_down();
// Wait for the mock server to return and check for any error
EXPECT_TRUE(server_future.get());
ASSERT_TRUE(server_future.get());
}
};
@ -42,7 +42,7 @@ TEST_F(Curl_Test, EffectiveUrl) {
int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_EFFECTIVE_URL,
effective_url_ptr.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK);
ASSERT_EQ(getinfo_code, CURLE_OK);
// Store effective URL in a string
SAPI_ASSERT_OK_AND_ASSIGN(std::string effective_url,
@ -50,7 +50,7 @@ TEST_F(Curl_Test, EffectiveUrl) {
effective_url_ptr.GetPointedVar())));
// Compare effective URL with original URL
EXPECT_EQ(effective_url, kUrl);
ASSERT_EQ(effective_url, kUrl);
}
TEST_F(Curl_Test, EffectivePort) {
@ -63,10 +63,10 @@ TEST_F(Curl_Test, EffectivePort) {
int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_PRIMARY_PORT,
effective_port.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK);
ASSERT_EQ(getinfo_code, CURLE_OK);
// Compare effective port with port set by the mock server
EXPECT_EQ(effective_port.GetValue(), port);
ASSERT_EQ(effective_port.GetValue(), port);
}
TEST_F(Curl_Test, ResponseCode) {
@ -79,10 +79,10 @@ TEST_F(Curl_Test, ResponseCode) {
int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_RESPONSE_CODE,
response_code.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK);
ASSERT_EQ(getinfo_code, CURLE_OK);
// Check response code
EXPECT_EQ(response_code.GetValue(), 200);
ASSERT_EQ(response_code.GetValue(), 200);
}
TEST_F(Curl_Test, ContentType) {
@ -95,7 +95,7 @@ TEST_F(Curl_Test, ContentType) {
int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_CONTENT_TYPE,
content_type_ptr.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK);
ASSERT_EQ(getinfo_code, CURLE_OK);
// Store content type in a string
SAPI_ASSERT_OK_AND_ASSIGN(std::string content_type,
@ -103,7 +103,7 @@ TEST_F(Curl_Test, ContentType) {
content_type_ptr.GetPointedVar())));
// Compare content type with "text/plain"
EXPECT_EQ(content_type, "text/plain");
ASSERT_EQ(content_type, "text/plain");
}
TEST_F(Curl_Test, GETResponse) {
@ -111,7 +111,7 @@ TEST_F(Curl_Test, GETResponse) {
perform_request(response);
// Compare response with expected response
EXPECT_EQ(response, kSimpleResponse);
ASSERT_EQ(response, kSimpleResponse);
}
TEST_F(Curl_Test, POSTResponse) {
@ -120,25 +120,25 @@ TEST_F(Curl_Test, POSTResponse) {
// Set request method to POST
SAPI_ASSERT_OK_AND_ASSIGN(int setopt_post, api->curl_easy_setopt_long(
curl.get(), CURLOPT_POST, 1l));
EXPECT_EQ(setopt_post, CURLE_OK);
ASSERT_EQ(setopt_post, CURLE_OK);
// Set the size of the POST fields
SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_post_fields_size,
api->curl_easy_setopt_long(curl.get(), CURLOPT_POSTFIELDSIZE,
post_fields.GetSize()));
EXPECT_EQ(setopt_post_fields_size, CURLE_OK);
ASSERT_EQ(setopt_post_fields_size, CURLE_OK);
// Set the POST fields
SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_post_fields,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_POSTFIELDS,
post_fields.PtrBefore()));
EXPECT_EQ(setopt_post_fields, CURLE_OK);
ASSERT_EQ(setopt_post_fields, CURLE_OK);
std::string response;
perform_request(response);
// Compare response with expected response
EXPECT_EQ(std::string(post_fields.GetData()), response);
ASSERT_EQ(std::string(post_fields.GetData()), response);
}