Разбор результатов SSH2 в PHP

Я использую PHP vc9 NTS 5.3.28 на Windows Server 2003 Standard 32bit с phpseclib 0.3.6. Я пытаюсь создать сценарий, который будет подключаться к брандмауэру Palo Alto Networks и выполнять команду для хеширования пароля. У меня есть следующий код:

<?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());
?>

У меня есть две проблемы с приведенным выше кодом:

  1. Если я пропущу setTimeout(10), тогда код никогда не будет существовать после следующего $ssh->read. Если он у меня есть, то код существует только после тайм-аута, но возвращает результаты.
  2. Результаты, которые он возвращает, включают в себя кучу вещей, которых там быть не должно:

    ?[Kuser@PA-3020> запрос пароля-хэш-пароля test123 ?[?1h?=?[24;1H?[K $1$dgkhwrxe$kddYFmKCq9.zfiBKPAyN61

    ?[24;1H?[K?[?1l?>пользователь@PA-3020>

Мне нужна только строка, начинающаяся с $1$ (строка 3 выше). Я полагаю, что это как-то связано с регулярным выражением, но я не могу понять, что.

Если я запускаю команду в интерактивном режиме с PuTTY, я получаю следующее:

user@PA-3020> request password-hash password test123

$1$pxqhdlco$MRsVusWtItC3QiMm4W.xZ1

user@PA-3020>

ОБНОВИТЬ:

В соответствии с предложениями от neubert ниже, замена строки на $output = $ssh->read... следующим кодом работает:

$output = $ssh->read('/\$1\$.*/', NET_SSH2_READ_REGEX);
$output = preg_replace('/.*\$1\$/s','\$1\$', $output);

person Caynadian    schedule 23.06.2014    source источник


Ответы (1)


Результаты, которые он возвращает, включают в себя кучу вещей, которых там быть не должно:

?[Kuser@PA-3020> запрос пароля-хэш-пароля test123 ?[?1h?=?[24;1H?[K $1$dgkhwrxe$kddYFmKCq9.zfiBKPAyN61

?[24;1H?[K?[?1l?>пользователь@PA-3020>

Это escape-коды ANSI. Вы можете использовать File_ANSI для их удаления. Больше информации:

http://phpseclib.sourceforge.net/ssh/examples.html#top

Во всяком случае, я предполагаю, что вам нужно переделать регулярное выражение. например.

$output = $ssh->read('/^\$1\$.*$/', NET_SSH2_READ_REGEX);

Вместо этого сделайте следующее:

$output = $ssh->read('/\$1\$/', NET_SSH2_READ_REGEX);

Дело в том, что... ^ соответствует началу строки, а $ соответствует концу. Обычно, когда вы делаете $ssh->write(...), команда возвращается к вам, а затем появляется новая строка, а затем вы получаете свой результат обратно. Так что это помешает ^ работать. А что касается $ в конце... ну, согласно вашему собственному примеру, $1$ не встречается в конце строки. Так вот почему ваш код не работает.

person neubert    schedule 23.06.2014
comment
Мне не нужно на самом деле обрабатывать escape-последовательности, поэтому я не думал, что мне понадобится модуль File_ANSI. Когда я использую предоставленное вами регулярное выражение, я получаю следующее: ←[Kchris@PA-3020› запрос пароля-хэша пароля test123 ←[?1h ←= ←[24;1H ←[K $1$ - person Caynadian; 23.06.2014
comment
Похоже, вы получили 1 доллар, который хотели. Или вам нужна вся линия, на которой стоит $1$? Если да, то \$1\$.*$ может сработать. Глядя на ваш код еще раз, я думаю, у вас действительно было .* между двумя $, поэтому я думаю, что оговорился, когда сказал, что $ в конце строки не будет работать.. - person neubert; 23.06.2014
comment
Мне нужна вся эта строка и ничего, предшествующее $1$. Я пытаюсь получить строку $1$dgkhwrxe$kddYFmKCq9.zfiBKPAyN61 в приведенном выше примере. - person Caynadian; 23.06.2014
comment
$ssh->read() вернет все, что предшествует регулярному выражению. Если вы хотите удалить символы перед $1$, вам нужно будет сделать это за пределами read. например. preg_replace('#.*\$1\$#','\$1\$', $ssh->read('#\$1\$.*$#')) - person neubert; 23.06.2014
comment
Спасибо! Ваш код с добавлением опции regex s (например: '#.*\$1\$#s') сработал! Не знаю, зачем нужна опция s. - person Caynadian; 23.06.2014