I am trying to set up Curl for use with FTPS on Visual Studio 2017 (Community) on Windows 10, but i keep getting strange errors (errors included in the different things i have tried). I currently have Curl working for FTPS on Mac and i dont need it on Linux at the moment.
Things i have tried:
Downloading the binaries at Curls Download Page To set up Curl for MacOs, all i had to do was download the MacOs binary and link it, so this is where i started for setting up Curl for Windows. On downloading a binary, however, it only included the .dll. It was missing headers and .lib files. I tried downloading about 5 other binaries, each of which was missing at least one essential file.
Installing through vcpkg After failing to get the binaries, i realized that Curl is probably on vcpkg. I ran
./vcpkg install curl
from vcpkg master. After compiling for a few minutes, it succeeded. I then went to my project and linked it to curl, with a test ftps transfer. This is the example from Curls Example page#include <stdio.h> #include <curl/curl.h> /* <DESC> * Get a single file from an FTP server. * </DESC> */ struct FtpFile { const char *filename; FILE *stream; }; static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { struct FtpFile *out = (struct FtpFile *)stream; if(out && !out->stream) { /* open file for writing */ out->stream = fopen(out->filename, "wb"); if(!out->stream) return -1; /* failure, can't open file to write */ } return fwrite(buffer, size, nmemb, out->stream); } int main(void) { CURL *curl; CURLcode res; struct FtpFile ftpfile = { "C:\Users\myUser\Desktop\file.png", /* name to store the file as if successful */ NULL }; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { /* * You better replace the URL with one that works! */ curl_easy_setopt(curl, CURLOPT_URL, "ftp://my.ip.adress.here/path/to/file.png"); //Not actual address /* Define our callback to get called when there's data to be written */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); /* Switch on full protocol/debug output */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //Extra options to enable ssl (not included in example) curl_easy_setopt(FTPAgent,CURLOPT_USE_SSL,CURLUSESSL_ALL); curl_easy_setopt(FTPAgent,CURLOPT_SSL_VERIFYPEER,0L); curl_easy_setopt(FTPAgent,CURLOPT_USERNAME,"Username"); //Not actual username curl_easy_setopt(FTPAgent,CURLOPT_PASSWORD,"Password"); //Not actual password for obvious reasons res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if(CURLE_OK != res) { /* we failed */ fprintf(stderr, "curl told us %d\n", res); } } if(ftpfile.stream) fclose(ftpfile.stream); /* close the local file */ curl_global_cleanup(); return 0; }
The project compiled and ran, but when it tried to download the file, an error appeared in the debug console saying Curl is not compatible with the FTPS protocol. It is intentional that i am using Explicit FTPS, because that is what i configured my server to accept, and i can connect to it using Explicit FTPS from Curl on Mac and from FileZilla from mac and windows. If anyone knows how to fix this, please lmk. For the time being i have given up using curl through vcpkg
Compiling Source Code I saved this for last, since i was unable to find any instructions for building Curl, but eventually i found This and followed the instructions in the answer, with the version of curl used there to eliminate any variables, other than the fact that i am on VS2017 not VS2013. the second time i did this, i had someone watch me do it to make sure i did all the steps correctly, so i am about 90% sure i did these instructions correctly. After completing the instructions, i used the same code as above. It compiled and ran with no errors, but whenever i try to download a file of any significant size (im not quite sure the cutoff, but a 4kb file works and 78kb file doesnt) it says failed to decrypt data need more data about 20 times then hangs:
* Trying my.ip.adress.here... * TCP_NODELAY set * Connected to my.ip.adress.here (my.ip.adress.here) port 21 (#0) < 220 (vsFTPd 2.2.2) > AUTH SSL < 234 Proceed with negotiation. * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 1/3) * schannel: disabled server certificate revocation checks * schannel: using IP address, SNI is not supported by OS. * schannel: sending initial handshake data: sending 147 bytes... * schannel: sent initial handshake data: sent 147 bytes * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: failed to receive handshake, need more data * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: encrypted data got 1034 * schannel: encrypted data buffer: offset 1034 length 4096 * schannel: a client certificate has been requested * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: encrypted data buffer: offset 1034 length 4096 * schannel: sending next handshake data: sending 349 bytes... * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: encrypted data got 250 * schannel: encrypted data buffer: offset 250 length 4096 * schannel: SSL/TLS handshake complete * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 3/3) * schannel: stored credential handle in session cache > USER Username * schannel: client wants to read 16384 bytes * schannel: encdata_buffer resized 17408 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 85 * schannel: encrypted data buffer: offset 85 length 17408 * schannel: decrypted data length: 34 * schannel: decrypted data added: 34 * schannel: decrypted data cached: offset 34 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 34 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 34 * schannel: decrypted data buffer: offset 0 length 16384 < 331 Please specify the password. > PASS Password * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 69 * schannel: encrypted data buffer: offset 69 length 17408 * schannel: decrypted data length: 23 * schannel: decrypted data added: 23 * schannel: decrypted data cached: offset 23 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 23 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 23 * schannel: decrypted data buffer: offset 0 length 16384 < 230 Login successful. > PBSZ 0 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 69 * schannel: encrypted data buffer: offset 69 length 17408 * schannel: decrypted data length: 20 * schannel: decrypted data added: 20 * schannel: decrypted data cached: offset 20 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 20 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 20 * schannel: decrypted data buffer: offset 0 length 16384 < 200 PBSZ set to 0. > PROT P * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 69 * schannel: encrypted data buffer: offset 69 length 17408 * schannel: decrypted data length: 23 * schannel: decrypted data added: 23 * schannel: decrypted data cached: offset 23 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 23 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 23 * schannel: decrypted data buffer: offset 0 length 16384 < 200 PROT now Private. > PWD * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 53 * schannel: encrypted data buffer: offset 53 length 17408 * schannel: decrypted data length: 9 * schannel: decrypted data added: 9 * schannel: decrypted data cached: offset 9 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 9 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 9 * schannel: decrypted data buffer: offset 0 length 16384 < 257 "/" * Entry path is '/' > CWD path * ftp_perform ends with SECONDARY: 0 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 85 * schannel: encrypted data buffer: offset 85 length 17408 * schannel: decrypted data length: 37 * schannel: decrypted data added: 37 * schannel: decrypted data cached: offset 37 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 37 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 37 * schannel: decrypted data buffer: offset 0 length 16384 < 250 Directory successfully changed. > CWD to * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 85 * schannel: encrypted data buffer: offset 85 length 17408 * schannel: decrypted data length: 37 * schannel: decrypted data added: 37 * schannel: decrypted data cached: offset 37 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 37 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 37 * schannel: decrypted data buffer: offset 0 length 16384 < 250 Directory successfully changed. > EPSV * Connect data stream passively * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 101 * schannel: encrypted data buffer: offset 101 length 17408 * schannel: decrypted data length: 48 * schannel: decrypted data added: 48 * schannel: decrypted data cached: offset 48 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 48 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 48 * schannel: decrypted data buffer: offset 0 length 16384 < 229 Entering Extended Passive Mode (|||1040|). * Trying my.ip.adress.here... * TCP_NODELAY set * Connecting to my.ip.adress.here (my.ip.adress.here) port 1040 * Connected to my.ip.adress.here (my.ip.adress.here) port 21 (#0) > TYPE I * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 85 * schannel: encrypted data buffer: offset 85 length 17408 * schannel: decrypted data length: 31 * schannel: decrypted data added: 31 * schannel: decrypted data cached: offset 31 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 31 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 31 * schannel: decrypted data buffer: offset 0 length 16384 < 200 Switching to Binary mode. > SIZE file.png * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 53 * schannel: encrypted data buffer: offset 53 length 17408 * schannel: decrypted data length: 11 * schannel: decrypted data added: 11 * schannel: decrypted data cached: offset 11 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 11 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 11 * schannel: decrypted data buffer: offset 0 length 16384 < 213 84381 > RETR file.png * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 117 * schannel: encrypted data buffer: offset 117 length 17408 * schannel: decrypted data length: 68 * schannel: decrypted data added: 68 * schannel: decrypted data cached: offset 68 length 16384 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: decrypted data buffer: offset 68 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 68 * schannel: decrypted data buffer: offset 0 length 16384 < 150 Opening BINARY mode data connection for 001.png (84381 bytes). * Maxdownload = -1 * Getting file with size: 84381 * Doing the SSL/TLS handshake on the data stream * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 1/3) * schannel: re-using existing credential handle * schannel: incremented credential handle refcount = 3 * schannel: using IP address, SNI is not supported by OS. * schannel: sending initial handshake data: sending 307 bytes... * schannel: sent initial handshake data: sent 307 bytes * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: failed to receive handshake, need more data * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3) * schannel: encrypted data got 129 * schannel: encrypted data buffer: offset 129 length 4096 * schannel: sending next handshake data: sending 75 bytes... * schannel: SSL/TLS handshake complete * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 3/3) * schannel: client wants to read 16384 bytes * schannel: encdata_buffer resized 17408 * schannel: encrypted data buffer: offset 0 length 17408 * schannel: encrypted data got 10220 * schannel: encrypted data buffer: offset 10220 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 10220 length 17408 * schannel: encrypted data got 4380 * schannel: encrypted data buffer: offset 14600 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 14600 length 17408 * schannel: encrypted data got 1460 * schannel: encrypted data buffer: offset 16060 length 17408 * schannel: decrypted data length: 15872 * schannel: decrypted data added: 15872 * schannel: decrypted data cached: offset 15872 length 16384 * schannel: encrypted data length: 135 * schannel: encrypted data cached: offset 135 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: decrypted data returned 15872 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 135 length 17408 * schannel: encrypted data got 16060 * schannel: encrypted data buffer: offset 16195 length 17408 * schannel: decrypted data length: 15872 * schannel: decrypted data added: 15872 * schannel: decrypted data cached: offset 15872 length 16384 * schannel: encrypted data length: 270 * schannel: encrypted data cached: offset 270 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: decrypted data returned 15872 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 270 length 17408 * schannel: encrypted data got 16060 * schannel: encrypted data buffer: offset 16330 length 17408 * schannel: decrypted data length: 15872 * schannel: decrypted data added: 15872 * schannel: decrypted data cached: offset 15872 length 16384 * schannel: encrypted data length: 405 * schannel: encrypted data cached: offset 405 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: decrypted data returned 15872 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 405 length 17408 * schannel: encrypted data got 14600 * schannel: encrypted data buffer: offset 15005 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 15005 length 17408 * schannel: encrypted data got 2403 * schannel: encrypted data buffer: offset 17408 length 17408 * schannel: decrypted data length: 15872 * schannel: decrypted data added: 15872 * schannel: decrypted data cached: offset 15872 length 16384 * schannel: encrypted data length: 1483 * schannel: encrypted data cached: offset 1483 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: decrypted data returned 15872 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 1483 length 17408 * schannel: encrypted data got 15925 * schannel: encrypted data buffer: offset 17408 length 17408 * schannel: decrypted data length: 2048 * schannel: decrypted data added: 2048 * schannel: decrypted data cached: offset 2048 length 16384 * schannel: encrypted data length: 15307 * schannel: encrypted data cached: offset 15307 length 17408 * schannel: failed to decrypt data, need more data * schannel: schannel_recv cleanup * schannel: decrypted data returned 2048 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 16384 bytes * schannel: encrypted data buffer: offset 15307 length 17408 * schannel: encrypted data got 2101 * schannel: encrypted data buffer: offset 17408 length 17408 * schannel: decrypted data length: 16384 * schannel: decrypted data added: 16384 * schannel: decrypted data cached: offset 16384 length 16384 * schannel: encrypted data length: 971 * schannel: encrypted data cached: offset 971 length 17408 * schannel: encrypted data buffer: offset 971 length 17408 * schannel: decrypted data buffer: offset 16384 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 16384 * schannel: decrypted data buffer: offset 0 length 16384 * schannel: client wants to read 2461 bytes * schannel: encrypted data buffer: offset 971 length 17408 * schannel: encrypted data got 1599 * schannel: encrypted data buffer: offset 2570 length 17408 * schannel: decrypted data length: 2461 * schannel: decrypted data added: 2461 * schannel: decrypted data cached: offset 2461 length 16384 * schannel: encrypted data length: 53 * schannel: encrypted data cached: offset 53 length 17408 * schannel: encrypted data buffer: offset 53 length 17408 * schannel: decrypted data buffer: offset 2461 length 16384 * schannel: schannel_recv cleanup * schannel: decrypted data returned 2461 * schannel: decrypted data buffer: offset 0 length 16384
Again, i replaced the IP, Username, and Password with dummy values for obvious reasons.
Notes:
- HTTPS works with method 3 (did not try it with method 2 so i dont know if it works) Curl successfully performed an https get request on both my server and google.
- I am assuming the problem is with my installation of curl, or with my code, but it is possible that it is with my server because i do not have another ftps server to test it against. I do know i can do ftps with my server from Curl on Mac, and from Filezilla on mac and windows.
- I tried method 2 three times, and method 3 two times.
If there is any more information that i can provide, let me know. Thank you for any help you might have. I will be so happy if i get this working after a week...