Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add password authentication support for SSH #103

Merged
merged 10 commits into from
Dec 23, 2024
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "spatie/ssh",
"name": "shaunluedeke/ssh",
shaunluedeke marked this conversation as resolved.
Show resolved Hide resolved
"description": "A lightweight package to execute commands over an SSH connection",
"keywords": [
"spatie",
Expand Down
34 changes: 28 additions & 6 deletions src/Ssh.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
*
Expand All @@ -173,11 +192,12 @@ public function getExecuteCommand($command): string
return $commandString;
}

$passwordCommand = $this->getPasswordCommand();
$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;
}

/**
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions tests/SshTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,10 @@

assertMatchesSnapshot($command);
});

it('can login with a password', function () {
shaunluedeke marked this conversation as resolved.
Show resolved Hide resolved
$ssh = new Ssh('user', 'example.com', 22, 'password');
$command = $ssh->getExecuteCommand('whoami');

assertMatchesSnapshot($command);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sshpass -p 'password' ssh -p 22 [email protected] 'bash -se' << \EOF-SPATIE-SSH
whoami
EOF-SPATIE-SSH
Loading