mirror of
https://github.com/danog/tgseclib.git
synced 2024-12-04 18:48:37 +01:00
Merge branch '2.0'
This commit is contained in:
commit
e34e5f5135
@ -303,6 +303,9 @@ class SCP
|
|||||||
$response = $this->ssh->_get_binary_packet();
|
$response = $this->ssh->_get_binary_packet();
|
||||||
switch ($response[SSH1::RESPONSE_TYPE]) {
|
switch ($response[SSH1::RESPONSE_TYPE]) {
|
||||||
case NET_SSH1_SMSG_STDOUT_DATA:
|
case NET_SSH1_SMSG_STDOUT_DATA:
|
||||||
|
if (strlen($response[SSH1::RESPONSE_DATA]) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
|
extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
|
||||||
return Strings::shift($response[SSH1::RESPONSE_DATA], $length);
|
return Strings::shift($response[SSH1::RESPONSE_DATA], $length);
|
||||||
case NET_SSH1_SMSG_STDERR_DATA:
|
case NET_SSH1_SMSG_STDERR_DATA:
|
||||||
|
@ -476,11 +476,20 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_VERSION');
|
throw new \UnexpectedValueException('Expected SSH_FXP_VERSION');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nversion', Strings::shift($response, 4)));
|
extract(unpack('Nversion', Strings::shift($response, 4)));
|
||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
while (!empty($response)) {
|
while (!empty($response)) {
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$key = Strings::shift($response, $length);
|
$key = Strings::shift($response, $length);
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$value = Strings::shift($response, $length);
|
$value = Strings::shift($response, $length);
|
||||||
$this->extensions[$key] = $value;
|
$this->extensions[$key] = $value;
|
||||||
@ -591,12 +600,15 @@ class SFTP extends SSH2
|
|||||||
function _logError($response, $status = -1)
|
function _logError($response, $status = -1)
|
||||||
{
|
{
|
||||||
if ($status == -1) {
|
if ($status == -1) {
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = $this->status_codes[$status];
|
$error = $this->status_codes[$status];
|
||||||
|
|
||||||
if ($this->version > 2) {
|
if ($this->version > 2 || strlen($response) < 4) {
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$this->sftp_errors[] = $error . ': ' . Strings::shift($response, $length);
|
$this->sftp_errors[] = $error . ': ' . Strings::shift($response, $length);
|
||||||
} else {
|
} else {
|
||||||
@ -646,6 +658,9 @@ class SFTP extends SSH2
|
|||||||
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
|
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
|
||||||
// at is the first part and that part is defined the same in SFTP versions 3 through 6.
|
// at is the first part and that part is defined the same in SFTP versions 3 through 6.
|
||||||
Strings::shift($response, 4); // skip over the count - it should be 1, anyway
|
Strings::shift($response, 4); // skip over the count - it should be 1, anyway
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
return Strings::shift($response, $length);
|
return Strings::shift($response, $length);
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
@ -879,10 +894,19 @@ class SFTP extends SSH2
|
|||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
switch ($this->packet_type) {
|
switch ($this->packet_type) {
|
||||||
case NET_SFTP_NAME:
|
case NET_SFTP_NAME:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ncount', Strings::shift($response, 4)));
|
extract(unpack('Ncount', Strings::shift($response, 4)));
|
||||||
for ($i = 0; $i < $count; $i++) {
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$shortname = Strings::shift($response, $length);
|
$shortname = Strings::shift($response, $length);
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$longname = Strings::shift($response, $length);
|
$longname = Strings::shift($response, $length);
|
||||||
$attributes = $this->_parseAttributes($response);
|
$attributes = $this->_parseAttributes($response);
|
||||||
@ -909,6 +933,9 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_EOF) {
|
if ($status != NET_SFTP_STATUS_EOF) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -1502,6 +1529,9 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -1614,12 +1644,18 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ncount', Strings::shift($response, 4)));
|
extract(unpack('Ncount', Strings::shift($response, 4)));
|
||||||
// the file isn't a symlink
|
// the file isn't a symlink
|
||||||
if (!$count) {
|
if (!$count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
return Strings::shift($response, $length);
|
return Strings::shift($response, $length);
|
||||||
}
|
}
|
||||||
@ -1654,7 +1690,11 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
|
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
return false;
|
return false;
|
||||||
@ -1717,6 +1757,9 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -1754,6 +1797,9 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
|
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
|
||||||
@ -1980,6 +2026,9 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -2011,6 +2060,9 @@ class SFTP extends SSH2
|
|||||||
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -2210,6 +2262,9 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -2635,6 +2690,9 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
extract(unpack('Nstatus', Strings::shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
$this->_logError($response, $status);
|
$this->_logError($response, $status);
|
||||||
@ -2662,6 +2720,10 @@ class SFTP extends SSH2
|
|||||||
function _parseAttributes(&$response)
|
function _parseAttributes(&$response)
|
||||||
{
|
{
|
||||||
$attr = array();
|
$attr = array();
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return array();
|
||||||
|
}
|
||||||
extract(unpack('Nflags', Strings::shift($response, 4)));
|
extract(unpack('Nflags', Strings::shift($response, 4)));
|
||||||
// SFTPv4+ have a type field (a byte) that follows the above flag field
|
// SFTPv4+ have a type field (a byte) that follows the above flag field
|
||||||
foreach ($this->attributes as $key => $value) {
|
foreach ($this->attributes as $key => $value) {
|
||||||
@ -2676,9 +2738,17 @@ class SFTP extends SSH2
|
|||||||
$attr['size'] = hexdec(Hex::encode(Strings::shift($response, 8)));
|
$attr['size'] = hexdec(Hex::encode(Strings::shift($response, 8)));
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
||||||
|
if (strlen($response) < 8) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
$attr+= unpack('Nuid/Ngid', Strings::shift($response, 8));
|
$attr+= unpack('Nuid/Ngid', Strings::shift($response, 8));
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
|
case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
$attr+= unpack('Npermissions', Strings::shift($response, 4));
|
$attr+= unpack('Npermissions', Strings::shift($response, 4));
|
||||||
// mode == permissions; permissions was the original array key and is retained for bc purposes.
|
// mode == permissions; permissions was the original array key and is retained for bc purposes.
|
||||||
// mode was added because that's the more industry standard terminology
|
// mode was added because that's the more industry standard terminology
|
||||||
@ -2689,13 +2759,29 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
|
case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
|
||||||
|
if (strlen($response) < 8) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
$attr+= unpack('Natime/Nmtime', Strings::shift($response, 8));
|
$attr+= unpack('Natime/Nmtime', Strings::shift($response, 8));
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_EXTENDED: // 0x80000000
|
case NET_SFTP_ATTR_EXTENDED: // 0x80000000
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
extract(unpack('Ncount', Strings::shift($response, 4)));
|
extract(unpack('Ncount', Strings::shift($response, 4)));
|
||||||
for ($i = 0; $i < $count; $i++) {
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$key = Strings::shift($response, $length);
|
$key = Strings::shift($response, $length);
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
//user_error('Malformed file attributes');
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$attr[$key] = Strings::shift($response, $length);
|
$attr[$key] = Strings::shift($response, $length);
|
||||||
}
|
}
|
||||||
@ -2849,6 +2935,9 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
$this->packet_buffer.= $temp;
|
$this->packet_buffer.= $temp;
|
||||||
}
|
}
|
||||||
|
if (strlen($this->packet_buffer) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4)));
|
extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4)));
|
||||||
$tempLength = $length;
|
$tempLength = $length;
|
||||||
$tempLength-= strlen($this->packet_buffer);
|
$tempLength-= strlen($this->packet_buffer);
|
||||||
|
@ -575,28 +575,46 @@ class SSH1
|
|||||||
|
|
||||||
Strings::shift($response[self::RESPONSE_DATA], 4);
|
Strings::shift($response[self::RESPONSE_DATA], 4);
|
||||||
|
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
||||||
$server_key_public_exponent = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
$server_key_public_exponent = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||||
$this->server_key_public_exponent = $server_key_public_exponent;
|
$this->server_key_public_exponent = $server_key_public_exponent;
|
||||||
|
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
||||||
$server_key_public_modulus = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
$server_key_public_modulus = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||||
|
|
||||||
$this->server_key_public_modulus = $server_key_public_modulus;
|
$this->server_key_public_modulus = $server_key_public_modulus;
|
||||||
|
|
||||||
Strings::shift($response[self::RESPONSE_DATA], 4);
|
Strings::shift($response[self::RESPONSE_DATA], 4);
|
||||||
|
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
||||||
$host_key_public_exponent = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
$host_key_public_exponent = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||||
$this->host_key_public_exponent = $host_key_public_exponent;
|
$this->host_key_public_exponent = $host_key_public_exponent;
|
||||||
|
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
$temp = unpack('nlen', Strings::shift($response[self::RESPONSE_DATA], 2));
|
||||||
$host_key_public_modulus = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
$host_key_public_modulus = new BigInteger(Strings::shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||||
|
|
||||||
$this->host_key_public_modulus = $host_key_public_modulus;
|
$this->host_key_public_modulus = $host_key_public_modulus;
|
||||||
|
|
||||||
Strings::shift($response[self::RESPONSE_DATA], 4);
|
Strings::shift($response[self::RESPONSE_DATA], 4);
|
||||||
|
|
||||||
// get a list of the supported ciphers
|
// get a list of the supported ciphers
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nsupported_ciphers_mask', Strings::shift($response[self::RESPONSE_DATA], 4)));
|
extract(unpack('Nsupported_ciphers_mask', Strings::shift($response[self::RESPONSE_DATA], 4)));
|
||||||
|
|
||||||
foreach ($this->supported_ciphers as $mask => $name) {
|
foreach ($this->supported_ciphers as $mask => $name) {
|
||||||
if (($supported_ciphers_mask & (1 << $mask)) == 0) {
|
if (($supported_ciphers_mask & (1 << $mask)) == 0) {
|
||||||
unset($this->supported_ciphers[$mask]);
|
unset($this->supported_ciphers[$mask]);
|
||||||
@ -604,6 +622,9 @@ class SSH1
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get a list of the supported authentications
|
// get a list of the supported authentications
|
||||||
|
if (strlen($response[self::RESPONSE_DATA]) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nsupported_authentications_mask', Strings::shift($response[self::RESPONSE_DATA], 4)));
|
extract(unpack('Nsupported_authentications_mask', Strings::shift($response[self::RESPONSE_DATA], 4)));
|
||||||
foreach ($this->supported_authentications as $mask => $name) {
|
foreach ($this->supported_authentications as $mask => $name) {
|
||||||
if (($supported_authentications_mask & (1 << $mask)) == 0) {
|
if (($supported_authentications_mask & (1 << $mask)) == 0) {
|
||||||
@ -1085,7 +1106,11 @@ class SSH1
|
|||||||
}
|
}
|
||||||
|
|
||||||
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
||||||
$temp = unpack('Nlength', fread($this->fsock, 4));
|
$data = fread($this->fsock, 4);
|
||||||
|
if (strlen($data) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$temp = unpack('Nlength', $data);
|
||||||
|
|
||||||
$padding_length = 8 - ($temp['length'] & 7);
|
$padding_length = 8 - ($temp['length'] & 7);
|
||||||
$length = $temp['length'] + $padding_length;
|
$length = $temp['length'] + $padding_length;
|
||||||
@ -1106,6 +1131,9 @@ class SSH1
|
|||||||
$type = $raw[$padding_length];
|
$type = $raw[$padding_length];
|
||||||
$data = substr($raw, $padding_length + 1, -4);
|
$data = substr($raw, $padding_length + 1, -4);
|
||||||
|
|
||||||
|
if (strlen($raw) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Ncrc', substr($raw, -4));
|
$temp = unpack('Ncrc', substr($raw, -4));
|
||||||
|
|
||||||
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
|
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
|
||||||
|
@ -1121,7 +1121,7 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,37 +1320,71 @@ class SSH2
|
|||||||
Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
|
Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
|
||||||
$server_cookie = Strings::shift($response, 16);
|
$server_cookie = Strings::shift($response, 16);
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->kex_algorithms = explode(',', Strings::shift($response, $temp['length']));
|
$this->kex_algorithms = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->server_host_key_algorithms = explode(',', Strings::shift($response, $temp['length']));
|
$this->server_host_key_algorithms = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->encryption_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
$this->encryption_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->encryption_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
$this->encryption_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->mac_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
$this->mac_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->mac_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
$this->mac_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->compression_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
$this->compression_algorithms_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->compression_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
$this->compression_algorithms_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->languages_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
$this->languages_client_to_server = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->languages_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
$this->languages_server_to_client = explode(',', Strings::shift($response, $temp['length']));
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Cfirst_kex_packet_follows', Strings::shift($response, 1)));
|
extract(unpack('Cfirst_kex_packet_follows', Strings::shift($response, 1)));
|
||||||
|
|
||||||
$first_kex_packet_follows = $first_kex_packet_follows != 0;
|
$first_kex_packet_follows = $first_kex_packet_follows != 0;
|
||||||
|
|
||||||
// the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
|
// the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
|
||||||
@ -1449,10 +1483,16 @@ class SSH2
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('NprimeLength', Strings::shift($response, 4)));
|
extract(unpack('NprimeLength', Strings::shift($response, 4)));
|
||||||
$primeBytes = Strings::shift($response, $primeLength);
|
$primeBytes = Strings::shift($response, $primeLength);
|
||||||
$prime = new BigInteger($primeBytes, -256);
|
$prime = new BigInteger($primeBytes, -256);
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('NgLength', Strings::shift($response, 4)));
|
extract(unpack('NgLength', Strings::shift($response, 4)));
|
||||||
$gBytes = Strings::shift($response, $gLength);
|
$gBytes = Strings::shift($response, $gLength);
|
||||||
$g = new BigInteger($gBytes, -256);
|
$g = new BigInteger($gBytes, -256);
|
||||||
@ -1533,24 +1573,42 @@ class SSH2
|
|||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
if ($type != $serverKexReplyMessage) {
|
if ($type != $serverKexReplyMessage) {
|
||||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->server_public_host_key = $server_public_host_key = Strings::shift($response, $temp['length']);
|
$this->server_public_host_key = $server_public_host_key = Strings::shift($response, $temp['length']);
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$public_key_format = Strings::shift($server_public_host_key, $temp['length']);
|
$public_key_format = Strings::shift($server_public_host_key, $temp['length']);
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$fBytes = Strings::shift($response, $temp['length']);
|
$fBytes = Strings::shift($response, $temp['length']);
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($response, 4));
|
$temp = unpack('Nlength', Strings::shift($response, 4));
|
||||||
$this->signature = Strings::shift($response, $temp['length']);
|
$this->signature = Strings::shift($response, $temp['length']);
|
||||||
|
|
||||||
|
if (strlen($this->signature) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($this->signature, 4));
|
$temp = unpack('Nlength', Strings::shift($this->signature, 4));
|
||||||
$this->signature_format = Strings::shift($this->signature, $temp['length']);
|
$this->signature_format = Strings::shift($this->signature, $temp['length']);
|
||||||
|
|
||||||
@ -1620,6 +1678,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
||||||
@ -1954,6 +2015,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
||||||
@ -2001,6 +2065,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
@ -2055,6 +2122,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
@ -2062,14 +2132,25 @@ class SSH2
|
|||||||
if (defined('NET_SSH2_LOGGING')) {
|
if (defined('NET_SSH2_LOGGING')) {
|
||||||
$this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ';
|
$this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode(Strings::shift($response, $length));
|
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode(Strings::shift($response, $length));
|
||||||
|
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
||||||
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
||||||
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
||||||
// multi-factor authentication
|
// multi-factor authentication
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$auth_methods = explode(',', Strings::shift($response, $length));
|
$auth_methods = explode(',', Strings::shift($response, $length));
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Cpartial_success', Strings::shift($response, 1)));
|
extract(unpack('Cpartial_success', Strings::shift($response, 1)));
|
||||||
$partial_success = $partial_success != 0;
|
$partial_success = $partial_success != 0;
|
||||||
|
|
||||||
@ -2144,16 +2225,31 @@ class SSH2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case NET_SSH2_MSG_USERAUTH_INFO_REQUEST:
|
case NET_SSH2_MSG_USERAUTH_INFO_REQUEST:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
Strings::shift($response, $length); // name; may be empty
|
Strings::shift($response, $length); // name; may be empty
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
Strings::shift($response, $length); // instruction; may be empty
|
Strings::shift($response, $length); // instruction; may be empty
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
Strings::shift($response, $length); // language tag; may be empty
|
Strings::shift($response, $length); // language tag; may be empty
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nnum_prompts', Strings::shift($response, 4)));
|
extract(unpack('Nnum_prompts', Strings::shift($response, 4)));
|
||||||
|
|
||||||
for ($i = 0; $i < count($responses); $i++) {
|
for ($i = 0; $i < count($responses); $i++) {
|
||||||
@ -2168,6 +2264,9 @@ class SSH2
|
|||||||
|
|
||||||
if (isset($this->keyboard_requests_responses)) {
|
if (isset($this->keyboard_requests_responses)) {
|
||||||
for ($i = 0; $i < $num_prompts; $i++) {
|
for ($i = 0; $i < $num_prompts; $i++) {
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
// prompt - ie. "Password: "; must not be empty
|
// prompt - ie. "Password: "; must not be empty
|
||||||
$prompt = Strings::shift($response, $length);
|
$prompt = Strings::shift($response, $length);
|
||||||
@ -2313,12 +2412,19 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . Strings::shift($response, $length);
|
$this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . Strings::shift($response, $length);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case NET_SSH2_MSG_USERAUTH_PK_OK:
|
case NET_SSH2_MSG_USERAUTH_PK_OK:
|
||||||
// we'll just take it on faith that the public key blob and the public key algorithm name are as
|
// we'll just take it on faith that the public key blob and the public key algorithm name are as
|
||||||
@ -2347,6 +2453,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
@ -2465,6 +2574,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
list(, $type) = unpack('C', Strings::shift($response, 1));
|
list(, $type) = unpack('C', Strings::shift($response, 1));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
@ -2602,6 +2714,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
list(, $type) = unpack('C', Strings::shift($response, 1));
|
list(, $type) = unpack('C', Strings::shift($response, 1));
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
@ -2935,6 +3050,9 @@ class SSH2
|
|||||||
throw new \RuntimeException('Unable to decrypt content');
|
throw new \RuntimeException('Unable to decrypt content');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($raw) < 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5)));
|
extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5)));
|
||||||
|
|
||||||
$remaining_length = $packet_length + 4 - $this->decrypt_block_size;
|
$remaining_length = $packet_length + 4 - $this->decrypt_block_size;
|
||||||
@ -3006,6 +3124,9 @@ class SSH2
|
|||||||
switch (ord($payload[0])) {
|
switch (ord($payload[0])) {
|
||||||
case NET_SSH2_MSG_DISCONNECT:
|
case NET_SSH2_MSG_DISCONNECT:
|
||||||
Strings::shift($payload, 1);
|
Strings::shift($payload, 1);
|
||||||
|
if (strlen($payload) < 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nreason_code/Nlength', Strings::shift($payload, 8)));
|
extract(unpack('Nreason_code/Nlength', Strings::shift($payload, 8)));
|
||||||
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode(Strings::shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode(Strings::shift($payload, $length));
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
@ -3015,6 +3136,9 @@ class SSH2
|
|||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_DEBUG:
|
case NET_SSH2_MSG_DEBUG:
|
||||||
Strings::shift($payload, 2);
|
Strings::shift($payload, 2);
|
||||||
|
if (strlen($payload) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
||||||
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode(Strings::shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode(Strings::shift($payload, $length));
|
||||||
$payload = $this->_get_binary_packet();
|
$payload = $this->_get_binary_packet();
|
||||||
@ -3034,6 +3158,9 @@ class SSH2
|
|||||||
// see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
|
// see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
|
||||||
if (($this->bitmap & self::MASK_CONNECTED) && !($this->bitmap & self::MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
if (($this->bitmap & self::MASK_CONNECTED) && !($this->bitmap & self::MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
||||||
Strings::shift($payload, 1);
|
Strings::shift($payload, 1);
|
||||||
|
if (strlen($payload) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
||||||
$this->banner_message = utf8_decode(Strings::shift($payload, $length));
|
$this->banner_message = utf8_decode(Strings::shift($payload, $length));
|
||||||
$payload = $this->_get_binary_packet();
|
$payload = $this->_get_binary_packet();
|
||||||
@ -3043,6 +3170,9 @@ class SSH2
|
|||||||
if (($this->bitmap & self::MASK_CONNECTED) && ($this->bitmap & self::MASK_LOGIN)) {
|
if (($this->bitmap & self::MASK_CONNECTED) && ($this->bitmap & self::MASK_LOGIN)) {
|
||||||
switch (ord($payload[0])) {
|
switch (ord($payload[0])) {
|
||||||
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
|
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
|
||||||
|
if (strlen($payload) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
||||||
$this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . Strings::shift($payload, $length);
|
$this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . Strings::shift($payload, $length);
|
||||||
|
|
||||||
@ -3054,8 +3184,14 @@ class SSH2
|
|||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
|
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
|
||||||
Strings::shift($payload, 1);
|
Strings::shift($payload, 1);
|
||||||
|
if (strlen($payload) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
extract(unpack('Nlength', Strings::shift($payload, 4)));
|
||||||
$data = Strings::shift($payload, $length);
|
$data = Strings::shift($payload, $length);
|
||||||
|
if (strlen($payload) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nserver_channel', Strings::shift($payload, 4)));
|
extract(unpack('Nserver_channel', Strings::shift($payload, 4)));
|
||||||
switch ($data) {
|
switch ($data) {
|
||||||
case 'auth-agent':
|
case 'auth-agent':
|
||||||
@ -3063,6 +3199,9 @@ class SSH2
|
|||||||
if (isset($this->agent)) {
|
if (isset($this->agent)) {
|
||||||
$new_channel = self::CHANNEL_AGENT_FORWARD;
|
$new_channel = self::CHANNEL_AGENT_FORWARD;
|
||||||
|
|
||||||
|
if (strlen($payload) < 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nremote_window_size', Strings::shift($payload, 4)));
|
extract(unpack('Nremote_window_size', Strings::shift($payload, 4)));
|
||||||
extract(unpack('Nremote_maximum_packet_size', Strings::shift($payload, 4)));
|
extract(unpack('Nremote_maximum_packet_size', Strings::shift($payload, 4)));
|
||||||
|
|
||||||
@ -3108,8 +3247,12 @@ class SSH2
|
|||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||||
Strings::shift($payload, 1);
|
Strings::shift($payload, 1);
|
||||||
|
if (strlen($payload) < 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nchannel', Strings::shift($payload, 4)));
|
extract(unpack('Nchannel', Strings::shift($payload, 4)));
|
||||||
extract(unpack('Nwindow_size', Strings::shift($payload, 4)));
|
extract(unpack('Nwindow_size', Strings::shift($payload, 4)));
|
||||||
|
|
||||||
$this->window_size_client_to_server[$channel]+= $window_size;
|
$this->window_size_client_to_server[$channel]+= $window_size;
|
||||||
|
|
||||||
$payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet();
|
$payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet();
|
||||||
@ -3238,8 +3381,14 @@ class SSH2
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strlen($response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ctype', Strings::shift($response, 1)));
|
extract(unpack('Ctype', Strings::shift($response, 1)));
|
||||||
|
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
|
if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
} else {
|
} else {
|
||||||
@ -3263,15 +3412,26 @@ class SSH2
|
|||||||
case NET_SSH2_MSG_CHANNEL_OPEN:
|
case NET_SSH2_MSG_CHANNEL_OPEN:
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
|
case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nserver_channel', Strings::shift($response, 4)));
|
extract(unpack('Nserver_channel', Strings::shift($response, 4)));
|
||||||
$this->server_channels[$channel] = $server_channel;
|
$this->server_channels[$channel] = $server_channel;
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nwindow_size', Strings::shift($response, 4)));
|
extract(unpack('Nwindow_size', Strings::shift($response, 4)));
|
||||||
|
|
||||||
if ($window_size < 0) {
|
if ($window_size < 0) {
|
||||||
$window_size&= 0x7FFFFFFF;
|
$window_size&= 0x7FFFFFFF;
|
||||||
$window_size+= 0x80000000;
|
$window_size+= 0x80000000;
|
||||||
}
|
}
|
||||||
$this->window_size_client_to_server[$channel] = $window_size;
|
$this->window_size_client_to_server[$channel] = $window_size;
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Npacket_size_client_to_server', Strings::shift($response, 4));
|
$temp = unpack('Npacket_size_client_to_server', Strings::shift($response, 4));
|
||||||
|
|
||||||
$this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
|
$this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
|
||||||
$result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
|
$result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
|
||||||
$this->_on_channel_open();
|
$this->_on_channel_open();
|
||||||
@ -3310,6 +3470,9 @@ class SSH2
|
|||||||
$this->_send_channel_packet($channel, chr(0));
|
$this->_send_channel_packet($channel, chr(0));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$data = Strings::shift($response, $length);
|
$data = Strings::shift($response, $length);
|
||||||
|
|
||||||
@ -3336,8 +3499,12 @@ class SSH2
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
|
// currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
|
||||||
|
if (strlen($response) < 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Ndata_type_code/Nlength', Strings::shift($response, 8)));
|
extract(unpack('Ndata_type_code/Nlength', Strings::shift($response, 8)));
|
||||||
$data = Strings::shift($response, $length);
|
$data = Strings::shift($response, $length);
|
||||||
|
|
||||||
$this->stdErrorLog.= $data;
|
$this->stdErrorLog.= $data;
|
||||||
if ($skip_extended || $this->quiet_mode) {
|
if ($skip_extended || $this->quiet_mode) {
|
||||||
break;
|
break;
|
||||||
@ -3351,13 +3518,22 @@ class SSH2
|
|||||||
$this->channel_buffers[$channel][] = $data;
|
$this->channel_buffers[$channel][] = $data;
|
||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$value = Strings::shift($response, $length);
|
$value = Strings::shift($response, $length);
|
||||||
switch ($value) {
|
switch ($value) {
|
||||||
case 'exit-signal':
|
case 'exit-signal':
|
||||||
Strings::shift($response, 1);
|
Strings::shift($response, 1);
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . Strings::shift($response, $length);
|
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . Strings::shift($response, $length);
|
||||||
|
if (strlen($response) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Strings::shift($response, 1);
|
Strings::shift($response, 1);
|
||||||
extract(unpack('Nlength', Strings::shift($response, 4)));
|
extract(unpack('Nlength', Strings::shift($response, 4)));
|
||||||
if ($length) {
|
if ($length) {
|
||||||
@ -3371,7 +3547,11 @@ class SSH2
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 'exit-status':
|
case 'exit-status':
|
||||||
|
if (strlen($response) < 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Cfalse/Nexit_status', Strings::shift($response, 5)));
|
extract(unpack('Cfalse/Nexit_status', Strings::shift($response, 5)));
|
||||||
|
|
||||||
$this->exit_status = $exit_status;
|
$this->exit_status = $exit_status;
|
||||||
|
|
||||||
// "The client MAY ignore these messages."
|
// "The client MAY ignore these messages."
|
||||||
@ -3983,6 +4163,9 @@ class SSH2
|
|||||||
$signature = $this->signature;
|
$signature = $this->signature;
|
||||||
$server_public_host_key = $this->server_public_host_key;
|
$server_public_host_key = $this->server_public_host_key;
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
extract(unpack('Nlength', Strings::shift($server_public_host_key, 4)));
|
extract(unpack('Nlength', Strings::shift($server_public_host_key, 4)));
|
||||||
Strings::shift($server_public_host_key, $length);
|
Strings::shift($server_public_host_key, $length);
|
||||||
|
|
||||||
@ -3998,15 +4181,27 @@ class SSH2
|
|||||||
case 'ssh-dss':
|
case 'ssh-dss':
|
||||||
$zero = new BigInteger();
|
$zero = new BigInteger();
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$p = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
$p = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$q = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
$q = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$g = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
$g = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$y = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
$y = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
@ -4053,15 +4248,24 @@ class SSH2
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 'ssh-rsa':
|
case 'ssh-rsa':
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$e = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
$e = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
|
||||||
|
|
||||||
|
if (strlen($server_public_host_key) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
$temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
|
||||||
$rawN = Strings::shift($server_public_host_key, $temp['length']);
|
$rawN = Strings::shift($server_public_host_key, $temp['length']);
|
||||||
$n = new BigInteger($rawN, -256);
|
$n = new BigInteger($rawN, -256);
|
||||||
$nLength = strlen(ltrim($rawN, "\0"));
|
$nLength = strlen(ltrim($rawN, "\0"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
if (strlen($signature) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($signature, 4));
|
$temp = unpack('Nlength', Strings::shift($signature, 4));
|
||||||
$signature = Strings::shift($signature, $temp['length']);
|
$signature = Strings::shift($signature, $temp['length']);
|
||||||
|
|
||||||
@ -4074,6 +4278,9 @@ class SSH2
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (strlen($signature) < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$temp = unpack('Nlength', Strings::shift($signature, 4));
|
$temp = unpack('Nlength', Strings::shift($signature, 4));
|
||||||
$s = new BigInteger(Strings::shift($signature, $temp['length']), 256);
|
$s = new BigInteger(Strings::shift($signature, $temp['length']), 256);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user