SSH2 change a user password - php

I've been playing around with SSH and now I need to change a user's password via the PHP's ssh2,
Here's my code:
$stream = ssh2_exec($ssh, 'passwd test1234');
stream_set_blocking($stream, true);
$data = '';
while($buffer = fread($stream, 4096)) {
$data .= $buffer;
}
fclose($stream);
echo $data."<hr/>";
$stream = ssh2_exec($ssh, 'saulius123');
stream_set_blocking($stream, true);
$data = '';
while($buffer = fread($stream, 4096)) {
$data .= $buffer;
}
echo $data."<hr/>";
$stream = ssh2_exec($ssh, 'saulius123');
stream_set_blocking($stream, true);
$data = '';
while($buffer = fread($stream, 4096)) {
$data .= $buffer;
}
echo $data."<hr/>";
However this just make's my PHP script hang, any ideas?

ssh2_exec invokes the command; to send input, you'll need to write to the stream.
That is, $stream gives you access to standard input and standard output. So you'll need to write the password you wish to set using fwrite on $stream before trying to read back the output.
Since you've put the stream in blocking mode, passwd is awaiting your input (the password) at the same time your script is waiting for passwd. As a result, the script hangs.

Personally, I'd use phpseclib, a pure PHP SSH implementation. Example:
<?php
include('Net/SSH2.php');
$key = new Crypt_RSA();
//$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', $key)) {
exit('Login Failed');
}
echo $ssh->read('username#username:~$');
$ssh->write("ls -la\n");
echo $ssh->read('username#username:~$');
?>
The biggest advantage of it over libssh2 is portability. We use Amazon Web Services were I work and sometimes we move over to new prod servers or dev servers and the most difficult part in setting them up is installing all the PECL extensions and what not.
phpseclib, in contrast, doesn't have any requirements.

Related

ssh2_exec execution stops after 32kb of data

I am using the php ssh2 methods to establish a connection to a server and transmit a string of ~39Kb. However, after 32Kb the transmission stops with an exception:
ErrorException: ssh2_exec(): Unable to request command execution on remote host in /var/www/xxx/xxxSSH.php:36
Is there an artificial limit on how many bytes can be transmitted in a session and if so, how can I change the limit?
UPDATE
Here's the method producing the error:
public function exec($cmd)
{
if (!($stream = ssh2_exec($this->connection, $cmd))) {
throw new Exception('SSH command failed');
}
stream_set_blocking($stream, true);
$data = "";
while ($buf = fread($stream, 4096)) {
$data .= $buf;
}
fclose($stream);
return $data;
}
$cmd contains the string that seems to cause the trouble. What it does is call echo '$extremelyLongString' > /etc/someconfig.cfg

Using ftp_fget using SFTP / phpseclib

I'm currently having a horrible time with SFTP.
Is there a way to use ftp_fget using SFTP?
I'm using the phpseclibrary, but it only offers their own implementation of $sftp->get() howver I would like $sftp->fget();
In the latest Git version (ie. later than 0.3.7), instead of $sftp->fget(), you can do something like this:
$fp = fopen('filename.ext', 'w');
$sftp->get('file_to_download.ext', $fp);
fclose($fp);
You could also alternatively use Net/SFTP/Stream.php . eg.
$resFile = fopen("sftp://{$resSFTP}/".$filename, 'w');
$srcFile = fopen("/home/myusername/".$filename, 'r');
$writtenBytes = stream_copy_to_stream($srcFile, $resFile);
fclose($resFile);
fclose($srcFile);

PHP - TCP/IP fsockopen

I was wondering if anyone has had any experience with this before. I'm trying to write a simple script that will continously read data from the TCP/IP stream but for some reason or another the script reads in a bunch of data, writes it out and then just stops.
$fp = fsockopen("xxxx", 3000, $errno, $errstr, 5);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
while (!feof($fp)) {
echo fgets($fp, 128)."\n";
fflush($fp);
}
fclose($fp);
}
I'd like it to have a constant flow to it, rather then echo out a bunch of data then wait 30 seconds and output a bunch more data. Anyone have any ideas?
---- EDIT ----
ZMQ Code
include 'zmsg.php';
$context = new ZMQContext();
$client = new ZMQSocket($context, ZMQ::SOCKET_DEALER);
// Generate printable identity for the client
$identity = sprintf ("%04X", rand(0, 0x10000));
$client->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity);
$client->connect("tcp://xxxx:3000");
$read = $write = array();
$poll = new ZMQPoll();
$poll->add($client, ZMQ::POLL_IN);
$request_nbr = 0;
while (true) {
// Tick once per second, pulling in arriving messages
for ($centitick = 0; $centitick < 100; $centitick++) {
$events = $poll->poll($read, $write, 1000);
$zmsg = new Zmsg($client);
if ($events) {
$zmsg->recv();
echo $zmsg->body()."\n";
//printf ("%s: %s%s", $identity, $zmsg->body(), PHP_EOL);
}
}
$zmsg = new Zmsg($client);
//$zmsg->body_fmt("request #%d", ++$request_nbr)->send();
}
Here is how you connect to a server (as a client) if your goal is ONLY to PULL data (read).
<?php
$context = new ZMQContext();
$sock = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$sock->connect("tcp://ADDRESS:3000");
while (true)
{
$request = $sock->recv(); # recv is blocking by default, no need to put timers.
printf ("Received: %s;%s", $request, PHP_EOL);
}
?>
if you want to reply, you'll need to use a pair socket (ZMQ::SOCKET_PAIR), then you can use:
$sock->send("data to send");
Also, if instead of you connecting to clients, clients connects to you, use the bind method instead of connect.
EDIT: use the PUSH socket type on the other side if you use the pull here, else, use the pair socket on both sides.

AWS S3 Download counter

I have a file uploaded in AWS s3 bucket and set that file to public permission . i want to share that file in my Facebook .. the thing is i can just copy that public link and share it . but i also want the count of the downloads to stored .. in other way i want to host a php file in my web hosting where there will be a tab like bar in which that file name,file size, download link and total download count will be there . Please help me with the code
I tried the following code which i got from google search but no use
<?php
$aws_key = '_YOUR_AWS_KEY_000000';
$aws_secret = '_your_aws_secret_00000000000000000000000';
$aws_bucket = 'anyexample-test'; // AWS bucket
$aws_object = 'test.png'; // AWS object name (file name)
if (strlen($aws_secret) != 40) die("$aws_secret should be exactly 40 bytes long");
$dt = gmdate('r'); // GMT based timestamp
// preparing string to sign
$string2sign = "GET
{$dt}
/{$aws_bucket}/{$aws_object}";
// preparing HTTP query
$query = "GET /{$aws_bucket}/{$aws_object} HTTP/1.1
Host: s3.amazonaws.com
Connection: close
Date: {$dt}
Authorization: AWS {$aws_key}:".amazon_hmac($string2sign)."\n\n";
echo "Downloading: http://s3.amazonaws.com/{$aws_bucket}/{$aws_object}\n";
list($header, $resp) = downloadREST($fp, $query);
echo "\n\n";
if (strpos($header, '200 OK') === false) // checking for error
die($header."\r\n\r\n".$resp);
$aws_object_fs = str_replace('/', '_', $aws_object);
// AWS object may contain slashes. We're replacing them with underscores
#$fh = fopen($aws_object_fs, 'wb');
if ($fh == false)
die("Can't open file {$aws_object_fs} for writing. Fatal error!\n");
echo "Saving data to {$aws_object_fs}...\n";
fwrite($fh, $resp);
fclose($fh);
// Sending HTTP query, without keep-alive support
function downloadREST($fp, $q)
{
// opening HTTP connection to Amazon S3
// since there is no keep-alive we open new connection for each request
$fp = fsockopen("s3.amazonaws.com", 80, $errno, $errstr, 30);
if (!$fp) die("$errstr ($errno)\n"); // connection failed, pity
fwrite($fp, $q); // sending query
$r = ''; // buffer for result
$check_header = true; // header check flag
$header_end = 0;
while (!feof($fp)) {
$r .= fgets($fp, 256); // reading response
if ($check_header) // checking for header
{
$header_end = strpos($r, "\r\n\r\n"); // this is HTTP header boundary
if ($header_end !== false)
$check_header = false; // We've found it, no more checking
}
}
fclose($fp);
$header_boundary = $header_end+4; // 4 is length of "\r\n\r\n"
return array(substr($r, 0, $header_boundary), substr($r, $header_boundary));
}
// hmac-sha1 code START
// hmac-sha1 function: assuming key is global $aws_secret 40 bytes long
// http://en.wikipedia.org/wiki/HMAC
// warning: key is padded to 64 bytes with 0x0 after first function call
// hmac-sha1 function
function amazon_hmac($stringToSign)
{
if (!function_exists('binsha1'))
{ // helper function binsha1 for amazon_hmac (returns binary value of sha1 hash)
if (version_compare(phpversion(), "5.0.0", ">=")) {
function binsha1($d) { return sha1($d, true); }
} else {
function binsha1($d) { return pack('H*', sha1($d)); }
}
}
global $aws_secret;
if (strlen($aws_secret) == 40)
$aws_secret = $aws_secret.str_repeat(chr(0), 24);
$ipad = str_repeat(chr(0x36), 64);
$opad = str_repeat(chr(0x5c), 64);
$hmac = binsha1(($aws_secret^$opad).binsha1(($aws_secret^$ipad).$stringToSign));
return base64_encode($hmac);
}
// hmac-sha1 code END
?>
I would suggest using the official AWS SDK for PHP, because it has all of the request signing and handling logic implemented for you. Here is an article by one of the SDK's developers that is relevant to what you are doing: Streaming Amazon S3 Objects From a Web Server
Infact if you just need to see the number of downloads, you can achieve this without running yourown server with php.
This info is already available in the S3 bucket logs, if you enable. This will be more accurate, since the in the PHP approach there is no way to track download, if the user take the S3 link directly and share/download.
These logs are little difficult to parse though, but the services like https://qloudstat.com and http://www.s3stat.com/ help here.
Another point: Downloads will be considerably faster, if you enable CDN - Cloudfront in front of the S3 bucket.

Executing Python Script in PHP

I have written a simple chat program using twisted library in Python. Basically I have a server program(server.py) and a chat program ( client.py)
client.py is a simple python script which would connect to the server on a particular port and print the messages on the terminal.
I can run the server.py and the client.py on a local system and I can chat on different terminals.
I would like to integrate the client.py in PHP and be able to chat through the browser.
I am calling python script through exec in PHP. However it is not working.
exec("python client.py")
Any idea, if I am missing anything ?
Not sure if I can help you, but here's some things I'd consider:
Have you tried executing a different command, does that work?
Have you set the permissions of the .php file and Python.exe correctly?
Can you run your command from a terminal window (either Windows/Mac/Linux) from the folder your PHP file is in?
If you've already tried all of these things, I can't think of another solution.. Good luck!
You might find the following program helpful as a starting point. It is designed to run a Python program:
<?php
// Check that test is not FALSE; otherwise, show user an error.
function assert_($test)
{
if ($test === FALSE)
{
echo '<html><head><title>Proxy</title></head><body><h1>Fatal Error</h1></body></html>';
exit(1);
}
}
// Patch this version of PHP with curl_setopt_array as needed.
if (!function_exists('curl_setopt_array')) {
function curl_setopt_array($ch, $curl_options)
{
foreach ($curl_options as $option => $value) {
if (!curl_setopt($ch, $option, $value)) {
return FALSE;
}
}
return TRUE;
}
}
// Fetch the URL by logging into proxy with credentials.
function fetch($url, $proxy, $port, $user, $pwd)
{
$ch = curl_init($url);
assert_($ch);
$options = array(
CURLOPT_PROXY => $proxy . ':' . $port,
CURLOPT_PROXYAUTH => CURLAUTH_NTLM,
CURLOPT_PROXYUSERPWD => $user . ':' . $pwd,
CURLOPT_RETURNTRANSFER => TRUE
);
assert_(curl_setopt_array($ch, $options));
$transfer = curl_exec($ch);
curl_close($ch);
assert_($transfer);
return $transfer;
}
// Run path with stdin and return program's status code.
function order($path, $stdin, &$stdout, &$stderr)
{
$cmd = './' . basename($path);
$descriptorspec = array(
array('pipe', 'r'),
array('pipe', 'w'),
array('pipe', 'w')
);
$cwd = dirname($path);
$process = proc_open($cmd, $descriptorspec, $pipes, $cwd, $_REQUEST);
assert_($process);
for ($total = 0; $total < strlen($stdin); $total += $written)
{
$written = fwrite($pipes[0], substr($stdin, $total));
assert_($written);
}
assert_(fclose($pipes[0]));
$stdout = stream_get_contents($pipes[1]);
assert_($stdout);
assert_(fclose($pipes[1]));
$stderr = stream_get_contents($pipes[2]);
assert_($stderr);
assert_(fclose($pipes[2]));
return proc_close($process);
}
// Collect information to run over the proxy.
# $user = $_REQUEST['user'];
# $pwd = $_REQUEST['pwd'];
// Fetch the URL and process it with the backend.
$transfer = fetch('http://rssblog.whatisrss.com/feed/', 'labproxy.pcci.edu', 8080, $user, $pwd);
$status = order('/home/Chappell_Stephen/public_html/backend.py', $transfer, $stdout, $stderr);
// Check for errors and display the final output.
assert_(strlen($stderr) == 0);
echo $stdout;
?>

Categories