Dear R. Eric Wheeler,
Thank you! After several weeks of posting my question in several fora,
you are the first to reply with an example that works. Thank you! I am
so happy. After I have time to clean up the formatting and document it a
bit more fully I plan to post it everywhere, since no one seemed to know
how to make this simple and valuable example. I will give you credit,
and you deserve it!
One minor problem: the file is uploaded to the document root instead of
the $remoteDir directory. I can probably figure this out, but it would
help if you correct my code. I may have messed something up.
Here is your code after I modified it to work in my environment. Note
that I commented out your code to list the remote dir since it gave an
error message and I don't need it anyway. If there are no errors
detected, and it passes a simple test for successful upload once, I'm
satisfied that the file was uploaded.
One question: what is the "copy" function there for? I don't think I
need any files copied locally in order to upload a file.
One more question: can it work without knowing the user's password? I'm
thinking of disabling passwords on my remote webserver, so access is by
public/private keys only.
Thank you!
David
<?php declare(strict_types=1);
// From R. Eric Wheeler sikofitt@xxxxxxxxx
// Tested on
// PHP 7.4.14 (cli) (built: Jan 5 2021 15:12:29) ( ZTS Visual C++ 2017
x64 )
// Windows 10 Pro
// pecl ssh2 v1.2
// Remote server
// Gentoo GNU/Linux Base System release 2.7
error_reporting(E_ALL);
ini_set('display_errors', '1');
$c=GetConfigArr("secret.json");
extract($c);
file_put_contents(__DIR__.'/test.txt', 'worked!');
$host = $hostIP;
$port = (int)$securePort;
$connection = ssh2_connect($host, $port); // let libssh2 figure it out.
if(!is_resource($connection)) {
exit('Connection failed.');
}
// Without the __DIR__ php will just try to get 'id_rsa' and will fail.
// if your keys are elsewhere __DIR__ should be changed to
C:\path\to\your\files
$privateKey = __DIR__.'\w.key'; // id_rsa
$publicKey = __DIR__.'\w1.pub'; // id_rsa.pub
$username = $user;
$passphrase = $passphrase; // set this to passphrase if you have one.
if(false === ssh2_auth_pubkey_file($connection, $username, $publicKey,
$privateKey, $passphrase)) {
ssh2_disconnect($connection);
exit('Authentication failed.');
}
$sftp = ssh2_sftp($connection);
$streamUrl = sprintf("ssh2.sftp://%d", (int)$sftp);
$path = sprintf($remoteDir, $streamUrl);
$file = sprintf('%s/test.txt', $path);
$localFile = __DIR__ . '/test.txt';
if(!file_exists($file)) {
if(true === copy($localFile, $file)) {
print 'Successfully copied ' . $localFile . PHP_EOL;
}
} else {
print 'File exists' . PHP_EOL;
}
// using ssh2_scp_send, if all you need to do is upload a file.
// There doesn't seem to be another way to check if the file exists
// using just the ssh2 resource without using the ssh2.sftp stream wrapper.
// If you want to check if the file exists use ssh2_sftp_stat() it will
// return false if the file does not exist.
$file2 = 'test.txt';
$res = ssh2_scp_send($connection, $localFile, $file2);
if($res) {
print 'Sent file ' . $file . PHP_EOL;
} else {
print 'There was an error copying file to remote.' . PHP_EOL;
}
/*
// List contents of remote directory
$i = new \RecursiveDirectoryIterator($path,
\RecursiveDirectoryIterator::SKIP_DOTS);
while($i->valid()) {
print $i->getPathname();
if($i->isDir()) {
print $i->getPath() . PHP_EOL;
} else {
print $i->getFilename() . PHP_EOL;
}
$i->next();
}
*/
// shutdown
unset($sftp); // If you don't unset $sftp ssh2_disconnect will throw a
segfault.
ssh2_disconnect($connection);
function GetConfigArr($file)
{
global $pagesDir;
$configStr=@file_get_contents($file);
if ($configStr===false)
exit("*** HMAC: Config file '$file' is missing from $pagesDir; please
read ".
"file HMAC\Installation.txt for the steps to set up your HMAC website.");
return json_decode($configStr,true);
} // GetConfigArr
?>