php - ssh2_exec failed allocating pty - php

Using PHP, I need to periodically execute a remote command on a Draytek 2925 router using SSH.
I can already connect to the router using the standard "ssh" command on Linux, but after authenticating I am getting "PTY allocation request failed on channel 0". However despite that message, I can still send commands.
When I try doing the same with PHP, I am getting 1 of 2 results and neither of which is returning the results I need.
My code is as follows:
<?
if (!($connection = ssh2_connect('my.router.local', 22)))
die('CONN');
else if (!ssh2_auth_password($connection, 'admin', 'password'))
die('AUTH');
else
{
$stream = ssh2_exec($connection, 'sys version');
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
echo stream_get_contents($stream_out);
exit();
}
?>
The PHP fails at ssh2_exec(). If I specify the 3rd argument (pty), I get this result:
Warning: ssh2_exec(): Failed allocating 1 pty at 80x25 characters
However, not specifying the 3rd argument results in:
Warning: ssh2_exec(): Unable to request command execution on remote host
Even if I type #ssh2_exec(), I don't get a warning, but I don't get a result either.
If PHP is a no-go, I tried using sshpass in the same way, but that results in the following:
# sshpass -f sshpwd -v ssh admin#my.router.local 'sys version'
SSHPASS searching for password prompt using match "assword"
SSHPASS read: admin#my.router.local's password:
SSHPASS detected prompt. Sending password.
SSHPASS read:
exec request failed on channel 0
#
I ultimately just need to authenticate, send a command and return the result. Is there anything I am doing wrong or is there a simpler way?

I have resolved my query by using TELNET instead. Yes it's not secure like SSH, but since it's being used internally over the LAN, it doesn't matter.
For anyone interested, I used Net_Telnet and the following code:
<?php
require_once "Net/Telnet.php";
$router = 'my.router.local';
$password = 'password';
try
{
$t = new Net_Telnet($router);
$t->connect();
$t->login([
'login_prompt' => 'Account:',
'login_success' => ' User login successful, expired time is "Unlimited".',
'login_fail' => '% Access denied',
'login' => 'admin',
'password' => $password,
'prompt' => "{$router}>",
]
);
echo $t->cmd('sys version');
$t->disconnect();
// catch any buffered data
echo $t->get_data();
echo "\n";
} catch (Exception $e)
{
echo "Caught Exception ('{$e->getMessage()}')\n{$e}\n";
}
exit();
?>
Which results in:
# php -f telnet.php
sys version
Router Model: Vigor2925n Version: 3.8.4 English
Profile version: 3.0.0 Status: 1 (0x48245e4c)
Router IP: 0.0.0.0 Netmask: 255.255.255.0
Firmware Build Date/Time: Dec 15 2016 17:26:01
Router Name: my.router.local
Revision: 61327 V384_2925
>
#

Related

PHP MongoDb driver: How to set timeout for executing a code

I have the following code which executes a piece of code on the MongoDb's side:
$mongoCode = new MongoCode('/* Some JS code */');
$db->execute($mongoCode, array(
'socketTimeoutMS' => 1000000,
));
As you see I have tried to set timeout for the code's execution by setting the socketTimeoutMS value in second parameter of execute() function. But it does not work. Documentations in PHP website indicate that the second parameter of execute() command is sent to code as arguments.
How can I set timeout for MongoDB::execute()? Please note that I am using version 1.5 of MongoDB driver for php and MongoCursor::$timeout is deprecated and does not work anymore.
You can set the socketTimeoutMS on MongoClient:
$mongo = new MongoClient("mongodb://localhost:27017",
array(
"socketTimeoutMS" => 100000
)
);
The args parameters for the execute method are passed to the code not to the driver.
You can also set a timeout just when executing the command:
$result = $mongo->dbname->command(
['eval' => $code],
['socketTimeoutMS' => 1]
);
Alternatively, if you're not executing commands, you can set the timeout on the cursor:
$cursor = $collection->find([]);
$cursor->timeout(10000);
This will obviously not work on the execute command, because that command doesn't return a cursor.
You want the MongoDB::command implementation for this which actually accepts the argument:
<?php
$mongo = new MongoClient('mongodb://192.168.2.3/test');
$db = $mongo->test;
$code = new MongoCode( 'sleep(100); return "hello";' );
try {
$res = $db->command(
array("eval" => $code),
array( 'socketTimeoutMS' => 1 )
);
echo var_dump( $res );
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
?>
Note that even though the exception will be thrown for the timeout, this does not not actually stop the code running on the server. That you would have to handle yourself.
Look into the killOp() and currentOP() methods, with their usage and implementation for a way to control and processes left running after your timeout expires on this operation.
Really try to look for other approaches rather than executing JavaScript on the server like this.

Parsing SSH2 Results in PHP

I am running PHP vc9 NTS 5.3.28 on Windows Server 2003 Standard 32bit with phpseclib 0.3.6. I am trying to creating a script that will connect to a Palo Alto Networks firewall and execute a command to hash a password. I have the following code:
<?php
include 'Net/SSH2.php';
define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX);
$ssh = new Net_SSH2('hostname');
echo ">Logging in...\n";
if (!$ssh->login('user', 'password')) {
exit('Login Failed');
}
echo ">Reading login results...\n";
/*echo $ssh->exec('request password-hash password test123');*/
$output = $ssh->read('user#PA-3020>');
echo $output . "\n";
echo ">Writing request...\n";
$ssh->write("request password-hash password test123\n");
$ssh->setTimeout(10);
echo ">Reading result...\n";
$output = $ssh->read('/^\$1\$.*$/', NET_SSH2_READ_REGEX);
echo $output . "\n";
echo ">Done.\n";
file_put_contents ('E:\PHP53\ssh2.log', $ssh->getLog());
?>
I have two problems with the above code:
If I leave out the setTimeout(10) then the code never exists the next $ssh->read. If I have it in, then the code exists only after the timeout but does return results.
The results it returns are including a bunch of stuff that shouldn't be there:
?[Kuser#PA-3020> request password-hash password test123
?[?1h?=?[24;1H?[K
$1$dgkhwrxe$kddYFmKCq9.zfiBKPAyN61
?[24;1H?[K?[?1l?>user#PA-3020>
I only want the line that starts with $1$ (line 3 above). I figure it has something to do with the regex but I can't figure out what.
If I run the command interactively with PuTTY I get the following:
user#PA-3020> request password-hash password test123
$1$pxqhdlco$MRsVusWtItC3QiMm4W.xZ1
user#PA-3020>
UPDATE:
As per suggestions from neubert below, replacing the line with $output = $ssh->read... with the following code works:
$output = $ssh->read('/\$1\$.*/', NET_SSH2_READ_REGEX);
$output = preg_replace('/.*\$1\$/s','\$1\$', $output);
The results it returns are including a bunch of stuff that shouldn't
be there:
?[Kuser#PA-3020> request password-hash password test123
?[?1h?=?[24;1H?[K $1$dgkhwrxe$kddYFmKCq9.zfiBKPAyN61
?[24;1H?[K?[?1l?>user#PA-3020>
Those are ANSI escape codes. You can use File_ANSI to remove them. More info:
http://phpseclib.sourceforge.net/ssh/examples.html#top
Anyway, my guess would be that you need to redo your regex. eg.
$output = $ssh->read('/^\$1\$.*$/', NET_SSH2_READ_REGEX);
Instead of doing that do this:
$output = $ssh->read('/\$1\$/', NET_SSH2_READ_REGEX);
The thing is... ^ matches at the start of the line and $ matches at the end. Usually when you do $ssh->write(...) the command is echo'd back to you and then there's a new line and then you get your output back. So that'd prevent ^ from working. And as for the $ at the end.. well per your own example $1$ doesn't occur at the end of a line. So that's why your code isn't working.

Can not execute CL Command (AS400 command) in PHP script

I login to AS400 and go to QSHELL(STRQSH). After that I pasted the following command and run it in QSHELL
system "IVIEW/PRTDISTL APPNAME(MYJOBLOG) STMF(TEST_89.PDF) HOLD(*NO)"
It works. But when I execute the above command using PHP script as the follow
$cmd = "IVIEW/PRTDISTL APPNAME(MYJOBLOG) STMF(TEST_89.PDF) HOLD(*NO)";
$cmd = 'system "' . $cmd . '"';
$output = array();
exec ($cmd, $output , $retVal);
echo "return value code: " . $retVal;
It returns error code of 255. Please help me how to fix this issue. Thanks
Try the PHP Toolkit for i5/OS. There is a older Redbook that describes it: http://www.redbooks.ibm.com/redbooks/pdfs/sg247327.pdf
An example from there:
<HTML>
<?php
/* Connect to server */
$conn = i5_connect("localhost", "PHPUSER", "MYPASSWORD");
if (!$conn)
die("<br>Connection using \"localhost\" with USERID and PASSWORD failed. Error
number =".i5_errno()." msg=".i5_errormsg())."<br>";
else
echo "<br>Connection using \"localhost\" with USERID and PASSWORD OK!<br>\n";
/* Call Retrieve Network Attributes command */
$ret = i5_command("rtvneta", array(), array("sysname" => "sysn", "lclnetid"=>"lclnet"));
if (!$ret) die("<br>rtvneta command failed. errno=".i5_errno()."
msg=".i5_errormsg());
print "<h1><b>Results of \"rtvneta\" command </b></h1><br>" ;
print "System Name : $sysn<br>" ;
print "Local Net ID : $lclnet<br>" ;
/* Close connection */
i5_close($conn);
?>
</HTML>
I see two pontential problems:
PHP runs in PASE, not in QShell. Try to manually run your call from QP2TERM.
User rights. Make sure QTMHHTTP (or whatever user runs PHP) has the apropriate rights to the program you try to call.
You can check for further information in stdout, which you should have in $output, and your PHP-server joblog as mentioned at IBM i information center (possibly needing the flag 'system -K').

WSO2 WS Security Password only without certificate possible?

we want to create a PHP WSO2 Webservice Client which uses WS Security, but without signature nor encryption. Instead we want to use a simple Password. Problem is: we always get an certificate error (see below). Do we really have to install a certificate, and if so: where ? Java Keystore ?
Environment: PHP 5.3.10, WSO2 PHP 2.10, Apache 2.2.x
wfs_client_log:
[error] key_mgr.c(295) [rampart][rampart_signature] Public key certificate file is not specified.
[error] rampart_signature.c(856) [rampart][rampart_signature] Cannot get certificate
[error] rampart_sec_header_builder.c(131) [rampart][shb] Signing failed. ERROR
[error] rampart_sec_header_builder.c(601) [rampart][shb] Asymmetric Binding failed
[error] rampart_out_handler.c(130) [rampart]Security header building failed.
[error] phase.c(224) Handler RampartOutHandler invoke failed within phase Security
[error] engine.c(657) Invoking phase Security failed
PHP Code is:
<?php
// Endpoint WebService
$endPoint = 'http://xxx.xxxx.xxx:7000/orabpel/selfservice/passwortAendernMBE/1.0';
// Security-Payload
$user = 'mustermann123';
$passwortAlt = 'foo';
$passwortNeu = 'bar';
// create Security-Token
$secToken = new WSSecurityToken(array(
"user" => $user,
"password" => $passwortAlt,
"passwordType" => "PlainText"));
// create SecurityPolicy
$policy = new WSPolicy(array(
"security" => array(
"useUsernameToken" => TRUE)));
// create WS-Client
$client = new WSClient( array(
"to" => $endPoint,
"useSOAP" => "1.1",
"action" => "process",
"policy" => $policy,
"securityToken" => $secToken));
// create SOAP-Payload
$soapPayload = '
<ns1:passwortAendern_processElement xmlns:ns1="http://xxxx.xxxx.xxxxxe/Integration/prozesse/xxxxxxSchema"
xmlns:ns2="http://xxxx.xxxx.xxx/types/xx.xxx.xxxx.selfService.prozesse.xxx.xxxxMessage">
<ns1:passwortAendernMessage>
<ns2:benutzerkennung>' . $user . '</ns2:benutzerkennung>
<ns2:passwortAlt>' . $passwortAlt . '</ns2:passwortAlt>
<ns2:passwortNeu>' . $passwortNeu . '</ns2:passwortNeu>
</ns1:passwortAendernMessage>
</ns1:passwortAendern_processElement>';
// Request
$soapResponse = null;
try {
// soap Request
$soapResponse = $client->request( $soapPayload );
// print out Response
echo '<pre>';
print_r(htmlspecialchars( str_replace('>','>'.PHP_EOL,$soapResponse->str ) ));
echo '</pre>';
} catch(Exception $e) {
echo '<h1>Error:</h1>' . PHP_EOL;
var_dump($e);
}
// dump Soap-Parameters
echo '<h1>Soap-Parameter</h1>' . PHP_EOL;
var_dump($soapPayload);
// dump Soap-Response
echo '<h1>Soap-Response</h1>' . PHP_EOL;
var_dump($soapResponse);
Finally successful! Calling the Webservice (with above mentioned vector/intent) now works.
Many attempts and another example by Nandika later we've found out that for us (Matthias and I) changing the creation of the WS-SecurityPolicy -object did the trick.
Instead of using above array as initialisation-parameter:
// create SecurityPolicy
$policy = new WSPolicy(array(
"security" => array(
"useUsernameToken" => TRUE)));
...we now use a xml-policy-file like so:
// load Policy (xml) file...
$policy_file = file_get_contents("policy.xml");
// ...and create SecurityPolicy
$policy = new WSPolicy($policy_file);
Content of "policy.xml":
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding>
<wsp:Policy>
</wsp:Policy>
</sp:TransportBinding>
<sp:SignedSupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10 />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SignedSupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Beginning to use WSO2 with WS-Security WSF/PHP 2.1 feels rather touchy. Therefore I'll try to list some thoughts that knowing (would have) helped me save time:
most common error reflected to me by wsf/php is (an exception-object with the message): "Error , NO Response Received". This now happens almost whenever anything goes wrong, for example:
my request-xml (-structure) is not valid
a parameter has an incorrect type
the webservice throws an Exception (any exception really: be it because of a wrong WS-Security user/password, missing/unknown namespace, even some exceptions of type 'WS-Fault')
anything going wrong on the service-side really
a misconfiguration / configuration-change on php/wsf -side that disallowes anything relevant
network problems? (...not confirmed)
no request is sent by wso2 (for example when having trouble with TransportBinding -confinguration)
sometimes I do get a WS-Fault -ojbect (in a resopnse envelope) which I can check for my client-code [$e typeof WSFault]
always have a tool with proxy-capabilities nearby to route through + inspect your request and response. At the moment I use Oracles JDeveloper 10 and 11 which both have a neat little "HTTP Analyzer" inside (but there sure are smaller and/or better tools out there for this purpose).
Playing around with the settings in policy.xml a comrad and I found out that:
having a instead of the needed node (in your security_policy.xml) you'll get a WS-Fault: "policy requires authentication token"
having an empty node results in connection terminated in browser and wsf/php crashing (without signifficant error message - as far as i can see).
Thanks everyone (especially Nandika) for your help!
I've encountered the same issue once, but it was concerning WSServer, not WSClient. Since version 2.1 (or even earlier) WSF consideres WS-Policy signed by default, you need a WSPolicy file which declared signatureless behaviour. I've posted an article on this topic, but it's in Russian. Use Google Translate.
http://habrahabr.ru/post/132353/
The default generated policy is failing because, wsf/php 2.1.0 version is expecting signed messages for default generated policy for
$policy = new WSPolicy(array( "security" => array("useUsernameToken" => TRUE)));
Try with the following policy file.
https://svn.wso2.org/repos/wso2/trunk/wsf/php/samples/security/username_token/call_back/policy.xml
You can load the policy as
$policy_file = file_get_contents("policy.xml");
$policy = new WSPolicy($policy_file);

Cannot connect to Cassandra on a cloud server using phpcassa

I have setup a test cloud server (Ubuntu 10.10 on Rackspace) to play with Cassandra database (0.6.8).
I can connect no problem both from within the server and from a computer external to the cloud using the cassandra-cli basic client: I have created and retrieved sample data.
I have then installed phpcassa on the cloud server and on an external computer.
I have created a very simple php program to test the connection:
<?php
$GLOBALS['THRIFT_ROOT'] = dirname(__FILE__) . '/include/thrift/';
require_once $GLOBALS['THRIFT_ROOT'].'/packages/cassandra/Cassandra.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TFramedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
include_once(dirname(__FILE__) . '/include/phpcassa.php');
include_once(dirname(__FILE__) . '/include/uuid.php');
echo 'phpcassa test01<br /><br />';
CassandraConn::add_node('184.106.97.245', 9160);
$users = new CassandraCF('Keyspace1', 'Standard2');
try {
$res = $users->get('jsmith');
print_r($res);
} catch (Exception $e) {
print CassandraConn::$last_error;
}
echo 'End.'
?>
I am using buffered transport.
I can happily connect and read data from within the server (I have also installed LAMP on it):
phpcassa test01
Array ( [age] => 42 [first] => John [last] => Smith )
End.
but not from outside because I am always getting the exception:
phpcassa test01
TException: TSocket: Could not connect to 184.106.97.245:9160 (Operation timed out [60])
End.
This is my storage-conf.xml file:
<Storage>
<ClusterName>Test Cluster</ClusterName>
<AutoBootstrap>false</AutoBootstrap>
<HintedHandoffEnabled>true</HintedHandoffEnabled>
<IndexInterval>128</IndexInterval>
<Keyspaces>
<Keyspace Name="Keyspace1">
<ColumnFamily Name="Standard1" CompareWith="BytesType"
KeysCached="1000"
RowsCached="100"
RowCacheSavePeriodInSeconds="0"
KeyCacheSavePeriodInSeconds="3600"/>
<ColumnFamily Name="Standard2"
CompareWith="UTF8Type"
KeysCached="100%"/>
<ColumnFamily Name="StandardByUUID1" CompareWith="TimeUUIDType" />
<ColumnFamily Name="Super1"
ColumnType="Super"
CompareWith="BytesType"
CompareSubcolumnsWith="BytesType" />
<ColumnFamily Name="Super2"
ColumnType="Super"
CompareWith="UTF8Type"
CompareSubcolumnsWith="UTF8Type"
RowsCached="10000"
KeysCached="50%"
Comment="A column family with supercolumns, whose column and subcolumn names are UTF8 strings"/>
<ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
<ReplicationFactor>1</ReplicationFactor>
<EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
</Keyspace>
</Keyspaces>
<Authenticator>org.apache.cassandra.auth.AllowAllAuthenticator</Authenticator>
<Partitioner>org.apache.cassandra.dht.RandomPartitioner</Partitioner>
<InitialToken></InitialToken>
<SavedCachesDirectory>/var/lib/cassandra/saved_caches</SavedCachesDirectory>
<CommitLogDirectory>/var/lib/cassandra/commitlog</CommitLogDirectory>
<DataFileDirectories>
<DataFileDirectory>/var/lib/cassandra/data</DataFileDirectory>
</DataFileDirectories>
<Seeds>
<Seed>184.106.97.245</Seed>
</Seeds>
<RpcTimeoutInMillis>10000</RpcTimeoutInMillis>
<CommitLogRotationThresholdInMB>128</CommitLogRotationThresholdInMB>
<ListenAddress>184.106.97.245</ListenAddress>
<StoragePort>7000</StoragePort>
<ThriftAddress>184.106.97.245</ThriftAddress>
<ThriftPort>9160</ThriftPort>
<ThriftFramedTransport>false</ThriftFramedTransport>
<DiskAccessMode>auto</DiskAccessMode>
<RowWarningThresholdInMB>64</RowWarningThresholdInMB>
<SlicedBufferSizeInKB>64</SlicedBufferSizeInKB>
<FlushDataBufferSizeInMB>32</FlushDataBufferSizeInMB>
<FlushIndexBufferSizeInMB>8</FlushIndexBufferSizeInMB>
<ColumnIndexSizeInKB>64</ColumnIndexSizeInKB>
<MemtableThroughputInMB>64</MemtableThroughputInMB>
<BinaryMemtableThroughputInMB>256</BinaryMemtableThroughputInMB>
<MemtableOperationsInMillions>0.3</MemtableOperationsInMillions>
<MemtableFlushAfterMinutes>60</MemtableFlushAfterMinutes>
<ConcurrentReads>8</ConcurrentReads>
<ConcurrentWrites>32</ConcurrentWrites>
<CommitLogSync>periodic</CommitLogSync>
<CommitLogSyncPeriodInMS>10000</CommitLogSyncPeriodInMS>
<GCGraceSeconds>864000</GCGraceSeconds>
<DoConsistencyChecksBoolean>true</DoConsistencyChecksBoolean>
</Storage>
Rackspace support suggested changing the firewall settings but I have no firewall:
root#Oahu:~# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Any help very much appreciated!!!
Cheers, Rujero
Access the node (first) with http://wiki.apache.org/cassandra/CassandraCli

Categories