1

Does anybody have any recent experiences with phpseclib / Flysystem/SFTP in dual factor authentication (private key AND password)?

I just ran into this issue yesterday, and need a fix. My searches lead me to:

It's 3years old, and phpseclib still doesn't appear to be fixed -- or is it?

Is there anyway to get this working without modifying the base library?

Using: "league/flysystem-sftp": "~1.0-stable", which uses "phpseclib/phpseclib": "~2.0"

Community
  • 1
  • 1
guice
  • 976
  • 4
  • 11
  • 31

2 Answers2

2

Here's a solution I found. And it's actually quite simple.

I'm following @neubert's idea by double authenticating: extended the SftpAdapter, and overloaded the login() method:

<?php
use LogicException;

/**
 * Class SftpAdapter
 *
 * We're going to overload SftpAdapter in order to fix a bug handling key AND password authentication
 *
 * @package App\MyPackage
 */
class SftpAdapter extends \League\Flysystem\Sftp\SftpAdapter
{
    /**
     * Login.
     *
     * @throws LogicException
     */
    protected function login()
    {
        if (! $this->connection->login($this->username, $this->getPrivateKey())
            && ! $this->connection->login($this->username, $this->getPassword())) {
            throw new LogicException('Could not login with username: '.$this->username.', host: '.$this->host);
        }
    }

}

Now. It works. The disadvantage here is you are now dependent on SftpAdapter (i.e. no injectability). But, since this is a very specific use-case, we can work with this.

guice
  • 976
  • 4
  • 11
  • 31
1

I answered that question three years ago and I would still give that same answer.

It's kinda rare that SFTP servers use both password and publickey authentication. My guess would be that what you most likely have is a password protected private key. If so you can login thusly:

<?php
include('Net/SFTP.php');
include('Crypt/RSA.php');

$sftp = new Net_SFTP('www.domain.tld');
$key = new Crypt_RSA();
$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key)) {
    exit('Login Failed');
}

print_r($sftp->nlist());
?>

If indeed your server truly is doing both the following should work:

<?php
include('Net/SFTP.php');
include('Crypt/RSA.php');

$sftp = new Net_SFTP('www.domain.tld');
$key = new Crypt_RSA();
$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key) && !$sftp->login('username', 'password')) {
    exit('Login Failed');
}

print_r($sftp->nlist());
?>

Note that that's for the 1.0 version. If you're using the 2.0 version the code will need to be changed somewhat. Since you haven't posted your own code it's impossible to know what version you're using.

Also, in reviewing that 3.5 year old post... it looks like there were issues but those issues should now be fixed. I've done multi factor auth myself with phpseclib without issue. Do you have reason to believe it doesn't work?

edit: for 2.0 you'd need to do this:

For 2.0 you'll need to do this:

$sftp = new SFTP('www.domain.tld');
$key = new RSA();
//$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
if (!$sftp->login('username', $key) && !$sftp->login('username', 'password')) {
    exit('Login Failed');
}

print_r($sftp->nlist());
Community
  • 1
  • 1
neubert
  • 15,947
  • 24
  • 120
  • 212
  • It is a password AND key authentication. I know for a fact they are using "publickey,password" Authentication method. And the fact I'm the one who actually created the key. It's a passwordless key. I've verified/replicated the issue in the library by modifying my personal server to use "publickey,password" – guice Aug 29 '16 at 16:01
  • In addition: using "league/flysystem-sftp": "~1.0-stable", which uses "phpseclib/phpseclib": "~2.0". – guice Aug 29 '16 at 16:05
  • @guice666 - idk too much about league/flysystem-sftp but I've none-the-less updated my post to show how you'd do it with phpseclib 2.0. – neubert Aug 29 '16 at 18:09
  • Thanks. I've added the Flysystem solution (above/below? somewhere!). It's even simpler. Thanks for the suggestion / heads-up. – guice Aug 29 '16 at 18:14