SFTP / SSH stuck on login when using Curl/Multi and password auth
Describe the bug
When connecting to an SFTP using Curl/Multi with a provided password, it appears to get stuck at login.
This only seems to apply to some SFTP servers, perhaps depending on supported auth types?
I managed to reproduce the same behavior when passing an incorrect password to another server.
To Reproduce
import { Curl } from 'node-libcurl'
const curl = new Curl()
curl.setOpt('URL', 'sftp://nxtest:[email protected]/')
curl.setOpt('SSL_VERIFYHOST', 0)
curl.setOpt('SSL_VERIFYPEER', 0)
curl.setOpt('VERBOSE', true)
// This should force it to only use provided password I think, but doesn't help
// curl.setOpt('SSH_AUTH_TYPES', 2)
// This will make the request timeout
// curl.setOpt('CONNECTTIMEOUT', 10)
// None of these trigger...
curl.on('data', (chunk) => {
console.log('DATA', chunk.toString())
})
curl.on('header', (chunk) => {
console.log('HEADER', chunk.toString())
})
curl.on('end', (statusCode, body, headers) => {
console.info('Status Code: ', statusCode)
console.info('Headers: ', headers)
console.info('Body length: ', body.length)
curl.close()
})
curl.on('error', (error, errorCode) => {
console.error('Error: ', error, errorCode)
curl.close()
})
curl.perform()
// necessary to keep process alive
setTimeout(() => console.log('done waiting'), 20e3)
The output:
* Trying 10.0.1.209:22...
* Connected to 10.0.1.209 (10.0.1.209) port 22 (#0)
* User: nxtest
* Authentication using SSH public key file
done waiting
When using Easy it works correctly (just replaced Curl with Easy and removed event-listeners):
* Trying 10.0.1.209:22...
* Connected to 10.0.1.209 (10.0.1.209) port 22 (#0)
* User: nxtest
* Authentication using SSH public key file
* Completed password authentication
* Authentication complete
* Connection #0 to host 10.0.1.209 left intact
Also when using curl cli:
$ curl -k -v sftp://nxtest:[email protected]/
* Trying 10.0.1.209:22...
* Connected to 10.0.1.209 (10.0.1.209) port 22 (#0)
* User: nxtest
* Authentication using SSH public key file
* Completed password authentication
* Authentication complete
drwxr-xr-x 3 root root 4096 May 3 2023 docker
drwxr-xr-x 7 root root 4096 Nov 27 14:03 homes
drwxrwxrwx 4 root root 4096 Dec 14 14:59 SMB-test
drwxrwxrwx 8 nxtest users 4096 Apr 26 2023 home
* Connection #0 to host 10.0.1.209 left intact
I also tried a simple c application using multi, and it worked correctly:
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <curl/curl.h>
int main(void)
{
CURL *handle;
CURLM *multi_handle;
int still_running = 1;
int i;
CURLMsg *msg;
int msgs_left;
handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, "sftp://nxtest:[email protected]/");
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(handle, CURLOPT_SSH_AUTH_TYPES, 2);
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle, handle);
while(still_running) {
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
if(still_running)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
if(mc)
break;
}
while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
if(msg->msg == CURLMSG_DONE) {
printf("transfer completed with status %d\n", msg->data.result);
}
}
curl_multi_remove_handle(multi_handle, handle);
curl_easy_cleanup(handle);
curl_multi_cleanup(multi_handle);
return 0;
}
Output:
* Trying 10.0.1.209:22...
* Connected to 10.0.1.209 (10.0.1.209) port 22 (#0)
* User: nxtest
* Authentication using SSH public key file
* Completed password authentication
* Authentication complete
drwxr-xr-x 3 root root 4096 May 3 2023 docker
drwxr-xr-x 7 root root 4096 Nov 27 14:03 homes
drwxrwxrwx 4 root root 4096 Dec 14 14:59 SMB-test
drwxrwxrwx 8 nxtest users 4096 Apr 26 2023 home
* Connection #0 to host 10.0.1.209 left intact
transfer completed with status 0
Version information:
Version:
Version: libcurl/7.81.0 OpenSSL/3.0.10 zlib/1.2.13.1-motley brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.16
Protocols: dict, file, ftp, ftps, gopher, gophers, http, https, imap, imaps, ldap, ldaps, mqtt, pop3, pop3s, rtmp, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
Features: AsynchDNS, IDN, IPv6, Largefile, GSS-API, Kerberos, SPNEGO, NTLM, NTLM_WB, SSL, libz, brotli, TLS-SRP, HTTP2, UnixSockets, HTTPS-proxy, PSL, alt-svc
OS: Ubuntu 22.04.3 LTS Node.js Version: v20.9.0
Additional context Add any other context about the problem here.
Hi @deadbeef84 thanks for the report. I am not finding time right now to look into these, but as soon as go through my backlog on project I will try to reproduce your issue.
Thank you, let me know if there's anything I can do to help.