in adapters/httpapi_curl.c [891:1147]
HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, const void* value)
{
HTTPAPI_RESULT result;
if (
(handle == NULL) ||
(optionName == NULL) ||
(value == NULL)
)
{
result = HTTPAPI_INVALID_ARG;
LogError("invalid parameter (NULL) passed to HTTPAPI_SetOption");
}
else
{
HTTP_HANDLE_DATA* httpHandleData = (HTTP_HANDLE_DATA*)handle;
if (strcmp(OPTION_HTTP_TIMEOUT, optionName) == 0)
{
long timeout = (long)(*(unsigned int*)value);
httpHandleData->timeout = timeout;
result = HTTPAPI_OK;
}
else if (strcmp(OPTION_CURL_LOW_SPEED_LIMIT, optionName) == 0)
{
httpHandleData->lowSpeedLimit = *(const long*)value;
result = HTTPAPI_OK;
}
else if (strcmp(OPTION_CURL_LOW_SPEED_TIME, optionName) == 0)
{
httpHandleData->lowSpeedTime = *(const long*)value;
result = HTTPAPI_OK;
}
else if (strcmp(OPTION_CURL_FRESH_CONNECT, optionName) == 0)
{
httpHandleData->freshConnect = *(const long*)value;
result = HTTPAPI_OK;
}
else if (strcmp(OPTION_CURL_FORBID_REUSE, optionName) == 0)
{
httpHandleData->forbidReuse = *(const long*)value;
result = HTTPAPI_OK;
}
else if (strcmp(OPTION_CURL_VERBOSE, optionName) == 0)
{
httpHandleData->verbose = *(const long*)value;
result = HTTPAPI_OK;
}
#ifdef USE_OPENSSL
else if (strcmp(OPTION_OPENSSL_PRIVATE_KEY_TYPE, optionName) == 0)
{
const OPTION_OPENSSL_KEY_TYPE type = *(const OPTION_OPENSSL_KEY_TYPE*)value;
if (type == KEY_TYPE_DEFAULT || type == KEY_TYPE_ENGINE)
{
httpHandleData->x509privatekeytype = type;
result = HTTPAPI_OK;
}
else
{
LogError("Unknown x509PrivatekeyType: %i", type);
result = HTTPAPI_ERROR;
}
}
#ifndef OPENSSL_NO_ENGINE
else if (strcmp(OPTION_OPENSSL_ENGINE, optionName) == 0)
{
if (mallocAndStrcpy_s((char**)&httpHandleData->engineId, value) != 0)
{
LogError("unable to mallocAndStrcpy_s x509PrivatekeyType");
result = HTTPAPI_ERROR;
}
else
{
result = HTTPAPI_OK;
}
}
#endif // OPENSSL_NO_ENGINE
#endif
else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
{
httpHandleData->x509privatekey = value;
if (httpHandleData->x509certificate != NULL)
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
{
LogError("unable to curl_easy_setopt");
result = HTTPAPI_ERROR;
}
else
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
{
LogError("unable to curl_easy_setopt");
result = HTTPAPI_ERROR;
}
else
{
result = HTTPAPI_OK;
}
}
}
else
{
/*if privatekey comes 1st and certificate is not set yet, then return OK and wait for the certificate to be set*/
result = HTTPAPI_OK;
}
}
else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
{
httpHandleData->x509certificate = value;
if (httpHandleData->x509privatekey != NULL)
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
{
LogError("unable to curl_easy_setopt");
result = HTTPAPI_ERROR;
}
else
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
{
LogError("unable to curl_easy_setopt");
result = HTTPAPI_ERROR;
}
else
{
result = HTTPAPI_OK;
}
}
}
else
{
/*if certificate comes 1st and private key is not set yet, then return OK and wait for the private key to be set*/
result = HTTPAPI_OK;
}
}
else if (strcmp(OPTION_HTTP_PROXY, optionName) == 0)
{
char proxy[MAX_HOSTNAME_LEN];
char* proxy_auth;
HTTP_PROXY_OPTIONS* proxy_data = (HTTP_PROXY_OPTIONS*)value;
if (sprintf_s(proxy, MAX_HOSTNAME_LEN, "%s:%d", proxy_data->host_address, proxy_data->port) <= 0)
{
LogError("failure constructing proxy address");
result = HTTPAPI_ERROR;
}
else
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_PROXY, proxy) != CURLE_OK)
{
LogError("failure setting curl proxy address");
result = HTTPAPI_ERROR;
}
else
{
if (proxy_data->username != NULL && proxy_data->password != NULL)
{
size_t authLen = safe_add_size_t(strlen(proxy_data->username), strlen(proxy_data->password));
authLen = safe_add_size_t(authLen, 2);
if (authLen == SIZE_MAX)
{
LogError("Invalid malloc size");
proxy_auth = NULL;
}
else
{
proxy_auth = malloc(authLen);
}
if (proxy_auth == NULL)
{
LogError("failure allocating proxy authentication");
result = HTTPAPI_ERROR;
}
else
{
// From curl website 'Pass a char * as parameter, which should be [user name]:[password]'
if (sprintf_s(proxy_auth, MAX_HOSTNAME_LEN, "%s:%s", proxy_data->username, proxy_data->password) <= 0)
{
LogError("failure constructing proxy authentication");
result = HTTPAPI_ERROR;
}
else
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_PROXYUSERPWD, proxy_auth) != CURLE_OK)
{
LogError("failure setting curl proxy authentication");
result = HTTPAPI_ERROR;
}
else
{
result = HTTPAPI_OK;
}
}
free(proxy_auth);
proxy_auth = NULL;
}
}
else
{
result = HTTPAPI_OK;
}
}
}
}
else if (strcmp("TrustedCerts", optionName) == 0)
{
/*TrustedCerts needs to trigger the CURLOPT_SSL_CTX_FUNCTION in curl so we can pass the CAs*/
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback) != CURLE_OK)
{
LogError("failure in curl_easy_setopt - CURLOPT_SSL_CTX_FUNCTION");
result = HTTPAPI_ERROR;
}
else
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_SSL_CTX_DATA, httpHandleData) != CURLE_OK)
{
LogError("failure in curl_easy_setopt - CURLOPT_SSL_CTX_DATA");
result = HTTPAPI_ERROR;
}
else
{
httpHandleData->certificates = (const char*)value;
result = HTTPAPI_OK;
}
}
}
else if (strcmp(OPTION_CURL_INTERFACE, optionName) == 0)
{
const char *interfaceName = (const char*)value;
if (interfaceName != NULL && interfaceName[0] != '\0')
{
if (curl_easy_setopt(httpHandleData->curl, CURLOPT_INTERFACE, interfaceName) != CURLE_OK)
{
LogError("unable to curl_easy_setopt for CURLOPT_INTERFACE");
result = HTTPAPI_ERROR;
}
else
{
result = HTTPAPI_OK;
}
}
else
{
LogError("unable to curl_easy_setopt for CURLOPT_INTERFACE option as option-value is invalid/empty");
result = HTTPAPI_ERROR;
}
}
else
{
result = HTTPAPI_INVALID_ARG;
LogError("unknown option %s", optionName);
}
}
return result;
}