Skip to content

Commit

Permalink
[SFTP-v3] Allow to set preferred algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
Slamdunk committed Apr 6, 2022
1 parent 36619b5 commit 1cad557
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 2 deletions.
10 changes: 10 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ services:
- ./test_files/sftp/id_rsa.pub:/home/bar/.ssh/keys/id_rsa.pub
ports:
- "2222:22"
sftp_eddsa_only:
container_name: sftp_eddsa_only
restart: always
image: atmoz/sftp
volumes:
- ./test_files/sftp/users.conf:/etc/sftp/users.conf
- ./test_files/sftp/sshd_custom_configs.sh:/etc/sftp.d/sshd_custom_configs.sh
- ./test_files/sftp/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key
ports:
- "2223:22"
ftp:
container_name: ftp
restart: always
Expand Down
13 changes: 11 additions & 2 deletions src/PhpseclibV3/SftpConnectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class SftpConnectionProvider implements ConnectionProvider
*/
private $maxTries;

/**
* @var array
*/
private $preferredAlgorithms;

public function __construct(
string $host,
string $username,
Expand All @@ -89,7 +94,8 @@ public function __construct(
int $timeout = 10,
int $maxTries = 4,
string $hostFingerprint = null,
ConnectivityChecker $connectivityChecker = null
ConnectivityChecker $connectivityChecker = null,
array $preferredAlgorithms = []
) {
$this->host = $host;
$this->username = $username;
Expand All @@ -102,6 +108,7 @@ public function __construct(
$this->hostFingerprint = $hostFingerprint;
$this->connectivityChecker = $connectivityChecker ?: new SimpleConnectivityChecker();
$this->maxTries = $maxTries;
$this->preferredAlgorithms = $preferredAlgorithms;
}

public function provideConnection(): SFTP
Expand Down Expand Up @@ -131,6 +138,7 @@ public function provideConnection(): SFTP
private function setupConnection(): SFTP
{
$connection = new SFTP($this->host, $this->port, $this->timeout);
$connection->setPreferredAlgorithms($this->preferredAlgorithms);
$connection->disableStatCache();

try {
Expand Down Expand Up @@ -190,7 +198,8 @@ public static function fromArray(array $options): SftpConnectionProvider
$options['timeout'] ?? 10,
$options['maxTries'] ?? 4,
$options['hostFingerprint'] ?? null,
$options['connectivityChecker'] ?? null
$options['connectivityChecker'] ?? null,
$options['preferredAlgorithms'] ?? [],
);
}

Expand Down
57 changes: 57 additions & 0 deletions src/PhpseclibV3/SftpConnectionProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace League\Flysystem\PhpseclibV3;

use phpseclib3\Exception\NoSupportedAlgorithmsException;
use phpseclib3\Net\SFTP;
use PHPUnit\Framework\TestCase;

Expand All @@ -21,6 +22,8 @@
*/
class SftpConnectionProviderTest extends TestCase
{
const KEX_ACCEPTED_BY_DEFAULT_OPENSSH_BUT_DISABLED_IN_EDDSA_ONLY = 'diffie-hellman-group14-sha256';

public static function setUpBeforeClass(): void
{
if ( ! class_exists(SFTP::class)) {
Expand Down Expand Up @@ -241,6 +244,60 @@ public function providing_an_invalid_password(): void
$provider->provideConnection();
}

/**
* @test
*/
public function authenticate_with_supported_preferred_kex_algorithm_succedes(): void
{
$provider = SftpConnectionProvider::fromArray(
[
'host' => 'localhost',
'username' => 'foo',
'password' => 'pass',
'port' => 2222,
'preferredAlgorithms' => [
'kex' => [self::KEX_ACCEPTED_BY_DEFAULT_OPENSSH_BUT_DISABLED_IN_EDDSA_ONLY],
],
]
);
$this->assertInstanceOf(SFTP::class, $provider->provideConnection());

$provider = SftpConnectionProvider::fromArray(
[
'host' => 'localhost',
'username' => 'foo',
'password' => 'pass',
'port' => 2223,
'preferredAlgorithms' => [
'kex' => ['curve25519-sha256'],
],
]
);
$provider->provideConnection();
$this->assertInstanceOf(SFTP::class, $provider->provideConnection());
}

/**
* @test
*/
public function authenticate_with_unsupported_preferred_kex_algorithm_failes(): void
{
$provider = SftpConnectionProvider::fromArray(
[
'host' => 'localhost',
'username' => 'foo',
'password' => 'pass',
'port' => 2223,
'preferredAlgorithms' => [
'kex' => [self::KEX_ACCEPTED_BY_DEFAULT_OPENSSH_BUT_DISABLED_IN_EDDSA_ONLY],
],
]
);

$this->expectException(NoSupportedAlgorithmsException::class);
$provider->provideConnection();
}

private function computeFingerPrint(string $publicKey): string
{
$content = explode(' ', $publicKey, 3);
Expand Down
10 changes: 10 additions & 0 deletions test_files/sftp/sshd_custom_configs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

cat <<'EOF' >> /etc/ssh/sshd_config
KexAlgorithms curve25519-sha256
Ciphers [email protected]
MACs [email protected]
HostKeyAlgorithms ssh-ed25519
EOF

0 comments on commit 1cad557

Please sign in to comment.