Hello all. I'm relatively new to libcurl C++, and I have been hopelessly stuck.
Bit of a background for this app. It is very legacy, having been made in the early 2000s. LPSTRs abound. It looks in FTPs for files from suppliers (who have an SFTP they interact with and a script grabs files from that and puts them on the FTP) and it processes them and sends the orders to our warehouse. We have a security item to cut out the FTP, which means making a C/C++ program interact with SFTPs directly. That is a long story short.
To that end, we implemented libcurl C++. It works with SFTPs that are through our b2b2 domain, but not with SFTPs that interact with ftp2 domains. Unfortunately, we are also being forced to migrate all the b2b2 SFTPs to our ftp2 domain.
The error is CURLE_FAILED_INIT, and CURLE_ERRORBUFFER further expands that to "Failure establishing ssh session: -43, Failed getting banner". I assume it does not mean Bruce Banner. I have Googled so much I have nightmares and nothing seems to work, like retries and CURLOPT_SSL_VERIFYHOST being 0L. I contacted our networking team and they confirmed the issue is NOT on their end. Same story with the team that creates and manages the SFTPs. I have stumped a lot of people with this.
The code I have follows:

struct SftpConnectionInfo {
    std::string strUsername;
    std::string strPassword;
    std::string strServerPath;
};


    struct GetDirListData {
    std::string strFilePrefix;
    std::vector<std::string> strMatchedFilenames;
};




static size_t GetDirListCallbackFunction(char* izard, size_t size, size_t nmemb, GetDirListData* dirListData)
{
    size_t totalSize = size * nmemb;
    std::string strFilename = izard;
    const size_t underscorePos = strFilename.find("_");
    std::string strFilePrefix = dirListData->strFilePrefix;
    std::string strPrefixOnFile = (strFilename.substr(0, underscorePos));
    std::transform(strPrefixOnFile.begin(), strPrefixOnFile.end(), strPrefixOnFile.begin(), ::toupper);
    std::transform(strFilePrefix.begin(), strFilePrefix.end(), strFilePrefix.begin(), ::toupper);
    if (totalSize > 0 && strcmp(strFilePrefix.c_str(), strPrefixOnFile.c_str()) == 0)
    {
        dirListData->strMatchedFilenames.emplace_back(izard, totalSize);
    }
    return totalSize;
}



BOOL GetDirectoryListFromSFTP(SftpConnectionInfo connectionInfo, GetDirListData *dirListData)
{
    CURL* curl;
    CURLcode result = CURLE_GOT_NOTHING;
    char errbuff[CURL_ERROR_SIZE];
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, connectionInfo.strServerPath.c_str());
        curl_easy_setopt(curl, CURLOPT_USERNAME, connectionInfo.strUsername.c_str());
        curl_easy_setopt(curl, CURLOPT_PASSWORD, connectionInfo.strPassword.c_str());
        curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
        curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetDirListCallbackFunction);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, dirListData);
        curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "+diffie-hellman-group1-sha1");
        curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PASSWORD);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuff); // Will provide a detailed error message if a CURL error occurs.
        errbuff[0] = 0; // Must make sure this buffer is empty prior to use.
        result = curl_easy_perform(curl);
    }

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return result == CURLE_OK;
}

That code just looks in the SFTP to find files with the various prefixes, like order and ack. I have put breakpoints in the callback function, but it does not seem to get there. The error appears on the curl_easy_perform line.
I have also tried to do CURLOPT_VERBOSE, but for some reason no matter what I try with that the output file for that remains empty.
We are going to be working on a modernized replacement for this eventually, but another app is ahead of it in that queue so this change needs to be done in the meantime.

Anyone have any ideas to help?

Thank you! <3

Recommended Answers

All 6 Replies

I am not using this library so I can't help directly. Also, the code above won't compile so I can't do any testing.

In spite of that, have you ruled out a DNS failure in this app? That is, use the IP address instead the URL/sitename?

  • Check that you’re using a valid username and password and that those credentials have proper access to the path you’re attempting to connect to
  • I’m not personally too savvy about this, but does SSH require you to send a private key?

Are you able to connect via regular command line?

Also, I did a Google search to try to get you an answer. Is this you by any chance? https://stackoverflow.com/questions/77404068/libcurl-c-curle-failed-init-failure-establishing-ssh-session-43-failed-get

Yeah, the SO post is me. I was having all kinds of issues making a standalone thing that reproduces this error, so I let the post get closed.

I can connect using FileZilla to the ftp2 SFTPs just fine, and I can Telnet to the ftp2 server. I am using valid creds as it works for the b2b2 SFTPs. The suppliers are also connecting to the SFTPs just fine right now using the same creds.

Thank you!

I hadn't thought of using the IP instead of the URL. I'll check into that.

I’m not personally too savvy about this, but does SSH require you to send a private key?

Forgive that portion of my question, as I personally upload via SSH, which I believe cURL is able to handle as well. So for a moment I thought you were doing the same.

OMG I got it!

It needed CURLOPT_PROXY. I won't put the line here for obvious reasons, but adding that one line got me past the error.

I’m so glad you got it figured out! Sorry we weren’t able to help you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.