From 45a438ef3e9707522d4df01582abb7a72626245b Mon Sep 17 00:00:00 2001 From: Pavan Shah Date: Mon, 2 Aug 2021 16:19:27 -0400 Subject: [PATCH] support curl operations with ssl credentials --- bazel/curl.BUILD | 292 +++++++++++++++++- bazel/curl.bzl | 40 ++- .../exporters/otlp/otlp_http_exporter.h | 3 + exporters/otlp/src/otlp_http_exporter.cc | 1 + .../ext/http/client/curl/http_client_curl.h | 10 +- .../http/client/curl/http_operation_curl.h | 16 +- .../ext/http/client/http_client.h | 2 + 7 files changed, 354 insertions(+), 10 deletions(-) diff --git a/bazel/curl.BUILD b/bazel/curl.BUILD index 2c668b895c..73bb9bc805 100644 --- a/bazel/curl.BUILD +++ b/bazel/curl.BUILD @@ -22,7 +22,7 @@ config_setting( cc_library( name = "curl", - srcs = glob([ + srcs = ["include/curl_config.h",] + glob([ "lib/**/*.c", ]), hdrs = glob([ @@ -31,7 +31,18 @@ cc_library( ]), copts = CURL_COPTS + [ "-DOS=\"os\"", - ], + ] + select({ + "//:osx": [ + "-fno-constant-cfstrings", + ], + "//:windows": [ + # See curl.h for discussion of write size and Windows + "/DCURL_MAX_WRITE_SIZE=16384", + ], + "//conditions:default": [ + "-DCURL_MAX_WRITE_SIZE=65536", + ], + }), defines = ["CURL_STATICLIB"], includes = [ "include/", @@ -47,10 +58,287 @@ cc_library( "//:osx": [ "-framework SystemConfiguration", "-lpthread", + "-Wl,-framework", + "-Wl,CoreFoundation", + "-Wl,-framework", + "-Wl,Security", ], "//conditions:default": [ "-lpthread", + "-lrt", + ], + }), + deps = select({ + "//:windows": [], + "//conditions:default": [ + "@boringssl//:ssl", ], }), visibility = ["//visibility:public"], ) + +genrule( + name = "configure", + outs = ["include/curl_config.h"], + cmd = "\n".join([ + "cat <<'EOF' >$@", + "#ifndef EXTERNAL_CURL_INCLUDE_CURL_CONFIG_H_", + "#define EXTERNAL_CURL_INCLUDE_CURL_CONFIG_H_", + "", + "#if !defined(_WIN32) && !defined(__APPLE__)", + "# include ", + "# if defined(OPENSSL_IS_BORINGSSL)", + "# define HAVE_BORINGSSL 1", + "# endif", + "#endif", + "", + "#if defined(_WIN32)", + "# include \"lib/config-win32.h\"", + "# define BUILDING_LIBCURL 1", + "# define CURL_DISABLE_CRYPTO_AUTH 1", + "# define CURL_DISABLE_DICT 1", + "# define CURL_DISABLE_FILE 1", + "# define CURL_DISABLE_GOPHER 1", + "# define CURL_DISABLE_IMAP 1", + "# define CURL_DISABLE_LDAP 1", + "# define CURL_DISABLE_LDAPS 1", + "# define CURL_DISABLE_POP3 1", + "# define CURL_PULL_WS2TCPIP_H 1", + "# define CURL_DISABLE_SMTP 1", + "# define CURL_DISABLE_TELNET 1", + "# define CURL_DISABLE_TFTP 1", + "# define CURL_PULL_WS2TCPIP_H 1", + "# define USE_WINDOWS_SSPI 1", + "# define USE_WIN32_IDN 1", + "# define USE_SCHANNEL 1", + "# define WANT_IDN_PROTOTYPES 1", + "#elif defined(__APPLE__)", + "# define HAVE_FSETXATTR_6 1", + "# define HAVE_SETMODE 1", + "# define HAVE_SYS_FILIO_H 1", + "# define HAVE_SYS_SOCKIO_H 1", + "# define OS \"x86_64-apple-darwin15.5.0\"", + "# define USE_SECTRANSP 1", + "#else", + "# define CURL_CA_BUNDLE \"/etc/ssl/certs/ca-certificates.crt\"", + "# define GETSERVBYPORT_R_ARGS 6", + "# define GETSERVBYPORT_R_BUFSIZE 4096", + "# define HAVE_BORINGSSL 1", + "# define HAVE_CLOCK_GETTIME_MONOTONIC 1", + "# define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1", + "# define HAVE_FSETXATTR_5 1", + "# define HAVE_GETHOSTBYADDR_R 1", + "# define HAVE_GETHOSTBYADDR_R_8 1", + "# define HAVE_GETHOSTBYNAME_R 1", + "# define HAVE_GETHOSTBYNAME_R_6 1", + "# define HAVE_GETSERVBYPORT_R 1", + "# define HAVE_LIBSSL 1", + "# define HAVE_MALLOC_H 1", + "# define HAVE_MSG_NOSIGNAL 1", + "# define HAVE_OPENSSL_CRYPTO_H 1", + "# define HAVE_OPENSSL_ERR_H 1", + "# define HAVE_OPENSSL_PEM_H 1", + "# define HAVE_OPENSSL_PKCS12_H 1", + "# define HAVE_OPENSSL_RSA_H 1", + "# define HAVE_OPENSSL_SSL_H 1", + "# define HAVE_OPENSSL_X509_H 1", + "# define HAVE_RAND_EGD 1", + "# define HAVE_RAND_STATUS 1", + "# define HAVE_SSL_GET_SHUTDOWN 1", + "# define HAVE_TERMIOS_H 1", + "# define OS \"x86_64-pc-linux-gnu\"", + "# define RANDOM_FILE \"/dev/urandom\"", + "# define USE_OPENSSL 1", + "#endif", + "", + "#if !defined(_WIN32)", + "# define CURL_DISABLE_DICT 1", + "# define CURL_DISABLE_FILE 1", + "# define CURL_DISABLE_GOPHER 1", + "# define CURL_DISABLE_IMAP 1", + "# define CURL_DISABLE_LDAP 1", + "# define CURL_DISABLE_LDAPS 1", + "# define CURL_DISABLE_POP3 1", + "# define CURL_DISABLE_SMTP 1", + "# define CURL_DISABLE_TELNET 1", + "# define CURL_DISABLE_TFTP 1", + "# define CURL_EXTERN_SYMBOL __attribute__ ((__visibility__ (\"default\")))", + "# define ENABLE_IPV6 1", + "# define GETHOSTNAME_TYPE_ARG2 size_t", + "# define GETNAMEINFO_QUAL_ARG1 const", + "# define GETNAMEINFO_TYPE_ARG1 struct sockaddr *", + "# define GETNAMEINFO_TYPE_ARG2 socklen_t", + "# define GETNAMEINFO_TYPE_ARG46 socklen_t", + "# define GETNAMEINFO_TYPE_ARG7 int", + "# define HAVE_ALARM 1", + "# define HAVE_ALLOCA_H 1", + "# define HAVE_ARPA_INET_H 1", + "# define HAVE_ARPA_TFTP_H 1", + "# define HAVE_ASSERT_H 1", + "# define HAVE_BASENAME 1", + "# define HAVE_BOOL_T 1", + "# define HAVE_CONNECT 1", + "# define HAVE_DLFCN_H 1", + "# define HAVE_ERRNO_H 1", + "# define HAVE_FCNTL 1", + "# define HAVE_FCNTL_H 1", + "# define HAVE_FCNTL_O_NONBLOCK 1", + "# define HAVE_FDOPEN 1", + "# define HAVE_FORK 1", + "# define HAVE_FREEADDRINFO 1", + "# define HAVE_FREEIFADDRS 1", + "# if !defined(__ANDROID__)", + "# define HAVE_FSETXATTR 1", + "# endif", + "# define HAVE_FTRUNCATE 1", + "# define HAVE_GAI_STRERROR 1", + "# define HAVE_GETADDRINFO 1", + "# define HAVE_GETADDRINFO_THREADSAFE 1", + "# define HAVE_GETEUID 1", + "# define HAVE_GETHOSTBYADDR 1", + "# define HAVE_GETHOSTBYNAME 1", + "# define HAVE_GETHOSTNAME 1", + "# if !defined(__ANDROID__)", + "# define HAVE_GETIFADDRS 1", + "# endif", + "# define HAVE_GETNAMEINFO 1", + "# define HAVE_GETPPID 1", + "# define HAVE_GETPROTOBYNAME 1", + "# define HAVE_GETPWUID 1", + "# if !defined(__ANDROID__)", + "# define HAVE_GETPWUID_R 1", + "# endif", + "# define HAVE_GETRLIMIT 1", + "# define HAVE_GETTIMEOFDAY 1", + "# define HAVE_GMTIME_R 1", + "# if !defined(__ANDROID__)", + "# define HAVE_IFADDRS_H 1", + "# endif", + "# define HAVE_IF_NAMETOINDEX 1", + "# define HAVE_INET_ADDR 1", + "# define HAVE_INET_NTOP 1", + "# define HAVE_INET_PTON 1", + "# define HAVE_INTTYPES_H 1", + "# define HAVE_IOCTL 1", + "# define HAVE_IOCTL_FIONBIO 1", + "# define HAVE_IOCTL_SIOCGIFADDR 1", + "# define HAVE_LIBGEN_H 1", + "# define HAVE_LIBZ 1", + "# define HAVE_LIMITS_H 1", + "# define HAVE_LL 1", + "# define HAVE_LOCALE_H 1", + "# define HAVE_LOCALTIME_R 1", + "# define HAVE_LONGLONG 1", + "# define HAVE_MEMORY_H 1", + "# define HAVE_NETDB_H 1", + "# define HAVE_NETINET_IN_H 1", + "# define HAVE_NETINET_TCP_H 1", + "# define HAVE_NET_IF_H 1", + "# define HAVE_PERROR 1", + "# define HAVE_PIPE 1", + "# define HAVE_POLL 1", + "# define HAVE_POLL_FINE 1", + "# define HAVE_POLL_H 1", + "# define HAVE_POSIX_STRERROR_R 1", + "# define HAVE_PWD_H 1", + "# define HAVE_RECV 1", + "# define HAVE_SELECT 1", + "# define HAVE_SEND 1", + "# define HAVE_SETJMP_H 1", + "# define HAVE_SETLOCALE 1", + "# define HAVE_SETRLIMIT 1", + "# define HAVE_SETSOCKOPT 1", + "# define HAVE_SGTTY_H 1", + "# define HAVE_SIGACTION 1", + "# define HAVE_SIGINTERRUPT 1", + "# define HAVE_SIGNAL 1", + "# define HAVE_SIGNAL_H 1", + "# define HAVE_SIGSETJMP 1", + "# define HAVE_SIG_ATOMIC_T 1", + "# define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1", + "# define HAVE_SOCKET 1", + "# define HAVE_SOCKETPAIR 1", + "# define HAVE_STDBOOL_H 1", + "# define HAVE_STDINT_H 1", + "# define HAVE_STDIO_H 1", + "# define HAVE_STDLIB_H 1", + "# define HAVE_STRCASECMP 1", + "# define HAVE_STRDUP 1", + "# define HAVE_STRERROR_R 1", + "# define HAVE_STRINGS_H 1", + "# define HAVE_STRING_H 1", + "# define HAVE_STRNCASECMP 1", + "# define HAVE_STRSTR 1", + "# define HAVE_STRTOK_R 1", + "# define HAVE_STRTOLL 1", + "# define HAVE_STRUCT_SOCKADDR_STORAGE 1", + "# define HAVE_STRUCT_TIMEVAL 1", + "# define HAVE_SYS_IOCTL_H 1", + "# define HAVE_SYS_PARAM_H 1", + "# define HAVE_SYS_POLL_H 1", + "# define HAVE_SYS_RESOURCE_H 1", + "# define HAVE_SYS_SELECT_H 1", + "# define HAVE_SYS_SOCKET_H 1", + "# define HAVE_SYS_STAT_H 1", + "# define HAVE_SYS_TIME_H 1", + "# define HAVE_SYS_TYPES_H 1", + "# define HAVE_SYS_UIO_H 1", + "# define HAVE_SYS_UN_H 1", + "# define HAVE_SYS_WAIT_H 1", + "# define HAVE_SYS_XATTR_H 1", + "# define HAVE_TIME_H 1", + "# define HAVE_UNAME 1", + "# define HAVE_UNISTD_H 1", + "# define HAVE_UTIME 1", + "# define HAVE_UTIME_H 1", + "# define HAVE_VARIADIC_MACROS_C99 1", + "# define HAVE_VARIADIC_MACROS_GCC 1", + "# define HAVE_WRITABLE_ARGV 1", + "# define HAVE_WRITEV 1", + "# define HAVE_ZLIB_H 1", + "# define LT_OBJDIR \".libs/\"", + "# define PACKAGE \"curl\"", + "# define PACKAGE_BUGREPORT \"a suitable curl mailing list: https://curl.haxx.se/mail/\"", + "# define PACKAGE_NAME \"curl\"", + "# define PACKAGE_STRING \"curl -\"", + "# define PACKAGE_TARNAME \"curl\"", + "# define PACKAGE_URL \"\"", + "# define PACKAGE_VERSION \"-\"", + "# define RECV_TYPE_ARG1 int", + "# define RECV_TYPE_ARG2 void *", + "# define RECV_TYPE_ARG3 size_t", + "# define RECV_TYPE_ARG4 int", + "# define RECV_TYPE_RETV ssize_t", + "# define RETSIGTYPE void", + "# define SELECT_QUAL_ARG5", + "# define SELECT_TYPE_ARG1 int", + "# define SELECT_TYPE_ARG234 fd_set *", + "# define SELECT_TYPE_ARG5 struct timeval *", + "# define SELECT_TYPE_RETV int", + "# define SEND_QUAL_ARG2 const", + "# define SEND_TYPE_ARG1 int", + "# define SEND_TYPE_ARG2 void *", + "# define SEND_TYPE_ARG3 size_t", + "# define SEND_TYPE_ARG4 int", + "# define SEND_TYPE_RETV ssize_t", + "# define SIZEOF_INT 4", + "# define SIZEOF_LONG 8", + "# define SIZEOF_OFF_T 8", + "# define SIZEOF_CURL_OFF_T 8", + "# define SIZEOF_SHORT 2", + "# define SIZEOF_SIZE_T 8", + "# define SIZEOF_TIME_T 8", + "# define SIZEOF_VOIDP 8", + "# define STDC_HEADERS 1", + "# define STRERROR_R_TYPE_ARG3 size_t", + "# define TIME_WITH_SYS_TIME 1", + "# define VERSION \"-\"", + "# ifndef _DARWIN_USE_64_BIT_INODE", + "# define _DARWIN_USE_64_BIT_INODE 1", + "# endif", + "#endif", + "", + "#endif // EXTERNAL_CURL_INCLUDE_CURL_CONFIG_H_", + "EOF", + ]), +) \ No newline at end of file diff --git a/bazel/curl.bzl b/bazel/curl.bzl index 6a887c50c6..946a71e601 100644 --- a/bazel/curl.bzl +++ b/bazel/curl.bzl @@ -195,7 +195,41 @@ CURL_COPTS = select({ "/DUSE_IPV6", "/DUSE_WINDOWS_SSPI", "/DUSE_SCHANNEL", + # for https + "/Iexternal/curl/lib", + "/DBUILDING_LIBCURL", + "/DHAVE_CONFIG_H", + "/DCURL_DISABLE_FTP", + "/DCURL_DISABLE_NTLM", + "/DCURL_DISABLE_PROXY", + "/DHAVE_LIBZ", + "/DHAVE_ZLIB_H", + # Defining _USING_V110_SDK71_ is hackery to defeat curl's incorrect + # detection of what OS releases we can build on with VC 2012. This + # may not be needed (or may have to change) if the WINVER setting + # changes in //third_party/msvc/vc_12_0/CROSSTOOL. + "/D_USING_V110_SDK71_", + ], + "//:osx": BASE_CURL_COPTS + [ + "-Iexternal/curl/lib", + "-D_GNU_SOURCE", + "-DBUILDING_LIBCURL", + "-DHAVE_CONFIG_H", + "-DCURL_DISABLE_FTP", + "-DCURL_DISABLE_NTLM", # turning it off in configure is not enough + "-DHAVE_LIBZ", + "-DHAVE_ZLIB_H", + "-Wno-string-plus-int", + ], + "//conditions:default": BASE_CURL_COPTS + LINUX_CURL_COPTS + [ + "-Iexternal/curl/lib", + "-D_GNU_SOURCE", + "-DBUILDING_LIBCURL", + "-DHAVE_CONFIG_H", + "-DCURL_DISABLE_FTP", + "-DCURL_DISABLE_NTLM", # turning it off in configure is not enough + "-DHAVE_LIBZ", + "-DHAVE_ZLIB_H", + "-Wno-string-plus-int", ], - "//:osx": BASE_CURL_COPTS, - "//conditions:default": BASE_CURL_COPTS + LINUX_CURL_COPTS, -}) +}) \ No newline at end of file diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h index 0d6f04e653..e46280b6c3 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h @@ -68,6 +68,9 @@ struct OtlpHttpExporterOptions // TODO: Enable/disable to verify SSL certificate std::chrono::milliseconds timeout = std::chrono::milliseconds(30000); + + // filepath of the sll certifcate, this is empty if there is none. + std::string sslCertPath; }; /** diff --git a/exporters/otlp/src/otlp_http_exporter.cc b/exporters/otlp/src/otlp_http_exporter.cc index 80cbfa40c7..380f1d3128 100644 --- a/exporters/otlp/src/otlp_http_exporter.cc +++ b/exporters/otlp/src/otlp_http_exporter.cc @@ -634,6 +634,7 @@ sdk::common::ExportResult OtlpHttpExporter::Export( request->SetMethod(http_client::Method::Post); request->SetBody(body_vec); request->AddHeader("Content-Type", content_type); + request->IncludePermissionsFilePath(options_.sslCertPath); // Send the request std::unique_ptr handler(new ResponseHandler(options_.console_debug)); diff --git a/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h b/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h index 126b09acf8..0e0dd002f0 100644 --- a/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h +++ b/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h @@ -58,12 +58,20 @@ class Request : public http_client::Request timeout_ms_ = timeout_ms; } + void IncludePermissionsFilePath(std::string filepath) noexcept override + { + permissions_path_ = filepath; + } + + public: http_client::Method method_; http_client::Body body_; http_client::Headers headers_; std::string uri_; std::chrono::milliseconds timeout_ms_{5000}; // ms + std::string permissions_path_; + }; class Response : public http_client::Response @@ -138,7 +146,7 @@ class Session : public http_client::Session auto callback_ptr = &callback; curl_operation_.reset(new HttpOperation( http_request_->method_, url, callback_ptr, RequestMode::Async, http_request_->headers_, - http_request_->body_, false, http_request_->timeout_ms_)); + http_request_->body_, false, http_request_->timeout_ms_, http_request_->permissions_path_)); curl_operation_->SendAsync([this, callback_ptr](HttpOperation &operation) { if (operation.WasAborted()) { diff --git a/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h b/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h index 9aafbbf27c..78bef2c894 100644 --- a/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h +++ b/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h @@ -78,7 +78,8 @@ class HttpOperation const http_client::Body &request_body = http_client::Body(), // Default connectivity and response size options bool is_raw_response = false, - std::chrono::milliseconds http_conn_timeout = default_http_conn_timeout) + std::chrono::milliseconds http_conn_timeout = default_http_conn_timeout, + std::string ssl_cert_path = "") : is_aborted_(false), is_finished_(false), // Optional connection params @@ -111,9 +112,16 @@ class HttpOperation // Specify target URL curl_easy_setopt(curl_, CURLOPT_URL, url_.c_str()); - // TODO: support ssl cert verification for https request - curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0); // 1L - curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYHOST, 0); // 2L + if (ssl_cert_path.empty()){ + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYHOST, 0); // 2L + } else { + curl_easy_setopt(curl_, CURLOPT_CAPATH, ssl_cert_path.c_str()); + curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 1); + } + + curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, request_body.size()); + // Specify our custom headers for (auto &kv : this->request_headers_) diff --git a/ext/include/opentelemetry/ext/http/client/http_client.h b/ext/include/opentelemetry/ext/http/client/http_client.h index 308335e492..b701bce511 100644 --- a/ext/include/opentelemetry/ext/http/client/http_client.h +++ b/ext/include/opentelemetry/ext/http/client/http_client.h @@ -125,6 +125,8 @@ class Request virtual void SetTimeoutMs(std::chrono::milliseconds timeout_ms) noexcept = 0; + virtual void IncludePermissionsFilePath(std::string filepath) noexcept = 0; + virtual ~Request() = default; };