-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Closed
Labels
Description
Hello
I am experiencing issues with FTP connection after updating to libcurl 7.87.0 and 7.88.0. Unable to reproduce the issue on 7.86.0.
I did this
There is a simple C utility to reproduce the issue:
int debug_curl(CURL* handle, curl_infotype type, char* data, size_t size, void* userptr)
{
switch (type) {
case CURLINFO_TEXT:
printf("Curl output: * %s\n", data);
break;
case CURLINFO_HEADER_IN:
printf("Curl output: < %s\n", data);
break;
case CURLINFO_HEADER_OUT:
printf("Curl output: > %s\n", data);
break;
case CURLINFO_DATA_IN:
case CURLINFO_DATA_OUT:
case CURLINFO_SSL_DATA_IN:
case CURLINFO_SSL_DATA_OUT:
case CURLINFO_END:
break;
}
return 0;
}
int result(char *buf, size_t size, size_t nmemb, void *context)
{
printf("result: %s\n", buf);
return 0;
}
int main(int argc, char **argv)
{
char *url_with_user = argv[1];
char *password = argv[2];
CURL *curl = curl_easy_init();
struct curl_slist *m_headers = NULL;
if (!curl) {
printf("unable to init curl");
return 1;
}
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 300);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 60);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 60);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_curl);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, NULL);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_FTPPORT, "-");
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_3);
curl_easy_setopt(curl, CURLOPT_URL, url_with_user);
curl_easy_setopt(curl, CURLOPT_USERPWD, password);
curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 0L);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, result);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
curl_easy_perform(curl);
return 0;
}It works fine with 7.86.0, but when I build it with 7.87.0 or 7.88.0, the connection hangs for a wait timeout and closes without output.
There is the output of the program with libcurl 7.87.0:
Curl output: * Trying 10.69.41.135:21...
Curl output: * Connected to 10.69.41.135 (10.69.41.135) port 21 (#0)
Curl output: < 220 ProFTPD Server (ProFTPD) [10.69.41.135]
Curl output: > AUTH SSL
Curl output: < 234 AUTH SSL successful
PD) [10.69.41.135]
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (OUT), TLS handshake, Client hello (1):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Server hello (2):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Certificate (11):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, CERT verify (15):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Finished (20):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (OUT), TLS handshake, Finished (20):
Curl output: * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
Curl output: * Server certificate:
Curl output: * subject: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * start date: Feb 28 06:04:14 2023 GMT
Curl output: * expire date: Feb 28 06:04:14 2024 GMT
Curl output: * issuer: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * SSL certificate verify result: self signed certificate (18), continuing anyway.
Curl output: > USER tftp
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
Curl output: * old SSL session ID is stale, removing
Curl output: < 331 Password required for tftp
.69.41.135]
Curl output: > PASS 1qazxsw2
Curl output: < 230 User tftp logged in
tftp
Curl output: > PBSZ 0
Curl output: < 200 PBSZ 0 successful
Curl output: > PROT P
Curl output: < 200 Protection set to Private
Curl output: > PWD
Curl output: < 257 "/home/tftp" is the current directory
Curl output: * Entry path is '/home/tftp'
Curl output: * Request has same path as previous transfer
Curl output: > EPRT |1|10.69.41.80|38691|
Curl output: * ftp_perform ends with SECONDARY: 1
Curl output: < 200 EPRT command successful
nt directory
Curl output: * Connect data stream actively
Curl output: > TYPE A
Curl output: < 200 Type set to A
ccessful
Curl output: > LIST
Curl output: < 150 Opening ASCII mode data connection for file list
Curl output: * Maxdownload = -1
Curl output: * Preparing for accepting server on data port
Curl output: * Checking for server connect
Curl output: * Ready to accept data connection from server
Curl output: * Connection accepted from server
Curl output: * Operation timed out after 300001 milliseconds with 0 bytes received
Curl output: * Closing connection 0
Curl output: * [CONN-0-0][CF-SSL] TLSv1.3 (OUT), TLS alert, close notify (256):
The issue disappears when I remove SSL parts of the code. So likely the problem somewhere in this part. Unfortunately, I can't see where exactly.
I expected the following
I expect to see the line:
result: drwxr-xr-x 2 tftp root 4096 Feb 28 10:46 tftpboot
Received from the other side.
For example this is the utility output built with libcurl 7.86.0:
Curl output: * Trying 10.69.41.135:21...
Curl output: * Connected to 10.69.41.135 (10.69.41.135) port 21 (#0)
Curl output: < 220 ProFTPD Server (ProFTPD) [10.69.41.135]
Curl output: > AUTH SSL
Curl output: < 234 AUTH SSL successful
PD) [10.69.41.135]
Curl output: * TLSv1.3 (OUT), TLS handshake, Client hello (1):
Curl output: * TLSv1.3 (IN), TLS handshake, Server hello (2):
Curl output: * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
Curl output: * TLSv1.3 (IN), TLS handshake, Certificate (11):
Curl output: * TLSv1.3 (IN), TLS handshake, CERT verify (15):
Curl output: * TLSv1.3 (IN), TLS handshake, Finished (20):
Curl output: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
Curl output: * TLSv1.3 (OUT), TLS handshake, Finished (20):
Curl output: * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
Curl output: * Server certificate:
Curl output: * subject: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * start date: Feb 28 06:04:14 2023 GMT
Curl output: * expire date: Feb 28 06:04:14 2024 GMT
Curl output: * issuer: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * SSL certificate verify result: self signed certificate (18), continuing anyway.
Curl output: > USER tftp
Curl output: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
Curl output: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
Curl output: * old SSL session ID is stale, removing
Curl output: < 331 Password required for tftp
.69.41.135]
Curl output: > PASS 1qazxsw2
Curl output: < 230 User tftp logged in
tftp
Curl output: > PBSZ 0
Curl output: < 200 PBSZ 0 successful
Curl output: > PROT P
Curl output: < 200 Protection set to Private
Curl output: > PWD
Curl output: < 257 "/home/tftp" is the current directory
Curl output: * Entry path is '/home/tftp'
Curl output: * Request has same path as previous transfer
Curl output: > EPRT |1|10.69.41.80|39219|
Curl output: * ftp_perform ends with SECONDARY: 1
Curl output: < 200 EPRT command successful
nt directory
Curl output: * Connect data stream actively
Curl output: > TYPE A
Curl output: < 200 Type set to A
ccessful
Curl output: > LIST
Curl output: < 150 Opening ASCII mode data connection for file list
Curl output: * Maxdownload = -1
Curl output: * Preparing for accepting server on data port
Curl output: * Checking for server connect
Curl output: * Ready to accept data connection from server
Curl output: * Connection accepted from server
Curl output: * Doing the SSL/TLS handshake on the data stream
Curl output: * SSL re-using session ID
Curl output: * TLSv1.3 (OUT), TLS handshake, Client hello (1):
Curl output: * TLSv1.3 (IN), TLS handshake, Server hello (2):
Curl output: * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
Curl output: * TLSv1.3 (IN), TLS handshake, Finished (20):
Curl output: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
Curl output: * TLSv1.3 (OUT), TLS handshake, Finished (20):
Curl output: * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
Curl output: * Server certificate:
Curl output: * subject: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * start date: Feb 28 06:04:14 2023 GMT
Curl output: * expire date: Feb 28 06:04:14 2024 GMT
Curl output: * issuer: C=CH; L=Schaffhausen; O=Plesk; CN=Plesk; emailAddress=info@plesk.com
Curl output: * SSL certificate verify result: self signed certificate (18), continuing anyway.
Curl output: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
Curl output: * old SSL session ID is stale, removing
result: drwxr-xr-x 2 tftp root 4096 Feb 28 10:46 tftpboot <------------------------------- THE LINE
Curl output: * Failure writing output to destination
Curl output: * TLSv1.3 (IN), TLS alert, close notify (256):
Curl output: * TLSv1.3 (OUT), TLS alert, close notify (256):
Curl output: * Closing connection 0
curl/libcurl version
libcurl 7.87.0 and 7.88.0
operating system
Ubuntu 20