SSH2: keyboard-interactive changes

Let's say your SSH server had a two-part keyboard-interactive auth. One prompt is for "Password" and the other is for "Verification code". Previously you'd have to do this:

$ssh->login($username, 'pass1', 'code1');

It'd try password authentication with pass1, fail, then do keyboard-interactive with pass1 and then keyboard-interacitve with code1.

ie. the order in which it tried stuff was dependent on the order it was past to the Net_SSH2 object.  And it'd always try password auth first.

Now you can go straight to keyboard-interactive and mix the order as follows:

$ssh->login($username, array('Password' => 'pass1'), array('Verification code' => 'code1'));
This commit is contained in:
terrafrost 2013-04-20 14:35:08 -05:00
parent 04c24f6bbc
commit e0abab9bb4
1 changed files with 42 additions and 8 deletions

View File

@ -744,6 +744,14 @@ class Net_SSH2 {
*/
var $last_interactive_response = '';
/**
* Keyboard Interactive Request / Responses
*
* @see Net_SSH2::_keyboard_interactive_process()
* @access private
*/
var $keyboard_requests_responses = array();
/**
* Default Constructor.
*
@ -1476,6 +1484,7 @@ class Net_SSH2 {
if (empty($args)) {
return $this->_login_helper($username);
}
foreach ($args as $arg) {
if ($this->_login_helper($username, $arg)) {
return true;
@ -1525,7 +1534,7 @@ class Net_SSH2 {
}
if (strlen($this->last_interactive_response)) {
return !is_string($password) ? false : $this->_keyboard_interactive_process($password);
return !is_string($password) && !is_array($password) ? false : $this->_keyboard_interactive_process($password);
}
// although PHP5's get_class() preserves the case, PHP4's does not
@ -1533,6 +1542,14 @@ class Net_SSH2 {
return $this->_privatekey_login($username, $password);
}
if (is_array($password)) {
if ($this->_keyboard_interactive_login($username, $password)) {
$this->bitmap |= NET_SSH2_MASK_LOGIN;
return true;
}
return false;
}
if (!isset($password)) {
$packet = pack('CNa*Na*Na*',
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
@ -1675,14 +1692,31 @@ class Net_SSH2 {
extract(unpack('Nlength', $this->_string_shift($response, 4)));
$this->_string_shift($response, $length); // language tag; may be empty
extract(unpack('Nnum_prompts', $this->_string_shift($response, 4)));
/*
for ($i = 0; $i < $num_prompts; $i++) {
extract(unpack('Nlength', $this->_string_shift($response, 4)));
// prompt - ie. "Password: "; must not be empty
$this->_string_shift($response, $length);
$echo = $this->_string_shift($response) != chr(0);
for ($i = 0; $i < count($responses); $i++) {
if (is_array($responses[$i])) {
foreach ($responses[$i] as $key => $value) {
$this->keyboard_requests_responses[$key] = $value;
}
unset($responses[$i]);
}
}
$responses = array_values($responses);
if (isset($this->keyboard_requests_responses)) {
for ($i = 0; $i < $num_prompts; $i++) {
extract(unpack('Nlength', $this->_string_shift($response, 4)));
// prompt - ie. "Password: "; must not be empty
$prompt = $this->_string_shift($response, $length);
//$echo = $this->_string_shift($response) != chr(0);
foreach ($this->keyboard_requests_responses as $key => $value) {
if (substr($prompt, 0, strlen($key)) == $key) {
$responses[] = $value;
break;
}
}
}
}
*/
// see http://tools.ietf.org/html/rfc4256#section-3.2
if (strlen($this->last_interactive_response)) {