I am unable to sftp a file to a server using my code. But only under a very specific scenario.
MyClient can successfully connect to any SFTP Server I try, except MyHost. Every other client I try, can connect to the MyHost. I even used the client PHP Code on a windows machine and it connects successfully.
MyClient: PHP 7.4 on Ubuntu 20. (code below).
MyHost: Windows Server 2016 with OpenSSH SFTP.
Why?
The log acts as if the password is incorrect. However as the same password is used on other clients successfully I know that is not the case.
I thought it was strange the auth skips password and goes to keyboard-interactive. However the successful login from an alternate OS client does the same thing, but succeeds with the keyboard-interactive.
// Create connection string.
$connection_handle = curl_init($this->protocol .'://' . $this->server . ':' . $this->port . $this->remote_directory . '/test.txt');
// Create a test file.
$file_content = 'We the people of the United States of America in order to form a more perfect union:';
$file_handle = fopen('php://temp', 'r+');
fwrite($file_handle, $file_content);
rewind($file_handle);
if (!$file_handle)
{
throw new APIException('Unable to create memory file handle.');
}
// Set up
curl_setopt($connection_handle, CURLOPT_USERPWD, $this->user_id . ':' . $this->password);
curl_setopt($connection_handle, CURLOPT_UPLOAD, true);
curl_setopt($connection_handle, CURLOPT_PROTOCOLS, $this->protocol == 'sftp' ? CURLPROTO_SFTP : CURLPROTO_FTP);
curl_setopt($connection_handle, CURLOPT_INFILE, $file_handle);
curl_setopt($connection_handle, CURLOPT_INFILESIZE, strlen($file_content));
curl_setopt($connection_handle, CURLOPT_VERBOSE, true);
curl_setopt($connection_handle, CURLOPT_CONNECTTIMEOUT, 5);
// Using a self signed cert locally.
curl_setopt($connection_handle, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($connection_handle);
MyClient Log:
* Trying MyHost
* TCP_NODELAY set
* Connected to MyHost (MyHost) port 22 (#0)
* User: wsftptest
* Authentication using SSH public key file
* Authentication failure
* Closing connection 0
MyHost Log:
debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
debug1: userauth-request for user MyHostUser service ssh-connection method keyboard-interactive [preauth]
debug1: attempt 1 failures 0 [preauth]
debug2: input_userauth_request: try method keyboard-interactive [preauth]
debug1: keyboard-interactive devs [preauth]
debug1: auth2_challenge: user=wsftptest devs= [preauth]
debug1: kbdint_alloc: devices '' [preauth]
debug2: auth2_challenge_start: devices [preauth]
debug3: user_specific_delay: user specific delay 0.000ms [preauth]
debug3: ensure_minimum_time_since: elapsed 0.000ms, delaying 5.311ms (requested 5.311ms) [preauth]
debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
debug3: send packet: type 51 [preauth]
debug3: receive packet: type 1 [preauth]
Received disconnect from MyHost port 38392:11: Bye Bye [preauth]
Disconnected from authenticating user MyHostUser MyHost port 38392 [preauth]
I am unable to sftp a file to a server using my code. But only under a very specific scenario.
MyClient can successfully connect to any SFTP Server I try, except MyHost. Every other client I try, can connect to the MyHost. I even used the client PHP Code on a windows machine and it connects successfully.
MyClient: PHP 7.4 on Ubuntu 20. (code below).
MyHost: Windows Server 2016 with OpenSSH SFTP.
Why?
The log acts as if the password is incorrect. However as the same password is used on other clients successfully I know that is not the case.
I thought it was strange the auth skips password and goes to keyboard-interactive. However the successful login from an alternate OS client does the same thing, but succeeds with the keyboard-interactive.
// Create connection string.
$connection_handle = curl_init($this->protocol .'://' . $this->server . ':' . $this->port . $this->remote_directory . '/test.txt');
// Create a test file.
$file_content = 'We the people of the United States of America in order to form a more perfect union:';
$file_handle = fopen('php://temp', 'r+');
fwrite($file_handle, $file_content);
rewind($file_handle);
if (!$file_handle)
{
throw new APIException('Unable to create memory file handle.');
}
// Set up
curl_setopt($connection_handle, CURLOPT_USERPWD, $this->user_id . ':' . $this->password);
curl_setopt($connection_handle, CURLOPT_UPLOAD, true);
curl_setopt($connection_handle, CURLOPT_PROTOCOLS, $this->protocol == 'sftp' ? CURLPROTO_SFTP : CURLPROTO_FTP);
curl_setopt($connection_handle, CURLOPT_INFILE, $file_handle);
curl_setopt($connection_handle, CURLOPT_INFILESIZE, strlen($file_content));
curl_setopt($connection_handle, CURLOPT_VERBOSE, true);
curl_setopt($connection_handle, CURLOPT_CONNECTTIMEOUT, 5);
// Using a self signed cert locally.
curl_setopt($connection_handle, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($connection_handle);
MyClient Log:
* Trying MyHost
* TCP_NODELAY set
* Connected to MyHost (MyHost) port 22 (#0)
* User: wsftptest
* Authentication using SSH public key file
* Authentication failure
* Closing connection 0
MyHost Log:
debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
debug1: userauth-request for user MyHostUser service ssh-connection method keyboard-interactive [preauth]
debug1: attempt 1 failures 0 [preauth]
debug2: input_userauth_request: try method keyboard-interactive [preauth]
debug1: keyboard-interactive devs [preauth]
debug1: auth2_challenge: user=wsftptest devs= [preauth]
debug1: kbdint_alloc: devices '' [preauth]
debug2: auth2_challenge_start: devices [preauth]
debug3: user_specific_delay: user specific delay 0.000ms [preauth]
debug3: ensure_minimum_time_since: elapsed 0.000ms, delaying 5.311ms (requested 5.311ms) [preauth]
debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
debug3: send packet: type 51 [preauth]
debug3: receive packet: type 1 [preauth]
Received disconnect from MyHost port 38392:11: Bye Bye [preauth]
Disconnected from authenticating user MyHostUser MyHost port 38392 [preauth]
Share
Improve this question
asked Mar 13 at 4:33
danielson317danielson317
3,2983 gold badges30 silver badges45 bronze badges
3
- Are you 100% sure that $this->password has a value? – shingo Commented Mar 13 at 6:11
- Besides the fact that I would never suggest to write such code by hand (there's a good reason to use a library for this): you're still using PHP 7.4? Please keep in mind that this version is horribly outdated! – Nico Haase Commented Mar 13 at 6:51
- @shingo As stated the code works perfect if run on top of windows OS instead of Ubuntu. It has a password. The code also works with any other server I have ever tried. – danielson317 Commented Mar 13 at 13:42
1 Answer
Reset to default 0I discovered through guess an check that if I disable "keyboard-interactive" authentication on the SFTP Host the authentication starts to work correctly.
Add the line: KbdInteractiveAuthentication no
to the sshd_config file.
I do not know why this works. My thoughts are, php curl is skipping password authentication and jumping to keyboard-interactive. For some reason the password was not recognized coming from this client in the keyboard-interactive method. After disabling the keyboard-interactive the Host logs show the password method is used and accepted. Perhaps keyboard-interactive is broken on this version of OpenSSH, or perhaps it is expecting keyboard codes instead of actual ascii. Would love a full answer but I'm already over budget on this issue so I have to accept this workaround and move on.