3
<?php
$ssh = ssh2_connect('domain.tld'); 
ssh2_auth_password($ssh, 'username', 'password');

$shell = ssh2_shell($ssh);
echo fread($shell, 1024*1024);
fwrite($shell, "sudo ls -la\n");
$output = fread($shell, 1024*1024);
echo $output;
if (preg_match('#[pP]assword[^:]*:#', $output)) {
    fwrite($shell, "password\n");
    echo fread($shell, 1024*1024);
}

All that does is display the banner and prompt. It doesn't actually give me the output of the ls -la command. On phpseclib it works just fine.

Any ideas?

  • What did you try for debugging yourself? For example, did you check if a password is asked? – kokx Jan 13 '13 at 22:56
  • Yes. My own testing confirms what the documentation on sudo says. You enter a password in and it's cached for some amount of time (5 minutes). That's why I dump the output to a string. I output the string and if it's prompting for a password I provide it the password and ask for the output again. And it's not working. Works fine with phpseclib - an alternative SSH2 library, as noted in my original post. –  Jan 13 '13 at 23:41

1 Answers1

6

I wrote an SSH wrapper (https://github.com/bubba-h57/PHP-SSH2) to facilitate a lot of my own PHP scripting that needs to SSH into remote servers, and run into this issue quite often.

I solved it with this incantation:

echo <password> | sudo -S <command>

Which for you might look like:

fwrite($shell, "echo $mySudoPassword | sudo -S ls -la\n");

I just pipe the password everytime I use sudo, whether I think I need it or not.

Using my own wrapper, it looks like:

require_once 'SSH2.php';
// Test Unix
$username = 'someuser';
$password = 'somepwd';
$host = 'somenixhost.com';
$port = 22;
$ssh2 = new My_SSH2($host, $port);
$ssh2->authPassword( $username, $password);
$ssh2->setPrompt(':~#'); // Set initial expected prompt
$ssh2->openShell();
$ssh2->setPrompt("MYCUSTOMSSHPROMPT> "); // Create a unique, easily found prompt
$ssh2->exec("PS1='MYCUSTOMSSHPROMPT> '"); // Execute the command.
echo $ssh2->exec('cd /var/www') . "\n";   // Change directories.
echo $ssh2->exec("echo $password | sudo -S ls -la\n") . "\n"; // Print LS
echo "\n===================Begin History=============\n";
echo $ssh2->getHistory();
$ssh2->disconnect();
echo "\n===================end=============\n";
exit;
bubba
  • 3,839
  • 21
  • 25
  • Hmmm - hadn't thought of pipping the output. I guess what I'm more generally interested in though isn't clever tricks one can do in the shell - I'm more interested in how libssh2 can be used to interact with non-shell prompts. Maybe a better example is passwd. You're prompted three times there. Once for the current pw and twice for the new one. I don't think you can pipe into that. Of course since I offered a bounty on a question that isn't my own and since I'd probably need to edit the original question a lot to better reflect what I'm wanting to know... oh well :( – neubert Mar 28 '13 at 02:23
  • 1
    And here I thought I'd win an easy bounty! ;-) In general PHP/libssh2 simply isn't going to interact well with a non-shell prompt and I've not found any ways to do what you seem to be asking without clever tricks one can do in the shell. With the passwd example, I would use libssh2 to pass an expect script to the remote host, then execute the script, and then delete the script. – bubba Mar 28 '13 at 02:51
  • Well I think you might win anyway lol. We have some days to figure it out lol. And I think using phpseclib it's easy enough but I'm trying to see if it can be done with libssh2 to better compare / contrast the two. – neubert Mar 28 '13 at 02:54