diff --git a/README.md b/README.md index 9decafc..a339701 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,21 @@ Alternatively you can use the `usePort` function: ```php Ssh::create('user', 'host')->usePort($port); ``` + +### Using a password + +You can use the constructor to specify a password to use. + +```php +Ssh::create('user', 'host', port, 'password'); +``` + +Alternatively you can use the `usePassword` function: + +```php +Ssh::create('user', 'host')->usePassword('password'); +``` + ### Setting a timeout You can set a timeout for the command. diff --git a/src/Ssh.php b/src/Ssh.php index 225d66f..ff2fc6c 100755 --- a/src/Ssh.php +++ b/src/Ssh.php @@ -22,7 +22,9 @@ class Ssh private int $timeout = 0; - public function __construct(?string $user, string $host, ?int $port = null) + protected ?string $password = null; + + public function __construct(?string $user, string $host, ?int $port = null, ?string $password = null) { $this->user = $user; @@ -32,6 +34,8 @@ public function __construct(?string $user, string $host, ?int $port = null) $this->usePort($port); } + $this->password = $password; + $this->addBash = true; $this->processConfigurationClosure = fn (Process $process) => null; @@ -68,6 +72,13 @@ public function usePort(int $port): self return $this; } + public function usePassword(?string $password): self + { + $this->password = $password; + + return $this; + } + public function useMultiplexing(string $controlPath, string $controlPersist = '10m'): self { $this->extraOptions['control_master'] = '-o ControlMaster=auto -o ControlPath=' . $controlPath . ' -o ControlPersist=' . $controlPersist; @@ -152,6 +163,14 @@ public function removeBash(): self return $this; } + protected function getPasswordCommand(): string + { + if ($this->password !== null) { + return 'sshpass -p \'' . $this->password . '\' '; + } + return ''; + } + /** * @param string|array $command * @@ -167,6 +186,7 @@ public function getExecuteCommand($command): string return $commandString; } + $passwordCommand = $this->getPasswordCommand(); $extraOptions = implode(' ', $this->getExtraOptions()); $target = $this->getTargetForSsh(); @@ -175,9 +195,9 @@ public function getExecuteCommand($command): string $bash = $this->addBash ? "'bash -se'" : ''; - return "ssh {$extraOptions} {$target} {$bash} << \\$delimiter".PHP_EOL - .$commandString.PHP_EOL - .$delimiter; + return "{$passwordCommand}ssh {$extraOptions} {$target} {$bash} << \\$delimiter".PHP_EOL + .$commandString.PHP_EOL + .$delimiter; } /** @@ -206,7 +226,8 @@ public function executeAsync($command): Process public function getDownloadCommand(string $sourcePath, string $destinationPath): string { - return "scp {$this->getExtraScpOptions()} {$this->getTargetForScp()}:$sourcePath $destinationPath"; + $passwordCommand = $this->getPasswordCommand(); + return "{$passwordCommand}scp {$this->getExtraScpOptions()} {$this->getTargetForScp()}:$sourcePath $destinationPath"; } public function download(string $sourcePath, string $destinationPath): Process @@ -218,7 +239,8 @@ public function download(string $sourcePath, string $destinationPath): Process public function getUploadCommand(string $sourcePath, string $destinationPath): string { - return "scp {$this->getExtraScpOptions()} $sourcePath {$this->getTargetForScp()}:$destinationPath"; + $passwordCommand = $this->getPasswordCommand(); + return "{$passwordCommand}scp {$this->getExtraScpOptions()} $sourcePath {$this->getTargetForScp()}:$destinationPath"; } public function upload(string $sourcePath, string $destinationPath): Process diff --git a/tests/SshTest.php b/tests/SshTest.php index 2ab1cbe..7e2f37d 100644 --- a/tests/SshTest.php +++ b/tests/SshTest.php @@ -164,3 +164,17 @@ assertMatchesSnapshot($command); }); + +it('can login with a password', function () { + $ssh = new Ssh('user', 'example.com', 22, 'password'); + $command = $ssh->getExecuteCommand('whoami'); + + assertMatchesSnapshot($command); +}); + +it('can login with a password failed', function () { + $ssh = new Ssh('user', 'example.com', 22, 'wrong_password'); + $command = $ssh->getExecuteCommand('whoami'); + + assertMatchesSnapshot($command); +}); diff --git a/tests/__snapshots__/SshTest__it_can_login_with_a_password__1.txt b/tests/__snapshots__/SshTest__it_can_login_with_a_password__1.txt new file mode 100644 index 0000000..9ece333 --- /dev/null +++ b/tests/__snapshots__/SshTest__it_can_login_with_a_password__1.txt @@ -0,0 +1,3 @@ +sshpass -p 'password' ssh -p 22 user@example.com 'bash -se' << \EOF-SPATIE-SSH +whoami +EOF-SPATIE-SSH \ No newline at end of file diff --git a/tests/__snapshots__/SshTest__it_can_login_with_a_password_failed__1.txt b/tests/__snapshots__/SshTest__it_can_login_with_a_password_failed__1.txt new file mode 100644 index 0000000..6e9f86d --- /dev/null +++ b/tests/__snapshots__/SshTest__it_can_login_with_a_password_failed__1.txt @@ -0,0 +1,3 @@ +sshpass -p 'wrong_password' ssh -p 22 user@example.com 'bash -se' << \EOF-SPATIE-SSH +whoami +EOF-SPATIE-SSH \ No newline at end of file