how to resolve SSL Connect Error in curl cpp - c++

I have been working on an application which uses curl for communication to a server. Sometimes I get an "SSL Connect" error.
curl/libcurl version
7.86
operating system
Windows
I tried to increase verbosity on a machine where this issue is occurring, and got an "ssl handshake" error.
static int trace(CURL* handle, curl_infotype type, char* data, size_t size, void* userp)
{
switch (type)
{
case CURLINFO_TEXT:
CLIENT_LOG_DEBUG("== Info: %s", data);
break;
default:
return 0;
case CURLINFO_HEADER_OUT:
CLIENT_LOG_DEBUG("=> Send header: %s", data);
break;
case CURLINFO_DATA_OUT:
CLIENT_LOG_DEBUG("=> Send data: %s", data);
break;
case CURLINFO_SSL_DATA_OUT:
CLIENT_LOG_DEBUG("=> Send SSL data: %s", data);
break;
case CURLINFO_HEADER_IN:
CLIENT_LOG_DEBUG("<= Recv header: %s", data);
break;
case CURLINFO_DATA_IN:
CLIENT_LOG_DEBUG("<= Recv data: %s", data);
break;
case CURLINFO_SSL_DATA_IN:
CLIENT_LOG_DEBUG("<= Recv SSL data: %s", data);
break;
}
return 0;
}
/// at caller method:
CLIENT_LOG_INFO("TRACE_LEVEL_HIGH");
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, trace);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
/// Other curl options set while making connection:
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
#ifndef PLATFORM_UNIX
curl_easy_setopt(curl, CURLOPT_CAINFO, "curl-ca-bundle.crt");
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteResponseCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
curl::SendRequest:314 TRACE_LEVEL_HIGH
trace:45 == Info: Connected to <URL> (<IP>) port 443 (#0)
trace:45 == Info: schannel: disabled automatic use of client certificate
trace:45 == Info: ALPN: offers http/1.1
trace:45 == Info: schannel: failed to receive handshake, SSL/TLS connection failed
trace:45 == Info: Closing connection 0
curl::SendRequest:387 Failed sending curl request with error:SSL connect error
I am only getting CURLINFO_TEXT logs, no header out, data out, etc.
I am stuck here. This doesn't seem to be a certificate-related issue.

This error indicates the TLS handshake key exchange does not finish successfully. Try to experiment with adding one of the lines below:
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_2);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_1);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_0);

Related

I cannot send an email using curl and c++

im trying to send an email with curl and c++ just like this example but when i execute the program:
#include <iostream>
#include <curl/curl.h>
int main()
{
int a;
char errbuf[CURL_ERROR_SIZE] = {0};
CURL *curl = curl_easy_init();
CURLcode res;
struct upload_status upload_ctx = { 0 };
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "smtps://smtp.gmail.com:465");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "");
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, "");
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\MinGW\\cacert.pem");
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
check_errors(res, errbuf);
return 0;
}
i get this error:
curl_easy_perform() failed: Failed sending data to the peer
libcurl: (55) MAIL failed: 530
I deleted most of the code because i couldn't post the question but the rest is in the example.
The problem i had in my code was that i thought that by using:
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "myemail#example.com"); i was specifyng the username, which was in fact, an error.
To specify the username libcurl has another option:
curl_easy_setopt(curl, CURLOPT_USERNAME, "myemail#example.com");

I try to implement curl script for request to server but it is not working

I have a curl script:
curl -k -H "Content-Type: application/txt" -X POST --data-binary "#name_file.txt" -g "https://ya.com/file.txt" > .\out.txt
I can use it via console ant it works good.
I implement this script in visual studio on C++:
auto curl = curl_easy_init();
if (curl)
{
FILE* fp = fopen(path_to_file.c_str(), "wb");
curl_easy_setopt(curl, CURLOPT_URL, "https://ya.com/file.txt");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
struct curl_slist *list = NULL;
list = curl_slist_append(list, "Content-Type: application/txt");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); // - H
std::string data_for_send = data_for_send_arr.c_str();
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data_for_send.size());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_for_send.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callbackfunction);
res = curl_easy_perform(curl);
if (res != CURLE_OK) AfxMessageBox(_T("error"));
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(fp);
}
size_t callbackfunction(void *ptr, size_t size, size_t nmemb, void* userdata)
{
FILE* stream = (FILE*)userdata;
if (!stream)
{
printf("!!! No stream\n");
return 0;
}
size_t written = fwrite((FILE*)ptr, size, nmemb, stream);
return written;
}
i also i need to tell that at one moment i use async call:
async(func_curl_1, data_1);
async(func_curl_2, data_2);
each function create curl and do request for server at the same time.
but this script do not work. it work one time from seven request
server returned for me empty file or broken file.
i do not know why...
try to add in your settings CURLOPT_VERBOSE
i.e.
/* ask libcurl to show us the verbose output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
and investigate output

Unable to delete email from gmail inbox

Hello I wrote the following code
string fetchdata;
size_t write_data(char* buf, size_t size, size_t nmemb, void* up) {
fetchdata.append((char*)buf, size*nmemb);
return size*nmemb;
}
void main()
{
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, "ghtyyuu3#gmail.com");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxxxxx");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993/INBOX;UID=1");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "UID STORE 1 +Flags \DELETE");
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
std::ofstream outfile("/home/ilia/Desktop/fetched.txt", std::ios_base::app);
outfile << fetchdata;
outfile.close();
}
I manage to read the mail into a text file but I am unable to delete the mail (gmail settings to delete the mail already set)
I probably have an error in:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "UID STORE 1 +Flags \DELETE");
While the CURL itself dont give me an error the mail is still not deleted
Please help

How to catch curl error i.e time out in multicurl environment

I know how to catch curl error(time out error) message in single curl request. It's something like as follows.
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 100);
res = curl_easy_perform(curl_handle);
If res is not curl_ok then it is some error like CURLE_OPERATION_TIMEDOUT
etc. But i want to know ,how to do that when we use multicurl request
where we use curl_multi_add_handle to add every curl request.How to set
timeout time and how to catch error message.
bool cuev_emit(struct curlev *cuev, char *url, struct curl_slist *headers,
curlev_cb_t cb, void *cb_data)
{
struct curlex *ex = NULL;
CURL *easy = curl_easy_init();
CURLMcode code;
if (!easy) {
xsyslog(LOG_WARNING, "curl_easy_init() failed for url '%s' (errno: %d)",
url, errno);
return false;
}
curl_easy_setopt(easy, CURLOPT_URL, url);
curl_easy_setopt(easy, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(easy, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, _curl_write_cb);
if (cb) {
ex = calloc(1, sizeof(*ex));
if (!ex) {
xsyslog(LOG_WARNING, "cuev_emit() failed: calloc(%d) with errno: %d",
(int)sizeof(*ex), errno);
curl_easy_cleanup(easy);
return false;
}
curl_easy_setopt(easy, CURLOPT_WRITEDATA, ex);
curl_easy_setopt(easy, CURLOPT_PRIVATE, ex);
} else {
curl_easy_setopt(easy, CURLOPT_WRITEDATA, NULL);
curl_easy_setopt(easy, CURLOPT_PRIVATE, NULL);
}
if (headers) {
/* TODO: добавить хидеры */
}
if ((code = curl_multi_add_handle(cuev->multi, easy)) != CURLM_OK) {
xsyslog(LOG_WARNING, "curl_multi_add_handle() failed for url '%s', code: %d",
url, code);
curl_easy_cleanup(easy);
return false;
}
return true;
}
Main part of the code is above. I am using https://gist.github.com/bhardwaj75/7600b67726ae2cdbfcf8c9c74300ab69#file-libvev-curl-c code.
The key is the curl_multi_info_read() function that returns info about completed transfers when the multi interface is used. Call that after curl_multi_perform() and timed out transfers will have that error code set.
See also the Driving with the multi interface chapter in the curl book, or a multi-interface using example such as multi-app.c.

libcurl crashing program after execution?

I am using libcurl to make request google server. The curl library is giving output , when i use curl variables as global every thing works fine but when i am using the curl variables as local inside a function or a class private members the program crashes. I am not able to catch where segmentation fault occurring.
Code is
void func1();
{
Internet_connection_through_curl internet_connection;
internet_connection.simple_program(query_url);
}
Internet_connection_through_curl::simple_program(string url)
{
CURL *curle;
CURLcode rese;
curle = curl_easy_init();
if(curle)
{
curl_easy_setopt(curle, CURLOPT_URL, url.c_str());
curl_easy_setopt(curle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curle, CURLOPT_WRITEDATA , (void *)(&UF));
curl_easy_setopt(curle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curle, CURLOPT_HEADERFUNCTION, HeaderMemoryCallback);
rese = curl_easy_perform(curle);
fprintf(stderr , "Curl easy perform error----> %s\n" , curl_easy_strerror(rese));
if(rese != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(rese));
curl_easy_cleanup(curle);
}
}