Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use PassiveMode? #10

Open
matteocostantini opened this issue May 20, 2020 · 11 comments
Open

How to use PassiveMode? #10

matteocostantini opened this issue May 20, 2020 · 11 comments

Comments

@matteocostantini
Copy link

No description provided.

@embeddedmz
Copy link
Owner

Hi Matteo,

It's possible to use the passive mode. I will give you an answer tonight.

Regards.

@embeddedmz
Copy link
Owner

@matteocostantini By default, the FTP client is in passive mode (m_bActive is initialized to false), so there's nothing to do.

To use the active mode use SetActive(true), in active mode, the client will choose a port and the FTP server will initialize the connection (not recommended if there's a firewall).

@matteocostantini
Copy link
Author

This is my implementation, dont connect . i'm in UI environment.

How i can use?

My FTP credentials is valid ('m tryng with WINSCP!!)

in FTPCLient.cpp go in this rows
else if (m_eSettingsFlags & ENABLE_LOG)
m_oLog(StringFormat(LOG_ERROR_CURL_FILELIST_FORMAT, strRemoteFolder.c_str(), res, curl_easy_strerror(res)));

void BDImport::OnRunButton()
{
//m_pFTPClient = new CFTPClient(CFTPClient::LogFnCallback);

CFTPClient FTPClient([](const std::string& strLogMsg) { std::cout << strLogMsg << std::endl; });

CString host = _T("fqdnftp");
std::string stdHost = CT2CA(host);

CString user = _T("");
std::string stdUser = CT2CA(user);

CString pwd = _T("");
std::string stdpwd = CT2CA(pwd);

FTPClient.InitSession(stdHost, 6321, stdUser, stdpwd, CFTPClient::FTP_PROTOCOL::FTPES);

std::string strList;

FTPClient.List("/", strList, false);

@embeddedmz
Copy link
Owner

embeddedmz commented May 21, 2020

I never tested the FTP Client with this protocol CFTPClient::FTP_PROTOCOL::FTPES.

If you are trying to access a normal FTP server (port 21), remove that parameter (it will default to FTP_PROTOCOL::FTP) or set the protocol to FTP_PROTOCOL::SFTP if you want to connect to an SFTP server (port 22).

Also, in a debugger, check that the string parameters are well encoded (I don't know if CT2CA is doing its job properly). And that "stdHost" doesn't contain any protocol scheme.

@embeddedmz
Copy link
Owner

embeddedmz commented May 21, 2020

I'm not sure but to access secure servers, I think you need to set an SSL cert file with the static method SetSSLCertFile.

You can use this file : https://curl.haxx.se/ca/cacert.pem (from libcurl website)

and then CFTPClient::SetSSLCertFile("C:\\etc...............\\cacert.pem");

UPDATE : ignore this comment

@embeddedmz
Copy link
Owner

embeddedmz commented May 21, 2020

@matteocostantini You can also compile with this preprocessor macro DEBUG_CURL, and use this method : static void SetCurlTraceLogDirectory(const std::string &strPath); to specify a directory where debug logs will be stored. They will give you an information on why things are not working properly.

Also, don't forget to set a preprocessor macro WINDOWS as I believe you are not using the CMake scripts.

Regards.

@matteocostantini
Copy link
Author

@embeddedmz : I'm able to connect to my server with this instructions:

curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTP_SSL, CURLOPT_FTPSSLAUTH);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);

Can you improve this calls in your ::Perform()?

@embeddedmz
Copy link
Owner

embeddedmz commented May 22, 2020

First of all, to what kind of FTP servers are you connecting (SFTP, FTPES or FTPS). I know that the client work with SFTP but not the 2 others (FTPES, FTPS).

You can remove these 2 lines :

curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYHOST, 0);

if you use this : curl_easy_setopt(m_pCurlSession, CURLOPT_CAINFO, "C:\....\cacert.pem");

In my previous comment I mistaken this for CFTPClient::SetSSLCertFile("C:\etc...............\cacert.pem"); it's missing in this client (but not in the httpclient-cpp). But your server must have a valid SSL certificate and not a quick & dirty one. Settings those 2 parameters to 0 is not good for all cases (security issues).

So, if you have the chance to add and test these getter/setters method :

// in .h
static const std::string& GetCertificateFile() { return s_strCertificationAuthorityFile; }
static void SetCertificateFile(const std::string& strPath) { s_strCertificationAuthorityFile = strPath; }
//....
//SSL
static std::string s_strCertificationAuthorityFile;

// in .cpp
// just look to this https://github.com/embeddedmz/httpclient-cpp/blob/master/HTTP/HTTPClient.cpp and to the code that sets CURLOPT_CAINFO

In line 857 (if (m_eFtpProtocol == FTP_PROTOCOL::FTPS || m_eFtpProtocol == FTP_PROTOCOL::FTPES)) , you can add :

curl_easy_setopt(m_pCurlSession, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTP_SSL, CURLOPT_FTPSSLAUTH);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);

and eventually remove curl_easy_setopt(m_pCurlSession, CURLOPT_USE_SSL, CURLUSESSL_ALL); if it's not necessary

If everything is OK, create a pull request and I will merge your patches.

@matteocostantini
Copy link
Author

the connection function successfully only if i put curl_easy_setopt(m_pCurlSession, CURLOPT_USE_SSL, CURLUSESSL_ALL);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_easy_setopt(m_pCurlSession, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTP_SSL, CURLOPT_FTPSSLAUTH);
curl_easy_setopt(m_pCurlSession, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);

@matteocostantini
Copy link
Author

The server is ftp with explicit autentication

@embeddedmz
Copy link
Owner

@matteocostantini OK, I googled curl FTPS/FTPES and I found the following stuff :

https://stackoverflow.com/questions/32491790/php-curl-ftpes-w-explicit-tls-ssl => in the code, instead of prefixing the URL with ftps:// prefix it with ftp:// that should be sufficient.

https://curl.haxx.se/docs/manual.html (curl doc.) => FTPS : It is just like for FTP, but you may also want to specify and use SSL-specific options for certificates etc.
Note that using FTPS:// as prefix is the "implicit" way as described in the standards while the recommended "explicit" way is done by using FTP:// and the --ftp-ssl option.

So, can you please try this fix and tell me if the example you posted in the beginning of this thread is working :
In line 194, add "case FTP_PROTOCOL::FTPES:" so that in a FTPES session, the url will be prefixed with ftp:// and remove the case of lines 203 and 205 (old code prefixing the url with ftpes://)

That should work fine (I hope so).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants